Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of VL Visualization v0.0.3
CustomTextures.dll
Decompiled 8 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+003dfdbd75fd910447d0fac30f7b8ff890ece525")] [assembly: AssemblyVersion("1.0.0.0")] public class TextureScale { public class ThreadData { public int start; public int end; public ThreadData(int s, int e) { start = s; end = e; } } private static Color[] texColors; private static Color[] newColors; private static int w; private static float ratioX; private static float ratioY; private static int w2; private static int finishCount; private static Mutex mutex; public static void Point(Texture2D tex, int newWidth, int newHeight) { ThreadedScale(tex, newWidth, newHeight, useBilinear: false); } public static void Bilinear(Texture2D tex, int newWidth, int newHeight) { ThreadedScale(tex, newWidth, newHeight, useBilinear: true); } private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear) { texColors = tex.GetPixels(); newColors = (Color[])(object)new Color[newWidth * newHeight]; if (useBilinear) { ratioX = 1f / ((float)newWidth / (float)(((Texture)tex).width - 1)); ratioY = 1f / ((float)newHeight / (float)(((Texture)tex).height - 1)); } else { ratioX = (float)((Texture)tex).width / (float)newWidth; ratioY = (float)((Texture)tex).height / (float)newHeight; } w = ((Texture)tex).width; w2 = newWidth; int num = Mathf.Min(SystemInfo.processorCount, newHeight); int num2 = newHeight / num; finishCount = 0; if (mutex == null) { mutex = new Mutex(initiallyOwned: false); } if (num > 1) { int num3 = 0; ThreadData parameter; for (num3 = 0; num3 < num - 1; num3++) { parameter = new ThreadData(num2 * num3, num2 * (num3 + 1)); ParameterizedThreadStart start = (useBilinear ? new ParameterizedThreadStart(BilinearScale) : new ParameterizedThreadStart(PointScale)); Thread thread = new Thread(start); thread.Start(parameter); } parameter = new ThreadData(num2 * num3, newHeight); if (useBilinear) { BilinearScale(parameter); } else { PointScale(parameter); } while (finishCount < num) { Thread.Sleep(1); } } else { ThreadData obj = new ThreadData(0, newHeight); if (useBilinear) { BilinearScale(obj); } else { PointScale(obj); } } tex.Resize(newWidth, newHeight); tex.SetPixels(newColors); tex.Apply(); texColors = null; newColors = null; } public static void BilinearScale(object obj) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) ThreadData threadData = (ThreadData)obj; for (int i = threadData.start; i < threadData.end; i++) { int num = (int)Mathf.Floor((float)i * ratioY); int num2 = num * w; int num3 = (num + 1) * w; int num4 = i * w2; for (int j = 0; j < w2; j++) { int num5 = (int)Mathf.Floor((float)j * ratioX); float value = (float)j * ratioX - (float)num5; newColors[num4 + j] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[num2 + num5], texColors[num2 + num5 + 1], value), ColorLerpUnclamped(texColors[num3 + num5], texColors[num3 + num5 + 1], value), (float)i * ratioY - (float)num); } } mutex.WaitOne(); finishCount++; mutex.ReleaseMutex(); } public static void PointScale(object obj) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) ThreadData threadData = (ThreadData)obj; for (int i = threadData.start; i < threadData.end; i++) { int num = (int)(ratioY * (float)i) * w; int num2 = i * w2; for (int j = 0; j < w2; j++) { newColors[num2 + j] = texColors[(int)((float)num + ratioX * (float)j)]; } } mutex.WaitOne(); finishCount++; mutex.ReleaseMutex(); } private static Color ColorLerpUnclamped(Color c1, Color c2, float value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) return new Color(c1.r + (c2.r - c1.r) * value, c1.g + (c2.g - c1.g) * value, c1.b + (c2.b - c1.b) * value, c1.a + (c2.a - c1.a) * value); } } namespace CustomTextures; [BepInPlugin("aedenthorn.CustomTextures", "Custom Textures", "3.4.3")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded"); return false; } return true; } } [HarmonyPatch(typeof(FejdStartup), "SetupObjectDB")] private static class FejdStartup_SetupObjectDB_Patch { private static void Postfix() { if (modEnabled.Value) { stopwatch.Restart(); outputDump.Clear(); Dbgl("SetupObjectDB postfix"); ReplaceObjectDBTextures(); LogStopwatch("SetupObjectDB"); } } } [HarmonyPatch(typeof(ZoneSystem), "Awake")] private static class ZoneSystem_Awake_Patch { private static void Prefix(ZoneSystem __instance) { outputDump.Clear(); ReplaceZoneSystemTextures(__instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance, Dictionary<int, GameObject> ___m_namedPrefabs) { Dbgl("ZNetScene awake"); stopwatch.Restart(); ReplaceZNetSceneTextures(); LogStopwatch("ZNetScene"); ReplaceEnvironmentTextures(); } } private static class Player_Start_Patch { private static void Prefix(Player __instance) { if (modEnabled.Value && !((Object)(object)Player.m_localPlayer != (Object)(object)__instance)) { Dbgl("Player Awake"); ReloadTextures(replaceLocationTextures.Value); } } } [HarmonyPatch(typeof(ClutterSystem), "Awake")] private static class ClutterSystem_Awake_Patch { private static void Postfix(ClutterSystem __instance) { Dbgl("Clutter system awake"); stopwatch.Restart(); logDump.Clear(); Dbgl($"Checking {__instance.m_clutter.Count} clutters"); foreach (Clutter item in __instance.m_clutter) { ReplaceOneGameObjectTextures(item.m_prefab, ((Object)item.m_prefab).name, "object"); } if (logDump.Any()) { Dbgl("\n" + string.Join("\n", logDump)); } LogStopwatch("Clutter System"); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_Patch { private static void Prefix() { if (replaceLocationTextures.Value) { Dbgl("Starting ZoneSystem Location prefab replacement"); stopwatch.Restart(); ReplaceLocationTextures(); LogStopwatch("ZoneSystem Locations"); } } } [HarmonyPatch(typeof(VisEquipment), "Awake")] private static class VisEquipment_Awake_Patch { private static void Postfix(VisEquipment __instance) { for (int i = 0; i < __instance.m_models.Length; i++) { string[] texturePropertyNames = __instance.m_models[i].m_baseMaterial.GetTexturePropertyNames(); foreach (string text in texturePropertyNames) { if (ShouldLoadCustomTexture($"player_model_{i}{text}")) { __instance.m_models[i].m_baseMaterial.SetTexture(text, (Texture)(object)LoadTexture($"player_model_{i}{text}", __instance.m_models[i].m_baseMaterial.GetTexture(text), isBump: false)); Dbgl($"set player_model_{i}_texture custom texture."); } else if (text == "_MainTex" && ShouldLoadCustomTexture($"player_model_{i}_texture")) { __instance.m_models[i].m_baseMaterial.SetTexture(text, (Texture)(object)LoadTexture($"player_model_{i}_texture", __instance.m_models[i].m_baseMaterial.GetTexture(text), isBump: false)); } else if (text == "_SkinBumpMap" && ShouldLoadCustomTexture($"player_model_{i}_bump")) { __instance.m_models[i].m_baseMaterial.SetTexture(text, (Texture)(object)LoadTexture($"player_model_{i}_bump", __instance.m_models[i].m_baseMaterial.GetTexture(text), isBump: true)); } } } } } [HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")] private static class Humanoid_SetupVisEquipment_Patch { private static void Postfix(Humanoid __instance) { if (modEnabled.Value) { SetupVisEquipment(__instance); } } } public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> dumpSceneTextures; public static ConfigEntry<bool> replaceLocationTextures; public static ConfigEntry<bool> reloadLocationTextures; public static ConfigEntry<string> hotKey; public static ConfigEntry<int> nexusID; private static readonly bool isDebug = true; private static BepInExPlugin context; private static Stopwatch stopwatch = new Stopwatch(); public static Dictionary<string, string> customTextures = new Dictionary<string, string>(); public static Dictionary<string, DateTime> fileWriteTimes = new Dictionary<string, DateTime>(); public static List<string> texturesToLoad = new List<string>(); public static List<string> layersToLoad = new List<string>(); public static Dictionary<string, Texture2D> cachedTextures = new Dictionary<string, Texture2D>(); public static List<string> outputDump = new List<string>(); public static List<string> logDump = new List<string>(); public static List<int> reloadedObjects = new List<int>(); public static void Dbgl(string str = "", bool pref = true) { if (isDebug) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); hotKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HotKey", "page down", "Key to reload textures"); replaceLocationTextures = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReplaceLocationTextures", true, "Replace textures for special locations (can take a long time)"); reloadLocationTextures = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReloadLocationTextures", false, "Reload textures for special locations on manual reload (can take a long time)"); dumpSceneTextures = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DumpSceneTextures", false, "Dump scene textures to BepInEx/plugins/CustomTextures/scene_dump.txt"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 48, "Nexus mod ID for updates"); if (modEnabled.Value) { LoadCustomTextures(); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } } private void Update() { if ((Object)(object)ZNetScene.instance != (Object)null && CheckKeyDown(hotKey.Value)) { Dbgl("Pressed reload key."); ReloadTextures(reloadLocationTextures.Value && replaceLocationTextures.Value); } } private static bool CheckKeyDown(string value) { try { return Input.GetKeyDown(value.ToLower()); } catch { return false; } } private static void LogStopwatch(string str) { stopwatch.Stop(); TimeSpan elapsed = stopwatch.Elapsed; string text = $"{elapsed.Hours:00}:{elapsed.Minutes:00}:{elapsed.Seconds:00}.{elapsed.Milliseconds / 10:00}"; Dbgl(str + " RunTime " + text); } private static bool HasCustomTexture(string id) { return customTextures.ContainsKey(id) || customTextures.Keys.ToList().Exists((string p) => p.StartsWith(id)); } private static bool ShouldLoadCustomTexture(string id) { return texturesToLoad.Contains(id) || layersToLoad.Contains(id); } private static void ReplaceOneGameObjectTextures(GameObject gameObject, string thingName, string prefix) { if (reloadedObjects.Contains(((Object)gameObject).GetInstanceID())) { return; } reloadedObjects.Add(((Object)gameObject).GetInstanceID()); if (thingName.Contains("_frac")) { if (dumpSceneTextures.Value) { outputDump.Add("skipping _frac " + thingName); } return; } bool flag = dumpSceneTextures.Value; if (flag && thingName.EndsWith("(Clone)")) { flag = false; } MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>(true); SkinnedMeshRenderer[] componentsInChildren2 = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true); InstanceRenderer[] componentsInChildren3 = gameObject.GetComponentsInChildren<InstanceRenderer>(true); ParticleSystemRenderer[] componentsInChildren4 = gameObject.GetComponentsInChildren<ParticleSystemRenderer>(true); LineRenderer[] componentsInChildren5 = gameObject.GetComponentsInChildren<LineRenderer>(true); if (componentsInChildren.Length != 0) { if (flag) { outputDump.Add($"{prefix} {thingName} has {componentsInChildren.Length} MeshRenderers:"); } MeshRenderer[] array = componentsInChildren; foreach (MeshRenderer val in array) { if ((Object)(object)val == (Object)null) { if (flag) { outputDump.Add("\tnull"); } continue; } if (flag) { outputDump.Add("\tMeshRenderer name: " + ((Object)val).name); } if (((Renderer)val).materials == null || !((Renderer)val).materials.Any()) { if (flag) { outputDump.Add("\t\trenderer " + ((Object)val).name + " has no materials"); } continue; } if (flag) { outputDump.Add($"\t\trenderer {((Object)val).name} has {((Renderer)val).materials.Length} materials"); } Material[] materials = ((Renderer)val).materials; foreach (Material val2 in materials) { if ((Object)(object)val2 == (Object)null) { continue; } try { if (flag) { outputDump.Add("\t\t\t" + ((Object)val2).name + ":"); } ReplaceMaterialTextures(((Object)gameObject).name, val2, thingName, prefix, "MeshRenderer", ((Object)val).name, flag); } catch (Exception arg) { logDump.Add($"\t\t\tError loading {((Object)val).name}:\r\n\r\n\t\t\t{arg}"); } } } } if (componentsInChildren2.Length != 0) { if (flag) { outputDump.Add($"{prefix} {thingName} has {componentsInChildren2.Length} SkinnedMeshRenderers:"); } SkinnedMeshRenderer[] array2 = componentsInChildren2; foreach (SkinnedMeshRenderer val3 in array2) { if ((Object)(object)val3 == (Object)null) { if (flag) { outputDump.Add("\tnull"); } continue; } if (flag) { outputDump.Add("\tSkinnedMeshRenderer name: " + ((Object)val3).name); } if (((Renderer)val3).materials == null || !((Renderer)val3).materials.Any()) { if (flag) { outputDump.Add("\t\tsmr " + ((Object)val3).name + " has no materials"); } continue; } if (flag) { outputDump.Add($"\t\tsmr {((Object)val3).name} has {((Renderer)val3).materials.Length} materials"); } Material[] materials2 = ((Renderer)val3).materials; foreach (Material val4 in materials2) { if ((Object)(object)val4 == (Object)null) { continue; } try { if (flag) { outputDump.Add("\t\t\t" + ((Object)val4).name + ":"); } ReplaceMaterialTextures(((Object)gameObject).name, val4, thingName, prefix, "SkinnedMeshRenderer", ((Object)val3).name, flag); } catch (Exception arg2) { logDump.Add($"\t\t\tError loading {((Object)val3).name}:\r\n\r\n\t\t\t{arg2}"); } } } } if (componentsInChildren3.Length != 0) { if (flag) { outputDump.Add($"{prefix} {thingName} has {componentsInChildren3.Length} InstanceRenderer:"); } InstanceRenderer[] array3 = componentsInChildren3; foreach (InstanceRenderer val5 in array3) { if ((Object)(object)val5 == (Object)null) { if (flag) { outputDump.Add("\tnull"); } continue; } if (flag) { outputDump.Add("\tInstanceRenderer name: " + ((Object)val5).name); } if ((Object)(object)val5.m_material == (Object)null) { if (flag) { outputDump.Add("\t\tir " + ((Object)val5).name + " has no material"); } continue; } try { if (flag) { outputDump.Add("\t\t\t" + ((Object)val5.m_material).name + ":"); } ReplaceMaterialTextures(((Object)gameObject).name, val5.m_material, thingName, prefix, "InstanceRenderer", ((Object)val5).name, flag); } catch (Exception arg3) { logDump.Add($"\t\t\tError loading {((Object)val5).name}:\r\n\r\n\t\t\t{arg3}"); } } } if (componentsInChildren4.Length != 0) { if (flag) { outputDump.Add($"{prefix} {thingName} has {componentsInChildren4.Length} ParticleSystemRenderers:"); } ParticleSystemRenderer[] array4 = componentsInChildren4; foreach (ParticleSystemRenderer val6 in array4) { if ((Object)(object)val6 == (Object)null) { if (flag) { outputDump.Add("\tnull"); } continue; } if (flag) { outputDump.Add("\tParticleSystemRenderer name: " + ((Object)val6).name); } Material[] materials3 = ((Renderer)val6).materials; foreach (Material val7 in materials3) { if ((Object)(object)val7 == (Object)null) { continue; } try { if (flag) { outputDump.Add("\t\t\t" + ((Object)val7).name + ":"); } ReplaceMaterialTextures(((Object)gameObject).name, val7, thingName, prefix, "ParticleSystemRenderer", ((Object)val6).name, flag); } catch (Exception arg4) { logDump.Add($"\t\t\tError loading {((Object)val6).name}:\r\n\r\n\t\t\t{arg4}"); } } } } if (componentsInChildren5.Length != 0) { if (flag) { outputDump.Add($"{prefix} {thingName} has {componentsInChildren5.Length} LineRenderers:"); } LineRenderer[] array5 = componentsInChildren5; foreach (LineRenderer val8 in array5) { if ((Object)(object)val8 == (Object)null) { if (flag) { outputDump.Add("\tnull"); } continue; } if (flag) { outputDump.Add("\tLineRenderers name: " + ((Object)val8).name); } Material[] materials4 = ((Renderer)val8).materials; foreach (Material val9 in materials4) { if ((Object)(object)val9 == (Object)null) { continue; } try { if (flag) { outputDump.Add("\t\t\t" + ((Object)val9).name + ":"); } ReplaceMaterialTextures(((Object)gameObject).name, val9, thingName, prefix, "LineRenderer", ((Object)val8).name, flag); } catch (Exception arg5) { logDump.Add($"\t\t\tError loading {((Object)val8).name}:\r\n\r\n\t\t\t{arg5}"); } } } } ItemDrop[] componentsInChildren6 = gameObject.GetComponentsInChildren<ItemDrop>(); ItemDrop[] array6 = componentsInChildren6; foreach (ItemDrop val10 in array6) { if ((Object)(object)val10 != (Object)null && (Object)(object)val10.m_itemData.m_shared.m_armorMaterial != (Object)null) { if (flag) { outputDump.Add("armor " + thingName + " has Material:"); } Material armorMaterial = val10.m_itemData.m_shared.m_armorMaterial; if (flag) { outputDump.Add("\tArmor name: " + ((Object)armorMaterial).name); } ReplaceMaterialTextures(((Object)gameObject).name, armorMaterial, thingName, "armor", "Armor", ((Object)gameObject).name, flag); } } } private static void ReplaceMaterialTextures(string goName, Material m, string thingName, string prefix, string rendererType, string rendererName, bool dump) { if ((Object)(object)m == (Object)null) { return; } if (dumpSceneTextures.Value) { outputDump.Add("\t\t\t\tproperties:"); } if (prefix == "item") { prefix = "object"; } string[] texturePropertyNames = m.GetTexturePropertyNames(); foreach (string text in texturePropertyNames) { if (dumpSceneTextures.Value) { List<string> list = outputDump; Texture texture = m.GetTexture(text); list.Add("\t\t\t\t\t" + text + " " + ((texture != null) ? ((Object)texture).name : null)); } int num = Shader.PropertyToID(text); Texture texture2 = m.GetTexture(num); string text2 = ((texture2 != null) ? ((Object)texture2).name : null); if (text2 == null) { text2 = thingName; } CheckSetMatTextures(goName, m, prefix, thingName, rendererType, rendererName, text2, text); } } private static void CheckSetMatTextures(string goName, Material m, string prefix, string thingName, string rendererType, string rendererName, string name, string property) { //IL_0242: Unknown result type (might be due to invalid IL or missing references) string[] array = MakePrefixStrings(prefix, thingName, rendererName, ((Object)m).name, name); foreach (string text in array) { if (!ShouldLoadCustomTexture(text + property)) { continue; } int num = Shader.PropertyToID(property); if (!m.HasProperty(num)) { continue; } Dbgl(prefix + " " + thingName + ", " + rendererType + " " + rendererName + ", material " + ((Object)m).name + ", texture " + name + ", using " + text + property + " for " + property + "."); Texture texture = m.GetTexture(num); Texture2D val = null; bool isBump = property.Contains("Bump") || property.Contains("Normal"); if (ShouldLoadCustomTexture(text + property)) { val = LoadTexture(text + property, texture, isBump); } else if (property == "_MainTex" && ShouldLoadCustomTexture(text + "_texture")) { val = LoadTexture(text + "_texture", texture, isBump); } else if (property == "_BumpMap" && ShouldLoadCustomTexture(text + "_bump")) { val = LoadTexture(text + "_bump", texture, isBump); } else if (property == "_StyleTex" && ShouldLoadCustomTexture(text + "_style")) { val = LoadTexture(text + "_style", texture, isBump); } if (!((Object)(object)val == (Object)null)) { ((Object)val).name = name; m.SetTexture(num, (Texture)(object)val); if ((Object)(object)val != (Object)null && property == "_MainTex") { m.SetColor(num, Color.white); } break; } } } private static string[] MakePrefixStrings(string prefix, string thingName, string rendererName, string matName, string name) { string[] array = new string[10] { prefix + "_" + thingName, prefix + "mesh_" + thingName + "_" + rendererName, prefix + "renderer_" + thingName + "_" + rendererName, prefix + "mat_" + thingName + "_" + matName, prefix + "renderermat_" + thingName + "_" + rendererName + "_" + matName, prefix + "texture_" + thingName + "_" + name, "mesh_" + rendererName, "renderer_" + rendererName, "mat_" + matName, "texture_" + name }; if (!thingName.EndsWith("(Clone)")) { return array; } List<string> list = new List<string>(array); thingName = thingName.Substring(0, thingName.Length - "(Clone)".Length); list.AddRange(new string[10] { prefix + "_" + thingName, prefix + "mesh_" + thingName + "_" + rendererName, prefix + "renderer_" + thingName + "_" + rendererName, prefix + "mat_" + thingName + "_" + matName, prefix + "renderermat_" + thingName + "_" + rendererName + "_" + matName, prefix + "texture_" + thingName + "_" + name, "mesh_" + rendererName, "renderer_" + rendererName, "mat_" + matName, "texture_" + name }); return list.ToArray(); } private static Texture2D LoadTexture(string id, Texture vanilla, bool isBump, bool point = true, bool needCustom = false, bool isSprite = false) { //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Expected O, but got Unknown //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Expected O, but got Unknown //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_071b: Unknown result type (might be due to invalid IL or missing references) //IL_06fc: Unknown result type (might be due to invalid IL or missing references) //IL_0701: Unknown result type (might be due to invalid IL or missing references) //IL_070f: Unknown result type (might be due to invalid IL or missing references) //IL_0736: Unknown result type (might be due to invalid IL or missing references) //IL_073b: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Unknown result type (might be due to invalid IL or missing references) //IL_0741: Unknown result type (might be due to invalid IL or missing references) //IL_074e: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Unknown result type (might be due to invalid IL or missing references) //IL_075a: Unknown result type (might be due to invalid IL or missing references) Texture2D val; if (cachedTextures.ContainsKey(id)) { logDump.Add("loading cached texture for " + id); val = cachedTextures[id]; if (customTextures.ContainsKey(id)) { if (customTextures[id].Contains("bilinear")) { ((Texture)val).filterMode = (FilterMode)1; } else if (customTextures[id].Contains("trilinear")) { ((Texture)val).filterMode = (FilterMode)2; } else if (customTextures[id].Contains($"{Path.DirectorySeparatorChar}point{Path.DirectorySeparatorChar}")) { ((Texture)val).filterMode = (FilterMode)2; } else if (point) { ((Texture)val).filterMode = (FilterMode)0; } } return val; } IEnumerable<KeyValuePair<string, string>> source = customTextures.Where((KeyValuePair<string, string> p) => p.Key.StartsWith(id + "_")); if (!customTextures.ContainsKey(id) && source.Count() == 0) { if (needCustom) { return null; } return (Texture2D)vanilla; } logDump.Add($"loading custom texture for {id} {source.Count()} layers"); if ((Object)(object)vanilla == (Object)null) { val = new Texture2D(2, 2, (TextureFormat)4, true, isBump); if (!customTextures.ContainsKey(id)) { byte[] array = File.ReadAllBytes(source.First().Value); ImageConversion.LoadImage(val, array); } } else { val = new Texture2D(vanilla.width, vanilla.height, (TextureFormat)4, true, isBump); } if (customTextures.ContainsKey(id)) { if (customTextures[id].Contains($"{Path.DirectorySeparatorChar}bilinear{Path.DirectorySeparatorChar}")) { ((Texture)val).filterMode = (FilterMode)1; } else if (customTextures[id].Contains($"{Path.DirectorySeparatorChar}trilinear{Path.DirectorySeparatorChar}")) { ((Texture)val).filterMode = (FilterMode)2; } else if (customTextures[id].Contains($"{Path.DirectorySeparatorChar}point{Path.DirectorySeparatorChar}")) { ((Texture)val).filterMode = (FilterMode)2; } else if (point) { ((Texture)val).filterMode = (FilterMode)0; } } else if (point) { ((Texture)val).filterMode = (FilterMode)0; } if (customTextures.ContainsKey(id)) { logDump.Add("loading custom texture file for " + id); byte[] array2 = File.ReadAllBytes(customTextures[id]); ImageConversion.LoadImage(val, array2); } else if ((Object)(object)vanilla != (Object)null) { Dbgl("texture " + id + " has no custom texture, using vanilla"); RenderTexture temporary = RenderTexture.GetTemporary(((Texture)val).width, ((Texture)val).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)(isBump ? 1 : 0)); Graphics.Blit(vanilla, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val2 = new Texture2D(vanilla.width, vanilla.height, (TextureFormat)4, true, isBump); val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0); val2.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); val.SetPixels(val2.GetPixels()); val.Apply(); } if (source.Count() > 0) { Dbgl($"texture {id} has {source.Count()} layers"); foreach (KeyValuePair<string, string> item in source.Skip(((Object)(object)vanilla == (Object)null && !customTextures.ContainsKey(id)) ? 1 : 0)) { Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, true, isBump); ((Texture)val3).filterMode = (FilterMode)(isSprite ? 1 : 0); byte[] array3 = File.ReadAllBytes(item.Value); ImageConversion.LoadImage(val3, array3); int result = 0; int result2 = 0; int result3 = ((Texture)val3).width; int result4 = ((Texture)val3).height; if (isSprite) { string[] array4 = item.Key.Substring(id.Length + 1).Split(new char[1] { '_' }); if (array4.Length != 4 || !int.TryParse(array4[0], out result) || !int.TryParse(array4[1], out result2) || !int.TryParse(array4[2], out result3) || !int.TryParse(array4[3], out result4)) { continue; } } float num = (float)((Texture)val).width / (float)result3; float num2 = (float)((Texture)val).height / (float)result4; if (num != num2) { continue; } logDump.Add($"adding layer {item.Key} to {id}, scale diff {num}"); int num3 = 0; int num4 = 0; int num5 = ((Texture)val3).width; int num6 = ((Texture)val3).height; if (isSprite) { num3 = result; num4 = result2; num5 = result + ((Texture)val3).width; num6 = result2 + ((Texture)val3).height; } if (num < 1f) { TextureScale.Bilinear(val, (int)((float)((Texture)val).width / num), (int)((float)((Texture)val).height / num)); } else if (num > 1f) { TextureScale.Bilinear(val3, (int)((float)((Texture)val3).width * num), (int)((float)((Texture)val3).height * num)); num3 = (int)((float)result * num); num4 = (int)((float)result2 * num); num5 = (int)((float)(result + ((Texture)val3).width) * num); num6 = (int)((float)(result2 + ((Texture)val3).height) * num); } List<string> list = new List<string>(); for (int i = num3; i < num5; i++) { for (int j = num4; j < num6; j++) { int num7 = i - num3; int num8 = j - num4; Color pixel = val3.GetPixel(num7, num8); if (isSprite) { pixel = val3.GetPixel(num7, ((Texture)val3).height - num8); val.SetPixel(i, ((Texture)val).height - j, pixel); } else if (pixel.a != 0f) { Color pixel2 = val.GetPixel(i, j); Color val4 = Color.Lerp(pixel2, pixel, pixel.a / 1f); val.SetPixel(i, j, val4); } } } val.Apply(); } bool flag = false; } cachedTextures[id] = val; return val; } private static void LoadCustomTextures() { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomTextures"); if (!Directory.Exists(text)) { Dbgl("Directory " + text + " does not exist! Creating."); Directory.CreateDirectory(text); return; } texturesToLoad.Clear(); string[] files = Directory.GetFiles(text, "*.*", SearchOption.AllDirectories); foreach (string text2 in files) { string fileName = Path.GetFileName(text2); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); if (!fileWriteTimes.ContainsKey(fileNameWithoutExtension) || (cachedTextures.ContainsKey(fileNameWithoutExtension) && !DateTime.Equals(File.GetLastWriteTimeUtc(text2), fileWriteTimes[fileNameWithoutExtension]))) { cachedTextures.Remove(fileNameWithoutExtension); texturesToLoad.Add(fileNameWithoutExtension); layersToLoad.Add(Regex.Replace(fileNameWithoutExtension, "_[^_]+\\.", ".")); fileWriteTimes[fileNameWithoutExtension] = File.GetLastWriteTimeUtc(text2); } customTextures[fileNameWithoutExtension] = text2; } } private static void ReloadTextures(bool locations) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown reloadedObjects.Clear(); outputDump.Clear(); logDump.Clear(); LoadCustomTextures(); ReplaceObjectDBTextures(); ReplaceSceneObjects(); Dbgl($"Replaced textures for {reloadedObjects.Count()} found unique objects"); Scene activeScene = SceneManager.GetActiveScene(); IEnumerable<GameObject> enumerable = from go in ((Scene)(ref activeScene)).GetRootGameObjects() where ((Object)go).name.StartsWith("_Zone") select go; Dbgl($"Replacing textures for {enumerable.Count()} zones"); foreach (GameObject item in enumerable) { ReplaceOneZoneTextures("_GameMain", item); } ReplaceZoneSystemTextures((ZoneSystem)typeof(ZoneSystem).GetField("m_instance", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null)); ReplaceHeightmapTextures(); ReplaceEnvironmentTextures(); ReplaceZNetSceneTextures(); if (locations) { Dbgl("Starting ZoneSystem Location prefab replacement"); stopwatch.Restart(); ReplaceLocationTextures(); LogStopwatch("ZoneSystem Locations"); } foreach (Player allPlayer in Player.GetAllPlayers()) { SetupVisEquipment((Humanoid)(object)allPlayer); } if (logDump.Any()) { Dbgl("\n" + string.Join("\n", logDump)); } Dbgl($"Checked {reloadedObjects.Count} objects total"); reloadedObjects.Clear(); if (dumpSceneTextures.Value) { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomTextures", "scene_dump.txt"); Dbgl("Writing " + text); File.WriteAllLines(text, outputDump); dumpSceneTextures.Value = false; } } private static void SetupVisEquipment(Humanoid humanoid) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown VisEquipment val = (VisEquipment)typeof(Humanoid).GetField("m_visEquipment", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(humanoid); if ((Object)(object)val != (Object)null) { SetEquipmentTexture(Traverse.Create((object)val).Field("m_leftItem").GetValue<string>(), Traverse.Create((object)val).Field("m_leftItemInstance").GetValue<GameObject>()); SetEquipmentTexture(Traverse.Create((object)val).Field("m_rightItem").GetValue<string>(), Traverse.Create((object)val).Field("m_rightItemInstance").GetValue<GameObject>()); SetEquipmentTexture(Traverse.Create((object)val).Field("m_helmetItem").GetValue<string>(), Traverse.Create((object)val).Field("m_helmetItemInstance").GetValue<GameObject>()); SetEquipmentTexture(Traverse.Create((object)val).Field("m_leftBackItem").GetValue<string>(), Traverse.Create((object)val).Field("m_leftBackItemInstance").GetValue<GameObject>()); SetEquipmentTexture(Traverse.Create((object)val).Field("m_rightBackItem").GetValue<string>(), Traverse.Create((object)val).Field("m_rightBackItemInstance").GetValue<GameObject>()); SetEquipmentListTexture(Traverse.Create((object)val).Field("m_shoulderItem").GetValue<string>(), Traverse.Create((object)val).Field("m_shoulderItemInstances").GetValue<List<GameObject>>()); SetEquipmentListTexture(Traverse.Create((object)val).Field("m_utilityItem").GetValue<string>(), Traverse.Create((object)val).Field("m_utilityItemInstances").GetValue<List<GameObject>>()); SetBodyEquipmentTexture(val, Traverse.Create((object)val).Field("m_legItem").GetValue<string>(), val.m_bodyModel, Traverse.Create((object)val).Field("m_legItemInstances").GetValue<List<GameObject>>()); SetBodyEquipmentTexture(val, Traverse.Create((object)val).Field("m_chestItem").GetValue<string>(), val.m_bodyModel, Traverse.Create((object)val).Field("m_chestItemInstances").GetValue<List<GameObject>>()); } } private static void ReplaceObjectDBTextures() { //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) logDump.Clear(); ObjectDB instance = ObjectDB.instance; Texture2D vanilla = null; foreach (GameObject item in instance.m_items) { if (item != null && item.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_icons.Length > 0) { vanilla = item.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0].texture; Dbgl("got atlas at item: " + ((Object)item).name); break; } } Texture2D val = LoadTexture("atlas_item_icons", (Texture)(object)vanilla, isBump: false, point: true, needCustom: true); Dbgl($"Replacing textures for {instance.m_items.Count} objects"); foreach (GameObject item2 in instance.m_items) { ItemDrop component = item2.GetComponent<ItemDrop>(); ReplaceOneGameObjectTextures(item2, ((Object)item2).name, "object"); if ((Object)(object)val != (Object)null) { for (int i = 0; i < component.m_itemData.m_shared.m_icons.Length; i++) { Sprite val2 = component.m_itemData.m_shared.m_icons[i]; float num = (float)((Texture)val).width / (float)((Texture)val2.texture).width; float num2 = (float)((Texture)val).height / (float)((Texture)val2.texture).height; float num3 = (num + num2) / 2f; Rect textureRect = val2.textureRect; float num4 = ((Rect)(ref textureRect)).x * num; textureRect = val2.textureRect; float num5 = ((Rect)(ref textureRect)).y * num2; textureRect = val2.textureRect; float num6 = ((Rect)(ref textureRect)).width * num; textureRect = val2.textureRect; val2 = Sprite.Create(val, new Rect(num4, num5, num6, ((Rect)(ref textureRect)).height * num2), Vector2.zero, val2.pixelsPerUnit * num3); component.m_itemData.m_shared.m_icons[i] = val2; } } } Traverse.Create((object)instance).Method("UpdateRegisters", Array.Empty<object>()).GetValue(); if (logDump.Any()) { Dbgl("\n" + string.Join("\n", logDump)); } } private static void ReplaceZNetSceneTextures() { logDump.Clear(); List<GameObject> list = new List<GameObject>(); foreach (Clutter item in ClutterSystem.instance.m_clutter) { if (!list.Contains(item.m_prefab)) { list.Add(item.m_prefab); } } Dictionary<int, GameObject>.ValueCollection values = ((Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(ZNetScene.instance)).Values; foreach (GameObject item2 in values) { if (!list.Contains(item2)) { list.Add(item2); } } Dbgl($"Checking {list.Count} prefabs"); foreach (GameObject item3 in list) { if (!((Object)(object)item3 == (Object)null) && !(((Object)item3).name == "_NetSceneRoot")) { ReplaceOneGameObjectTextures(item3, ((Object)item3).name, "object"); } } ReplaceSkyBoxTexture(); if (logDump.Any()) { Dbgl("\n" + string.Join("\n", logDump)); } } private static void ReplaceSceneObjects() { SkinnedMeshRenderer[] array = Object.FindObjectsOfType<SkinnedMeshRenderer>(); MeshRenderer[] array2 = Object.FindObjectsOfType<MeshRenderer>(); ParticleSystemRenderer[] array3 = Object.FindObjectsOfType<ParticleSystemRenderer>(); InstanceRenderer[] collection = Object.FindObjectsOfType<InstanceRenderer>(); LineRenderer[] array4 = Object.FindObjectsOfType<LineRenderer>(); ItemDrop[] array5 = Object.FindObjectsOfType<ItemDrop>(); Dbgl($"smrs {array.Length}, mrs {array2.Length}, psrs {array3.Length}, lrs {array4.Length}, ids {array5.Length}"); List<Component> list = new List<Component>(); list.AddRange((IEnumerable<Component>)(object)array); list.AddRange((IEnumerable<Component>)(object)array2); list.AddRange((IEnumerable<Component>)(object)array3); list.AddRange((IEnumerable<Component>)(object)collection); list.AddRange((IEnumerable<Component>)(object)array4); list.AddRange((IEnumerable<Component>)(object)array5); foreach (Component item in list) { Transform val = item.transform; GameObject gameObject = item.gameObject; while ((Object)(object)val.parent != (Object)null) { if ((Object)(object)((Component)val).GetComponent<MeshRenderer>() != (Object)null || (Object)(object)((Component)val).GetComponent<SkinnedMeshRenderer>() != (Object)null || (Object)(object)((Component)val).GetComponent<InstanceRenderer>() != (Object)null || (Object)(object)((Component)val).GetComponent<LineRenderer>() != (Object)null || (Object)(object)((Component)val).GetComponent<ParticleSystemRenderer>() != (Object)null || (Object)(object)((Component)val).GetComponent<ItemDrop>() != (Object)null) { gameObject = ((Component)val).gameObject; } val = val.parent; } ReplaceOneGameObjectTextures(gameObject, ((Object)gameObject).name, "object"); } } private static void ReplaceSkyBoxTexture() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown if (customTextures.ContainsKey("skybox_StarFieldTex")) { Texture texture = RenderSettings.skybox.GetTexture("_StarFieldTex"); Cubemap val = (Cubemap)(object)((texture is Cubemap) ? texture : null); Dbgl(string.Format("original skybox {0}x{1} {2} {3}", RenderSettings.skybox.GetTexture("_StarFieldTex").width, RenderSettings.skybox.GetTexture("_StarFieldTex").height, RenderSettings.skybox.GetTexture("_StarFieldTex").graphicsFormat, RenderSettings.skybox.GetTexture("_StarFieldTex").filterMode)); Cubemap val2 = new Cubemap(((Texture)val).width, (TextureFormat)3, false); Texture2D val3 = LoadTexture("skybox_StarFieldTex", null, isBump: false); Color[] pixels = val3.GetPixels(); for (int i = 0; i < 6; i++) { val2.SetPixels(pixels, (CubemapFace)i); val2.Apply(); } RenderSettings.skybox.SetTexture("_StarFieldTex", (Texture)(object)val2); Dbgl("set skybox texture"); } if (customTextures.ContainsKey("skybox_MoonTex")) { Texture2D val4 = LoadTexture("skybox_MoonTex", null, isBump: false); Color[] pixels2 = val4.GetPixels(); RenderSettings.skybox.SetTexture("_MoonTex", (Texture)(object)val4); Dbgl("set moon texture"); } } private static void ReplaceZoneSystemTextures(ZoneSystem __instance) { Dbgl("Reloading ZoneSystem textures " + ((Object)__instance).name + " " + ((Object)__instance.m_zonePrefab).name); ReplaceOneZoneTextures(((Object)__instance).name, __instance.m_zonePrefab); } private static void ReplaceOneZoneTextures(string zoneSystem, GameObject prefab) { ReplaceOneGameObjectTextures(prefab, zoneSystem, "zone"); Transform obj = prefab.transform.Find("Terrain"); Heightmap val = ((obj != null) ? ((Component)obj).GetComponent<Heightmap>() : null); Material val2 = val?.m_material; if ((Object)(object)val2 != (Object)null && AccessTools.Field(typeof(Heightmap), "m_meshRenderer").GetValue(val) != null) { outputDump.Add("terrain " + zoneSystem + ", prefab " + ((Object)prefab).name); ReplaceMaterialTextures(((Object)prefab).name, val2, zoneSystem, "terrain", "Terrain", ((Object)prefab).name, dumpSceneTextures.Value); val.Regenerate(); } } private static void ReplaceLocationTextures() { if (!dumpSceneTextures.Value) { try { customTextures.First((KeyValuePair<string, string> k) => k.Key.StartsWith("location")); } catch { return; } } GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); GameObject[] array2 = array; foreach (GameObject val in array2) { if (!(((Object)val).name == "_Locations")) { continue; } Location[] componentsInChildren = val.GetComponentsInChildren<Location>(true); Dbgl($"Checking {componentsInChildren.Length} locations"); Location[] array3 = componentsInChildren; foreach (Location location in array3) { if (!dumpSceneTextures.Value) { try { customTextures.First((KeyValuePair<string, string> k) => k.Key.StartsWith("location_") && k.Key.Contains(((Object)((Component)location).gameObject).name)); } catch { continue; } } ReplaceOneGameObjectTextures(((Component)location).gameObject, ((Object)((Component)location).gameObject).name, "location"); } break; } } private static void ReplaceHeightmapTextures() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown Dbgl($"Reloading Heightmap textures for {Heightmap.GetAllHeightmaps().Count} heightmaps"); ZoneSystem val = (ZoneSystem)typeof(ZoneSystem).GetField("m_instance", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); logDump.Clear(); Heightmap val2 = (Heightmap)typeof(EnvMan).GetField("m_cachedHeightmap", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(EnvMan.instance); if ((Object)(object)val2 != (Object)null) { Material material = val2.m_material; if ((Object)(object)material != (Object)null) { outputDump.Add($"terrain {((Object)val).name}, prefab {val.m_zonePrefab}"); ReplaceMaterialTextures(((Object)val.m_zonePrefab).name, material, ((Object)val).name, "terrain", "Terrain", ((Object)val.m_zonePrefab).name, dumpSceneTextures.Value); val2.Regenerate(); } } foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps()) { Material material2 = allHeightmap.m_material; if ((Object)(object)material2 != (Object)null) { outputDump.Add($"terrain {((Object)val).name}, prefab {val.m_zonePrefab}"); ReplaceMaterialTextures(((Object)val.m_zonePrefab).name, material2, ((Object)val).name, "terrain", "Terrain", ((Object)val.m_zonePrefab).name, dumpSceneTextures.Value); } } if (logDump.Any()) { Dbgl("\n" + string.Join("\n", logDump)); } } private static void ReplaceEnvironmentTextures() { Dbgl("Reloading Environment textures"); GameObject val = GameObject.Find("_GameMain/_Environment"); if ((Object)(object)val != (Object)null) { int childCount = val.transform.childCount; Dbgl($"Reloading {childCount} Environment textures"); logDump.Clear(); for (int i = 0; i < childCount; i++) { GameObject gameObject = ((Component)val.transform.GetChild(i)).gameObject; ReplaceOneGameObjectTextures(gameObject, ((Object)gameObject).name, "environment"); } if (logDump.Any()) { Dbgl("\n" + string.Join("\n", logDump)); } } } private static void SetEquipmentTexture(string itemName, GameObject item) { if ((Object)(object)item != (Object)null && itemName != null && itemName.Length > 0) { ReplaceOneGameObjectTextures(item.gameObject, itemName, "object"); } } private static void SetEquipmentListTexture(string itemName, List<GameObject> items) { if (items == null || !items.Any() || itemName == null || itemName.Length <= 0) { return; } for (int i = 0; i < items.Count; i++) { if (!((Object)(object)items[i] == (Object)null)) { SetEquipmentTexture(itemName, items[i]); } } } private static void SetBodyEquipmentTexture(VisEquipment instance, string itemName, SkinnedMeshRenderer smr, List<GameObject> itemInstances) { if ((Object)(object)smr != (Object)null) { ReplaceOneGameObjectTextures(((Component)smr).gameObject, itemName, "object"); } if (itemInstances == null) { return; } foreach (GameObject itemInstance in itemInstances) { ReplaceOneGameObjectTextures(itemInstance, itemName, "object"); } } }
CursorSwapper.dll
Decompiled 8 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("CursorSwapper")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("CursorSwapper")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.1.5")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.5.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace CursorSwapper { [BepInPlugin("Azumatt.CursorSwapper", "CursorSwapper", "1.1.5")] public class CursorSwapperPlugin : BaseUnityPlugin { private enum Toggle { On = 1, Off = 0 } internal const string ModName = "CursorSwapper"; internal const string ModVersion = "1.1.5"; internal const string Author = "Azumatt"; private const string ModGuid = "Azumatt.CursorSwapper"; private const string ConfigFileName = "Azumatt.CursorSwapper.cfg"; private static readonly string ConfigFileFullPath; internal static string ConnectionError; private readonly Harmony _harmony = new Harmony("Azumatt.CursorSwapper"); private static readonly ManualLogSource CursorSwapperLogger; private static Texture2D _cursorSprite; private static Texture2D _vanillaCursorSprite; private static ConfigEntry<Toggle> _useCustomCursor; public void Awake() { _useCustomCursor = ((BaseUnityPlugin)this).Config.Bind<Toggle>("1 - General", "Use Custom Cursor", Toggle.On, "If set to on, the mod will attempt to search for a cursor.png file located in the plugins folder.\nIf it's not found, a warning will be presented in the console and the default game cursor will be used."); _vanillaCursorSprite = Resources.FindObjectsOfTypeAll<Texture2D>().First((Texture2D s) => ((Object)s).name == "cursor" && ((Texture)s).isReadable); if (_useCustomCursor.Value == Toggle.On) { ApplyCursor(); } _useCustomCursor.SettingChanged += delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (_useCustomCursor.Value == Toggle.Off) { Cursor.SetCursor(_vanillaCursorSprite, Vector2.zero, (CursorMode)0); } else { ApplyCursor(); } }; Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "Azumatt.CursorSwapper.cfg"); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; FileSystemWatcher fileSystemWatcher2 = new FileSystemWatcher(Paths.PluginPath); fileSystemWatcher2.Changed += UpdateCursor; fileSystemWatcher2.Created += UpdateCursor; fileSystemWatcher2.Deleted += UpdateCursor; fileSystemWatcher2.Renamed += UpdateCursor; fileSystemWatcher2.Error += OnError; fileSystemWatcher2.IncludeSubdirectories = true; fileSystemWatcher2.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher2.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { CursorSwapperLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { CursorSwapperLogger.LogError((object)"There was an issue loading your Azumatt.CursorSwapper.cfg"); CursorSwapperLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private static void UpdateCursor(object sender, FileSystemEventArgs e) { if (_useCustomCursor.Value == Toggle.On) { ApplyCursor(); } } private static void OnError(object sender, ErrorEventArgs e) { PrintException(e.GetException()); } private static void PrintException(Exception? ex) { while (ex != null) { CursorSwapperLogger.LogError((object)("Message: " + ex.Message)); CursorSwapperLogger.LogError((object)"Stacktrace:"); CursorSwapperLogger.LogError((object)ex.StackTrace); ex = ex.InnerException; } } internal static void ApplyCursor() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) _cursorSprite = LoadTexture("cursor.png"); if ((Object)(object)_cursorSprite != (Object)null) { Cursor.SetCursor(_cursorSprite, new Vector2(6f, 5f), (CursorMode)0); } else if ((Object)(object)_vanillaCursorSprite != (Object)null) { Cursor.SetCursor(_vanillaCursorSprite, Vector2.zero, (CursorMode)0); } } private static Texture2D LoadTexture(string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown string name2 = name; Texture2D val = new Texture2D(0, 0); string directoryName = Path.GetDirectoryName(Paths.PluginPath); if (directoryName == null) { return val; } List<string> list = Directory.GetFiles(directoryName, "cursor.png", SearchOption.AllDirectories).OrderBy(Path.GetFileName).ToList(); try { byte[] array = File.ReadAllBytes(list.Find((string x) => x.Contains(name2))); ImageConversion.LoadImage(val, array); } catch { CursorSwapperLogger.LogWarning((object)("The file " + name2 + " couldn't be found in the directory path. Please make sure you are naming your files correctly and they are location somewhere in the BepInEx/plugins folder.\nOptionally, you can turn off 'Use Custom Cursor' inside of your configuration file. If you no longer wish to see this error.")); val = _vanillaCursorSprite; } return val; } static CursorSwapperPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + "Azumatt.CursorSwapper.cfg"; ConnectionError = ""; CursorSwapperLogger = Logger.CreateLogSource("CursorSwapper"); _cursorSprite = null; _vanillaCursorSprite = null; _useCustomCursor = null; } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class SwapAfterJewelcraftingBullshit { [HarmonyAfter(new string[] { "org.bepinex.plugins.jewelcrafting" })] private static void Postfix(ZNetScene __instance) { CursorSwapperPlugin.ApplyCursor(); } } }