Fixed clients not being notified when a campaign is exited and a new one started, causing them to think they still have up-to-date save files for the new campaign and get kicked out due to desync as soon as a round starts. (See #315)

This commit is contained in:
Joonas Rikkonen
2018-03-06 14:18:37 +02:00
parent 8e8b8464af
commit 08ade1dc6f
3 changed files with 28 additions and 4 deletions
@@ -1073,6 +1073,7 @@ namespace Barotrauma.Networking
else else
{ {
outmsg.Write(campaign.LastSaveID); outmsg.Write(campaign.LastSaveID);
outmsg.Write(campaign.CampaignID);
outmsg.Write(campaign.LastUpdateID); outmsg.Write(campaign.LastUpdateID);
} }
@@ -30,9 +30,18 @@ namespace Barotrauma
set; set;
} }
private static byte currentCampaignID;
public byte CampaignID
{
get; private set;
}
public MultiplayerCampaign(GameModePreset preset, object param) : public MultiplayerCampaign(GameModePreset preset, object param) :
base(preset, param) base(preset, param)
{ {
currentCampaignID++;
CampaignID = currentCampaignID;
} }
#if CLIENT #if CLIENT
@@ -303,6 +312,7 @@ namespace Barotrauma
{ {
System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue); System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue);
msg.Write(CampaignID);
msg.Write(lastUpdateID); msg.Write(lastUpdateID);
msg.Write(lastSaveID); msg.Write(lastSaveID);
msg.Write(map.Seed); msg.Write(map.Seed);
@@ -319,10 +329,10 @@ namespace Barotrauma
} }
#if CLIENT #if CLIENT
//static because we may need to instantiate the campaign if it hasn't been done yet
public static void ClientRead(NetBuffer msg) public static void ClientRead(NetBuffer msg)
{ {
//static because we may need to instantiate the campaign if it hasn't been done yet byte campaignID = msg.ReadByte();
UInt16 updateID = msg.ReadUInt16(); UInt16 updateID = msg.ReadUInt16();
UInt16 saveID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16();
string mapSeed = msg.ReadString(); string mapSeed = msg.ReadString();
@@ -333,20 +343,21 @@ namespace Barotrauma
UInt16 purchasedItemCount = msg.ReadUInt16(); UInt16 purchasedItemCount = msg.ReadUInt16();
List<ItemPrefab> purchasedItems = new List<ItemPrefab>(); List<ItemPrefab> purchasedItems = new List<ItemPrefab>();
for (int i = 0; i<purchasedItemCount; i++) for (int i = 0; i < purchasedItemCount; i++)
{ {
UInt16 itemPrefabIndex = msg.ReadUInt16(); UInt16 itemPrefabIndex = msg.ReadUInt16();
purchasedItems.Add(MapEntityPrefab.List[itemPrefabIndex] as ItemPrefab); purchasedItems.Add(MapEntityPrefab.List[itemPrefabIndex] as ItemPrefab);
} }
MultiplayerCampaign campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign; MultiplayerCampaign campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
if (campaign == null || mapSeed != campaign.Map.Seed) if (campaign == null || campaignID != campaign.CampaignID)
{ {
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.list.Find(g => g.Name == "Campaign")); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.list.Find(g => g.Name == "Campaign"));
campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode); campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode);
campaign.CampaignID = campaignID;
campaign.GenerateMap(mapSeed); campaign.GenerateMap(mapSeed);
} }
@@ -605,7 +605,19 @@ namespace Barotrauma.Networking
c.LastRecvCampaignSave = inc.ReadUInt16(); c.LastRecvCampaignSave = inc.ReadUInt16();
if (c.LastRecvCampaignSave > 0) if (c.LastRecvCampaignSave > 0)
{ {
byte campaignID = inc.ReadByte();
c.LastRecvCampaignUpdate = inc.ReadUInt16(); c.LastRecvCampaignUpdate = inc.ReadUInt16();
if (GameMain.GameSession?.GameMode is MultiplayerCampaign)
{
//the client has a campaign save for another campaign
//(the server started a new campaign and the client isn't aware of it yet?)
if (((MultiplayerCampaign)GameMain.GameSession.GameMode).CampaignID != campaignID)
{
c.LastRecvCampaignSave = 0;
c.LastRecvCampaignUpdate = 0;
}
}
} }
break; break;
case ClientNetObject.CHAT_MESSAGE: case ClientNetObject.CHAT_MESSAGE: