Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix save game loading issues #244

Merged
merged 1 commit into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions NebulaHost/SaveManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using NebulaModel.DataStructures;
using HarmonyLib;
using NebulaModel.DataStructures;
using NebulaModel.Networking.Serialization;
using NebulaModel.Utils;
using NebulaWorld;
Expand All @@ -10,9 +11,7 @@ namespace NebulaHost
public class SaveManager
{
private const string FILE_EXTENSION = ".server";
private static string lastFileName = "";

public static bool SaveOnExit = false;
public static void SaveServerData(string saveName)
{
string path = GameConfig.gameSaveFolder + saveName + FILE_EXTENSION;
Expand All @@ -32,25 +31,50 @@ public static void SaveServerData(string saveName)
}

//Add host's data
netDataWriter.Put(CryptoUtils.GetCurrentUserPublicKeyHash());
netDataWriter.Put(CryptoUtils.GetCurrentUserPublicKeyHash());
LocalPlayer.Data.Serialize(netDataWriter);

File.WriteAllBytes(path, netDataWriter.Data);

// If the saveName is the autoSave, we need to rotate the server autosave file.
if (saveName == GameSave.AutoSaveTmp)
{
HandleAutoSave();
}
}

public static void SetLastSave(string fileName)
static void HandleAutoSave()
{
lastFileName = fileName;
string str1 = GameConfig.gameSaveFolder + GameSave.AutoSaveTmp + FILE_EXTENSION;
string str2 = GameConfig.gameSaveFolder + GameSave.AutoSave0 + FILE_EXTENSION;
string str3 = GameConfig.gameSaveFolder + AccessTools.Field(typeof(GameSave), "AutoSave1").GetValue(null) + FILE_EXTENSION;
string str4 = GameConfig.gameSaveFolder + AccessTools.Field(typeof(GameSave), "AutoSave2").GetValue(null) + FILE_EXTENSION;
string str5 = GameConfig.gameSaveFolder + AccessTools.Field(typeof(GameSave), "AutoSave3").GetValue(null) + FILE_EXTENSION;

if (File.Exists(str1))
{
if (File.Exists(str5))
File.Delete(str5);
if (File.Exists(str4))
File.Move(str4, str5);
if (File.Exists(str3))
File.Move(str3, str4);
if (File.Exists(str2))
File.Move(str2, str3);
File.Move(str1, str2);
}
}

public static void LoadServerData()
{
string path = GameConfig.gameSaveFolder + lastFileName + FILE_EXTENSION;
string path = GameConfig.gameSaveFolder + DSPGame.LoadFile + FILE_EXTENSION;

PlayerManager playerManager = MultiplayerHostSession.Instance.PlayerManager;
if (!File.Exists(path) || playerManager == null)
{
return;
}

byte[] source = File.ReadAllBytes(path);
NetDataReader netDataReader = new NetDataReader(source);
int playerNum = netDataReader.GetInt();
Expand Down
11 changes: 2 additions & 9 deletions NebulaPatcher/Patches/Dynamic/GameSave_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ public static bool SaveCurrentGame_Prefix(string saveName)
return (!SimulatedWorld.Initialized && !SimulatedWorld.ExitingMultiplayerSession) || LocalPlayer.IsMasterClient;
}

[HarmonyPrefix]
[HarmonyPatch("LoadCurrentGame")]
public static void LoadCurrentGame_Prefix(string saveName)
{
SaveManager.SetLastSave(saveName);
}

