Skip to content

Commit

Permalink
Merge pull request #598 from starfi5h/pr-features
Browse files Browse the repository at this point in the history
Add dedicated server argument -newgame + other features
  • Loading branch information
starfi5h authored Mar 11, 2023
2 parents 8edc691 + 1e96f28 commit d07500a
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 61 deletions.
19 changes: 11 additions & 8 deletions NebulaModel/MultiplayerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,17 @@ public class MultiplayerOptions : ICloneable

private bool _streamerMode = false;
[DisplayName("Streamer mode")]
[Description("If enabled specific personal information like your IP address is hidden from the ingame chat.")]
[Description("If enabled specific personal information like your IP address is hidden from the ingame chat and input fields.")]
public bool StreamerMode {
get => _streamerMode;
set {
_streamerMode = value;

InputField ngrokAuthTokenInput = GameObject.Find("list/scroll-view/viewport/content/Network/NgrokAuthtoken")?.GetComponentInChildren<InputField>();
UpdateNgrokAuthtokenInputFieldContentType(ref ngrokAuthTokenInput);
UpdateInputFieldContentType(ref ngrokAuthTokenInput);

InputField hostIpInput = GameObject.Find("UI Root/Overlay Canvas/Nebula - Multiplayer Menu/Host IP Address/InputField")?.GetComponentInChildren<InputField>();
UpdateInputFieldContentType(ref hostIpInput);
}
}

Expand Down Expand Up @@ -127,19 +130,19 @@ public object Clone()
return MemberwiseClone();
}

private void UpdateNgrokAuthtokenInputFieldContentType(ref InputField ngrokAuthTokenInput)
private void UpdateInputFieldContentType(ref InputField inputField)
{
if (ngrokAuthTokenInput != null)
if (inputField != null)
{
if (StreamerMode)
{
ngrokAuthTokenInput.contentType = InputField.ContentType.Password;
inputField.contentType = InputField.ContentType.Password;
}
else
{
ngrokAuthTokenInput.contentType = InputField.ContentType.Standard;
inputField.contentType = InputField.ContentType.Standard;
}
ngrokAuthTokenInput.UpdateLabel();
inputField.UpdateLabel();
}
}

Expand All @@ -149,7 +152,7 @@ public void ModifyInputFieldAtCreation(string displayName, ref InputField inputF
{
case _ngrokAuthtokenDisplayname:
{
UpdateNgrokAuthtokenInputFieldContentType(ref inputField);
UpdateInputFieldContentType(ref inputField);
break;
}
}
Expand Down
23 changes: 14 additions & 9 deletions NebulaNetwork/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,16 @@ private void ClientSocket_OnClose(object sender, CloseEventArgs e)
return;
}

if (e.Code == (ushort)DisconnectionReason.HostStillLoading)
{
InGamePopup.ShowWarning(
"Server Busy",
"Server is not ready to join. Please try again later.",
"OK".Translate(),
Multiplayer.LeaveGame);
return;
}

if (Multiplayer.Session.IsGameLoaded || Multiplayer.Session.IsInLobby)
{
InGamePopup.ShowWarning(
Expand All @@ -331,6 +341,7 @@ private void ClientSocket_OnClose(object sender, CloseEventArgs e)
}
else
{
Log.Warn("Disconnect code: " + e.Code + ", reason:" + e.Reason);
InGamePopup.ShowWarning(
"Server Unavailable",
$"Could not reach the server, please try again later.",
Expand All @@ -349,17 +360,11 @@ private static void DisableNagleAlgorithm(WebSocket socket)
}
}

private readonly AccessTools.FieldRef<WebSocket, MemoryStream> fragmentsBufferRef = AccessTools.FieldRefAccess<WebSocket, MemoryStream>("_fragmentsBuffer");
private int GetFragmentBufferLength()
{
MemoryStream buffer = (MemoryStream)AccessTools.Field(typeof(WebSocket), "_fragmentsBuffer").GetValue(clientSocket);
if (buffer != null)
{
return (int)buffer.Length;
}
else
{
return 0;
}
MemoryStream fragmentsBuffer = fragmentsBufferRef(clientSocket);
return (int)(fragmentsBuffer?.Length ?? 0);
}
}
}
1 change: 1 addition & 0 deletions NebulaNetwork/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public override void Start()
{
InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close");
Stop();
Multiplayer.LeaveGame();
return;
}

