Skip to content

Commit 6da56c7

Browse files
committed
Refactored patch loading (Skins handling doesnt work yet)
1 parent 0042774 commit 6da56c7

3 files changed

Lines changed: 121 additions & 63 deletions

File tree

src/Loader.cs

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,25 @@ namespace PolyMod;
2020

2121
public static class Loader
2222
{
23-
internal static Dictionary<string, Type> typeMappings = new()
23+
internal record TypeMapping(Type type, bool shouldCreateCache = true);
24+
internal static Dictionary<string, TypeMapping> typeMappings = new()
2425
{
25-
{ "tribeData", typeof(TribeData.Type) },
26-
{ "techData", typeof(TechData.Type) },
27-
{ "unitData", typeof(UnitData.Type) },
28-
{ "improvementData", typeof(ImprovementData.Type) },
29-
{ "terrainData", typeof(Polytopia.Data.TerrainData.Type) },
30-
{ "resourceData", typeof(ResourceData.Type) },
31-
{ "taskData", typeof(TaskData.Type) },
32-
{ "tribeAbility", typeof(TribeAbility.Type) },
33-
{ "unitAbility", typeof(UnitAbility.Type) },
34-
{ "improvementAbility", typeof(ImprovementAbility.Type) },
35-
{ "playerAbility", typeof(PlayerAbility.Type) },
36-
{ "weaponData", typeof(UnitData.WeaponEnum) }
26+
{ "tribeData", new TypeMapping(typeof(TribeData.Type)) },
27+
{ "techData", new TypeMapping(typeof(TechData.Type)) },
28+
{ "unitData", new TypeMapping(typeof(UnitData.Type)) },
29+
{ "improvementData", new TypeMapping(typeof(ImprovementData.Type)) },
30+
{ "terrainData", new TypeMapping(typeof(Polytopia.Data.TerrainData.Type)) },
31+
{ "resourceData", new TypeMapping(typeof(ResourceData.Type)) },
32+
{ "taskData", new TypeMapping(typeof(TaskData.Type)) },
33+
{ "tribeAbility", new TypeMapping(typeof(TribeAbility.Type)) },
34+
{ "unitAbility", new TypeMapping(typeof(UnitAbility.Type)) },
35+
{ "improvementAbility", new TypeMapping(typeof(ImprovementAbility.Type)) },
36+
{ "playerAbility", new TypeMapping(typeof(PlayerAbility.Type)) },
37+
{ "weaponData", new TypeMapping(typeof(UnitData.WeaponEnum)) },
38+
{ "skinData", new TypeMapping(typeof(SkinData), false) }
3739
};
3840
internal static List<GameModeButtonsInformation> gamemodes = new();
39-
private static readonly Dictionary<Type, Action<JObject, bool>> typeHandlers = new()
41+
internal static readonly Dictionary<Type, Action<JObject, bool>> typeHandlers = new()
4042
{
4143
[typeof(TribeData.Type)] = new((token, duringEnumCacheCreation) =>
4244
{
@@ -49,6 +51,31 @@ public static class Loader
4951
}
5052
else
5153
{
54+
if (token["skins"] != null) // Doesnt work, and I do not know why! Good luck.
55+
{
56+
JArray skins = token["skins"].Cast<JArray>();
57+
List<JToken> skinValues = skins._values.ToArray().ToList();
58+
foreach (var skin in skinValues)
59+
{
60+
string skinValue = skin.ToString();
61+
if (!Enum.TryParse<SkinType>(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(skinValue), out _))
62+
{
63+
EnumCache<SkinType>.AddMapping(skinValue.ToLowerInvariant(), (SkinType)Registry.autoidx);
64+
EnumCache<SkinType>.AddMapping(skinValue.ToLowerInvariant(), (SkinType)Registry.autoidx);
65+
Registry.skinInfo.Add(new Visual.SkinInfo(Registry.autoidx, skinValue, null));
66+
Plugin.logger.LogInfo("Created mapping for skinType with id " + skinValue + " and index " + Registry.autoidx);
67+
Registry.autoidx++;
68+
}
69+
}
70+
foreach (var skin in Registry.skinInfo)
71+
{
72+
if (skins._values.Contains(skin.id))
73+
{
74+
skins._values.Remove(skin.id);
75+
skins._values.Add(skin.idx);
76+
}
77+
}
78+
}
5279
if (token["preview"] != null)
5380
{
5481
Visual.PreviewTile[] preview = JsonSerializer.Deserialize<Visual.PreviewTile[]>(token["preview"].ToString())!;
@@ -128,7 +155,26 @@ public static class Loader
128155
}
129156
PrefabManager.resources.TryAdd((ResourceData.Type)Registry.autoidx, PrefabManager.resources[resourcePrefabType]);
130157
}
131-
})
158+
}),
159+
160+
[typeof(SkinData)] = new((token, duringEnumCacheCreation) =>
161+
{
162+
string id = Util.GetJTokenName(token);
163+
int index = Registry.skinInfo.FindIndex(t => t.id == id);
164+
if (Registry.skinInfo.ElementAtOrDefault(index) != null)
165+
{
166+
SkinData skinData = new();
167+
if (token["color"] != null)
168+
{
169+
skinData.color = (int)token["color"];
170+
}
171+
if (token["language"] != null)
172+
{
173+
skinData.language = token["language"].ToString();
174+
}
175+
Registry.skinInfo[index] = new Visual.SkinInfo(Registry.skinInfo[index].idx, Registry.skinInfo[index].id, skinData);
176+
}
177+
}),
132178
};
133179

