From 037bd09c2cc9dccc5ef2fac429ba120a1eac39c7 Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 11 Jan 2017 21:31:19 +0200 Subject: [PATCH] - clients ignore lobby updates if they already received a more up-to-date one - server tells clients their ID in the first lobby update - clients take control of a spawned character if their ID matches the ownerID of the character (-> respawning works now) --- Subsurface/Source/Characters/Character.cs | 4 +- Subsurface/Source/Networking/GameClient.cs | 81 ++++++++++++---------- Subsurface/Source/Networking/GameServer.cs | 13 ++-- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 6146ad8cd..7586d6c05 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -2436,10 +2436,10 @@ namespace Barotrauma CharacterInfo ch = new CharacterInfo(configPath, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab); ch.HeadSpriteId = headSpriteID; - character = Character.Create(configPath, position, ch, GameMain.Client.MyCharacterID != id, hasAi); + character = Character.Create(configPath, position, ch, GameMain.Client.ID != ownerId, hasAi); character.ID = id; - if (GameMain.Client.MyCharacterID == id) + if (GameMain.Client.ID == ownerId) { GameMain.Client.Character = character; Controlled = character; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 66ed3eb0f..f8ab1c0ee 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -47,14 +47,7 @@ namespace Barotrauma.Networking { get { return myID; } } - - public ushort MyCharacterID - { - get; - private set; - } - - + public override List ConnectedClients { get @@ -435,12 +428,6 @@ namespace Barotrauma.Networking { if (Screen.Selected != GameMain.GameScreen) { - List subList = GameMain.NetLobbyScreen.GetSubList(); - - GameMain.NetLobbyScreen = new NetLobbyScreen(); - GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, subList); - GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, subList); - GameMain.NetLobbyScreen.Select(); } connected = true; @@ -597,9 +584,7 @@ namespace Barotrauma.Networking bool respawnAllowed = inc.ReadBoolean(); bool loadSecondSub = inc.ReadBoolean(); - - MyCharacterID = inc.ReadUInt16(); - + GameModePreset gameMode = GameModePreset.list.Find(gm => gm.Name == modeName); if (gameMode == null) @@ -690,18 +675,22 @@ namespace Barotrauma.Networking case ServerNetObject.SYNC_IDS: bool lobbyUpdated = inc.ReadBoolean(); inc.ReadPadBits(); + if (lobbyUpdated) { - GameMain.NetLobbyScreen.LastUpdateID = inc.ReadUInt32(); - GameMain.NetLobbyScreen.ServerName = inc.ReadString(); - GameMain.NetLobbyScreen.ServerMessage.Text = inc.ReadString(); - - UInt16 subListCount = inc.ReadUInt16(); - if (subListCount > 0) + UInt32 updateID = inc.ReadUInt32(); + string serverName = inc.ReadString(); + string serverText = inc.ReadString(); + + if (inc.ReadBoolean()) { + myID = inc.ReadByte(); + + UInt16 subListCount = inc.ReadUInt16(); List submarines = new List(); for (int i = 0; i < subListCount; i++) { + string subName = inc.ReadString(); string subHash = inc.ReadString(); @@ -715,28 +704,48 @@ namespace Barotrauma.Networking submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName), subHash, false)); } } - GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines); - GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines); + + 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 selectSubHash = inc.ReadString(); - GameMain.NetLobbyScreen.TrySelectSub(selectSubName, selectSubHash, GameMain.NetLobbyScreen.SubList); - string selectShuttleName = inc.ReadString(); - string selectShuttleHash = inc.ReadString(); - GameMain.NetLobbyScreen.TrySelectSub(selectShuttleName, selectShuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox); - GameMain.NetLobbyScreen.SetTraitorsEnabled((YesNoMaybe)inc.ReadRangedInteger(0, 2)); + string selectSubName = inc.ReadString(); + string selectSubHash = inc.ReadString(); - GameMain.NetLobbyScreen.SetMissionType(inc.ReadRangedInteger(0, Mission.MissionTypes.Count - 1)); + string selectShuttleName = inc.ReadString(); + string selectShuttleHash = inc.ReadString(); - GameMain.NetLobbyScreen.SelectMode(inc.ReadByte()); + YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2); + int missionTypeIndex = inc.ReadRangedInteger(0, Mission.MissionTypes.Count - 1); + int modeIndex = inc.ReadByte(); - GameMain.NetLobbyScreen.LevelSeed = inc.ReadString(); + string levelSeed = inc.ReadString(); bool autoRestartEnabled = inc.ReadBoolean(); float autoRestartTimer = autoRestartEnabled ? inc.ReadFloat() : 0.0f; - GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer); + //ignore the message if we already a more up-to-date one + if (updateID > GameMain.NetLobbyScreen.LastUpdateID) + { + GameMain.NetLobbyScreen.LastUpdateID = updateID; + + GameMain.NetLobbyScreen.ServerName = serverName; + GameMain.NetLobbyScreen.ServerMessage.Text = serverText; + + GameMain.NetLobbyScreen.TrySelectSub(selectSubName, selectSubHash, GameMain.NetLobbyScreen.SubList); + GameMain.NetLobbyScreen.TrySelectSub(selectShuttleName, selectShuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox); + + GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled); + GameMain.NetLobbyScreen.SetMissionType(missionTypeIndex); + GameMain.NetLobbyScreen.SelectMode(modeIndex); + + GameMain.NetLobbyScreen.LevelSeed = levelSeed; + + GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer); + } } lastSentChatMsgID = inc.ReadUInt32(); break; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 91d1b45cb..97d762192 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -717,12 +717,17 @@ namespace Barotrauma.Networking { outmsg.Write(true); outmsg.WritePadBits(); + outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID); outmsg.Write(GameMain.NetLobbyScreen.GetServerName()); outmsg.Write(GameMain.NetLobbyScreen.ServerMessage.Text); var subList = GameMain.NetLobbyScreen.GetSubList(); + + outmsg.Write(c.lastRecvGeneralUpdate < 1); if (c.lastRecvGeneralUpdate < 1) { + outmsg.Write(c.ID); + outmsg.Write((UInt16)subList.Count); for (int i = 0; i < subList.Count; i++) { @@ -730,10 +735,6 @@ namespace Barotrauma.Networking outmsg.Write(subList[i].MD5Hash.ToString()); } } - else - { - outmsg.Write((UInt16)0); - } outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).Name); outmsg.Write((GameMain.NetLobbyScreen.SubList.SelectedData as Submarine).MD5Hash.ToString()); outmsg.Write((GameMain.NetLobbyScreen.ShuttleList.SelectedData as Submarine).Name); @@ -1009,9 +1010,7 @@ namespace Barotrauma.Networking msg.Write(AllowRespawn && missionAllowRespawn); msg.Write(Submarine.MainSubs[1] != null); //loadSecondSub - - msg.Write(client.Character.ID); - + server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered); }