using System; using System.Collections.Generic; using System.Reflection; using System.Text.Json; using HarmonyLib; using undead_universal_patch_il2cpp.Core; using undead_universal_patch_il2cpp.Core.AssetChanges; namespace undead_universal_patch_il2cpp.Patches.AssetManager { public static class AGConfigEntryPatch_Common { public static Dictionary> Config = AGRoomChanges.config.Get(); } [HarmonyPatch] public class AGConfigEntryPatch_RoomScene { static readonly string TargetTypeName = "AGRoomSettings"; static readonly string TargetMethodName = "TryGetRoomSceneConfigById"; static readonly string Description = "AGRoomSettings data patch"; static readonly Type targetType = AccessTools.TypeByName(TargetTypeName); public static bool Prepare() { if (!AssetChangesConfig.AGRoomChanges.Value) return false; if (targetType == null) { Plugin.Log.LogWarning($"'{Description}' disabled. The type for this patch was not found."); return false; } if (AccessTools.Method(targetType, TargetMethodName) == null) { Plugin.Log.LogWarning($"'{Description}' disabled. The method for this patch was not found."); return false; } Plugin.Log.LogInfo($"'{Description}' succeeded validation."); return true; } static MethodBase TargetMethod() => AccessTools.Method(targetType, TargetMethodName); static void Postfix(ref string replicationId, ref AGRoomRuntimeConfig.Room roomConfig, ref AGRoomRuntimeConfig.RoomScene roomSceneConfig) { if (GenericConfig.PatchDebug.Value) Plugin.Log.LogDebug($"RoomScene patch for repid '{replicationId}'"); if (!AGConfigEntryPatch_Common.Config.ContainsKey(replicationId)) return; var changes = AGConfigEntryPatch_Common.Config[replicationId]; foreach (var change in changes) { PropertyInfo prop = AccessTools.Property(roomSceneConfig.GetType(), change.RecKey); if (prop == null) { Plugin.Log.LogWarning($"Key '{change.RecKey}' does not exist on the room scene for replication ID '{replicationId}'!"); continue; } if (change.RecValue is JsonElement element) { object value; if (prop.PropertyType.IsEnum) value = Enum.Parse(prop.PropertyType, element.GetRawText()); else value = JsonSerializer.Deserialize(element.GetRawText(), prop.PropertyType); prop.SetValue(roomSceneConfig, value); } else prop.SetValue(roomSceneConfig, change.RecValue); if (GenericConfig.PatchDebug.Value) Plugin.Log.LogDebug($"'{change.RecKey}' on repId '{replicationId}' is now '{change.RecValue}'"); } } } [HarmonyPatch] public class AGConfigEntryPatch_Location { static readonly string TargetTypeName = "AGRoomSettings"; static readonly string TargetMethodName = "TryGetLocationConfigById"; static readonly MethodInfo connectMethod = AccessTools.Method(AccessTools.TypeByName(TargetTypeName), TargetMethodName); static bool Prepare() => AGConfigEntryPatch_RoomScene.Prepare(); static MethodBase TargetMethod() => connectMethod; static void Postfix(ref string replicationId, ref AGRoomRuntimeConfig.Location locationConfig) { if (GenericConfig.PatchDebug.Value) Plugin.Log.LogDebug($"Location patch for repid '{replicationId}'"); if (!AGConfigEntryPatch_Common.Config.ContainsKey(replicationId)) return; var changes = AGConfigEntryPatch_Common.Config[replicationId]; foreach (var change in changes) { PropertyInfo prop = AccessTools.Property(locationConfig.GetType(), change.RecKey); if (prop == null) { Plugin.Log.LogWarning($"Key '{change.RecKey}' does not exist on the room scene for replication ID '{replicationId}'!"); continue; } if (change.RecValue is JsonElement element) { object value; if (prop.PropertyType.IsEnum) value = Enum.Parse(prop.PropertyType, element.GetRawText()); else value = JsonSerializer.Deserialize(element.GetRawText(), prop.PropertyType); prop.SetValue(locationConfig, value); } else prop.SetValue(locationConfig, change.RecValue); if (GenericConfig.PatchDebug.Value) Plugin.Log.LogDebug($"'{change.RecKey}' on repId '{replicationId}' is now '{change.RecValue}'"); } } } [HarmonyPatch] public class AGConfigEntryPatch_Room { static readonly string TargetTypeName = "AGRoomSettings"; static readonly string TargetMethodName = "TryGetRoomConfigById"; static readonly MethodInfo connectMethod = AccessTools.Method(AccessTools.TypeByName(TargetTypeName), TargetMethodName); static bool Prepare() => AGConfigEntryPatch_RoomScene.Prepare(); static MethodBase TargetMethod() => connectMethod; static void Postfix(ref string replicationId, ref AGRoomRuntimeConfig.Room roomConfig) { if (GenericConfig.PatchDebug.Value) Plugin.Log.LogDebug($"Roomconfig patch for repid '{replicationId}'"); if (!AGConfigEntryPatch_Common.Config.ContainsKey(replicationId)) return; var changes = AGConfigEntryPatch_Common.Config[replicationId]; foreach (var change in changes) { PropertyInfo prop = AccessTools.Property(roomConfig.GetType(), change.RecKey); if (prop == null) { Plugin.Log.LogWarning($"Key '{change.RecKey}' does not exist on the room scene for replication ID '{replicationId}'!"); continue; } if (change.RecValue is JsonElement element) { object value; if (prop.PropertyType.IsEnum) value = Enum.Parse(prop.PropertyType, element.GetRawText()); else value = JsonSerializer.Deserialize(element.GetRawText(), prop.PropertyType); prop.SetValue(roomConfig, value); } else prop.SetValue(roomConfig, change.RecValue); if (GenericConfig.PatchDebug.Value) Plugin.Log.LogDebug($"'{change.RecKey}' on repId '{replicationId}' is now '{change.RecValue}'"); } } } }