134180
public record GameModeButtonsInformation(int gameModeIndex, UIButtonBase.ButtonAction action, int? buttonIndex, Sprite? sprite);
@@ -144,7 +190,13 @@ public static void AddGameModeButton(string id, UIButtonBase.ButtonAction action
144190
public static void AddPatchDataType(string typeId, Type type)
145191
{
146192
if (!typeMappings.ContainsKey(typeId))
147-
typeMappings.Add(typeId, type);
193+
typeMappings.Add(typeId, new TypeMapping(type));
194+
}
195+
196+
public static void AddPatchDataType(string typeId, Type type, bool shouldCreateCache)
197+
{
198+
if (!typeMappings.ContainsKey(typeId))
199+
typeMappings.Add(typeId, new TypeMapping(type, shouldCreateCache));
148200
}
149201

150202
internal static void LoadMods(Dictionary<string, Mod> mods)
@@ -571,50 +623,6 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch)
571623
{
572624
try
573625
{
574-
foreach (JToken jtoken in patch.SelectTokens("$.*.*").ToArray())
575-
{
576-
JObject? token = jtoken.TryCast<JObject>();
577-
if (token != null)
578-
{
579-
string dataType = Util.GetJTokenName(token, 2);
580-
if (typeMappings.TryGetValue(dataType, out Type? targetType))
581-
{
582-
if (token["idx"] != null && (int)token["idx"] == -1)
583-
{
584-
string id = Util.GetJTokenName(token);
585-
token["idx"] = Registry.autoidx;
586-
MethodInfo? methodInfo = typeof(EnumCache<>).MakeGenericType(targetType).GetMethod("AddMapping");
587-
if (methodInfo != null)
588-
{
589-
methodInfo.Invoke(null, new object[] { id, Registry.autoidx });
590-
methodInfo.Invoke(null, new object[] { id, Registry.autoidx });
591-
592-
if (typeHandlers.TryGetValue(targetType, out var handler))
593-
{
594-
handler(token, true);
595-
}
596-
Plugin.logger.LogInfo("Created mapping for " + targetType.ToString() + " with id " + id + " and index " + Registry.autoidx);
597-
Registry.autoidx++;
598-
}
599-
}
600-
}
601-
}
602-
}
603-
foreach (JToken jtoken in patch.SelectTokens("$.*.*").ToArray())
604-
{
605-
JObject? token = jtoken.TryCast<JObject>();
606-
if (token != null)
607-
{
608-
string dataType = Util.GetJTokenName(token, 2);
609-
if (typeMappings.TryGetValue(dataType, out Type? targetType))
610-
{
611-
if (typeHandlers.TryGetValue(targetType, out var handler))
612-
{
613-
handler(token, false);
614-
}
615-
}
616-
}
617-
}
618626
gld = JsonMerger.Merge(gld, patch);
619627
Plugin.logger.LogInfo($"Registered patch from {mod.id} mod");
620628
}

src/Managers/Loc.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ private static bool Localization_Get(ref string key, Il2CppReferenceArray<Il2Cpp
5050
}
5151
if (idx != null)
5252
{
53-
foreach (var targetType in Loader.typeMappings.Values)
53+
foreach (var typeMapping in Loader.typeMappings.Values)
5454
{
55-
MethodInfo? methodInfo = typeof(EnumCache<>).MakeGenericType(targetType).GetMethod("TryGetName");
55+
MethodInfo? methodInfo = typeof(EnumCache<>).MakeGenericType(typeMapping.type).GetMethod("TryGetName");
5656
if (methodInfo != null)
5757
{
5858
object?[] parameters = { idx, null };

src/Managers/Main.cs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using BepInEx.Unity.IL2CPP.Logging;
22
using HarmonyLib;
3+
using Il2CppSystem.Linq;
34
using Newtonsoft.Json.Linq;
45
using Polytopia.Data;
56
using PolytopiaBackendBase.Game;
7+
using System.Reflection;
68
using System.Diagnostics;
79
using System.Text;
810
using System.Text.Json;
@@ -27,11 +29,56 @@ public static class Main
2729

2830
[HarmonyPrefix]
2931
[HarmonyPatch(typeof(GameLogicData), nameof(GameLogicData.AddGameLogicPlaceholders))]
30-
private static void GameLogicData_Parse(GameLogicData __instance, JObject rootObject)
32+
private static void GameLogicData_Parse(GameLogicData __instance, ref JObject rootObject)
3133
{
3234
if (!fullyInitialized)
3335
{
3436
Load(rootObject);
37+
foreach (JToken jtoken in rootObject.SelectTokens("$.*.*").ToArray())
38+
{
39+
JObject? token = jtoken.TryCast<JObject>();
40+
if (token != null)
41+
{
42+
string dataType = Util.GetJTokenName(token, 2);
43+
if (Loader.typeMappings.TryGetValue(dataType, out Loader.TypeMapping? typeMapping))
44+
{
45+
if (token["idx"] != null && (int)token["idx"] == -1 && typeMapping.shouldCreateCache)
46+
{
47+
Type targetType = typeMapping.type;
48+
string id = Util.GetJTokenName(token);
49+
token["idx"] = Registry.autoidx;
50+
MethodInfo? methodInfo = typeof(EnumCache<>).MakeGenericType(targetType).GetMethod("AddMapping");
51+
if (methodInfo != null)
52+
{
53+
methodInfo.Invoke(null, new object[] { id, Registry.autoidx });
54+
methodInfo.Invoke(null, new object[] { id, Registry.autoidx });
55+
56+
if (Loader.typeHandlers.TryGetValue(targetType, out var handler))
57+
{
58+
handler(token, true);
59+
}
60+
Plugin.logger.LogInfo("Created mapping for " + targetType.ToString() + " with id " + id + " and index " + Registry.autoidx);
61+
Registry.autoidx++;
62+
}
63+
}
64+
}
65+
}
66+
}
67+
foreach (JToken jtoken in rootObject.SelectTokens("$.*.*").ToArray())
68+
{
69+
JObject? token = jtoken.TryCast<JObject>();
70+
if (token != null)
71+
{
72+
string dataType = Util.GetJTokenName(token, 2);
73+
if (Loader.typeMappings.TryGetValue(dataType, out Loader.TypeMapping? typeMapping))
74+
{
75+
if (Loader.typeHandlers.TryGetValue(typeMapping.type, out var handler))
76+
{
77+
handler(token, false);
78+
}
79+
}
80+
}
81+
}
3582
foreach (System.Collections.Generic.KeyValuePair<int, string> item in Registry.prefabNames)
3683
{
3784
UnitData.Type unitPrefabType = UnitData.Type.Scout;
@@ -102,6 +149,9 @@ private static void GameLogicData_Parse(GameLogicData __instance, JObject rootOb
102149
}
103150
}
104151
fullyInitialized = true;
152+
string formattedJson = rootObject.ToString(Newtonsoft.Json.Formatting.Indented);
153+
File.WriteAllText(Path.Combine(Plugin.BASE_PATH, "output.json"), formattedJson);
154+
Console.Write("Saved");
105155
}
106156
}
107157

0 commit comments

Comments
 (0)