Syncing campaign state & save files with clients (WIP)

This commit is contained in:
Joonas Rikkonen
2017-09-11 21:32:48 +03:00
parent 51cfef214c
commit 63bca3c7ea
13 changed files with 383 additions and 107 deletions
@@ -497,17 +497,22 @@ namespace Barotrauma
{
GameMain.Config.SettingsFrame.Draw(spriteBatch);
}
DebugConsole.Draw(spriteBatch);
if (GUIComponent.MouseOn != null && !string.IsNullOrWhiteSpace(GUIComponent.MouseOn.ToolTip)) GUIComponent.MouseOn.DrawToolTip(spriteBatch);
if (!GUI.DisableHUD)
cursor.Draw(spriteBatch, PlayerInput.LatestMousePosition);
cursor.Draw(spriteBatch, PlayerInput.LatestMousePosition);
}
public static void AddToGUIUpdateList()
{
if (GUIMessageBox.VisibleBox != null)
{
GUIMessageBox.VisibleBox.AddToGUIUpdateList();
}
if (pauseMenuOpen)
{
pauseMenu.AddToGUIUpdateList();
@@ -517,11 +522,6 @@ namespace Barotrauma
{
GameMain.Config.SettingsFrame.AddToGUIUpdateList();
}
if (GUIMessageBox.VisibleBox != null)
{
GUIMessageBox.VisibleBox.AddToGUIUpdateList();
}
}
public static void Update(float deltaTime)
@@ -11,8 +11,6 @@ namespace Barotrauma
private static Texture2D iceCraters;
private static Texture2D iceCrack;
public Action<Location, LocationConnection> OnLocationSelected;
public void Update(float deltaTime, Rectangle rect, float scale = 1.0f)
{
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
@@ -142,14 +142,18 @@ namespace Barotrauma.Networking
private List<FileTransferIn> activeTransfers;
private string downloadFolder;
private Dictionary<FileTransferType, string> downloadFolders = new Dictionary<FileTransferType, string>()
{
{ FileTransferType.Submarine, "Submarines/Downloaded" },
{ FileTransferType.CampaignSave, "Data/Saves/Multiplayer" }
};
public List<FileTransferIn> ActiveTransfers
{
get { return activeTransfers; }
}
public FileReceiver(string downloadFolder)
public FileReceiver()
{
if (GameMain.Server != null)
{
@@ -157,8 +161,6 @@ namespace Barotrauma.Networking
}
activeTransfers = new List<FileTransferIn>();
this.downloadFolder = downloadFolder;
}
public void ReadMessage(NetIncomingMessage inc)
@@ -201,11 +203,13 @@ namespace Barotrauma.Networking
if (GameSettings.VerboseLogging)
{
DebugConsole.Log("Received file transfer initiation message: ");
DebugConsole.Log(" File: "+fileName);
DebugConsole.Log(" File: " + fileName);
DebugConsole.Log(" Size: " + fileSize);
DebugConsole.Log(" Sequence channel: " + inc.SequenceChannel);
}
string downloadFolder = downloadFolders[(FileTransferType)fileType];
if (!Directory.Exists(downloadFolder))
{
try
@@ -214,7 +218,7 @@ namespace Barotrauma.Networking
}
catch (Exception e)
{
DebugConsole.ThrowError("Could not start a file transfer: failed to create the folder \""+downloadFolder+"\".", e);
DebugConsole.ThrowError("Could not start a file transfer: failed to create the folder \"" + downloadFolder + "\".", e);
return;
}
}
@@ -322,6 +326,13 @@ namespace Barotrauma.Networking
return false;
}
break;
case (byte)FileTransferType.CampaignSave:
if (Path.GetExtension(fileName) != ".save")
{
errorMessage = "Wrong file extension ''" + Path.GetExtension(fileName) + "''! (Expected .save)";
return false;
}
break;
}
return true;
@@ -376,6 +387,9 @@ namespace Barotrauma.Networking
stream.Close();
stream.Dispose();
break;
case FileTransferType.CampaignSave:
//TODO: verify that the received file is a valid save file
break;
}
return true;
@@ -89,7 +89,7 @@ namespace Barotrauma.Networking
entityEventManager = new ClientEntityEventManager(this);
fileReceiver = new FileReceiver("Submarines/Downloaded");
fileReceiver = new FileReceiver();
fileReceiver.OnFinished += OnFileReceived;
characterInfo = new CharacterInfo(Character.HumanConfigFile, name,Gender.None,null);
@@ -703,8 +703,11 @@ namespace Barotrauma.Networking
Rand.SetSyncedSeed(seed);
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
GameMain.GameSession.StartRound(levelSeed,loadSecondSub);
if (gameMode.Name != "Campaign")
{
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
}
GameMain.GameSession.StartRound(levelSeed, loadSecondSub);
if (respawnAllowed) respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.SelectedShuttle);
@@ -896,7 +899,16 @@ namespace Barotrauma.Networking
Voting.AllowModeVoting = allowModeVoting;
}
}
bool campaignUpdated = inc.ReadBoolean();
inc.ReadPadBits();
if (campaignUpdated)
{
MultiplayerCampaign.ClientRead(inc);
}
lastSentChatMsgID = inc.ReadUInt16();
break;
case ServerNetObject.CHAT_MESSAGE:
ChatMessage.ClientRead(inc);
@@ -961,6 +973,9 @@ namespace Barotrauma.Networking
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(ChatMessage.LastID);
var campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
outmsg.Write(campaign == null ? 0 : campaign.LastUpdateID);
chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID));
for (int i = 0; i < chatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++)
{
@@ -1038,8 +1053,8 @@ namespace Barotrauma.Networking
msg.Write((byte)ClientPacketHeader.FILE_REQUEST);
msg.Write((byte)FileTransferMessageType.Initiate);
msg.Write((byte)fileType);
msg.Write(file);
msg.Write(fileHash);
if (file != null) msg.Write(file);
if (fileHash != null) msg.Write(fileHash);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
@@ -1083,6 +1098,22 @@ namespace Barotrauma.Networking
textBlock.UserData = newSub;
textBlock.ToolTip = newSub.Description;
}
break;
case FileTransferType.CampaignSave:
var campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
if (campaign == null) return;
GameMain.GameSession.SavePath = transfer.FilePath;
campaign.LastSaveID = campaign.PendingSaveID;
if (GameMain.GameSession.Submarine == null)
{
var gameSessionDoc = SaveUtil.LoadGameSessionDoc(GameMain.GameSession.SavePath);
string subPath = Path.Combine(SaveUtil.TempPath, ToolBox.GetAttributeString(gameSessionDoc.Root, "submarine", "")) + ".sub";
GameMain.GameSession.Submarine = new Submarine(subPath, "");
}
break;
}
}
@@ -1,10 +1,7 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Barotrauma
@@ -18,6 +15,8 @@ namespace Barotrauma
private GUITextBox saveNameBox, seedBox;
private GUIButton loadGameButton;
public Action<Submarine, string, string> StartNewGame;
public Action<string> LoadGame;
@@ -138,8 +137,14 @@ namespace Barotrauma
textBlock.UserData = saveFile;
}
var button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, "", loadGameContainer);
button.OnClicked = (btn, obj) => { LoadGame?.Invoke(saveList.SelectedData as string); return true; };
loadGameButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, "", loadGameContainer);
loadGameButton.OnClicked = (btn, obj) =>
{
if (string.IsNullOrWhiteSpace(saveList.SelectedData as string)) return false;
LoadGame?.Invoke(saveList.SelectedData as string);
return true;
};
loadGameButton.Enabled = false;
}
private bool SelectSaveFile(GUIComponent component, object obj)
@@ -154,6 +159,8 @@ namespace Barotrauma
return false;
}
loadGameButton.Enabled = true;
RemoveSaveFrame();
string subName = ToolBox.GetAttributeString(doc.Root, "submarine", "");
@@ -1001,7 +1001,7 @@ namespace Barotrauma
if (campaignContainer.Visible && campaignUI != null)
{
campaignContainer.Update((float)deltaTime);
//campaignContainer.Update((float)deltaTime);
campaignUI.Update((float)deltaTime);
}
@@ -1096,9 +1096,18 @@ namespace Barotrauma
public void SelectMode(int modeIndex)
{
modeList.Select(modeIndex, true);
if (modeIndex < 0 || modeIndex >= modeList.children.Count) return;
ToggleCampaignMode(SelectedMode.Name == "Campaign");
if (GameMain.Server != null)
{
if (((GameModePreset)modeList.children[modeIndex].UserData).Name == "Campaign")
{
MultiplayerCampaign.StartCampaignSetup();
return;
}
}
modeList.Select(modeIndex, true);
missionTypeBlock.Visible = SelectedMode != null && SelectedMode.Name == "Mission";
}
@@ -1110,35 +1119,49 @@ namespace Barotrauma
if (modePreset == null) return false;
missionTypeBlock.Visible = modePreset.Name == "Mission";
if (modePreset.Name == "Campaign")
if (GameMain.Server != null)
{
MultiplayerCampaign.StartCampaignSetup();
}
//campaign selected and the campaign view has not been set up yet
// -> don't select the mode yet and start campaign setup
if (modePreset.Name == "Campaign" && !campaignContainer.Visible)
{
MultiplayerCampaign.StartCampaignSetup();
return false;
}
}
lastUpdateID++;
return true;
}
public void ToggleCampaignView(bool enabled)
{
defaultModeContainer.Visible = !enabled;
StartButton.Visible = !enabled;
campaignContainer.Visible = enabled;
defaultModeContainer.Visible = !enabled;
if (StartButton != null)
{
StartButton.Visible = !enabled;
}
}
public void ToggleCampaignMode(bool enabled)
{
StartButton.Visible = !enabled;
campaignViewButton.Visible = enabled;
ToggleCampaignView(enabled);
if (enabled && campaignUI == null)
if (enabled)
{
campaignUI = new CampaignUI(GameMain.GameSession.GameMode as CampaignMode, campaignContainer);
campaignUI.StartRound = () => { GameMain.Server.StartGame(); };
if (campaignUI == null)
{
campaignUI = new CampaignUI(GameMain.GameSession.GameMode as CampaignMode, campaignContainer);
campaignUI.StartRound = () => { GameMain.Server.StartGame(); };
}
modeList.Select(2, true);
}
if (GameMain.Server != null)
{
lastUpdateID++;
}
}