Expand Down
69 changes: 67 additions & 2 deletions NebulaPatcher/NebulaPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ private void Awake()

// Read command-line arguments
string[] args = Environment.GetCommandLineArgs();
(bool didLoad, bool loadArgExists, string saveName) = (false, false, string.Empty);
bool batchmode = false;
(bool didLoad, bool loadArgExists, bool newgameArgExists, string saveName) = (false, false, false, string.Empty);
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "-server")
Expand All @@ -44,6 +45,39 @@ private void Awake()
Log.Info($">> Initializing dedicated server");
}

if (args[i] == "-batchmode")
{
batchmode = true;
}

if (args[i] == "-newgame")
{
newgameArgExists = true;
if (i + 3 < args.Length)
{
if (!int.TryParse(args[i + 1], out int seed))
{
Log.Warn($">> Can't set galaxy seed: {args[i + 1]} is not a integer");
}
else if (!int.TryParse(args[i + 2], out int starCount))
{
Log.Warn($">> Can't set star count: {args[i + 2]} is not a integer");
}
else if (!float.TryParse(args[i + 3], out float resourceMultiplier))
{
Log.Warn($">> Can't set resource multiplier: {args[i + 3]} is not a floating point number");
}
else
{
Log.Info($">> Creating new game ({seed}, {starCount}, {resourceMultiplier:F1})");
GameDesc gameDesc = new GameDesc();
gameDesc.SetForNewGame(UniverseGen.algoVersion, seed, starCount, 1, resourceMultiplier);
NebulaWorld.GameStates.GameStatesManager.NewGameDesc = gameDesc;
didLoad = true;
}
}
}

if (args[i] == "-load" && i + 1 < args.Length)
{
loadArgExists = true;
Expand Down Expand Up @@ -109,13 +143,25 @@ private void Awake()
Log.Error($">> Can't find any save in the folder! Exiting...");
}
}
else if (newgameArgExists)
{
Log.Error($">> New game parameters incorrect! Exiting...\nExpect: -newgame seed starCount resourceMltiplier");
}
else
{
Log.Error(">> -load argument missing! Exiting...");
Log.Error(">> -load or -newgame argument missing! Exiting...");
}
Application.Quit();
}

if (Multiplayer.IsDedicated)
{
if (!batchmode)
{
Log.Warn("Dedicate server should start with -batchmode argument");
}
}

try
{
Initialize();
Expand Down Expand Up @@ -152,6 +198,25 @@ public static void StartDedicatedServer(string saveName)
}
}

public static void StartDedicatedServer(GameDesc gameDesc)
{
// Mimic UI buttons clicking
UIMainMenu_Patch.OnMultiplayerButtonClick();
if (gameDesc != null)
{
// Modified from DoLoadSelectedGame
Log.Info($"Starting dedicated server, create new game from parameters:");
Log.Info($"seed={gameDesc.galaxySeed} starCount={gameDesc.starCount} resourceMultiplier={gameDesc.resourceMultiplier:F1}");
DSPGame.StartGameSkipPrologue(gameDesc);
Log.Info($"Listening server on port {NebulaModel.Config.Options.HostPort}");
Multiplayer.HostGame(new Server(NebulaModel.Config.Options.HostPort, true));
if (command_ups != 0)
{
FPSController.SetFixUPS(command_ups);
}
}
}

