Clients can join the game mid-round

This commit is contained in:
Regalis
2017-01-12 20:41:21 +02:00
parent 81f3d24070
commit 08053bec85
3 changed files with 97 additions and 56 deletions
+61 -45
View File
@@ -463,33 +463,20 @@ namespace Barotrauma.Networking
#endif #endif
} }
if (gameStarted && respawnManager != null)
{
respawnManager.Update(deltaTime);
}
if (updateTimer > DateTime.Now) return; if (updateTimer > DateTime.Now) return;
if (myCharacter != null) if (gameStarted && Screen.Selected == GameMain.GameScreen)
{ {
if (myCharacter.IsDead) if (respawnManager != null)
{ {
//Character.Controlled = null; respawnManager.Update(deltaTime);
//GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
} }
else if (gameStarted) SendIngameUpdate();
{
}
}
if (!gameStarted)
{
SendLobbyUpdate();
} }
else else
{ {
SendIngameUpdate(); SendLobbyUpdate();
} }
// Update current time // Update current time
@@ -665,6 +652,49 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
private void ReadInitialUpdate(NetIncomingMessage inc, bool isDuplicate)
{
myID = inc.ReadByte();
UInt16 subListCount = inc.ReadUInt16();
List<Submarine> submarines = new List<Submarine>();
for (int i = 0; i < subListCount; i++)
{
string subName = inc.ReadString();
string subHash = inc.ReadString();
var matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == subName);
if (matchingSub != null)
{
submarines.Add(matchingSub);
}
else
{
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName), subHash, false));
}
}
if (!isDuplicate)
{
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines);
}
gameStarted = inc.ReadBoolean();
bool allowSpectating = inc.ReadBoolean();
if (gameStarted && !isDuplicate)
{
new GUIMessageBox("Please wait",
(allowSpectating) ?
"A round is already running, but you can spectate the game while waiting for a respawn shuttle or a new round." :
"A round is already running and the admin has disabled spectating. You will have to wait for a new round to start.");
GameMain.NetLobbyScreen.Select();
}
}
private void ReadLobbyUpdate(NetIncomingMessage inc) private void ReadLobbyUpdate(NetIncomingMessage inc)
{ {
ServerNetObject objHeader; ServerNetObject objHeader;
@@ -684,32 +714,7 @@ namespace Barotrauma.Networking
if (inc.ReadBoolean()) if (inc.ReadBoolean())
{ {
myID = inc.ReadByte(); ReadInitialUpdate(inc, updateID <= GameMain.NetLobbyScreen.LastUpdateID);
UInt16 subListCount = inc.ReadUInt16();
List<Submarine> submarines = new List<Submarine>();
for (int i = 0; i < subListCount; i++)
{
string subName = inc.ReadString();
string subHash = inc.ReadString();
var matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == subName);
if (matchingSub != null)
{
submarines.Add(matchingSub);
}
else
{
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName), subHash, false));
}
}
if (updateID > GameMain.NetLobbyScreen.LastUpdateID)
{
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines);
}
} }
string selectSubName = inc.ReadString(); string selectSubName = inc.ReadString();
@@ -999,6 +1004,17 @@ namespace Barotrauma.Networking
{ {
if (button != null) button.Enabled = false; if (button != null) button.Enabled = false;
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
readyToStartMsg.Write((byte)ClientPacketHeader.RESPONSE_STARTGAME);
//correct sub & shuttle files found
//TODO: check if they're actually found
readyToStartMsg.Write(true);
WriteCharacterInfo(readyToStartMsg);
client.SendMessage(readyToStartMsg, NetDeliveryMethod.ReliableUnordered);
return false; return false;
} }
+27 -10
View File
@@ -518,6 +518,12 @@ namespace Barotrauma.Networking
{ {
connectedClient.ReadyToStart = inc.ReadBoolean(); connectedClient.ReadyToStart = inc.ReadBoolean();
UpdateCharacterInfo(inc, connectedClient); UpdateCharacterInfo(inc, connectedClient);
//game already started -> send start message immediately
if (gameStarted)
{
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset, connectedClients);
}
} }
break; break;
case ClientPacketHeader.UPDATE_LOBBY: case ClientPacketHeader.UPDATE_LOBBY:
@@ -647,6 +653,25 @@ namespace Barotrauma.Networking
} }
} }
/// <summary>
/// Write info that the client needs when joining the server
/// </summary>
private void ClientWriteInitial(Client c, NetBuffer outmsg)
{
outmsg.Write(c.ID);
var subList = GameMain.NetLobbyScreen.GetSubList();
outmsg.Write((UInt16)subList.Count);
for (int i = 0; i < subList.Count; i++)
{
outmsg.Write(subList[i].Name);
outmsg.Write(subList[i].MD5Hash.ToString());
}
outmsg.Write(GameStarted);
outmsg.Write(AllowSpectating);
}
private void ClientWriteIngame(Client c) private void ClientWriteIngame(Client c)
{ {
NetOutgoingMessage outmsg = server.CreateMessage(); NetOutgoingMessage outmsg = server.CreateMessage();
@@ -721,19 +746,11 @@ namespace Barotrauma.Networking
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID); outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(GameMain.NetLobbyScreen.GetServerName()); outmsg.Write(GameMain.NetLobbyScreen.GetServerName());
outmsg.Write(GameMain.NetLobbyScreen.ServerMessage.Text); outmsg.Write(GameMain.NetLobbyScreen.ServerMessage.Text);
var subList = GameMain.NetLobbyScreen.GetSubList();
outmsg.Write(c.lastRecvGeneralUpdate < 1); outmsg.Write(c.lastRecvGeneralUpdate < 1);
if (c.lastRecvGeneralUpdate < 1) if (c.lastRecvGeneralUpdate < 1)
{ {
outmsg.Write(c.ID); ClientWriteInitial(c, outmsg);
outmsg.Write((UInt16)subList.Count);
for (int i = 0; i < subList.Count; i++)
{
outmsg.Write(subList[i].Name);
outmsg.Write(subList[i].MD5Hash.ToString());
}
} }
outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).Name); outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).Name);
outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).MD5Hash.ToString()); outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).MD5Hash.ToString());
@@ -388,11 +388,19 @@ namespace Barotrauma.Networking
var clients = GetClientsToRespawn(); var clients = GetClientsToRespawn();
foreach (Client c in clients)
{
if (c.characterInfo == null) c.characterInfo = new CharacterInfo(Character.HumanConfigFile, c.name);
}
List<CharacterInfo> characterInfos = clients.Select(c => c.characterInfo).ToList(); List<CharacterInfo> characterInfos = clients.Select(c => c.characterInfo).ToList();
if (server.Character != null && server.Character.IsDead) characterInfos.Add(server.CharacterInfo); if (server.Character != null && server.Character.IsDead) characterInfos.Add(server.CharacterInfo);
server.AssignJobs(clients, server.Character != null && server.Character.IsDead); server.AssignJobs(clients, server.Character != null && server.Character.IsDead);
clients.ForEach(c => c.characterInfo.Job = new Job(c.assignedJob)); foreach (Client c in clients)
{
c.characterInfo.Job = new Job(c.assignedJob);
}
//the spawnpoints where the characters will spawn //the spawnpoints where the characters will spawn
var shuttleSpawnPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, respawnShuttle); var shuttleSpawnPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, respawnShuttle);