Skip to content

Commit e77df1f

Browse files
committed
Added dystopia stuff
1 parent 8bc3eb0 commit e77df1f

2 files changed

Lines changed: 158 additions & 23 deletions

File tree

src/Managers/Multiplayer.cs

Lines changed: 157 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,174 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading.Tasks;
5+
using BepInEx.Logging;
56
using HarmonyLib;
7+
using Polytopia.Data;
68

7-
namespace PolyMod.Managers
9+
namespace PolyMod.Managers;
10+
11+
public static class Multiplayer
812
{
9-
public static class Multiplayer
13+
internal const string DEFAULT_SERVER_URL = "https://dev.polydystopia.xyz";
14+
private const string GldMarker = "##GLD:";
15+
16+
// Cache parsed GLD by game Seed to handle rewinds/reloads
17+
private static readonly Dictionary<int, GameLogicData> _gldCache = new();
18+
private static readonly Dictionary<int, int> _versionCache = new(); // Seed -> modGldVersion
19+
20+
internal static void Init()
1021
{
11-
internal static void Init()
12-
{
13-
Harmony.CreateAndPatchAll(typeof(Multiplayer));
14-
BuildConfigHelper.GetSelectedBuildConfig().buildServerURL = BuildServerURL.Custom;
15-
BuildConfigHelper.GetSelectedBuildConfig().customServerURL = Plugin.config.backendUrl;
16-
}
22+
Harmony.CreateAndPatchAll(typeof(Multiplayer));
23+
BuildConfig buildConfig = BuildConfigHelper.GetSelectedBuildConfig();
24+
buildConfig.buildServerURL = BuildServerURL.Custom;
25+
buildConfig.customServerURL = Plugin.config.backendUrl;
26+
27+
Plugin.logger.LogInfo($"Polydystopia> Server URL set to: {Plugin.config.backendUrl}");
28+
Plugin.logger.LogInfo("Polydystopia> GLD patches applied");
29+
}
30+
31+
[HarmonyPostfix]
32+
[HarmonyPatch(typeof(MultiplayerScreen), nameof(MultiplayerScreen.Show))]
33+
public static void MultiplayerScreen_Show(MultiplayerScreen __instance)
34+
{
35+
__instance.multiplayerSelectionScreen.TournamentsButton.gameObject.SetActive(false);
36+
}
37+
1738

18-
[HarmonyPostfix]
19-
[HarmonyPatch(typeof(MultiplayerScreen), nameof(MultiplayerScreen.Show))]
20-
public static void MultiplayerScreen_Show(MultiplayerScreen __instance)
39+
[HarmonyPostfix]
40+
[HarmonyPatch(typeof(ProfileScreen), nameof(ProfileScreen.Start))]
41+
public static void ProfileScreen_Start(ProfileScreen __instance)
42+
{
43+
}
44+
45+
[HarmonyPostfix]
46+
[HarmonyPatch(typeof(StartScreen), nameof(StartScreen.Start))]
47+
private static void StartScreen_Start(StartScreen __instance)
48+
{
49+
__instance.highscoreButton.gameObject.SetActive(false);
50+
__instance.weeklyChallengesButton.gameObject.SetActive(false);
51+
}
52+
53+
/// <summary>
54+
/// After GameState deserialization, check for trailing GLD version ID and set mockedGameLogicData.
55+
/// The server appends "##GLD:" + modGldVersion (int) after the normal serialized data.
56+
/// </summary>
57+
[HarmonyPostfix]
58+
[HarmonyPatch(typeof(GameState), nameof(GameState.Deserialize))]
59+
private static void Deserialize_Postfix(GameState __instance, BinaryReader __0)
60+
{
61+
Plugin.logger?.LogDebug("Deserialize_Postfix: Entered");
62+
63+
try
2164
{
22-
__instance.multiplayerSelectionScreen.TournamentsButton.gameObject.SetActive(false);
23-
}
65+
var reader = __0;
66+
if (reader == null)
67+
{
68+
Plugin.logger?.LogWarning("Deserialize_Postfix: reader is null");
69+
return;
70+
}
71+
72+
var position = reader.BaseStream.Position;
73+
var length = reader.BaseStream.Length;
74+
var remaining = length - position;
2475

76+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Stream position={position}, length={length}, remaining={remaining}");
2577

26-
[HarmonyPostfix]
27-
[HarmonyPatch(typeof(ProfileScreen), nameof(ProfileScreen.Start))]
28-
public static void ProfileScreen_Start(ProfileScreen __instance)
78+
// Check if there's more data after normal deserialization
79+
if (position >= length)
80+
{
81+
Plugin.logger?.LogDebug("Deserialize_Postfix: No trailing data (position >= length)");
82+
83+
var sd = __instance.Seed;
84+
if (_gldCache.TryGetValue(sd, out var cachedGld))
85+
{
86+
__instance.mockedGameLogicData = cachedGld;
87+
var cachedVersion = _versionCache.GetValueOrDefault(sd, -1);
88+
Plugin.logger?.LogInfo($"Deserialize_Postfix: Applied cached GLD for Seed={sd}, ModGldVersion={cachedVersion}");
89+
}
90+
return;
91+
}
92+
93+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Found {remaining} bytes of trailing data, attempting to read marker");
94+
95+
var marker = reader.ReadString();
96+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Read marker string: '{marker}'");
97+
98+
if (marker != GldMarker)
99+
{
100+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Marker mismatch - expected '{GldMarker}', got '{marker}'");
101+
return;
102+
}
103+
104+
Plugin.logger?.LogInfo($"Deserialize_Postfix: Found GLD marker '{GldMarker}'");
105+
106+
var modGldVersion = reader.ReadInt32();
107+
Plugin.logger?.LogInfo($"Deserialize_Postfix: Found embedded ModGldVersion: {modGldVersion}");
108+
109+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Fetching GLD from server for version {modGldVersion}");
110+
var gldJson = FetchGldById(modGldVersion);
111+
if (string.IsNullOrEmpty(gldJson))
112+
{
113+
Plugin.logger?.LogError($"Deserialize_Postfix: Failed to fetch GLD for ModGldVersion: {modGldVersion}");
114+
return;
115+
}
116+
117+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Parsing GLD JSON ({gldJson.Length} chars)");
118+
119+
var customGld = new GameLogicData();
120+
customGld.Parse(gldJson);
121+
__instance.mockedGameLogicData = customGld;
122+
123+
// Cache for subsequent deserializations (rewinds, reloads)
124+
var seed = __instance.Seed;
125+
_gldCache[seed] = customGld;
126+
_versionCache[seed] = modGldVersion;
127+
128+
Plugin.logger?.LogInfo($"Deserialize_Postfix: Successfully set mockedGameLogicData from ModGldVersion: {modGldVersion}, cached for Seed={seed}");
129+
}
130+
catch (EndOfStreamException)
131+
{
132+
Plugin.logger?.LogDebug("Deserialize_Postfix: EndOfStreamException - no trailing data");
133+
}
134+
catch (Exception ex)
29135
{
136+
Plugin.logger?.LogError($"Deserialize_Postfix: Exception: {ex.GetType().Name}: {ex.Message}");
137+
Plugin.logger?.LogDebug($"Deserialize_Postfix: Stack trace: {ex.StackTrace}");
30138
}
139+
}
140+
141+
/// <summary>
142+
/// Fetch GLD from server using ModGldVersion ID
143+
/// </summary>
144+
private static string? FetchGldById(int modGldVersion)
145+
{
146+
try
147+
{
148+
using var client = new HttpClient();
149+
var url = $"{Plugin.config.backendUrl.TrimEnd('/')}/api/mods/gld/{modGldVersion}";
150+
Plugin.logger?.LogDebug($"FetchGldById: Requesting URL: {url}");
151+
152+
var response = client.GetAsync(url).Result;
153+
Plugin.logger?.LogDebug($"FetchGldById: Response status: {response.StatusCode}");
31154

32-
[HarmonyPostfix]
33-
[HarmonyPatch(typeof(StartScreen), nameof(StartScreen.Start))]
34-
private static void StartScreen_Start(StartScreen __instance)
155+
if (response.IsSuccessStatusCode)
156+
{
157+
var gld = response.Content.ReadAsStringAsync().Result;
158+
Plugin.logger?.LogInfo($"FetchGldById: Successfully fetched mod GLD ({gld.Length} chars)");
159+
return gld;
160+
}
161+
162+
var errorContent = response.Content.ReadAsStringAsync().Result;
163+
Plugin.logger?.LogError($"FetchGldById: Failed with status {response.StatusCode}: {errorContent}");
164+
}
165+
catch (Exception ex)
35166
{
36-
__instance.highscoreButton.gameObject.SetActive(false);
37-
__instance.weeklyChallengesButton.gameObject.SetActive(false);
167+
Plugin.logger?.LogError($"FetchGldById: Exception: {ex.GetType().Name}: {ex.Message}");
168+
if (ex.InnerException != null)
169+
{
170+
Plugin.logger?.LogError($"FetchGldById: Inner exception: {ex.InnerException.Message}");
171+
}
38172
}
173+
return null;
39174
}
40-
}
175+
}

src/Plugin.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public partial class Plugin : BepInEx.Unity.IL2CPP.BasePlugin
2222
/// <param name="updatePrerelease">Whether to include pre-release versions when updating.</param>
2323
internal record PolyConfig(
2424
bool debug = false,
25-
string backendUrl = "http://127.0.0.1:8090",
25+
string backendUrl = Multiplayer.DEFAULT_SERVER_URL,
2626
bool autoUpdate = true,
2727
bool updatePrerelease = false,
2828
bool allowUnsafeIndexes = false

0 commit comments

Comments
 (0)