private static async void ActivityManager_OnActivityJoin(string secret)
{
if(Multiplayer.IsActive)
Expand Down
8 changes: 7 additions & 1 deletion NebulaPatcher/Patches/Dynamic/UIGalaxySelect_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,19 @@ public static void UpdateParametersUIDisplay_Postfix(UIGalaxySelect __instance)
[HarmonyPostfix]
[HarmonyPatch(nameof(UIGalaxySelect._OnUpdate))]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")]
public static void _OnUpdate_Postfix()
public static void _OnUpdate_Postfix(UIGalaxySelect __instance)
{
if (Multiplayer.IsInMultiplayerMenu)
{
// as we need to load and generate planets for the detail view in the lobby, update the loading process here
PlanetModelingManager.ModelingPlanetCoroutine();
UIRoot.instance.uiGame.planetDetail._OnUpdate();
if (Input.mouseScrollDelta.y != 0)
{
// zoom in/out when scrolling
float delta = (Input.mouseScrollDelta.y < 0 ? 1f : -1f) * (VFInput.shift ? 1f : 0.1f);
__instance.cameraPoser.distRatio += delta;
}
}
}

Expand Down
85 changes: 49 additions & 36 deletions NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static void _OnOpen_Postfix()

[HarmonyPostfix]
[HarmonyPatch(nameof(UIMainMenu.OnUpdateLogButtonClick))]
public static void OnUpdateLogButtonClick_Postfix(UIMainMenu __instance)
public static void OnUpdateLogButtonClick_Postfix()
{
// Return to main menu when update log is opened
OnMultiplayerBackButtonClick();
Expand Down Expand Up @@ -166,38 +166,55 @@ private static void AddMultiplayerJoinMenu()
Object.Destroy(multiplayerMenu.gameObject.GetComponent<UIGalaxySelect>());

multiplayerMenu.gameObject.name = "Nebula - Multiplayer Menu";
multiplayerMenu.Find("star-count").gameObject.SetActive(false);
multiplayerMenu.Find("resource-multiplier").gameObject.SetActive(false);
multiplayerMenu.Find("right-group").gameObject.SetActive(false);
multiplayerMenu.Find("left-group").gameObject.SetActive(false);
multiplayerMenu.Find("property-multiplier").gameObject.SetActive(false);
multiplayerMenu.Find("seed-key").gameObject.SetActive(false);
multiplayerMenu.Find("sandbox-mode").gameObject.SetActive(false);

Transform topTitle = multiplayerMenu.Find("top-title");
topTitle.GetComponent<Localizer>().enabled = false;
topTitle.GetComponent<Text>().text = "Multiplayer";

Transform hostIpField = multiplayerMenu.Find("galaxy-seed");
hostIpField.GetComponent<Localizer>().enabled = false;
hostIpField.GetComponent<Text>().text = "Host IP Address";
hostIPAddressInput = hostIpField.GetComponentInChildren<InputField>();
hostIPAddressInput.onEndEdit.RemoveAllListeners();
hostIPAddressInput.onValueChanged.RemoveAllListeners();
//note: connectToUrl uses Dns.getHostEntry, which can only use up to 255 chars.
//256 will trigger an argument out of range exception
hostIPAddressInput.characterLimit = 255;

string ip = "127.0.0.1";
if (Config.Options.RememberLastIP && !string.IsNullOrWhiteSpace(Config.Options.LastIP))
for (int i = 0; i < multiplayerMenu.childCount; i++)
{
ip = Config.Options.LastIP;
}
hostIPAddressInput.text = ip;
Transform child = multiplayerMenu.GetChild(i);
if (child.name == "top-title")
{
Transform topTitle = child;
topTitle.GetComponent<Localizer>().enabled = false;
topTitle.GetComponent<Text>().text = "Multiplayer";
}
else if (child.name == "galaxy-seed")
{
Transform hostIpField = child;
hostIpField.GetComponent<Localizer>().enabled = false;
hostIpField.GetComponent<Text>().text = "Host IP Address";
hostIpField.name = "Host IP Address";
hostIPAddressInput = hostIpField.GetComponentInChildren<InputField>();
hostIPAddressInput.onEndEdit.RemoveAllListeners();
hostIPAddressInput.onValueChanged.RemoveAllListeners();
//note: connectToUrl uses Dns.getHostEntry, which can only use up to 255 chars.
//256 will trigger an argument out of range exception
hostIPAddressInput.characterLimit = 255;

string ip = "127.0.0.1";
if (Config.Options.RememberLastIP && !string.IsNullOrWhiteSpace(Config.Options.LastIP))
{
ip = Config.Options.LastIP;
}
hostIPAddressInput.text = ip;
hostIPAddressInput.contentType = Config.Options.StreamerMode ? InputField.ContentType.Password : InputField.ContentType.Standard;

Transform passwordField = Object.Instantiate(hostIpField, hostIpField.parent, false);
passwordField.localPosition = multiplayerMenu.Find("star-count").localPosition;
}
else if (child.name == "start-button")
{
OverrideButton(multiplayerMenu.Find("start-button").GetComponent<RectTransform>(), "Join Game", OnJoinGameButtonClick);
}
else if (child.name == "cancel-button")
{
OverrideButton(multiplayerMenu.Find("cancel-button").GetComponent<RectTransform>(), null, OnJoinGameBackButtonClick);
}
else
{
// Remove all unused elements that may be added by other mods
GameObject.Destroy(child.gameObject);
}
}
Transform passwordField = Object.Instantiate(multiplayerMenu.Find("Host IP Address"), multiplayerMenu, false);
passwordField.localPosition = galaxySelectTemplate.Find("star-count").localPosition;
passwordField.GetComponent<Text>().text = "Password (optional)";
passwordField.name = "Password (optional)";
passwordInput = passwordField.GetComponentInChildren<InputField>();
passwordInput.contentType = InputField.ContentType.Password;

Expand All @@ -207,10 +224,6 @@ private static void AddMultiplayerJoinMenu()
passwordInput.text = Config.Options.LastClientPassword;
}

