Decompiled source of CustomTextures v3.3.4

plugins/CustomTextures.dll

Decompiled 3 weeks ago
using 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")]
[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("cjayride.CustomTextures", "Custom Textures", "3.3.4")]
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("UpdateItemHashes", 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)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");
		}
	}
}