[HarmonyPrefix]
[HarmonyPatch("AutoSave")]
public static bool AutoSave_Prefix()
Expand All @@ -39,8 +32,8 @@ public static bool AutoSave_Prefix()
[HarmonyPatch("SaveAsLastExit")]
public static bool SaveAsLastExit_Prefix()
{
// Only save if in single player or if you are the host
return (!SimulatedWorld.Initialized && !SimulatedWorld.ExitingMultiplayerSession) || LocalPlayer.IsMasterClient;
// Only save if in single player, since multiplayer requires to load from the Load Save Window
return (!SimulatedWorld.Initialized && !SimulatedWorld.ExitingMultiplayerSession);
}
}
}
46 changes: 0 additions & 46 deletions NebulaPatcher/Patches/Dynamic/UIEscMenu_Patch.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
using HarmonyLib;
using NebulaModel;
using NebulaModel.Logger;
using NebulaPatcher.MonoBehaviours;
using NebulaWorld;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace NebulaPatcher.Patches.Dynamic
{
[HarmonyPatch(typeof(UIEscMenu))]
class UIEscMenu_Patch
{
private static RectTransform hostGameButton;

[HarmonyPrefix]
[HarmonyPatch("_OnOpen")]
public static void _OnOpen_Prefix(UIEscMenu __instance)
Expand All @@ -25,29 +19,6 @@ public static void _OnOpen_Prefix(UIEscMenu __instance)
// Disable load game button if in a multiplayer session
Button loadGameWindowButton = AccessTools.Field(typeof(UIEscMenu), "button3").GetValue(__instance) as Button;
SetButtonEnableState(loadGameWindowButton, !SimulatedWorld.Initialized);

// If we are in a multiplayer game already make sure to hide the host game button
if (SimulatedWorld.Initialized)
{
hostGameButton?.gameObject.SetActive(false);
return;
}

if (hostGameButton != null)
{
hostGameButton.gameObject.SetActive(true);
hostGameButton.GetComponentInChildren<Text>().text = "Host Game";
return;
}

RectTransform buttonTemplate = GameObject.Find("Esc Menu/button (6)").GetComponent<RectTransform>();
hostGameButton = Object.Instantiate(buttonTemplate, buttonTemplate.parent, false);
hostGameButton.name = "button-host-game";
hostGameButton.anchoredPosition = new Vector2(buttonTemplate.anchoredPosition.x, buttonTemplate.anchoredPosition.y - buttonTemplate.sizeDelta.y * 2);
hostGameButton.GetComponentInChildren<Text>().text = "Host Game";

hostGameButton.GetComponent<Button>().onClick.RemoveAllListeners();
hostGameButton.GetComponent<Button>().onClick.AddListener(new UnityAction(OnHostCurrentGameClick));
}

[HarmonyPrefix]
Expand All @@ -61,23 +32,6 @@ public static void OnGameQuit_Prefix()
}
}

private static void OnHostCurrentGameClick()
{
// Make sure to save the game before enabling the multiplayer mod
GameSave.AutoSave();

int port = Config.DefaultPort;

Log.Info($"Listening server on port {port}");
var session = NebulaBootstrapper.Instance.CreateMultiplayerHostSession();
session.StartServer(port, true);

// Manually call the OnGameLoadCompleted manually since we are already in a game.
SimulatedWorld.OnGameLoadCompleted();

GameMain.Resume();
}

private static void SetButtonEnableState(Button button, bool enable)
{
ColorBlock buttonColors = button.colors;
Expand Down
6 changes: 3 additions & 3 deletions NebulaPatcher/Patches/Dynamic/UILoadGameWindow_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ namespace NebulaPatcher.Patches.Dynamic
[HarmonyPatch(typeof(UILoadGameWindow))]
class UILoadGameWindow_Patch
{
[HarmonyPrefix]
[HarmonyPostfix]
[HarmonyPatch("DoLoadSelectedGame")]
public static void DoLoadSelectedGame_Prefix()
public static void DoLoadSelectedGame_Postfix()
{
if (MainMenuManager.IsInMultiplayerMenu)
{
Log.Info($"Listening server on port {Config.DefaultPort}");
var session = NebulaBootstrapper.Instance.CreateMultiplayerHostSession();
session.StartServer(Config.DefaultPort);
session.StartServer(Config.DefaultPort, true);
}
}
}
Expand Down