OverrideButton(multiplayerMenu.Find("start-button").GetComponent<RectTransform>(), "Join Game", OnJoinGameButtonClick);
OverrideButton(multiplayerMenu.Find("cancel-button").GetComponent<RectTransform>(), null, OnJoinGameBackButtonClick);
multiplayerMenu.Find("random-button").gameObject.SetActive(false);

multiplayerMenu.gameObject.SetActive(false);
}

Expand Down Expand Up @@ -293,7 +306,7 @@ public static void JoinGame(string ip, string password = "")

private static IEnumerator TryConnectToServer(string ip, int port, bool isIP, string password)
{
InGamePopup.ShowInfo("Connecting", $"Connecting to server {ip}:{port}...", null, null);
InGamePopup.ShowInfo("Connecting", $"Connecting to server...", null, null);
multiplayerMenu.gameObject.SetActive(false);

// We need to wait here to have time to display the Connecting popup since the game freezes during the connection.
Expand All @@ -303,7 +316,7 @@ private static IEnumerator TryConnectToServer(string ip, int port, bool isIP, st
{
InGamePopup.FadeOut();
//re-enabling the menu again after failed connect attempt
InGamePopup.ShowWarning("Connect failed", $"Was not able to connect to {hostIPAddressInput.text}", "OK");
InGamePopup.ShowWarning("Connect failed", $"Was not able to connect to server", "OK");
multiplayerMenu.gameObject.SetActive(true);
}
else
Expand Down
14 changes: 13 additions & 1 deletion NebulaPatcher/Patches/Dynamic/VFPreload_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static void InvokeOnLoad_Postfix()
{
if (Multiplayer.IsDedicated)
{
VFAudio.audioVolume = 0f;
NebulaModel.Utils.NativeInterop.HideWindow();
NebulaModel.Utils.NativeInterop.SetConsoleCtrlHandler();
// Logging to provide progression to user
Expand Down Expand Up @@ -56,7 +57,18 @@ public static void InvokeOnLoadWorkEnded_Postfix()

if (Multiplayer.IsDedicated)
{
NebulaPlugin.StartDedicatedServer(NebulaWorld.GameStates.GameStatesManager.ImportedSaveName);
if (GameStatesManager.ImportedSaveName != null)
{
NebulaPlugin.StartDedicatedServer(GameStatesManager.ImportedSaveName);
}
else if (GameStatesManager.NewGameDesc != null)
{
NebulaPlugin.StartDedicatedServer(GameStatesManager.NewGameDesc);
}
else
{
Log.Warn("No game start option provided!");
}
}
}
}
Expand Down
Loading

0 comments on commit d07500a

Please sign in to comment.