From 32080028d6e47857c404f28f5425523232ffaf3a Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:34:59 +0100 Subject: [PATCH 01/36] docs: clarify readme and add new instructions --- README.md | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 4ba11ed..2e19ad2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # GBSU (Gang Beasts Server Utility) -This mod allows you to connect to a Gang Beast server in recent versions (through LAN or Internet) by utilizing developer methods found in the game assembly. +This mod allows you to connect to a Gang Beasts server in recent versions (through LAN or Internet) by utilizing developer methods found in the game assembly. **NOTICE: This is not a "Cement" mod, and we don't want to be affiliated with their developers. This mod is standalone, and will work best on its own!** @@ -8,48 +8,46 @@ This mod allows you to connect to a Gang Beast server in recent versions (throug - Custom score handling made by the server (we don't want to use the game's score handler) # Installation -The mod is made for the game version **1.17.39_WS_8af7688** running on Unity **v2020.3.5.8426922** (check your version in the Settings menu in-game) -Other versions *MIGHT* work with the mod. Try at your own risk.* - -1. Check whether your game is Mono or IL2CPP: Go to 'Gang Beasts_Data' - - If you have a il2cpp_data folder: your game is **IL2CPP** - - If you have a folder called `MonoBleedingEdge` or the `Gang Beasts_Data/Managed` folder contains a file called 'Assembly-CSharp.dll': your game is **Mono** - -2. **Follow the instructions based on the game type:** +1. Check your game version in the "Settings" menu in-game. If the version is **1.17.39_WS_8af7688**, we fully support it. +2. Check whether your game is Mono or IL2CPP: Go to 'Gang Beasts_Data' + - If you have a folder called `MonoBleedingEdge` or the `Gang Beasts_Data/Managed` folder contains a file called 'Assembly-CSharp.dll': your game is **Mono**. Continue to [Mono instructions](#mono). + - If you have a il2cpp_data folder: your game is **IL2CPP**. Continue to [IL2CPP instructions](#il2cpp). ## Mono -Go to https://github.com/BepInEx/BepInEx/releases and get the latest stable release for Mono x64 (on Windows). - -1. As of March 2025, what we recommend doing is getting `BepInEx_win_x64_5.4.23.2.zip`. -2. Extract the zip file contents into your root game folder (not in the 'Gang Beasts_Data' folder!) +1. [Download the latest **BepInEx 5 stable** release for Mono x64](https://github.com/BepInEx/BepInEx/releases). As of March 2025, we recommend getting `BepInEx_win_x64_5.4.23.2.zip` +2. Extract the zip file contents into your root game folder (where the Gang Beasts.exe file is, and not in the 'Gang Beasts_Data' folder!) 3. Launch the game once. -4. Get the mod from our releases page. +4. Get the mod from our [releases page](https://git.gaboule.com/Gaboule/GBSU/releases). 5. Put the .dll file in the `BepInEx/plugins` folder. 6. Launch the game with launch arguments `-ip 1.2.3.4` and `-port 5999` with the IP address and port of the server you want to host or connect to. -7. You're good to go! Learn how to use the mod in [usage](#usage) + - To set those arguments on Steam, [please refer to this guide](https://help.steampowered.com/en/faqs/view/7D01-D2DD-D75E-2955). +7. You're good to go! Learn how to use the mod in [usage](#usage). ## IL2CPP -**WIP**: The mod will be ported to MelonLoader and recent game versions in the future. +**WIP**: You're currently out of luck! The mod doesn't support your game version at the moment. It will be ported to MelonLoader in the future. Try downgrading your game by getting older versions in Steam Betas or by using [DepotDownloader](https://github.com/SteamRE/DepotDownloader). # Usage Press `Right Shift` to open the mod GUI. Because of how the game is made, you need to be very careful when executing the steps else you will need to restart it. (will be fixed in future versions) ## Server (host) -1. Open the mod menu and press **Host** while you're in the main menu. -2. Don't pay attention to what's displayed on the game. It will be an infinite loading screen after the first round. +### Setting up the server +1. Open the `Gang Beasts_Data` folder in the "server" game instance files. +2. Create two new folders: `Config/Rotation` +3. Download the [one of the config files](https://git.gaboule.com/Gaboule/GBSU/src/branch/main/docs/configs) and place it inside the `Rotation` folder. +4. Rename the file to `config.json` + +### Configuring your custom server settings +* If you set `"random": true`, the map order will be randomized. +* Some maps may have different names in-game compared to their actual titles. Make sure to refer to the [`allmaps` configs](https://git.gaboule.com/Gaboule/GBSU/src/branch/main/docs/configs) for the map names. + +### Launching the server +Once the config file is in place, host your server by pressing the **Host** button in the mod menu. Don't pay attention to what's displayed on the game. It will be an infinite loading screen after the first round. ## Client (player) 1. In the game menu, choose **Online**. -2. Make sure to use a different color than your friends. +2. If you're planning to team up with friends, make sure your [server config]() is set to the `gang` gamemode and choose a shared color. Otherwise, use a different color than your friends. 3. Open the mod menu and press **Join**. -# Known Issues -- Scores tab on the server is expected be wrong. This is a temporary implementation and the scores will be reworked. -- The server is not headless. -- If you want to play on your server, you need to launch a different game instance. It is not possible to connect to the server after launching it at the moment. -- Getting the current scene isn't the most efficient way at the moment. - - # Troubleshooting ## I press the Host/Join button and nothing works! 1. Make sure you're in Online mode if you're **joining** a server. From 0fe4de92faf2291b8f8141cf5a23a928ebfcfef6 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:40:32 +0100 Subject: [PATCH 02/36] style: in-game guide formatting Make the in-game guide look nicer by formatting Add link to source code for further reference --- Addons/GBSUGui.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index fdd06f2..0dde94c 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -70,15 +70,15 @@ public class GBSUGui : MonoBehaviour GUI.skin.label.alignment = TextAnchor.UpperLeft; GUILayout.Label($@"==Guide== -CLI arguments have to be set to join or host: -ip, -port, -servername, -serverpassword +Set CLI arguments: -ip, -port, -servername, -serverpassword [Hosting] 1. Create a config in Gang Beasts_Data/Config/Rotation/config.json -2.Press the 'Host' button while in the Main Menu. +2. Press the 'Host' button while in the Main Menu [Joining] 1. Go to Online -2. Press the 'Join' button."); +2. Press the 'Join' button"); if (GUI.Button(new Rect(320f, 10f, 55f, 30f), "KILL")) { Application.Quit(0); @@ -139,14 +139,18 @@ CLI arguments have to be set to join or host: -ip, -port, -servername, -serverpa QualitySettings.vSyncCount = vsync_switch; } - GUI.Label(new Rect(20f, 365f, 365f, 400f), $@"Current map: {currentmap} + GUI.Label(new Rect(20f, 365f, 365f, 400f), $@" + +Current map: {currentmap} Lobby State: {LobbyManager.Instance.LobbyStates.SelfState} Game State: {_internalCurrentState} Vsync: {QualitySettings.vSyncCount} Target FPS: {Application.targetFrameRate} {UpdateScoreDisplay()} -Made with <3 by anavoi at Gaboule Community (gaboule.com)"); +Made with <3 by anavoi at Gaboule Community (gaboule.com) +Free and open-source software under GPLv3. Our source code is availaible at git.gaboule.com/Gaboule/GBSU +Please refer to the documentation for more information."); GUI.DragWindow(new Rect(0, 0, 10000, 10000)); } From 7af5036fb174516b5b956e8a393cba58bf9d49d1 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:42:45 +0100 Subject: [PATCH 03/36] docs: added server config files --- docs/configs/allmaps_gang.json | 93 +++++++++++++++++++++++++++++++++ docs/configs/allmaps_melee.json | 93 +++++++++++++++++++++++++++++++++ docs/configs/waves.json | 21 ++++++++ 3 files changed, 207 insertions(+) create mode 100644 docs/configs/allmaps_gang.json create mode 100644 docs/configs/allmaps_melee.json create mode 100644 docs/configs/waves.json diff --git a/docs/configs/allmaps_gang.json b/docs/configs/allmaps_gang.json new file mode 100644 index 0000000..1bf54f8 --- /dev/null +++ b/docs/configs/allmaps_gang.json @@ -0,0 +1,93 @@ +{ + "random": true, + "games": [ + { + "mode": "gang", + "map": "rooftop" + }, + { + "mode": "gang", + "map": "ring" + }, + { + "mode": "gang", + "map": "blimp" + }, + { + "mode": "gang", + "map": "containers" + }, + { + "mode": "gang", + "map": "elevators" + }, + { + "mode": "gang", + "map": "girders" + }, + { + "mode": "gang", + "map": "gondola" + }, + { + "mode": "gang", + "map": "grind" + }, + { + "mode": "gang", + "map": "incinerator" + }, + { + "mode": "gang", + "map": "ring" + }, + { + "mode": "gang", + "map": "towers" + }, + { + "mode": "gang", + "map": "train" + }, + { + "mode": "gang", + "map": "trucks" + }, + { + "mode": "gang", + "map": "aquarium" + }, + { + "mode": "gang", + "map": "billboard" + }, + { + "mode": "gang", + "map": "buoy" + }, + { + "mode": "gang", + "map": "chute" + }, + { + "mode": "gang", + "map": "billboard" + }, + { + "mode": "gang", + "map": "lighthouse" + }, + { + "mode": "gang", + "map": "subway" + }, + { + "mode": "gang", + "map": "vents" + }, + { + "mode": "gang", + "map": "wheel" + } + ] +} diff --git a/docs/configs/allmaps_melee.json b/docs/configs/allmaps_melee.json new file mode 100644 index 0000000..56b8c4f --- /dev/null +++ b/docs/configs/allmaps_melee.json @@ -0,0 +1,93 @@ +{ + "random": true, + "games": [ + { + "mode": "melee", + "map": "rooftop" + }, + { + "mode": "melee", + "map": "ring" + }, + { + "mode": "melee", + "map": "blimp" + }, + { + "mode": "melee", + "map": "containers" + }, + { + "mode": "melee", + "map": "elevators" + }, + { + "mode": "melee", + "map": "girders" + }, + { + "mode": "melee", + "map": "gondola" + }, + { + "mode": "melee", + "map": "grind" + }, + { + "mode": "melee", + "map": "incinerator" + }, + { + "mode": "melee", + "map": "ring" + }, + { + "mode": "melee", + "map": "towers" + }, + { + "mode": "melee", + "map": "train" + }, + { + "mode": "melee", + "map": "trucks" + }, + { + "mode": "melee", + "map": "aquarium" + }, + { + "mode": "melee", + "map": "billboard" + }, + { + "mode": "melee", + "map": "buoy" + }, + { + "mode": "melee", + "map": "chute" + }, + { + "mode": "melee", + "map": "billboard" + }, + { + "mode": "melee", + "map": "lighthouse" + }, + { + "mode": "melee", + "map": "subway" + }, + { + "mode": "melee", + "map": "vents" + }, + { + "mode": "melee", + "map": "wheel" + } + ] +} diff --git a/docs/configs/waves.json b/docs/configs/waves.json new file mode 100644 index 0000000..438f935 --- /dev/null +++ b/docs/configs/waves.json @@ -0,0 +1,21 @@ +{ + "random": true, + "games": [ + { + "mode": "waves", + "map": "rooftop" + }, + { + "mode": "waves", + "map": "incinerator" + }, + { + "mode": "waves", + "map": "subway" + }, + { + "mode": "waves", + "map": "grind" + } + ] +} From c095d824abcfe9dc00bea16d10c69b3afa520217 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:44:45 +0100 Subject: [PATCH 04/36] fix: resize menu for better score visibility --- Addons/GBSUGui.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 0dde94c..daf5943 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -15,7 +15,7 @@ public class GBSUGui : MonoBehaviour { private bool menu_shown; //private string _currentMap; - public Rect gmenu = new(Screen.width / 2, 0, 385f, 590f); + public Rect gmenu = new(Screen.width / 2, 0, 385f, 690f); readonly IInputSystem inputSystem = UnityInput.Current; string serverip = null; From 86a95a8e889a8f06768bd1de0de084ce66ae7eb8 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:48:38 +0100 Subject: [PATCH 05/36] style: minor formatting improvements --- Addons/GBSUGui.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index daf5943..561fb51 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -148,8 +148,10 @@ Vsync: {QualitySettings.vSyncCount} Target FPS: {Application.targetFrameRate} {UpdateScoreDisplay()} -Made with <3 by anavoi at Gaboule Community (gaboule.com) -Free and open-source software under GPLv3. Our source code is availaible at git.gaboule.com/Gaboule/GBSU + +Made with <3 by anavoi at Gaboule Community +Free and open-source software under GPLv3. +Our source code is availaible at git.gaboule.com/Gaboule/GBSU Please refer to the documentation for more information."); GUI.DragWindow(new Rect(0, 0, 10000, 10000)); From 3acfb446d1fb3a6809ac5cbd3f529add208eb7aa Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:52:34 +0100 Subject: [PATCH 06/36] perf: deprecate internalCurrentState tracking It isn't used at the moment. --- Addons/GBSUGui.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 561fb51..f30cfb2 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -21,8 +21,6 @@ public class GBSUGui : MonoBehaviour string serverip = null; int serverport = 0; string currentmap; - string _internalCurrentState; - Traverse _internalCurrentStateTraverse; int vsync_switch; bool hosting = false; private void Start() @@ -36,7 +34,6 @@ public class GBSUGui : MonoBehaviour int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", true), out serverport); } - _internalCurrentStateTraverse = Traverse.Create(nameof(GameManagerNew)).Field("internalCurrentState"); vsync_switch = QualitySettings.vSyncCount; } private void Update() @@ -48,7 +45,6 @@ public class GBSUGui : MonoBehaviour } currentmap = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; - _internalCurrentState = _internalCurrentStateTraverse.GetValue() as string; } private void ToggleMenu() @@ -143,7 +139,6 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword Current map: {currentmap} Lobby State: {LobbyManager.Instance.LobbyStates.SelfState} -Game State: {_internalCurrentState} Vsync: {QualitySettings.vSyncCount} Target FPS: {Application.targetFrameRate} {UpdateScoreDisplay()} From 6dd459582fbff8c0b4e52ff18903353e27ae9cc7 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 21:52:46 +0100 Subject: [PATCH 07/36] 1.0.1 --- GBSU.csproj | 2 +- Plugin.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GBSU.csproj b/GBSU.csproj index 804559c..866ce81 100644 --- a/GBSU.csproj +++ b/GBSU.csproj @@ -4,7 +4,7 @@ netstandard2.0 GBSU Gang Beasts Server Utility - 1.0.0 + 1.0.1 true latest diff --git a/Plugin.cs b/Plugin.cs index db2622f..f1e871c 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -67,5 +67,5 @@ public class Plugin : BaseUnityPlugin public const string PluginGUID = "com.gaboule.plugins.gbsu"; public const string PluginName = "Gang Beasts Server Utility"; - public const string PluginVersion = "1.0.0"; + public const string PluginVersion = "1.0.1"; } From 3258fcc4f5a24ef5b1534cd1ab4c5bb60c7b85f8 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 22:14:51 +0100 Subject: [PATCH 08/36] docs: added contact info for community feedback --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 2e19ad2..bf1dd14 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,13 @@ On Steam, simply put `WINEDLLOVERRIDES="winhttp.dll=n,b" %command%` in your laun If it's still not working, try using `winecfg` for your prefix or `protontricks` and go to the libraries tab in Wine Configuration. Simply add `winhttp` as an override and check if it's correctly set as "native, then builtin" (or "n,b"). +# Contact us +## Need help? +Ask us on [Matrix](https://matrix.to/#/#gbsu:gaboule.com). + +## Feature requests or bug reports +Want a new feature? Found a bug? [Open an issue!](https://git.gaboule.com/Gaboule/GBSU/issues). Please note that a Gaboule account is required. This will change once Forgejo supports federation. Alternatively, feel free to reach out to us for general feedback or questions. + # Developer information - The mod is made for BepInEx 5 - The targeted Unity version is `2020.3.5f1` From 4a5c66566719364ecf38d8c36246893d80a57f5d Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 22:15:24 +0100 Subject: [PATCH 09/36] style: remove trailing dot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf1dd14..36251ee 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ If it's still not working, try using `winecfg` for your prefix or `protontricks` Ask us on [Matrix](https://matrix.to/#/#gbsu:gaboule.com). ## Feature requests or bug reports -Want a new feature? Found a bug? [Open an issue!](https://git.gaboule.com/Gaboule/GBSU/issues). Please note that a Gaboule account is required. This will change once Forgejo supports federation. Alternatively, feel free to reach out to us for general feedback or questions. +Want a new feature? Found a bug? [Open an issue!](https://git.gaboule.com/Gaboule/GBSU/issues) Please note that a Gaboule account is currently required. This will change once Forgejo supports federation. Alternatively, feel free to reach out to us for general feedback or questions. # Developer information - The mod is made for BepInEx 5 From abe74e4ea51afef726e91372b62e3b52afafc117 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 22:19:03 +0100 Subject: [PATCH 10/36] style: fix spelling mistakes Add .vscode/settings.json for VSCode/VSCodium users using cspell --- .vscode/settings.json | 23 +++++++++++++++++++++++ Addons/GBSUGui.cs | 6 +++--- README.md | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..dc400bf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,23 @@ +{ + "cSpell.words": [ + "allmaps", + "Behaviour", + "currentmap", + "Dont", + "gamemode", + "GBSU", + "gmenu", + "hlapi", + "netstandard", + "protontricks", + "rotationconfig", + "serverip", + "serverpassword", + "serverport", + "vsync", + "winecfg", + "WINEDLLOVERRIDES", + "winhttp", + "ZeroTier" + ] +} \ No newline at end of file diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index f30cfb2..431c5c5 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -92,7 +92,7 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword Plugin.AddServerComp(); // add custom GBSU server component RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig("config.json", true); // load rotation config from Config/Rotation/config.json - ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, becauuse it can be overrided by args like -ip and -port + ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig } @@ -139,14 +139,14 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword Current map: {currentmap} Lobby State: {LobbyManager.Instance.LobbyStates.SelfState} -Vsync: {QualitySettings.vSyncCount} +VSync: {QualitySettings.vSyncCount} Target FPS: {Application.targetFrameRate} {UpdateScoreDisplay()} Made with <3 by anavoi at Gaboule Community Free and open-source software under GPLv3. -Our source code is availaible at git.gaboule.com/Gaboule/GBSU +Our source code is available at git.gaboule.com/Gaboule/GBSU Please refer to the documentation for more information."); GUI.DragWindow(new Rect(0, 0, 10000, 10000)); diff --git a/README.md b/README.md index 36251ee..ca415d8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This mod allows you to connect to a Gang Beasts server in recent versions (throu **NOTICE: This is not a "Cement" mod, and we don't want to be affiliated with their developers. This mod is standalone, and will work best on its own!** # Features -- LAN (ethernet switches at LAN parties) and Online (port forwarding, Zerotier, Wireguard) multiplayer +- LAN (ethernet switches at LAN parties) and Online (port forwarding, ZeroTier, Wireguard) multiplayer - Custom score handling made by the server (we don't want to use the game's score handler) # Installation From 5c6a96b800f72920db8e83e87fff2bb004161519 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 22:19:21 +0100 Subject: [PATCH 11/36] refactor: remove unused import --- Addons/GBSUGui.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 431c5c5..d1447a3 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -4,7 +4,6 @@ using GB.Config; using GB.Core; using GB.Game; using GB.Platform.Lobby; -using HarmonyLib; using UnityEngine; #pragma warning disable IDE0051 // Private member is unused From 89fcf1ed7b4395733a9bddd5957598537d5c3c57 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 22:20:33 +0100 Subject: [PATCH 12/36] refactor: bump severity from info to warning --- Addons/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Addons/Helper.cs b/Addons/Helper.cs index 535ec0a..d53cef5 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -14,7 +14,7 @@ public class Helper } catch (Exception e) { - Plugin.Log.LogInfo("Failed to disable analytics: " + e.Message); + Plugin.Log.LogWarning("Failed to disable analytics: " + e.Message); } } } \ No newline at end of file From bdc26f252867a09859e3096e2e734870c48bd891 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 15 Mar 2025 22:21:27 +0100 Subject: [PATCH 13/36] 1.0.2 --- GBSU.csproj | 2 +- Plugin.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GBSU.csproj b/GBSU.csproj index 866ce81..2a42d53 100644 --- a/GBSU.csproj +++ b/GBSU.csproj @@ -4,7 +4,7 @@ netstandard2.0 GBSU Gang Beasts Server Utility - 1.0.1 + 1.0.2 true latest diff --git a/Plugin.cs b/Plugin.cs index f1e871c..b98969d 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -67,5 +67,5 @@ public class Plugin : BaseUnityPlugin public const string PluginGUID = "com.gaboule.plugins.gbsu"; public const string PluginName = "Gang Beasts Server Utility"; - public const string PluginVersion = "1.0.1"; + public const string PluginVersion = "1.0.2"; } From 5aa379ca9d61889faddd76d334f77ff1afa8c71d Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 12 Jul 2025 19:15:51 +0200 Subject: [PATCH 14/36] fix: null check for localSingleGang --- Addons/GBSUServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index 0fa0a60..b2c57b8 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -26,7 +26,7 @@ public class GBSUServer : MonoBehaviour } void SetLocalGangToOff() { - localSingleGang.SetValue(false); + localSingleGang?.SetValue(false); } /* From 05256ecd8ab9fa27f2715f5332c8d30467829af4 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 12 Jul 2025 23:28:33 +0200 Subject: [PATCH 15/36] fix: keep only one server comp --- Plugin.cs | 154 +++++++++++++++++++++++++++++------------------------- 1 file changed, 83 insertions(+), 71 deletions(-) diff --git a/Plugin.cs b/Plugin.cs index b98969d..81e98a0 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,71 +1,83 @@ -using System.Collections.Generic; -using System.Reflection; -using BepInEx; -using BepInEx.Logging; -using GBSU.Addons; -using HarmonyLib; -using HarmonyLib.Tools; -using UnityEngine; - -#pragma warning disable IDE0051 // Private member is unused - -namespace GBSU; - -[BepInPlugin(PluginGUID, PluginName, PluginVersion)] -[BepInProcess("Gang Beasts.exe")] -public class Plugin : BaseUnityPlugin -{ - public static Dictionary GameScore = []; - private static GameObject _gbsuCompContainer; - internal static ManualLogSource Log; - - public static GameObject GBSUCompContainer - { - get - { - if (_gbsuCompContainer == null) - { - _gbsuCompContainer = new GameObject("GBSUSingletons"); - } - - return _gbsuCompContainer; - } - set - { - Destroy(_gbsuCompContainer); - _gbsuCompContainer = value; - } - } - private void Awake() - { - // Plugin startup logic - Log = base.Logger; - Log.LogInfo($"\n------\nPlugin {PluginName} [{PluginVersion}] is loaded!\n------\n"); - - HarmonyFileLog.Enabled = true; - var harmony = new Harmony(PluginGUID); - harmony.PatchAll(Assembly.GetExecutingAssembly()); - - GBSUCompInit(); - - Helper.DisableAnalytics(); // thank me later - } - - private static void GBSUCompInit() - { - // Create a container that wont lose our objects - GBSUCompContainer = new GameObject("GBSUSingletons"); - DontDestroyOnLoad(GBSUCompContainer); - GBSUCompContainer.hideFlags = HideFlags.DontUnloadUnusedAsset; - GBSUCompContainer.AddComponent(); - } - - public static void AddServerComp() - { - GBSUCompContainer.AddComponent(); - } - - public const string PluginGUID = "com.gaboule.plugins.gbsu"; - public const string PluginName = "Gang Beasts Server Utility"; - public const string PluginVersion = "1.0.2"; -} +using System.Collections.Generic; +using System.Reflection; +using BepInEx; +using BepInEx.Logging; +using GBSU.Addons; +using HarmonyLib; +using HarmonyLib.Tools; +using UnityEngine; + +#pragma warning disable IDE0051 // Private member is unused + +namespace GBSU; + +[BepInPlugin(PluginGUID, PluginName, PluginVersion)] +[BepInProcess("Gang Beasts.exe")] +public class Plugin : BaseUnityPlugin +{ + public static Dictionary GameScore = []; + private static GameObject _gbsuCompContainer; + internal static ManualLogSource Log; + + public static GameObject GBSUCompContainer + { + get + { + if (_gbsuCompContainer == null) + { + _gbsuCompContainer = new GameObject("GBSUSingletons"); + } + + return _gbsuCompContainer; + } + set + { + Destroy(_gbsuCompContainer); + _gbsuCompContainer = value; + } + } + private void Awake() + { + // Plugin startup logic + Log = base.Logger; + Log.LogInfo($"\n------\nPlugin {PluginName} [{PluginVersion}] is loaded!\n------\n"); + + HarmonyFileLog.Enabled = true; + var harmony = new Harmony(PluginGUID); + harmony.PatchAll(Assembly.GetExecutingAssembly()); + + GBSUCompInit(); + + Helper.DisableAnalytics(); // thank me later + } + + private static void GBSUCompInit() + { + // Create a container that wont lose our objects + GBSUCompContainer = new GameObject("GBSUSingletons"); + DontDestroyOnLoad(GBSUCompContainer); + GBSUCompContainer.hideFlags = HideFlags.DontUnloadUnusedAsset; + GBSUCompContainer.AddComponent(); + } + + public static void AddServerComp() + { + Component[] comps = GBSUCompContainer.GetComponents(typeof(Component)); + foreach (var comp in comps) + { + Log.LogDebug("iterating thru singleton comps"); + if(comp is GBSUServer) + { + Log.LogDebug("GBSUServer component was found! Destroying it"); + Destroy(comp); + } + } + + Log.LogDebug("Adding GBSUServer component"); + GBSUCompContainer.AddComponent(); + } + + public const string PluginGUID = "com.gaboule.plugins.gbsu"; + public const string PluginName = "Gang Beasts Server Utility"; + public const string PluginVersion = "1.0.2"; +} From 4b7b22aad4d2d59d717b6ab8666d49846412ae9b Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 12 Jul 2025 23:33:41 +0200 Subject: [PATCH 16/36] feat: create config folder at runtime --- Addons/Helper.cs | 14 ++++++++++++++ Plugin.cs | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/Addons/Helper.cs b/Addons/Helper.cs index d53cef5..b674c1c 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -4,6 +4,8 @@ using UnityEngine.Analytics; namespace GBSU.Addons; public class Helper { + public static string RotationFolderPath = Application.dataPath + "/Config/Rotation/"; + public static string GameConfigPath = RotationFolderPath + "config.json"; public static void DisableAnalytics() { // Try disabling analytics https://docs.unity3d.com/ScriptReference/Analytics.Analytics-deviceStatsEnabled.html @@ -17,4 +19,16 @@ public class Helper Plugin.Log.LogWarning("Failed to disable analytics: " + e.Message); } } + public static void CreateRotationFolder() + { + try + { + Plugin.Log.LogInfo("Creating rotation folder at " + RotationFolderPath); + Directory.CreateDirectory(RotationFolderPath); + } + catch (Exception e) + { + Plugin.Log.LogError("Could not create rotation folder path: " + e.Message); + } + } } \ No newline at end of file diff --git a/Plugin.cs b/Plugin.cs index 81e98a0..ac523ee 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -49,6 +49,11 @@ public class Plugin : BaseUnityPlugin GBSUCompInit(); Helper.DisableAnalytics(); // thank me later + + // create server config path + Helper.CreateRotationFolder(); + + Log.LogDebug("Server game config should be found at " + Helper.GameConfigPath); } private static void GBSUCompInit() From 9599a6d6521cea2ca2310c35f071aea4f2315468 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 12 Jul 2025 23:35:32 +0200 Subject: [PATCH 17/36] feat: make 5999 the default serverport --- Addons/GBSUGui.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index d1447a3..c3d1966 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -18,7 +18,7 @@ public class GBSUGui : MonoBehaviour readonly IInputSystem inputSystem = UnityInput.Current; string serverip = null; - int serverport = 0; + int serverport = 5999; string currentmap; int vsync_switch; bool hosting = false; @@ -78,7 +78,7 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword { Application.Quit(0); } - if (serverip != null && serverport != default) + if (serverip != null) { if (GUI.Button(new Rect(20f, 260f, 170f, 30f), "Host")) { From b4ffbc0a0da71ad32ca778a7d6415cf6dbbee575 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sat, 12 Jul 2025 23:39:20 +0200 Subject: [PATCH 18/36] feat: in-game error display --- Addons/GBSUGui.cs | 86 +++++++++++++++++++++++++++++++++++++++++------ Addons/Helper.cs | 26 ++++++++++++++ 2 files changed, 101 insertions(+), 11 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index c3d1966..7ee7580 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -1,3 +1,5 @@ +using System; +using System.IO; using BepInEx; using CoreNet.Config; using GB.Config; @@ -13,8 +15,11 @@ namespace GBSU.Addons; public class GBSUGui : MonoBehaviour { private bool menu_shown; + private bool error_shown; //private string _currentMap; public Rect gmenu = new(Screen.width / 2, 0, 385f, 690f); + public Rect error_dialog = new(Screen.width / 2, 0, 520f, 175f); + private string error_msg = "Unknown error!"; readonly IInputSystem inputSystem = UnityInput.Current; string serverip = null; @@ -84,23 +89,43 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword { if (LobbyManager.Instance.LobbyStates.SelfState == LobbyState.Game.Menu) { - hosting = true; - - AudioListener.volume = 0; // mute game audio + if (File.Exists(Helper.RotationFolderPath + "config.json")) + { + hosting = true; - Plugin.AddServerComp(); // add custom GBSU server component + AudioListener.volume = 0; // mute game audio - RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig("config.json", true); // load rotation config from Config/Rotation/config.json - ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port - MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config - MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig + Plugin.AddServerComp(); // add custom GBSU server component + + try + { + RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig("config.json", true); // load rotation config from Config/Rotation/config.json + ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port + MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config + MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig + } + catch (Exception e) + { + PushError("Looks like you've caught a bug! Please send your log file to us :)\n" + e); + } + } + else + { + PushError(@$"No config.json could be found in {Helper.RotationFolderPath} +Make sure to download a file from the examples given and rename it to config.json. +{Helper.FilesInRotationDir()}"); + } + } + else + { + PushError("Please stay on the main menu to begin hosting. Tip: You might need to exit your lobby."); } } if (GUI.Button(new Rect(195f, 260f, 170f, 30f), "Join")) { if (LobbyManager.Instance.LobbyStates.SelfState == LobbyState.Game.Online) { - if (!hosting && serverip != null && serverport != 0) + if (!hosting) { LobbyManager.Instance.LobbyStates.IP = serverip; LobbyManager.Instance.LobbyStates.Port = serverport; @@ -108,10 +133,22 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword LobbyManager.Instance.LocalBeasts.SetupNetMemberContext(true); MonoSingleton.Instance.UNetManager.LaunchClient(serverip, serverport); } - + else + { + PushError("You are currently hosting a match! Please restart the game before attempting to join."); + } + } + else + { + PushError("Failed to join lobby! Please select the Online option in-game before joining."); } } } + else + { + PushError("Couldn't find the -ip CLI argument. Please refer to the documentation."); + } + if (GUI.Button(new Rect(20f, 295f, 170f, 30f), "Cap FPS to 60")) { Application.targetFrameRate = 60; @@ -133,7 +170,7 @@ Set CLI arguments: -ip, -port, -servername, -serverpassword QualitySettings.vSyncCount = vsync_switch; } - + GUI.Label(new Rect(20f, 365f, 365f, 400f), $@" Current map: {currentmap} @@ -151,6 +188,19 @@ Please refer to the documentation for more information."); GUI.DragWindow(new Rect(0, 0, 10000, 10000)); } + private void ShowError(int window) + { + GUI.skin.label.alignment = TextAnchor.MiddleCenter; + + GUILayout.Label(error_msg); + + if (GUI.Button(new Rect(420f, 135f, 85f, 30f), "Close")) + { + error_shown = false; + } + + GUI.DragWindow(new Rect(0, 0, 10000, 10000)); + } private string UpdateScoreDisplay() { if (hosting) @@ -165,11 +215,25 @@ Please refer to the documentation for more information."); return null; } + private void PushError(string message) + { + Plugin.Log.LogError(message); + + // Push this error to the UI + error_msg = message; + error_shown = true; + } + public void OnGUI() { if (menu_shown) { gmenu = GUILayout.Window(121, gmenu, ShowOurWindow, $"{Plugin.PluginName} [{Plugin.PluginVersion}]"); } + + if (error_shown) + { + error_dialog = GUILayout.Window(122, error_dialog, ShowError, "An error occurred!"); + } } } \ No newline at end of file diff --git a/Addons/Helper.cs b/Addons/Helper.cs index b674c1c..c910d8b 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -1,4 +1,6 @@ using System; +using System.IO; +using UnityEngine; using UnityEngine.Analytics; namespace GBSU.Addons; @@ -31,4 +33,28 @@ public class Helper Plugin.Log.LogError("Could not create rotation folder path: " + e.Message); } } + public static string FilesInRotationDir() + { + // https://stackoverflow.com/a/14877330 + DirectoryInfo d = new(RotationFolderPath); + FileInfo[] files = d.GetFiles(); + int number = files.Length; + + // no files? + if (number == 0) + { + return @"No files were found in the directory."; + } + else + { + string names = ""; + + foreach(FileInfo file in files) + { + names = file.Name + " " + names; + } + + return $"There are {number} files: {names}"; + } + } } \ No newline at end of file From 2e5d5a99426600c5d03daf7c38990f5cae12e680 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 12:06:27 +0200 Subject: [PATCH 19/36] fix: remove useless cli arguments from in-game guide --- Addons/GBSUGui.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 7ee7580..8565f99 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -70,7 +70,7 @@ public class GBSUGui : MonoBehaviour GUI.skin.label.alignment = TextAnchor.UpperLeft; GUILayout.Label($@"==Guide== -Set CLI arguments: -ip, -port, -servername, -serverpassword +Set CLI arguments: -ip, -port [Hosting] 1. Create a config in Gang Beasts_Data/Config/Rotation/config.json From 2619d05374a8bcabf026351482935eff987f0c39 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 12:09:32 +0200 Subject: [PATCH 20/36] fix: vsync toggle --- Addons/GBSUGui.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 8565f99..44bddc7 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -25,7 +25,6 @@ public class GBSUGui : MonoBehaviour string serverip = null; int serverport = 5999; string currentmap; - int vsync_switch; bool hosting = false; private void Start() { @@ -37,8 +36,6 @@ public class GBSUGui : MonoBehaviour { int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", true), out serverport); } - - vsync_switch = QualitySettings.vSyncCount; } private void Update() { @@ -159,16 +156,14 @@ Make sure to download a file from the examples given and rename it to config.jso } if (GUI.Button(new Rect(20f, 330f, 170f, 30f), "Toggle VSync")) { - if (vsync_switch == 0) + if (QualitySettings.vSyncCount == 0) { - vsync_switch = 1; + QualitySettings.vSyncCount = 1; } else { - vsync_switch = 0; + QualitySettings.vSyncCount = 0; } - - QualitySettings.vSyncCount = vsync_switch; } GUI.Label(new Rect(20f, 365f, 365f, 400f), $@" From 31e2cda45bb997b28b98f222feba1942b539d06a Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 12:18:40 +0200 Subject: [PATCH 21/36] refactor: use MyPluginInfo for plugin attributes --- .vscode/settings.json | 3 +++ Addons/GBSUGui.cs | 2 +- Plugin.cs | 12 ++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index dc400bf..3a66143 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,14 +1,17 @@ { "cSpell.words": [ "allmaps", + "anavoi", "Behaviour", "currentmap", "Dont", + "Gaboule", "gamemode", "GBSU", "gmenu", "hlapi", "netstandard", + "playercount", "protontricks", "rotationconfig", "serverip", diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 44bddc7..e11e3c6 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -223,7 +223,7 @@ Please refer to the documentation for more information."); { if (menu_shown) { - gmenu = GUILayout.Window(121, gmenu, ShowOurWindow, $"{Plugin.PluginName} [{Plugin.PluginVersion}]"); + gmenu = GUILayout.Window(121, gmenu, ShowOurWindow, $"{MyPluginInfo.PLUGIN_NAME} [{MyPluginInfo.PLUGIN_VERSION}]"); } if (error_shown) diff --git a/Plugin.cs b/Plugin.cs index ac523ee..4345841 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Reflection; using BepInEx; using BepInEx.Logging; @@ -11,7 +11,7 @@ using UnityEngine; namespace GBSU; -[BepInPlugin(PluginGUID, PluginName, PluginVersion)] +[BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] [BepInProcess("Gang Beasts.exe")] public class Plugin : BaseUnityPlugin { @@ -40,10 +40,10 @@ public class Plugin : BaseUnityPlugin { // Plugin startup logic Log = base.Logger; - Log.LogInfo($"\n------\nPlugin {PluginName} [{PluginVersion}] is loaded!\n------\n"); + Log.LogInfo($"\n------\nPlugin {MyPluginInfo.PLUGIN_NAME} [{MyPluginInfo.PLUGIN_VERSION}] is loaded!\n------\n"); HarmonyFileLog.Enabled = true; - var harmony = new Harmony(PluginGUID); + var harmony = new Harmony(MyPluginInfo.PLUGIN_GUID); harmony.PatchAll(Assembly.GetExecutingAssembly()); GBSUCompInit(); @@ -81,8 +81,4 @@ public class Plugin : BaseUnityPlugin Log.LogDebug("Adding GBSUServer component"); GBSUCompContainer.AddComponent(); } - - public const string PluginGUID = "com.gaboule.plugins.gbsu"; - public const string PluginName = "Gang Beasts Server Utility"; - public const string PluginVersion = "1.0.2"; } From 06c4eba087b563246771cff4764d73f6750d10f7 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 12:23:33 +0200 Subject: [PATCH 22/36] 1.0.3 --- GBSU.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GBSU.csproj b/GBSU.csproj index 2a42d53..10a02a9 100644 --- a/GBSU.csproj +++ b/GBSU.csproj @@ -4,7 +4,7 @@ netstandard2.0 GBSU Gang Beasts Server Utility - 1.0.2 + 1.0.3 true latest From 02361d278dbe673597b2cb1a927b4383d2701cf5 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 12:36:26 +0200 Subject: [PATCH 23/36] refactor: avoid setting a variable (tracking the current scene) changing its value more often than it can be displayed --- Addons/GBSUGui.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index e11e3c6..432c611 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -24,7 +24,6 @@ public class GBSUGui : MonoBehaviour readonly IInputSystem inputSystem = UnityInput.Current; string serverip = null; int serverport = 5999; - string currentmap; bool hosting = false; private void Start() { @@ -44,8 +43,6 @@ public class GBSUGui : MonoBehaviour //Plugin.Log.LogInfo("Toggling GBSU menu..."); ToggleMenu(); } - - currentmap = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; } private void ToggleMenu() @@ -168,7 +165,7 @@ Make sure to download a file from the examples given and rename it to config.jso GUI.Label(new Rect(20f, 365f, 365f, 400f), $@" -Current map: {currentmap} +Current map: {UnityEngine.SceneManagement.SceneManager.GetActiveScene().name} Lobby State: {LobbyManager.Instance.LobbyStates.SelfState} VSync: {QualitySettings.vSyncCount} Target FPS: {Application.targetFrameRate} From 4b61948f68d3b5a806fbd53736c4c165533b4861 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 13:27:51 +0200 Subject: [PATCH 24/36] docs: added known issues section --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca415d8..a1dbf6c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This mod allows you to connect to a Gang Beasts server in recent versions (throu **NOTICE: This is not a "Cement" mod, and we don't want to be affiliated with their developers. This mod is standalone, and will work best on its own!** # Features -- LAN (ethernet switches at LAN parties) and Online (port forwarding, ZeroTier, Wireguard) multiplayer +- LAN (Ethernet switches at LAN parties) and Online (port forwarding, ZeroTier, Wireguard) multiplayer - Custom score handling made by the server (we don't want to use the game's score handler) # Installation @@ -62,6 +62,10 @@ On Steam, simply put `WINEDLLOVERRIDES="winhttp.dll=n,b" %command%` in your laun If it's still not working, try using `winecfg` for your prefix or `protontricks` and go to the libraries tab in Wine Configuration. Simply add `winhttp` as an override and check if it's correctly set as "native, then builtin" (or "n,b"). +# Known issues +- This mode uses the game's netcode. It is poorly made, and you get noticeable latency on localhost (RTT is 10ms). It seems that there's no client-side prediction. +- The custom score handler is broken + # Contact us ## Need help? Ask us on [Matrix](https://matrix.to/#/#gbsu:gaboule.com). From 0cb71314356bc7f8c0516d5b16033d684b7a6b05 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 16:16:41 +0200 Subject: [PATCH 25/36] refactor: wip --- Addons/GBSUClient.cs | 17 +++++++++++++++ Addons/GBSUGui.cs | 50 ++++++++------------------------------------ Addons/GBSUServer.cs | 10 +++++++++ Addons/Helper.cs | 15 +++++++++++++ Plugin.cs | 22 +++++++++++++++---- 5 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 Addons/GBSUClient.cs diff --git a/Addons/GBSUClient.cs b/Addons/GBSUClient.cs new file mode 100644 index 0000000..2fb7562 --- /dev/null +++ b/Addons/GBSUClient.cs @@ -0,0 +1,17 @@ +using GB.Core; +using GB.Platform.Lobby; +using UnityEngine; + +namespace GBSU.Addons; + +public class GBSUClient : MonoBehaviour +{ + public static void JoinServer(string serverip, int serverport) + { + LobbyManager.Instance.LobbyStates.IP = serverip; + LobbyManager.Instance.LobbyStates.Port = serverport; + LobbyManager.Instance.LobbyStates.CurrentState = LobbyState.State.Ready | LobbyState.State.InGame; + LobbyManager.Instance.LocalBeasts.SetupNetMemberContext(true); + MonoSingleton.Instance.UNetManager.LaunchClient(serverip, serverport); + } +} \ No newline at end of file diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 432c611..badbf38 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -1,10 +1,7 @@ using System; using System.IO; using BepInEx; -using CoreNet.Config; -using GB.Config; -using GB.Core; -using GB.Game; +using CoreNet.Utils; using GB.Platform.Lobby; using UnityEngine; @@ -22,20 +19,6 @@ public class GBSUGui : MonoBehaviour private string error_msg = "Unknown error!"; readonly IInputSystem inputSystem = UnityInput.Current; - string serverip = null; - int serverport = 5999; - bool hosting = false; - private void Start() - { - if (CommandLineParser.Instance.KeyExists("-ip")) - { - serverip = CommandLineParser.Instance.GetValueForKey("-ip", true); - } - if (CommandLineParser.Instance.KeyExists("-port")) - { - int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", true), out serverport); - } - } private void Update() { if (inputSystem.GetKeyDown(KeyCode.RightShift)) @@ -77,7 +60,7 @@ Set CLI arguments: -ip, -port { Application.Quit(0); } - if (serverip != null) + if (Helper.serverip != null) { if (GUI.Button(new Rect(20f, 260f, 170f, 30f), "Host")) { @@ -85,18 +68,14 @@ Set CLI arguments: -ip, -port { if (File.Exists(Helper.RotationFolderPath + "config.json")) { - hosting = true; + Helper.hosting = true; AudioListener.volume = 0; // mute game audio - Plugin.AddServerComp(); // add custom GBSU server component - try { - RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig("config.json", true); // load rotation config from Config/Rotation/config.json - ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port - MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config - MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig + Plugin.AddServerComp(); // add custom GBSU server component + GBSUServer.StartServer(); } catch (Exception e) { @@ -119,13 +98,9 @@ Make sure to download a file from the examples given and rename it to config.jso { if (LobbyManager.Instance.LobbyStates.SelfState == LobbyState.Game.Online) { - if (!hosting) + if (!Helper.hosting) { - LobbyManager.Instance.LobbyStates.IP = serverip; - LobbyManager.Instance.LobbyStates.Port = serverport; - LobbyManager.Instance.LobbyStates.CurrentState = LobbyState.State.Ready | LobbyState.State.InGame; - LobbyManager.Instance.LocalBeasts.SetupNetMemberContext(true); - MonoSingleton.Instance.UNetManager.LaunchClient(serverip, serverport); + GBSUClient.JoinServer(Helper.serverip, Helper.serverport); } else { @@ -153,14 +128,7 @@ Make sure to download a file from the examples given and rename it to config.jso } if (GUI.Button(new Rect(20f, 330f, 170f, 30f), "Toggle VSync")) { - if (QualitySettings.vSyncCount == 0) - { - QualitySettings.vSyncCount = 1; - } - else - { - QualitySettings.vSyncCount = 0; - } + Helper.FlipVSync(); } GUI.Label(new Rect(20f, 365f, 365f, 400f), $@" @@ -195,7 +163,7 @@ Please refer to the documentation for more information."); } private string UpdateScoreDisplay() { - if (hosting) + if (Helper.hosting) { string scoreString = "Score:\n"; foreach (var pair in Plugin.GameScore) diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index b2c57b8..2ab58be 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -1,3 +1,6 @@ +using CoreNet.Config; +using GB.Config; +using GB.Core; using GB.Game; using HarmonyLib; using UnityEngine; @@ -29,6 +32,13 @@ public class GBSUServer : MonoBehaviour localSingleGang?.SetValue(false); } + public static void StartServer() + { + RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig("config.json", true); // load rotation config from Config/Rotation/config.json + ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port + MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config + MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig + } /* public string GetRemainingRoundTime() { diff --git a/Addons/Helper.cs b/Addons/Helper.cs index c910d8b..daa4d4b 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -8,6 +8,9 @@ public class Helper { public static string RotationFolderPath = Application.dataPath + "/Config/Rotation/"; public static string GameConfigPath = RotationFolderPath + "config.json"; + public static string serverip = null; + public static int serverport = 5999; + public static bool hosting = false; public static void DisableAnalytics() { // Try disabling analytics https://docs.unity3d.com/ScriptReference/Analytics.Analytics-deviceStatsEnabled.html @@ -57,4 +60,16 @@ public class Helper return $"There are {number} files: {names}"; } } + + public static void FlipVSync() + { + if (QualitySettings.vSyncCount == 0) + { + QualitySettings.vSyncCount = 1; + } + else + { + QualitySettings.vSyncCount = 0; + } + } } \ No newline at end of file diff --git a/Plugin.cs b/Plugin.cs index 4345841..5b2b533 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Reflection; using BepInEx; using BepInEx.Logging; @@ -54,6 +54,16 @@ public class Plugin : BaseUnityPlugin Helper.CreateRotationFolder(); Log.LogDebug("Server game config should be found at " + Helper.GameConfigPath); + + // Parse CLI arguments + if (CommandLineParser.Instance.KeyExists("-ip")) + { + Helper.serverip = CommandLineParser.Instance.GetValueForKey("-ip", true); + } + if (CommandLineParser.Instance.KeyExists("-port")) + { + int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", true), out Helper.serverport); + } } private static void GBSUCompInit() @@ -66,6 +76,13 @@ public class Plugin : BaseUnityPlugin } public static void AddServerComp() + { + DestroyServerComp(); + Log.LogDebug("Adding GBSUServer component"); + GBSUCompContainer.AddComponent(); + } + + public static void DestroyServerComp() { Component[] comps = GBSUCompContainer.GetComponents(typeof(Component)); foreach (var comp in comps) @@ -77,8 +94,5 @@ public class Plugin : BaseUnityPlugin Destroy(comp); } } - - Log.LogDebug("Adding GBSUServer component"); - GBSUCompContainer.AddComponent(); } } From 20ca020d028ad9d61fa147fc313ab0425c839953 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 16:17:37 +0200 Subject: [PATCH 26/36] fix: remove hosting status if it fails --- Addons/GBSUGui.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index badbf38..0d3e369 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -80,6 +80,8 @@ Set CLI arguments: -ip, -port catch (Exception e) { PushError("Looks like you've caught a bug! Please send your log file to us :)\n" + e); + Helper.hosting = false; + Plugin.DestroyServerComp(); } } else From 4771a41fa7ba40a3de5f52f9eb309ca8164295aa Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 21:49:21 +0200 Subject: [PATCH 27/36] refactor: unused import --- Addons/GBSUGui.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 0d3e369..1d72761 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -1,7 +1,6 @@ using System; using System.IO; using BepInEx; -using CoreNet.Utils; using GB.Platform.Lobby; using UnityEngine; From 8132f69ed26790c397d8e84c511d49738aac51ab Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 23:32:42 +0200 Subject: [PATCH 28/36] fix(breaking): better handling of the server rotation config The config path was also changed to `BepInEx/config/GBSU/config.json` Tracks the -maplist argument --- .vscode/settings.json | 2 ++ Addons/GBSUGui.cs | 10 +++++----- Addons/GBSUServer.cs | 2 +- Addons/Helper.cs | 12 +++++++++++- GBSU.csproj | 3 +++ Patches/ConfigLoader.cs | 35 +++++++++++++++++++++++++++++++++++ Plugin.cs | 7 +++++-- README.md | 12 +++++++----- 8 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 Patches/ConfigLoader.cs diff --git a/.vscode/settings.json b/.vscode/settings.json index 3a66143..2ff4ec6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,9 @@ "GBSU", "gmenu", "hlapi", + "maplist", "netstandard", + "Newtonsoft", "playercount", "protontricks", "rotationconfig", diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 1d72761..2e6cd6e 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -11,11 +11,11 @@ namespace GBSU.Addons; public class GBSUGui : MonoBehaviour { private bool menu_shown; - private bool error_shown; + private static bool error_shown; //private string _currentMap; public Rect gmenu = new(Screen.width / 2, 0, 385f, 690f); public Rect error_dialog = new(Screen.width / 2, 0, 520f, 175f); - private string error_msg = "Unknown error!"; + private static string error_msg = "Unknown error!"; readonly IInputSystem inputSystem = UnityInput.Current; private void Update() @@ -46,7 +46,7 @@ public class GBSUGui : MonoBehaviour GUI.skin.label.alignment = TextAnchor.UpperLeft; GUILayout.Label($@"==Guide== -Set CLI arguments: -ip, -port +Set CLI arguments: -ip, -port (optionally -maplist) [Hosting] 1. Create a config in Gang Beasts_Data/Config/Rotation/config.json @@ -65,7 +65,7 @@ Set CLI arguments: -ip, -port { if (LobbyManager.Instance.LobbyStates.SelfState == LobbyState.Game.Menu) { - if (File.Exists(Helper.RotationFolderPath + "config.json")) + if (File.Exists(Helper.GameConfigPath)) { Helper.hosting = true; @@ -176,7 +176,7 @@ Please refer to the documentation for more information."); return null; } - private void PushError(string message) + public static void PushError(string message) { Plugin.Log.LogError(message); diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index 2ab58be..7f7302b 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -34,7 +34,7 @@ public class GBSUServer : MonoBehaviour public static void StartServer() { - RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig("config.json", true); // load rotation config from Config/Rotation/config.json + RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig(null); // the argument doesn't matter as we do stuff in the method ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig diff --git a/Addons/Helper.cs b/Addons/Helper.cs index daa4d4b..454b68f 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -6,7 +6,7 @@ using UnityEngine.Analytics; namespace GBSU.Addons; public class Helper { - public static string RotationFolderPath = Application.dataPath + "/Config/Rotation/"; + public static string RotationFolderPath = BepInEx.Paths.BepInExRootPath + "/config/GBSU/"; public static string GameConfigPath = RotationFolderPath + "config.json"; public static string serverip = null; public static int serverport = 5999; @@ -72,4 +72,14 @@ public class Helper QualitySettings.vSyncCount = 0; } } + + public static void CheckCustomRotationPath() + { + // Did the host request to use their own rotation config path? + if (CommandLineParser.Instance.KeyExists("-maplist")) + { + GameConfigPath = CommandLineParser.Instance.GetValueForKey("-maplist"); + Plugin.Log.LogInfo("Set custom rotation config path at " + GameConfigPath); + } + } } \ No newline at end of file diff --git a/GBSU.csproj b/GBSU.csproj index 10a02a9..e892787 100644 --- a/GBSU.csproj +++ b/GBSU.csproj @@ -42,5 +42,8 @@ ref/UnityEngine.CoreModule.dll + + ref/Newtonsoft.Json.dll + diff --git a/Patches/ConfigLoader.cs b/Patches/ConfigLoader.cs new file mode 100644 index 0000000..10f6c83 --- /dev/null +++ b/Patches/ConfigLoader.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using GB.Config; +using GBSU.Addons; +using HarmonyLib; +using Newtonsoft.Json; + +namespace GBSU.Patches; + +[HarmonyPatch] +class ConfigLoaderPatch +{ + [HarmonyPatch(typeof(GBConfigLoader), "LoadRotationConfig")] + private static bool Prefix(ref RotationConfig __result) + { + string text = ""; // contents of file + + Plugin.Log.LogInfo("Loading custom rotation config..."); + + // Reading from file + try + { + text = File.ReadAllText(Helper.GameConfigPath); + Plugin.Log.LogDebug("Provided rotation config:\n" + text); + RotationConfig rc = JsonConvert.DeserializeObject(text); + __result = rc; + } + catch (Exception e) + { + GBSUGui.PushError("Couldn't read game config file. A few details:\n" + e); + } + + return false; // skip + } +} \ No newline at end of file diff --git a/Plugin.cs b/Plugin.cs index 5b2b533..c4a2a57 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -58,12 +58,15 @@ public class Plugin : BaseUnityPlugin // Parse CLI arguments if (CommandLineParser.Instance.KeyExists("-ip")) { - Helper.serverip = CommandLineParser.Instance.GetValueForKey("-ip", true); + Helper.serverip = CommandLineParser.Instance.GetValueForKey("-ip", false); } if (CommandLineParser.Instance.KeyExists("-port")) { - int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", true), out Helper.serverport); + int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", false), out Helper.serverport); } + + // "-maplist" CLI + Helper.CheckCustomRotationPath(); } private static void GBSUCompInit() diff --git a/README.md b/README.md index a1dbf6c..30548cb 100644 --- a/README.md +++ b/README.md @@ -31,11 +31,13 @@ Press `Right Shift` to open the mod GUI. Because of how the game is made, you ne ## Server (host) ### Setting up the server -1. Open the `Gang Beasts_Data` folder in the "server" game instance files. -2. Create two new folders: `Config/Rotation` -3. Download the [one of the config files](https://git.gaboule.com/Gaboule/GBSU/src/branch/main/docs/configs) and place it inside the `Rotation` folder. +1. Open the `BepInEx` folder in the "server" game instance files. +2. Create a `GBSU` folder in `config`. +3. Download the [one of the config files](https://git.gaboule.com/Gaboule/GBSU/src/branch/main/docs/configs) and place it inside the `GBSU` folder. 4. Rename the file to `config.json` +**Tip: your config file can also be anywhere else! Use the -maplist argument followed by the path to the file,** for example `-ip 192.168.1.2 -port 5999 -maplist "/home/user/mycustomconfig.json"` + ### Configuring your custom server settings * If you set `"random": true`, the map order will be randomized. * Some maps may have different names in-game compared to their actual titles. Make sure to refer to the [`allmaps` configs](https://git.gaboule.com/Gaboule/GBSU/src/branch/main/docs/configs) for the map names. @@ -45,7 +47,7 @@ Once the config file is in place, host your server by pressing the **Host** butt ## Client (player) 1. In the game menu, choose **Online**. -2. If you're planning to team up with friends, make sure your [server config]() is set to the `gang` gamemode and choose a shared color. Otherwise, use a different color than your friends. +2. If you're planning to team up with friends, make sure your server config is set to the `gang` gamemode and choose a shared color. Otherwise, use a different color than your friends. 3. Open the mod menu and press **Join**. # Troubleshooting @@ -64,7 +66,7 @@ If it's still not working, try using `winecfg` for your prefix or `protontricks` # Known issues - This mode uses the game's netcode. It is poorly made, and you get noticeable latency on localhost (RTT is 10ms). It seems that there's no client-side prediction. -- The custom score handler is broken +- The custom score handler only tracks through colors, and is only visible on the host side. # Contact us ## Need help? From 962bcaf199db617665d886e40b47ace0c74728ce Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 23:33:10 +0200 Subject: [PATCH 29/36] perf: removed useless info logging --- Patches/MultiplayerPatches.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Patches/MultiplayerPatches.cs b/Patches/MultiplayerPatches.cs index c8b7f35..76c486e 100644 --- a/Patches/MultiplayerPatches.cs +++ b/Patches/MultiplayerPatches.cs @@ -49,8 +49,7 @@ class HandleScorePatch Plugin.Log.LogDebug("Done processing all scores!"); } - - Plugin.Log.LogInfo("Not letting HandleScore run..."); + return false; } } From 5eedbf2f1e6738476209149127b0a2bf32d23944 Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 23:47:40 +0200 Subject: [PATCH 30/36] feat: start/stop server handling The original app volume is also restored when the server is stopped. --- Addons/GBSUGui.cs | 15 ++++++++------- Addons/GBSUServer.cs | 23 +++++++++++++++++++++++ Addons/Helper.cs | 1 + Plugin.cs | 3 +++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 2e6cd6e..cac5917 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -67,20 +67,14 @@ Set CLI arguments: -ip, -port (optionally -maplist) { if (File.Exists(Helper.GameConfigPath)) { - Helper.hosting = true; - - AudioListener.volume = 0; // mute game audio - try { - Plugin.AddServerComp(); // add custom GBSU server component GBSUServer.StartServer(); } catch (Exception e) { PushError("Looks like you've caught a bug! Please send your log file to us :)\n" + e); - Helper.hosting = false; - Plugin.DestroyServerComp(); + GBSUServer.StopServer(); } } else @@ -131,6 +125,13 @@ Make sure to download a file from the examples given and rename it to config.jso { Helper.FlipVSync(); } + if (Helper.hosting) + { + if (GUI.Button(new Rect(195f, 330f, 170f, 30f), "Stop server")) + { + GBSUServer.StopServer(); + } + } GUI.Label(new Rect(20f, 365f, 365f, 400f), $@" diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index 7f7302b..2197a47 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -4,6 +4,7 @@ using GB.Core; using GB.Game; using HarmonyLib; using UnityEngine; +using UnityEngine.SceneManagement; #pragma warning disable IDE0051 // Private member is unused @@ -34,11 +35,33 @@ public class GBSUServer : MonoBehaviour public static void StartServer() { + Helper.hosting = true; + AudioListener.volume = 0; // mute game audio + + Plugin.AddServerComp(); // add custom GBSU server component + RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig(null); // the argument doesn't matter as we do stuff in the method ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig } + + public static void StopServer() + { + // WIP: At the moment the only way to stop the server is to exit/kill the game + Helper.hosting = false; + + AudioListener.volume = Helper.saved_volume; // restore volume + + // stop network listener + MonoSingleton.Instance.UNetManager.StopServer(); + + // destroy GBSU server comp + Plugin.DestroyServerComp(); + + // go back to main menu + SceneManager.LoadScene("Menu"); + } /* public string GetRemainingRoundTime() { diff --git a/Addons/Helper.cs b/Addons/Helper.cs index 454b68f..16b4a19 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -11,6 +11,7 @@ public class Helper public static string serverip = null; public static int serverport = 5999; public static bool hosting = false; + public static float saved_volume; public static void DisableAnalytics() { // Try disabling analytics https://docs.unity3d.com/ScriptReference/Analytics.Analytics-deviceStatsEnabled.html diff --git a/Plugin.cs b/Plugin.cs index c4a2a57..ed90b37 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -67,6 +67,9 @@ public class Plugin : BaseUnityPlugin // "-maplist" CLI Helper.CheckCustomRotationPath(); + + // store app volume in a variable to restore it if needed + Helper.saved_volume = AudioListener.volume; } private static void GBSUCompInit() From b9a7a1c4797153af5c4465578d6451c71a360cfe Mon Sep 17 00:00:00 2001 From: anavoi Date: Sun, 13 Jul 2025 23:55:54 +0200 Subject: [PATCH 31/36] fix: catch more edge cases --- Addons/GBSUClient.cs | 17 ++++++++++++----- Addons/GBSUGui.cs | 13 +------------ Addons/GBSUServer.cs | 19 +++++++++++-------- Plugin.cs | 4 ++++ 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/Addons/GBSUClient.cs b/Addons/GBSUClient.cs index 2fb7562..6b05a36 100644 --- a/Addons/GBSUClient.cs +++ b/Addons/GBSUClient.cs @@ -8,10 +8,17 @@ public class GBSUClient : MonoBehaviour { public static void JoinServer(string serverip, int serverport) { - LobbyManager.Instance.LobbyStates.IP = serverip; - LobbyManager.Instance.LobbyStates.Port = serverport; - LobbyManager.Instance.LobbyStates.CurrentState = LobbyState.State.Ready | LobbyState.State.InGame; - LobbyManager.Instance.LocalBeasts.SetupNetMemberContext(true); - MonoSingleton.Instance.UNetManager.LaunchClient(serverip, serverport); + if (!Helper.hosting) + { + LobbyManager.Instance.LobbyStates.IP = serverip; + LobbyManager.Instance.LobbyStates.Port = serverport; + LobbyManager.Instance.LobbyStates.CurrentState = LobbyState.State.Ready | LobbyState.State.InGame; + LobbyManager.Instance.LocalBeasts.SetupNetMemberContext(true); + MonoSingleton.Instance.UNetManager.LaunchClient(serverip, serverport); + } + else + { + GBSUGui.PushError("You are currently hosting a game! Please stop your server before attempting to join."); + } } } \ No newline at end of file diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index cac5917..24c080f 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -93,14 +93,7 @@ Make sure to download a file from the examples given and rename it to config.jso { if (LobbyManager.Instance.LobbyStates.SelfState == LobbyState.Game.Online) { - if (!Helper.hosting) - { - GBSUClient.JoinServer(Helper.serverip, Helper.serverport); - } - else - { - PushError("You are currently hosting a match! Please restart the game before attempting to join."); - } + GBSUClient.JoinServer(Helper.serverip, Helper.serverport); } else { @@ -108,10 +101,6 @@ Make sure to download a file from the examples given and rename it to config.jso } } } - else - { - PushError("Couldn't find the -ip CLI argument. Please refer to the documentation."); - } if (GUI.Button(new Rect(20f, 295f, 170f, 30f), "Cap FPS to 60")) { diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index 2197a47..157f6de 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -35,15 +35,18 @@ public class GBSUServer : MonoBehaviour public static void StartServer() { - Helper.hosting = true; - AudioListener.volume = 0; // mute game audio + if (!Helper.hosting) + { + Helper.hosting = true; + AudioListener.volume = 0; // mute game audio - Plugin.AddServerComp(); // add custom GBSU server component - - RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig(null); // the argument doesn't matter as we do stuff in the method - ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port - MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config - MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig + Plugin.AddServerComp(); // add custom GBSU server component + + RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig(null); // the argument doesn't matter as we do stuff in the method + ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port + MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config + MonoSingleton.Instance.UNetManager.GetComponent().ChangeRotationConfig(gameConfig, 0); // set server's rotationconfig + } } public static void StopServer() diff --git a/Plugin.cs b/Plugin.cs index ed90b37..98947a4 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -60,6 +60,10 @@ public class Plugin : BaseUnityPlugin { Helper.serverip = CommandLineParser.Instance.GetValueForKey("-ip", false); } + else + { + GBSUGui.PushError("Couldn't find the -ip CLI argument. Please refer to the documentation."); + } if (CommandLineParser.Instance.KeyExists("-port")) { int.TryParse(CommandLineParser.Instance.GetValueForKey("-port", false), out Helper.serverport); From 34d9e9261e3b5aea2831522e3c9aa1d8500fda5a Mon Sep 17 00:00:00 2001 From: anavoi Date: Mon, 14 Jul 2025 00:14:11 +0200 Subject: [PATCH 32/36] feat: added "menu" panic button This avoids restarting the game when encountering an unknown issue. --- Addons/GBSUClient.cs | 8 ++++++++ Addons/GBSUGui.cs | 4 ++++ Addons/GBSUServer.cs | 5 ++--- Addons/Helper.cs | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Addons/GBSUClient.cs b/Addons/GBSUClient.cs index 6b05a36..a800c62 100644 --- a/Addons/GBSUClient.cs +++ b/Addons/GBSUClient.cs @@ -1,4 +1,5 @@ using GB.Core; +using GB.Networking.Utils; using GB.Platform.Lobby; using UnityEngine; @@ -21,4 +22,11 @@ public class GBSUClient : MonoBehaviour GBSUGui.PushError("You are currently hosting a game! Please stop your server before attempting to join."); } } + + // this method should be used when something has went wrong + // because players can just use the escape menu to exit + public static void DisconnectFromServer() + { + GBNetUtils.DisconnectSelf(false); + } } \ No newline at end of file diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 24c080f..3053d5d 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -59,6 +59,10 @@ Set CLI arguments: -ip, -port (optionally -maplist) { Application.Quit(0); } + if (GUI.Button(new Rect(320f, 45f, 55f, 30f), "Menu")) + { + Helper.SwitchToMenu(); + } if (Helper.serverip != null) { if (GUI.Button(new Rect(20f, 260f, 170f, 30f), "Host")) diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index 157f6de..8df60df 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -4,7 +4,6 @@ using GB.Core; using GB.Game; using HarmonyLib; using UnityEngine; -using UnityEngine.SceneManagement; #pragma warning disable IDE0051 // Private member is unused @@ -41,7 +40,7 @@ public class GBSUServer : MonoBehaviour AudioListener.volume = 0; // mute game audio Plugin.AddServerComp(); // add custom GBSU server component - + RotationConfig gameConfig = GBConfigLoader.LoadRotationConfig(null); // the argument doesn't matter as we do stuff in the method ServerConfig serverConfig = NetConfigLoader.LoadServerConfig(); // load default server config, because it can be overridden by args like -ip and -port MonoSingleton.Instance.UNetManager.LaunchServer(serverConfig); // launch the server with the server config @@ -63,7 +62,7 @@ public class GBSUServer : MonoBehaviour Plugin.DestroyServerComp(); // go back to main menu - SceneManager.LoadScene("Menu"); + Helper.SwitchToMenu(); } /* public string GetRemainingRoundTime() diff --git a/Addons/Helper.cs b/Addons/Helper.cs index 16b4a19..0139ddc 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -1,7 +1,11 @@ using System; using System.IO; +using GB.Core; +using GB.Networking.Utils; +using GB.Platform.Lobby; using UnityEngine; using UnityEngine.Analytics; +using UnityEngine.SceneManagement; namespace GBSU.Addons; public class Helper @@ -83,4 +87,32 @@ public class Helper Plugin.Log.LogInfo("Set custom rotation config path at " + GameConfigPath); } } + + public static void SwitchToMenu() + { + if (hosting) + { + GBSUGui.PushError("Please press the Stop server button instead!"); + } + else + { + // uhm, time to panic! + + // let's begin by disconnecting if theres an active connection + try + { + GBNetUtils.DisconnectSelf(false); + } + catch (Exception e) + { + Plugin.Log.LogWarning("Couldn't disconnect from server:\n" + e); + } + + // go back to main menu + SceneManager.LoadScene(Global.MENU_SCENE_NAME); + + // make sure our lobby state is menu + LobbyManager.Instance.LobbyStates.SelfState = LobbyState.Game.Menu; + } + } } \ No newline at end of file From 60706fb255f8cbf67ad0d07a3750a5cf2d4a0b9a Mon Sep 17 00:00:00 2001 From: anavoi Date: Mon, 14 Jul 2025 00:15:04 +0200 Subject: [PATCH 33/36] fix: make sure volume is set to 0 when entering server mode --- Addons/GBSUServer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Addons/GBSUServer.cs b/Addons/GBSUServer.cs index 8df60df..06ee5e8 100644 --- a/Addons/GBSUServer.cs +++ b/Addons/GBSUServer.cs @@ -26,6 +26,8 @@ public class GBSUServer : MonoBehaviour //_gmInit = AccessTools.Method(typeof(GameMode), "Init"); localSingleGang = Traverse.Create(nameof(GameMode)).Field("localSingleGang"); gameTimer = Traverse.Create(nameof(GameMode)).Field("timer"); + + AudioListener.volume = 0; // mute game audio } void SetLocalGangToOff() { @@ -37,7 +39,6 @@ public class GBSUServer : MonoBehaviour if (!Helper.hosting) { Helper.hosting = true; - AudioListener.volume = 0; // mute game audio Plugin.AddServerComp(); // add custom GBSU server component From 3f155169853b3417bccc033ac0a3f1760a369462 Mon Sep 17 00:00:00 2001 From: anavoi Date: Mon, 14 Jul 2025 00:16:40 +0200 Subject: [PATCH 34/36] 1.1.0 --- GBSU.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GBSU.csproj b/GBSU.csproj index e892787..181772b 100644 --- a/GBSU.csproj +++ b/GBSU.csproj @@ -4,7 +4,7 @@ netstandard2.0 GBSU Gang Beasts Server Utility - 1.0.3 + 1.1.0 true latest From ea77c98c2fe9f41450312fb0c932634293bed5a0 Mon Sep 17 00:00:00 2001 From: anavoi Date: Mon, 14 Jul 2025 23:31:20 +0200 Subject: [PATCH 35/36] style: format code --- Addons/GBSUClient.cs | 2 +- Addons/GBSUGui.cs | 2 +- Addons/Helper.cs | 4 ++-- GBSU.csproj | 2 +- Patches/ConfigLoader.cs | 12 ++++++------ Patches/MultiplayerPatches.cs | 2 +- Plugin.cs | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Addons/GBSUClient.cs b/Addons/GBSUClient.cs index a800c62..bdf45f1 100644 --- a/Addons/GBSUClient.cs +++ b/Addons/GBSUClient.cs @@ -29,4 +29,4 @@ public class GBSUClient : MonoBehaviour { GBNetUtils.DisconnectSelf(false); } -} \ No newline at end of file +} diff --git a/Addons/GBSUGui.cs b/Addons/GBSUGui.cs index 3053d5d..367ef0a 100644 --- a/Addons/GBSUGui.cs +++ b/Addons/GBSUGui.cs @@ -191,4 +191,4 @@ Please refer to the documentation for more information."); error_dialog = GUILayout.Window(122, error_dialog, ShowError, "An error occurred!"); } } -} \ No newline at end of file +} diff --git a/Addons/Helper.cs b/Addons/Helper.cs index 0139ddc..5a35ade 100644 --- a/Addons/Helper.cs +++ b/Addons/Helper.cs @@ -57,7 +57,7 @@ public class Helper { string names = ""; - foreach(FileInfo file in files) + foreach (FileInfo file in files) { names = file.Name + " " + names; } @@ -115,4 +115,4 @@ public class Helper LobbyManager.Instance.LobbyStates.SelfState = LobbyState.Game.Menu; } } -} \ No newline at end of file +} diff --git a/GBSU.csproj b/GBSU.csproj index 181772b..ea614bf 100644 --- a/GBSU.csproj +++ b/GBSU.csproj @@ -21,7 +21,7 @@ - + diff --git a/Patches/ConfigLoader.cs b/Patches/ConfigLoader.cs index 10f6c83..b34bfda 100644 --- a/Patches/ConfigLoader.cs +++ b/Patches/ConfigLoader.cs @@ -19,17 +19,17 @@ class ConfigLoaderPatch // Reading from file try - { + { text = File.ReadAllText(Helper.GameConfigPath); Plugin.Log.LogDebug("Provided rotation config:\n" + text); RotationConfig rc = JsonConvert.DeserializeObject(text); - __result = rc; - } - catch (Exception e) - { + __result = rc; + } + catch (Exception e) + { GBSUGui.PushError("Couldn't read game config file. A few details:\n" + e); } return false; // skip } -} \ No newline at end of file +} diff --git a/Patches/MultiplayerPatches.cs b/Patches/MultiplayerPatches.cs index 76c486e..647331f 100644 --- a/Patches/MultiplayerPatches.cs +++ b/Patches/MultiplayerPatches.cs @@ -49,7 +49,7 @@ class HandleScorePatch Plugin.Log.LogDebug("Done processing all scores!"); } - + return false; } } diff --git a/Plugin.cs b/Plugin.cs index 98947a4..973fe75 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -18,7 +18,7 @@ public class Plugin : BaseUnityPlugin public static Dictionary GameScore = []; private static GameObject _gbsuCompContainer; internal static ManualLogSource Log; - + public static GameObject GBSUCompContainer { get @@ -98,7 +98,7 @@ public class Plugin : BaseUnityPlugin foreach (var comp in comps) { Log.LogDebug("iterating thru singleton comps"); - if(comp is GBSUServer) + if (comp is GBSUServer) { Log.LogDebug("GBSUServer component was found! Destroying it"); Destroy(comp); From 3964e268ee4e3ed64d1905ec74b6c8db4291455e Mon Sep 17 00:00:00 2001 From: anavoi Date: Mon, 11 Aug 2025 00:30:52 +0200 Subject: [PATCH 36/36] ci: bump SDK version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30548cb..2c366c7 100644 --- a/README.md +++ b/README.md @@ -79,4 +79,4 @@ Want a new feature? Found a bug? [Open an issue!](https://git.gaboule.com/Gaboul - The mod is made for BepInEx 5 - The targeted Unity version is `2020.3.5f1` - The TFM is `netstandard2.0` -- The mod is built using .NET SDK `9.0.103` \ No newline at end of file +- The mod is built using .NET SDK `9.0.304` \ No newline at end of file