Please disclose if your mod was created primarily 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 balrond BannerColorizer v1.0.7
plugins/BalrondBannerColorizer.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; 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 System.Text; using BepInEx; using HarmonyLib; using LitJson2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ProjectAshlands")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ProjectAshlands")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f405ea1c-ac25-47a3-9aa2-a8f56c14bfd6")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace BalrondBannerColorizer { public class BalrondTranslator { public static Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>(); public static Dictionary<string, string> getLanguage(string language) { if (string.IsNullOrEmpty(language)) { return null; } if (translations.TryGetValue(language, out var value)) { return value; } return null; } } public class ModResourceLoader { public AssetBundle assetBundle; public List<GameObject> items = new List<GameObject>(); public ShaderReplacment shaderReplacment = new ShaderReplacment(); public Material crystal01black; public Material crystal01blue; public Material crystal01green; public Material crystal01orange; public Material crystal01purple; public Material crystal01red; public Material crystal01white; public Material crystal01yellow; public Material banner01black; public Material banner01blue; public Material banner01green; public Material banner01orange; public Material banner01purple; public Material banner01red; public Material banner01white; public Material banner01yellow; public Material banner02black; public Material banner02blue; public Material banner02green; public Material banner02orange; public Material banner02purple; public Material banner02red; public Material banner02white; public Material banner02yellow; public Material banner03black; public Material banner03blue; public Material banner03green; public Material banner03orange; public Material banner03purple; public Material banner03red; public Material banner03white; public Material banner03yellow; public Material banner04black; public Material banner04blue; public Material banner04green; public Material banner04orange; public Material banner04purple; public Material banner04red; public Material banner04white; public Material banner04yellow; public Material banner05black; public Material banner05blue; public Material banner05green; public Material banner05orange; public Material banner05purple; public Material banner05red; public Material banner05white; public Material banner05yellow; public Material banner06black; public Material banner06blue; public Material banner06green; public Material banner06orange; public Material banner06purple; public Material banner06red; public Material banner06white; public Material banner06yellow; public Material banner07black; public Material banner07blue; public Material banner07green; public Material banner07orange; public Material banner07purple; public Material banner07red; public Material banner07white; public Material banner07yellow; public Material banner08black; public Material banner08blue; public Material banner08green; public Material banner08orange; public Material banner08purple; public Material banner08red; public Material banner08white; public Material banner08yellow; public Material banner09black; public Material banner09blue; public Material banner09green; public Material banner09orange; public Material banner09purple; public Material banner09red; public Material banner09white; public Material banner09yellow; public Material banner10black; public Material banner10blue; public Material banner10green; public Material banner10orange; public Material banner10purple; public Material banner10red; public Material banner10white; public Material banner10yellow; public Material banner11black; public Material banner11blue; public Material banner11green; public Material banner11orange; public Material banner11purple; public Material banner11red; public Material banner11white; public Material banner11yellow; public Material bannerHangingblack; public Material bannerHangingblue; public Material bannerHanginggreen; public Material bannerHangingorange; public Material bannerHangingpurple; public Material bannerHangingred; public Material bannerHangingwhite; public Material bannerHangingyellow; public Material bannerHanging2black; public Material bannerHanging2blue; public Material bannerHanging2green; public Material bannerHanging2orange; public Material bannerHanging2purple; public Material bannerHanging2red; public Material bannerHanging2white; public Material bannerHanging2yellow; public Material bannerHanging3black; public Material bannerHanging3blue; public Material bannerHanging3green; public Material bannerHanging3orange; public Material bannerHanging3purple; public Material bannerHanging3red; public Material bannerHanging3white; public Material bannerHanging3yellow; public Material juteCarpetblack; public Material juteCarpetblue; public Material juteCarpetgreen; public Material juteCarpetorange; public Material juteCarpetpurple; public Material juteCarpetred; public Material juteCarpetwhite; public Material juteCarpetyellow; public Material juteCarpetMainblack; public Material juteCarpetMainblue; public Material juteCarpetMaingreen; public Material juteCarpetMainorange; public Material juteCarpetMainpurple; public Material juteCarpetMainred; public Material juteCarpetMainwhite; public Material juteCarpetMainyellow; public Material juteCarpetDestructionblack; public Material juteCarpetDestructionblue; public Material juteCarpetDestructiongreen; public Material juteCarpetDestructionorange; public Material juteCarpetDestructionpurple; public Material juteCarpetDestructionred; public Material juteCarpetDestructionwhite; public Material juteCarpetDestructionyellow; public Material juteCarpet2black; public Material juteCarpet2blue; public Material juteCarpet2green; public Material juteCarpet2orange; public Material juteCarpet2purple; public Material juteCarpet2red; public Material juteCarpet2white; public Material juteCarpet2yellow; public Material juteCarpetMain2black; public Material juteCarpetMain2blue; public Material juteCarpetMain2green; public Material juteCarpetMain2orange; public Material juteCarpetMain2purple; public Material juteCarpetMain2red; public Material juteCarpetMain2white; public Material juteCarpetMain2yellow; public Material juteCarpetDestruction2black; public Material juteCarpetDestruction2blue; public Material juteCarpetDestruction2green; public Material juteCarpetDestruction2orange; public Material juteCarpetDestruction2purple; public Material juteCarpetDestruction2red; public Material juteCarpetDestruction2white; public Material juteCarpetDestruction2yellow; public Material roofDarkMain2black; public Material roofDarkMain2blue; public Material roofDarkMain2green; public Material roofDarkMain2orange; public Material roofDarkMain2purple; public Material roofDarkMain2red; public Material roofDarkMain2white; public Material roofDarkMain2yellow; public Material roofDarkDestructionblack; public Material roofDarkDestructionblue; public Material roofDarkDestructiongreen; public Material roofDarkDestructionorange; public Material roofDarkDestructionpurple; public Material roofDarkDestructionred; public Material roofDarkDestructionwhite; public Material roofDarkDestructionyellow; public static string[] prefabNames = new string[8] { "DyeBlack", "DyeBlue", "DyeGreen", "DyeOrange", "DyePurple", "DyeRed", "DyeWhite", "DyeYellow" }; private static readonly Dictionary<string, string> prefabTranslationTag = new Dictionary<string, string>(StringComparer.Ordinal) { { "DyeBlack", "$tag_dyeblack_bal" }, { "DyeBlue", "$tag_dyeblue_bal" }, { "DyeGreen", "$tag_dyegreen_bal" }, { "DyeOrange", "$tag_dyeorange_bal" }, { "DyePurple", "$tag_dyepurple_bal" }, { "DyeRed", "$tag_dyered_bal" }, { "DyeWhite", "$tag_dyewhite_bal" }, { "DyeYellow", "$tag_dyeyellow_bal" } }; public static readonly string[] colorNames = new string[8] { "black", "blue", "green", "orange", "purple", "red", "white", "yellow" }; public GameObject dyeTable; public void loadAssets() { assetBundle = GetAssetBundleFromResources("bannercolorizer"); string mainPath = "Assets/Custom/BalrondBannerColorizer/"; LoadPrefabs(mainPath); LoadDyeTable(mainPath); LoadMaterialSet("crystalWall1", mainPath, AssignCrystalWall1); LoadMaterialSet("banner01", mainPath, AssignBanner01); LoadMaterialSet("banner02", mainPath, AssignBanner02); LoadMaterialSet("banner03", mainPath, AssignBanner03); LoadMaterialSet("banner04", mainPath, AssignBanner04); LoadMaterialSet("banner05", mainPath, AssignBanner05); LoadMaterialSet("banner06", mainPath, AssignBanner06); LoadMaterialSet("banner07", mainPath, AssignBanner07); LoadMaterialSet("banner08", mainPath, AssignBanner08); LoadMaterialSet("banner09", mainPath, AssignBanner09); LoadMaterialSet("banner10", mainPath, AssignBanner10); LoadMaterialSet("banner11", mainPath, AssignBanner11); LoadMaterialSet("bannerHanging", mainPath, AssignBannerHanging); LoadMaterialSet("bannerHanging2", mainPath, AssignBannerHanging2); LoadMaterialSet("bannerHanging3", mainPath, AssignBannerHanging3); LoadMaterialSet("juteCarpet", mainPath, AssignJuteCarpet); LoadMaterialSet("juteCarpetMain", mainPath, AssignJuteCarpetMain); LoadMaterialSet("juteCarpetDestruction", mainPath, AssignJuteCarpetDestruction); LoadMaterialSet("juteCarpet2", mainPath, AssignJuteCarpet2); LoadMaterialSet("juteCarpetMain2", mainPath, AssignJuteCarpetMain2); LoadMaterialSet("juteCarpetDestruction2", mainPath, AssignJuteCarpetDestruction2); LoadMaterialSet("roofNew", mainPath, AssignRoofDarkMain2); LoadMaterialSet("roofWorn", mainPath, AssignRoofDarkDestruction); } private void LoadPrefabs(string mainPath) { items.Clear(); string[] array = prefabNames; foreach (string text in array) { string text2 = mainPath + "prefabs/" + text + ".prefab"; GameObject val = assetBundle.LoadAsset<GameObject>(text2); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Prefab not found: " + text2)); continue; } setTranslationTags(val); items.Add(val); } } private void setTranslationTags(GameObject prefab) { string value = ""; prefabTranslationTag.TryGetValue(((Object)prefab).name, out value); if (value != "" && value != null) { prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name = value; } prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_description = "$tag_dyedescription_bal"; } private void LoadDyeTable(string mainPath) { string text = mainPath + "prefabs/piece_dyestation.prefab"; dyeTable = assetBundle.LoadAsset<GameObject>(text); if ((Object)(object)dyeTable == (Object)null) { Debug.LogWarning((object)("Dye table prefab not found: " + text)); return; } dyeTable.GetComponent<Piece>().m_name = "$tag_dyetable_bal"; dyeTable.GetComponent<Piece>().m_description = "$tag_dyetable_bal_description"; dyeTable.GetComponent<CraftingStation>().m_name = "$tag_dyetable_bal"; } private void LoadMaterialSet(string folderName, string mainPath, Action<Material[]> assignAction) { Material[] obj = LoadColorMaterials(folderName, mainPath); assignAction?.Invoke(obj); } private Material[] LoadColorMaterials(string folderName, string mainPath) { Material[] array = (Material[])(object)new Material[colorNames.Length]; for (int i = 0; i < colorNames.Length; i++) { string text = mainPath + folderName + "/" + colorNames[i] + ".mat"; Material val = assetBundle.LoadAsset<Material>(text); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Material not found: " + text)); array[i] = null; } else { ShaderReplacment.ReplaceMaterial(val); array[i] = val; } } return array; } private void AssignCrystalWall1(Material[] mats) { crystal01black = mats[0]; crystal01blue = mats[1]; crystal01green = mats[2]; crystal01orange = mats[3]; crystal01purple = mats[4]; crystal01red = mats[5]; crystal01white = mats[6]; crystal01yellow = mats[7]; } private void AssignBanner01(Material[] mats) { banner01black = mats[0]; banner01blue = mats[1]; banner01green = mats[2]; banner01orange = mats[3]; banner01purple = mats[4]; banner01red = mats[5]; banner01white = mats[6]; banner01yellow = mats[7]; } private void AssignBanner02(Material[] mats) { banner02black = mats[0]; banner02blue = mats[1]; banner02green = mats[2]; banner02orange = mats[3]; banner02purple = mats[4]; banner02red = mats[5]; banner02white = mats[6]; banner02yellow = mats[7]; } private void AssignBanner03(Material[] mats) { banner03black = mats[0]; banner03blue = mats[1]; banner03green = mats[2]; banner03orange = mats[3]; banner03purple = mats[4]; banner03red = mats[5]; banner03white = mats[6]; banner03yellow = mats[7]; } private void AssignBanner04(Material[] mats) { banner04black = mats[0]; banner04blue = mats[1]; banner04green = mats[2]; banner04orange = mats[3]; banner04purple = mats[4]; banner04red = mats[5]; banner04white = mats[6]; banner04yellow = mats[7]; } private void AssignBanner05(Material[] mats) { banner05black = mats[0]; banner05blue = mats[1]; banner05green = mats[2]; banner05orange = mats[3]; banner05purple = mats[4]; banner05red = mats[5]; banner05white = mats[6]; banner05yellow = mats[7]; } private void AssignBanner06(Material[] mats) { banner06black = mats[0]; banner06blue = mats[1]; banner06green = mats[2]; banner06orange = mats[3]; banner06purple = mats[4]; banner06red = mats[5]; banner06white = mats[6]; banner06yellow = mats[7]; } private void AssignBanner07(Material[] mats) { banner07black = mats[0]; banner07blue = mats[1]; banner07green = mats[2]; banner07orange = mats[3]; banner07purple = mats[4]; banner07red = mats[5]; banner07white = mats[6]; banner07yellow = mats[7]; } private void AssignBanner08(Material[] mats) { banner08black = mats[0]; banner08blue = mats[1]; banner08green = mats[2]; banner08orange = mats[3]; banner08purple = mats[4]; banner08red = mats[5]; banner08white = mats[6]; banner08yellow = mats[7]; } private void AssignBanner09(Material[] mats) { banner09black = mats[0]; banner09blue = mats[1]; banner09green = mats[2]; banner09orange = mats[3]; banner09purple = mats[4]; banner09red = mats[5]; banner09white = mats[6]; banner09yellow = mats[7]; } private void AssignBanner10(Material[] mats) { banner10black = mats[0]; banner10blue = mats[1]; banner10green = mats[2]; banner10orange = mats[3]; banner10purple = mats[4]; banner10red = mats[5]; banner10white = mats[6]; banner10yellow = mats[7]; } private void AssignBanner11(Material[] mats) { banner11black = mats[0]; banner11blue = mats[1]; banner11green = mats[2]; banner11orange = mats[3]; banner11purple = mats[4]; banner11red = mats[5]; banner11white = mats[6]; banner11yellow = mats[7]; } private void AssignBannerHanging(Material[] mats) { bannerHangingblack = mats[0]; bannerHangingblue = mats[1]; bannerHanginggreen = mats[2]; bannerHangingorange = mats[3]; bannerHangingpurple = mats[4]; bannerHangingred = mats[5]; bannerHangingwhite = mats[6]; bannerHangingyellow = mats[7]; } private void AssignBannerHanging2(Material[] mats) { bannerHanging2black = mats[0]; bannerHanging2blue = mats[1]; bannerHanging2green = mats[2]; bannerHanging2orange = mats[3]; bannerHanging2purple = mats[4]; bannerHanging2red = mats[5]; bannerHanging2white = mats[6]; bannerHanging2yellow = mats[7]; } private void AssignBannerHanging3(Material[] mats) { bannerHanging3black = mats[0]; bannerHanging3blue = mats[1]; bannerHanging3green = mats[2]; bannerHanging3orange = mats[3]; bannerHanging3purple = mats[4]; bannerHanging3red = mats[5]; bannerHanging3white = mats[6]; bannerHanging3yellow = mats[7]; } private void AssignJuteCarpet(Material[] mats) { juteCarpetblack = mats[0]; juteCarpetblue = mats[1]; juteCarpetgreen = mats[2]; juteCarpetorange = mats[3]; juteCarpetpurple = mats[4]; juteCarpetred = mats[5]; juteCarpetwhite = mats[6]; juteCarpetyellow = mats[7]; } private void AssignJuteCarpetMain(Material[] mats) { juteCarpetMainblack = mats[0]; juteCarpetMainblue = mats[1]; juteCarpetMaingreen = mats[2]; juteCarpetMainorange = mats[3]; juteCarpetMainpurple = mats[4]; juteCarpetMainred = mats[5]; juteCarpetMainwhite = mats[6]; juteCarpetMainyellow = mats[7]; } private void AssignJuteCarpetDestruction(Material[] mats) { juteCarpetDestructionblack = mats[0]; juteCarpetDestructionblue = mats[1]; juteCarpetDestructiongreen = mats[2]; juteCarpetDestructionorange = mats[3]; juteCarpetDestructionpurple = mats[4]; juteCarpetDestructionred = mats[5]; juteCarpetDestructionwhite = mats[6]; juteCarpetDestructionyellow = mats[7]; } private void AssignJuteCarpet2(Material[] mats) { juteCarpet2black = mats[0]; juteCarpet2blue = mats[1]; juteCarpet2green = mats[2]; juteCarpet2orange = mats[3]; juteCarpet2purple = mats[4]; juteCarpet2red = mats[5]; juteCarpet2white = mats[6]; juteCarpet2yellow = mats[7]; } private void AssignJuteCarpetMain2(Material[] mats) { juteCarpetMain2black = mats[0]; juteCarpetMain2blue = mats[1]; juteCarpetMain2green = mats[2]; juteCarpetMain2orange = mats[3]; juteCarpetMain2purple = mats[4]; juteCarpetMain2red = mats[5]; juteCarpetMain2white = mats[6]; juteCarpetMain2yellow = mats[7]; } private void AssignJuteCarpetDestruction2(Material[] mats) { juteCarpetDestruction2black = mats[0]; juteCarpetDestruction2blue = mats[1]; juteCarpetDestruction2green = mats[2]; juteCarpetDestruction2orange = mats[3]; juteCarpetDestruction2purple = mats[4]; juteCarpetDestruction2red = mats[5]; juteCarpetDestruction2white = mats[6]; juteCarpetDestruction2yellow = mats[7]; } private void AssignRoofDarkMain2(Material[] mats) { roofDarkMain2black = mats[0]; roofDarkMain2blue = mats[1]; roofDarkMain2green = mats[2]; roofDarkMain2orange = mats[3]; roofDarkMain2purple = mats[4]; roofDarkMain2red = mats[5]; roofDarkMain2white = mats[6]; roofDarkMain2yellow = mats[7]; } private void AssignRoofDarkDestruction(Material[] mats) { roofDarkDestructionblack = mats[0]; roofDarkDestructionblue = mats[1]; roofDarkDestructiongreen = mats[2]; roofDarkDestructionorange = mats[3]; roofDarkDestructionpurple = mats[4]; roofDarkDestructionred = mats[5]; roofDarkDestructionwhite = mats[6]; roofDarkDestructionyellow = mats[7]; } private AssetBundle GetAssetBundleFromResources(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().SingleOrDefault((string str) => str.EndsWith(filename, StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrEmpty(text)) { Debug.LogError((object)("Embedded asset bundle not found: " + filename)); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { Debug.LogError((object)("Could not open resource stream for: " + text)); return null; } AssetBundle val = AssetBundle.LoadFromStream(stream); if ((Object)(object)val == (Object)null) { Debug.LogError((object)("Failed to load AssetBundle from resource: " + text)); } return val; } } public class ShaderReplacment { public static List<GameObject> prefabsToReplaceShader = new List<GameObject>(); public static List<Material> materialsInPrefabs = new List<Material>(); public string[] shaderlist = new string[49] { "Custom/AlphaParticle", "Custom/Blob", "Custom/Bonemass", "Custom/Clouds", "Custom/Creature", "Custom/Decal", "Custom/Distortion", "Custom/Flow", "Custom/FlowOpaque", "Custom/Grass", "Custom/GuiScroll", "Custom/Heightmap", "Custom/icon", "Custom/InteriorSide", "Custom/LitGui", "Custom/LitParticles", "Custom/mapshader", "Custom/ParticleDecal", "Custom/Piece", "Custom/Player", "Custom/Rug", "Custom/ShadowBlob", "Custom/SkyboxProcedural", "Custom/SkyObject", "Custom/StaticRock", "Custom/Tar", "Custom/Trilinearmap", "Custom/UI/BGBlur", "Custom/Vegetation", "Custom/Water", "Custom/WaterBottom", "Custom/WaterMask", "Custom/Yggdrasil", "Custom/Yggdrasil/root", "Hidden/BlitCopyHDRTonemap", "Hidden/Dof/DepthOfFieldHdr", "Hidden/Dof/DX11Dof", "Hidden/Internal-Loading", "Hidden/Internal-UIRDefaultWorld", "Hidden/SimpleClear", "Hidden/SunShaftsComposite", "Lux Lit Particles/ Bumped", "Lux Lit Particles/ Tess Bumped", "Particles/Standard Surface2", "Particles/Standard Unlit2", "Standard TwoSided", "ToonDeferredShading2017", "Unlit/DepthWrite", "Unlit/Lighting" }; public static List<Shader> shaders = new List<Shader>(); private static readonly HashSet<Shader> CachedShaders = new HashSet<Shader>(); public static bool debug = true; public static void ReplaceMaterial(Material material) { materialsInPrefabs.Add(material); } public static Shader findShader(string name) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); if (array.Length == 0) { Debug.LogWarning((object)"SHADER LIST IS EMPTY!"); return null; } if (debug) { } return shaders.Find((Shader x) => ((Object)x).name == name); } public static Shader GetShaderByName(string name) { return shaders.Find((Shader x) => ((Object)x).name == name.Trim()); } public static void debugShaderList(List<Shader> shadersRes) { foreach (Shader shadersRe in shadersRes) { Debug.LogWarning((object)("SHADER NAME IS: " + ((Object)shadersRe).name)); } debug = false; } public static void Replace(GameObject gameObject) { prefabsToReplaceShader.Add(gameObject); GetMaterialsInPrefab(gameObject); } public static void GetMaterialsInPrefab(GameObject gameObject) { Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } Material[] array2 = sharedMaterials; foreach (Material val2 in array2) { if ((Object)(object)val2 != (Object)null) { materialsInPrefabs.Add(val2); } } } } public static void getMeShaders() { AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable<Shader> enumerable3; try { IEnumerable<Shader> enumerable2; if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val)) { IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item in enumerable3) { CachedShaders.Add(item); } } } public static void runMaterialFix() { getMeShaders(); shaders.AddRange(CachedShaders); foreach (Material materialsInPrefab in materialsInPrefabs) { Shader shader = materialsInPrefab.shader; if (!((Object)(object)shader == (Object)null)) { string name = ((Object)shader).name; if (!(name == "Standard") && name.Contains("Balrond")) { setProperValue(materialsInPrefab, name); } } } } private static void setProperValue(Material material, string shaderName) { string name = shaderName.Replace("Balrond", "Custom"); name = checkNaming(name); Shader shaderByName = GetShaderByName(name); if ((Object)(object)shaderByName == (Object)null) { Debug.LogWarning((object)("Shader not found " + name)); } else { material.shader = shaderByName; } } private static string checkNaming(string name) { string result = name; if (name.Contains("Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Tess Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Standard Surface")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Surface2", "Standard Surface"); } if (name.Contains("Standard Unlit")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Unlit", "Standard Unlit2"); result = result.Replace("Standard Unlit22", "Standard Unlit2"); } return result; } } [Serializable] public class BannerColorizer : MonoBehaviour, Hoverable, Interactable { private const string ZdoColorKey = "colorizerSet"; private const string ZdoActiveKey = "colorizerIsActive"; private static readonly HashSet<string> RoofPrefabNames = new HashSet<string>(StringComparer.Ordinal) { "darkwood_roof_icorner", "darkwood_roof_icorner_45", "darkwood_roof_ocorner", "darkwood_roof_ocorner_45", "darkwood_roof_top", "darkwood_roof_top_45", "darkwood_roof_45", "darkwood_roof" }; private static readonly Dictionary<string, string> DefaultSkinByPrefab = new Dictionary<string, string>(StringComparer.Ordinal) { { "darkwood_roof_icorner", "black" }, { "darkwood_roof_icorner_45", "black" }, { "darkwood_roof_ocorner", "black" }, { "darkwood_roof_ocorner_45", "black" }, { "darkwood_roof_top", "black" }, { "darkwood_roof_top_45", "black" }, { "darkwood_roof_45", "black" }, { "darkwood_roof", "black" }, { "crystal_wall_1x1", "white" }, { "piece_banner01", "black" }, { "piece_banner02", "blue" }, { "piece_banner03", "red" }, { "piece_banner04", "red" }, { "piece_banner05", "green" }, { "piece_banner06", "blue" }, { "piece_banner07", "blue" }, { "piece_banner08", "yellow" }, { "piece_banner09", "purple" }, { "piece_banner10", "orange" }, { "piece_banner11", "white" }, { "piece_cloth_hanging_door", "red" }, { "piece_cloth_hanging_door_blue", "blue" }, { "piece_cloth_hanging_door_blue2", "blue" }, { "jute_carpet", "red" }, { "jute_carpet_blue", "blue" } }; private ZNetView m_zview; private Piece m_piece; public List<ColorizerPack> m_packs; private string skinName = ""; public string defaultSkinName = ""; public static ModResourceLoader modResourceLoader = Launch.modResourceLoader; private List<ColorizerPack> colorizerPacks = new List<ColorizerPack>(); private ColorizerPack m_colorizerPack; public List<MeshRenderer> banner = new List<MeshRenderer>(); private List<MeshRenderer> m_destruction = new List<MeshRenderer>(); private MeshRenderer main; private string m_useItemText = "Add dye"; private List<ColorizerPack> colorizerPacksFull => Launch.colorizerPacks; private void Awake() { if (!validatePrefab()) { Debug.LogWarning((object)("I should not be randomized: " + ((Object)((Component)this).gameObject).name)); return; } filterPacks(); m_zview = ((Component)this).GetComponent<ZNetView>(); m_piece = ((Component)this).GetComponent<Piece>(); if ((Object)(object)m_zview == (Object)null || !m_zview.IsValid() || m_zview.GetZDO() == null) { return; } m_zview.Register<string>("RPC_Paint", (Action<long, string>)RPC_Paint); setDefaulDyeName(); if (!setupColorizer()) { Debug.LogWarning((object)("Unable to setup colorizer for: " + ((Object)((Component)this).gameObject).name)); return; } if (m_packs == null || m_packs.Count == 0) { Debug.LogWarning((object)("Material list is empty for: " + ((Object)((Component)this).gameObject).name)); } bool dye = IsColorizerActive(); setDye(dye); } public string GetHoverText() { string text = (((Object)(object)m_piece != (Object)null) ? m_piece.m_name : ((Object)((Component)this).gameObject).name); return Localization.instance.Localize(text + "\n[<color=yellow><b>1-8</b></color>] " + m_useItemText + "\n[Current dye] " + skinName + "\n[<color=yellow>Default dye</color>] " + defaultSkinName); } public string GetHoverName() { return ((Object)(object)m_piece != (Object)null) ? m_piece.m_name : ((Object)((Component)this).gameObject).name; } public bool Interact(Humanoid character, bool repeat, bool alt) { return false; } public bool UseItem(Humanoid user, ItemData item) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)user == (Object)null || item == null) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } ColorizerPack colorPackByItemData = getColorPackByItemData(item); if (colorPackByItemData == null) { ((Character)user).Message((MessageType)2, "$msg_wrongitem", 0, (Sprite)null); return false; } if (skinName == colorPackByItemData.skin) { ((Character)user).Message((MessageType)2, "$msg_wrongitem", 0, (Sprite)null); return false; } ((Character)user).Message((MessageType)2, "$msg_added " + item.m_shared.m_name, 0, (Sprite)null); user.GetInventory().RemoveItem(item.m_shared.m_name, 1, -1, true); Paint(colorPackByItemData.skin); return true; } private void Paint(string dyeName) { if (!((Object)(object)m_zview == (Object)null) && m_zview.IsValid()) { m_zview.InvokeRPC(ZNetView.Everybody, "RPC_Paint", new object[1] { dyeName }); } } private void RPC_Paint(long caller, string dyeName) { if (string.IsNullOrWhiteSpace(dyeName)) { dyeName = defaultSkinName; } setColorizerId(dyeName); ColorizerPack colorizerPack = findDyeByName(dyeName); if (colorizerPack == null) { Debug.LogWarning((object)("Colorizer pack not found for dye: " + dyeName + " on " + ((Object)((Component)this).gameObject).name)); } else { useDye(colorizerPack); } } public void filterPacks() { colorizerPacks.Clear(); string text = editZnetName(((Object)this).name); List<ColorizerPack> list = colorizerPacksFull; if (list == null) { return; } foreach (ColorizerPack item in list) { if (item != null && text == item.buildPieceName) { colorizerPacks.Add(item); } } } private void setColorizerId(string id) { if ((Object)(object)m_zview != (Object)null && m_zview.IsValid() && m_zview.m_zdo != null) { m_zview.m_zdo.Set("colorizerSet", id); m_zview.m_zdo.Set("colorizerIsActive", true); } } private bool IsColorizerActive() { if ((Object)(object)m_zview == (Object)null || m_zview.m_zdo == null) { return false; } return m_zview.m_zdo.GetBool("colorizerIsActive", false); } private bool validatePrefab() { string value = editZnetName(((Object)((Component)this).gameObject).name); return Launch.buildPieceNames.Contains(value); } private void setDefaulDyeName() { string key = editZnetName(((Object)((Component)this).gameObject).name); if (DefaultSkinByPrefab.TryGetValue(key, out var value)) { defaultSkinName = value; } else { defaultSkinName = "black"; } } private string editZnetName(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } value = value.Replace("(Clone)", ""); int num = value.IndexOf("("); if (num >= 0) { value = value.Substring(0, num); } return value.Trim(); } private void setDye(bool isColorizerActive) { string @string = defaultSkinName; if (isColorizerActive && (Object)(object)m_zview != (Object)null && m_zview.m_zdo != null) { @string = m_zview.m_zdo.GetString("colorizerSet", ""); } if (string.IsNullOrWhiteSpace(@string)) { @string = defaultSkinName; } Paint(@string); } private ColorizerPack findDyeByName(string name) { string text = editZnetName(((Object)this).name); foreach (ColorizerPack colorizerPack in colorizerPacks) { if (colorizerPack != null && name == colorizerPack.skin && text == colorizerPack.buildPieceName) { return colorizerPack; } } return null; } private ColorizerPack getColorPackByItemData(ItemData itemData) { if (itemData == null || (Object)(object)itemData.m_dropPrefab == (Object)null) { return null; } string name = ((Object)itemData.m_dropPrefab).name; foreach (ColorizerPack colorizerPack in colorizerPacks) { if (colorizerPack != null && (Object)(object)colorizerPack.dyeItem != (Object)null && name == ((Object)colorizerPack.dyeItem).name) { return colorizerPack; } } return null; } private void useDye(ColorizerPack colorizerPack) { if (colorizerPack != null) { ApplyMaterialList(banner, colorizerPack.body); skinName = colorizerPack.skin; m_colorizerPack = colorizerPack; if ((Object)(object)main != (Object)null && (Object)(object)colorizerPack.rugmain != (Object)null) { ApplyMaterial(main, colorizerPack.rugmain); } if ((Object)(object)colorizerPack.rugdestruction != (Object)null) { ApplyMaterialList(m_destruction, colorizerPack.rugdestruction); } } } private bool setupColorizer() { banner.Clear(); m_destruction.Clear(); main = null; string prefabName = editZnetName(((Object)((Component)this).gameObject).name); m_packs = colorizerPacks.FindAll((ColorizerPack x) => x != null && x.buildPieceName == prefabName); if (RoofPrefabNames.Contains(prefabName)) { Transform val = ((Component)this).transform.Find("New"); Transform source = ((Component)this).transform.Find("Worn"); Transform source2 = ((Component)this).transform.Find("Broken"); Transform source3 = ((Component)this).transform.Find("Destruction"); if ((Object)(object)val != (Object)null) { AddRendererFromChild(val, 0, banner); AddRendererFromChild(val, 1, banner); } AddRenderersFromTransform(source, m_destruction); AddRenderersFromTransform(source2, m_destruction); AddRenderersFromTransform(source3, m_destruction); return banner.Count > 0; } switch (prefabName) { case "crystal_wall_1x1": { Transform val2 = ((Component)this).transform.Find("New"); if ((Object)(object)val2 != (Object)null) { AddRendererFromChild(val2, 0, banner); AddRendererFromChild(val2, 1, banner); } return banner.Count > 0; } case "piece_banner01": case "piece_banner02": case "piece_banner03": case "piece_banner04": case "piece_banner05": case "piece_banner06": case "piece_banner07": case "piece_banner08": case "piece_banner09": case "piece_banner10": case "piece_banner11": AddRendererFromPath("default", banner); return banner.Count > 0; case "piece_cloth_hanging_door": AddRendererFromPath("new/cloth", banner); return banner.Count > 0; case "piece_cloth_hanging_door_blue": { Transform val7 = ((Component)this).transform.Find("new"); if ((Object)(object)val7 != (Object)null) { AddRendererFromChild(val7, 0, banner); AddRendererFromChild(val7, 1, banner); } return banner.Count > 0; } case "piece_cloth_hanging_door_blue2": { Transform val3 = ((Component)this).transform.Find("new"); Transform val4 = ((Component)this).transform.Find("worn"); Transform val5 = ((Component)this).transform.Find("broken"); Transform val6 = ((Component)this).transform.Find("destruction"); if ((Object)(object)val3 != (Object)null) { AddRendererFromChild(val3, 1, banner); AddRendererFromChild(val3, 2, banner); } if ((Object)(object)val4 != (Object)null) { AddRendererFromChild(val4, 1, banner); AddRendererFromChild(val4, 2, banner); } if ((Object)(object)val5 != (Object)null) { AddRendererFromChild(val5, 1, banner); AddRendererFromChild(val5, 2, banner); } if ((Object)(object)val6 != (Object)null) { AddRendererFromChild(val6, 0, banner); } return banner.Count > 0; } case "jute_carpet": case "jute_carpet_blue": { main = GetRendererFromChildIndex(((Component)this).transform, 1); AddRendererFromRootChildIndex(2, banner); AddRendererFromRootChildIndex(3, banner); Transform source4 = ((Component)this).transform.Find("destruction"); AddRenderersFromTransform(source4, m_destruction); return banner.Count > 0 || (Object)(object)main != (Object)null; } default: return false; } } private void ApplyMaterialList(List<MeshRenderer> renderers, Material sourceMaterial) { if (renderers == null || (Object)(object)sourceMaterial == (Object)null) { return; } foreach (MeshRenderer renderer in renderers) { ApplyMaterial(renderer, sourceMaterial); } } private void ApplyMaterial(MeshRenderer renderer, Material sourceMaterial) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (!((Object)(object)renderer == (Object)null) && !((Object)(object)sourceMaterial == (Object)null)) { Material sharedMaterial = (((Renderer)renderer).material = new Material(sourceMaterial)); ((Renderer)renderer).sharedMaterial = sharedMaterial; } } private void AddRendererFromPath(string path, List<MeshRenderer> target) { Transform val = ((Component)this).transform.Find(path); if (!((Object)(object)val == (Object)null)) { MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { target.Add(component); } } } private void AddRendererFromChild(Transform parent, int childIndex, List<MeshRenderer> target) { if (!((Object)(object)parent == (Object)null) && childIndex >= 0 && childIndex < parent.childCount) { MeshRenderer component = ((Component)parent.GetChild(childIndex)).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { target.Add(component); } } } private void AddRendererFromRootChildIndex(int childIndex, List<MeshRenderer> target) { MeshRenderer rendererFromChildIndex = GetRendererFromChildIndex(((Component)this).transform, childIndex); if ((Object)(object)rendererFromChildIndex != (Object)null) { target.Add(rendererFromChildIndex); } } private MeshRenderer GetRendererFromChildIndex(Transform parent, int childIndex) { if ((Object)(object)parent == (Object)null || childIndex < 0 || childIndex >= parent.childCount) { return null; } return ((Component)parent.GetChild(childIndex)).GetComponent<MeshRenderer>(); } private void AddRenderersFromTransform(Transform source, List<MeshRenderer> target) { if (!((Object)(object)source == (Object)null)) { MeshRenderer[] componentsInChildren = ((Component)source).GetComponentsInChildren<MeshRenderer>(); if (componentsInChildren != null && componentsInChildren.Length != 0) { target.AddRange(componentsInChildren); } } } } public class ItemSetBuilder { public List<GameObject> prefabs = new List<GameObject>(); public ModResourceLoader modResourceLoader = null; public static List<ColorizerPack> colorizerPacks = new List<ColorizerPack>(); public static List<ColorizerPack> createColorPacks(ModResourceLoader modResourceLoader) { if (modResourceLoader == null) { Debug.LogError((object)"ItemSetBuilder.createColorPacks: modResourceLoader is null."); return colorizerPacks; } colorizerPacks.Clear(); Dictionary<string, GameObject> dyeLookup = BuildDyeLookup(modResourceLoader); AddSimpleSet(modResourceLoader, dyeLookup, "crystal_wall_1x1", (Material[])(object)new Material[8] { modResourceLoader.crystal01black, modResourceLoader.crystal01blue, modResourceLoader.crystal01green, modResourceLoader.crystal01orange, modResourceLoader.crystal01purple, modResourceLoader.crystal01red, modResourceLoader.crystal01white, modResourceLoader.crystal01yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner01", (Material[])(object)new Material[8] { modResourceLoader.banner01black, modResourceLoader.banner01blue, modResourceLoader.banner01green, modResourceLoader.banner01orange, modResourceLoader.banner01purple, modResourceLoader.banner01red, modResourceLoader.banner01white, modResourceLoader.banner01yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner02", (Material[])(object)new Material[8] { modResourceLoader.banner02black, modResourceLoader.banner02blue, modResourceLoader.banner02green, modResourceLoader.banner02orange, modResourceLoader.banner02purple, modResourceLoader.banner02red, modResourceLoader.banner02white, modResourceLoader.banner02yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner03", (Material[])(object)new Material[8] { modResourceLoader.banner03black, modResourceLoader.banner03blue, modResourceLoader.banner03green, modResourceLoader.banner03orange, modResourceLoader.banner03purple, modResourceLoader.banner03red, modResourceLoader.banner03white, modResourceLoader.banner03yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner04", (Material[])(object)new Material[8] { modResourceLoader.banner04black, modResourceLoader.banner04blue, modResourceLoader.banner04green, modResourceLoader.banner04orange, modResourceLoader.banner04purple, modResourceLoader.banner04red, modResourceLoader.banner04white, modResourceLoader.banner04yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner05", (Material[])(object)new Material[8] { modResourceLoader.banner05black, modResourceLoader.banner05blue, modResourceLoader.banner05green, modResourceLoader.banner05orange, modResourceLoader.banner05purple, modResourceLoader.banner05red, modResourceLoader.banner05white, modResourceLoader.banner05yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner06", (Material[])(object)new Material[8] { modResourceLoader.banner06black, modResourceLoader.banner06blue, modResourceLoader.banner06green, modResourceLoader.banner06orange, modResourceLoader.banner06purple, modResourceLoader.banner06red, modResourceLoader.banner06white, modResourceLoader.banner06yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner07", (Material[])(object)new Material[8] { modResourceLoader.banner07black, modResourceLoader.banner07blue, modResourceLoader.banner07green, modResourceLoader.banner07orange, modResourceLoader.banner07purple, modResourceLoader.banner07red, modResourceLoader.banner07white, modResourceLoader.banner07yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner08", (Material[])(object)new Material[8] { modResourceLoader.banner08black, modResourceLoader.banner08blue, modResourceLoader.banner08green, modResourceLoader.banner08orange, modResourceLoader.banner08purple, modResourceLoader.banner08red, modResourceLoader.banner08white, modResourceLoader.banner08yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner09", (Material[])(object)new Material[8] { modResourceLoader.banner09black, modResourceLoader.banner09blue, modResourceLoader.banner09green, modResourceLoader.banner09orange, modResourceLoader.banner09purple, modResourceLoader.banner09red, modResourceLoader.banner09white, modResourceLoader.banner09yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner10", (Material[])(object)new Material[8] { modResourceLoader.banner10black, modResourceLoader.banner10blue, modResourceLoader.banner10green, modResourceLoader.banner10orange, modResourceLoader.banner10purple, modResourceLoader.banner10red, modResourceLoader.banner10white, modResourceLoader.banner10yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_banner11", (Material[])(object)new Material[8] { modResourceLoader.banner11black, modResourceLoader.banner11blue, modResourceLoader.banner11green, modResourceLoader.banner11orange, modResourceLoader.banner11purple, modResourceLoader.banner11red, modResourceLoader.banner11white, modResourceLoader.banner11yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_cloth_hanging_door", (Material[])(object)new Material[8] { modResourceLoader.bannerHangingblack, modResourceLoader.bannerHangingblue, modResourceLoader.bannerHanginggreen, modResourceLoader.bannerHangingorange, modResourceLoader.bannerHangingpurple, modResourceLoader.bannerHangingred, modResourceLoader.bannerHangingwhite, modResourceLoader.bannerHangingyellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_cloth_hanging_door_blue", (Material[])(object)new Material[8] { modResourceLoader.bannerHanging2black, modResourceLoader.bannerHanging2blue, modResourceLoader.bannerHanging2green, modResourceLoader.bannerHanging2orange, modResourceLoader.bannerHanging2purple, modResourceLoader.bannerHanging2red, modResourceLoader.bannerHanging2white, modResourceLoader.bannerHanging2yellow }); AddSimpleSet(modResourceLoader, dyeLookup, "piece_cloth_hanging_door_blue2", (Material[])(object)new Material[8] { modResourceLoader.bannerHanging3black, modResourceLoader.bannerHanging3blue, modResourceLoader.bannerHanging3green, modResourceLoader.bannerHanging3orange, modResourceLoader.bannerHanging3purple, modResourceLoader.bannerHanging3red, modResourceLoader.bannerHanging3white, modResourceLoader.bannerHanging3yellow }); AddComplexSet(modResourceLoader, dyeLookup, "jute_carpet", (Material[])(object)new Material[8] { modResourceLoader.juteCarpetblack, modResourceLoader.juteCarpetblue, modResourceLoader.juteCarpetgreen, modResourceLoader.juteCarpetorange, modResourceLoader.juteCarpetpurple, modResourceLoader.juteCarpetred, modResourceLoader.juteCarpetwhite, modResourceLoader.juteCarpetyellow }, (Material[])(object)new Material[8] { modResourceLoader.juteCarpetMainblack, modResourceLoader.juteCarpetMainblue, modResourceLoader.juteCarpetMaingreen, modResourceLoader.juteCarpetMainorange, modResourceLoader.juteCarpetMainpurple, modResourceLoader.juteCarpetMainred, modResourceLoader.juteCarpetMainwhite, modResourceLoader.juteCarpetMainyellow }, (Material[])(object)new Material[8] { modResourceLoader.juteCarpetDestructionblack, modResourceLoader.juteCarpetDestructionblue, modResourceLoader.juteCarpetDestructiongreen, modResourceLoader.juteCarpetDestructionorange, modResourceLoader.juteCarpetDestructionpurple, modResourceLoader.juteCarpetDestructionred, modResourceLoader.juteCarpetDestructionwhite, modResourceLoader.juteCarpetDestructionyellow }); AddComplexSet(modResourceLoader, dyeLookup, "jute_carpet_blue", (Material[])(object)new Material[8] { modResourceLoader.juteCarpet2black, modResourceLoader.juteCarpet2blue, modResourceLoader.juteCarpet2green, modResourceLoader.juteCarpet2orange, modResourceLoader.juteCarpet2purple, modResourceLoader.juteCarpet2red, modResourceLoader.juteCarpet2white, modResourceLoader.juteCarpet2yellow }, (Material[])(object)new Material[8] { modResourceLoader.juteCarpetMain2black, modResourceLoader.juteCarpetMain2blue, modResourceLoader.juteCarpetMain2green, modResourceLoader.juteCarpetMain2orange, modResourceLoader.juteCarpetMain2purple, modResourceLoader.juteCarpetMain2red, modResourceLoader.juteCarpetMain2white, modResourceLoader.juteCarpetMain2yellow }, (Material[])(object)new Material[8] { modResourceLoader.juteCarpetDestruction2black, modResourceLoader.juteCarpetDestruction2blue, modResourceLoader.juteCarpetDestruction2green, modResourceLoader.juteCarpetDestruction2orange, modResourceLoader.juteCarpetDestruction2purple, modResourceLoader.juteCarpetDestruction2red, modResourceLoader.juteCarpetDestruction2white, modResourceLoader.juteCarpetDestruction2yellow }); string[] array = new string[8] { "darkwood_roof_icorner", "darkwood_roof_icorner_45", "darkwood_roof_ocorner", "darkwood_roof_ocorner_45", "darkwood_roof_top", "darkwood_roof_top_45", "darkwood_roof_45", "darkwood_roof" }; Material[] array2 = (Material[])(object)new Material[8] { modResourceLoader.roofDarkMain2black, modResourceLoader.roofDarkMain2blue, modResourceLoader.roofDarkMain2green, modResourceLoader.roofDarkMain2orange, modResourceLoader.roofDarkMain2purple, modResourceLoader.roofDarkMain2red, modResourceLoader.roofDarkMain2white, modResourceLoader.roofDarkMain2yellow }; Material[] destructionMaterials = (Material[])(object)new Material[8] { modResourceLoader.roofDarkDestructionblack, modResourceLoader.roofDarkDestructionblue, modResourceLoader.roofDarkDestructiongreen, modResourceLoader.roofDarkDestructionorange, modResourceLoader.roofDarkDestructionpurple, modResourceLoader.roofDarkDestructionred, modResourceLoader.roofDarkDestructionwhite, modResourceLoader.roofDarkDestructionyellow }; for (int i = 0; i < array.Length; i++) { AddComplexSet(modResourceLoader, dyeLookup, array[i], array2, array2, destructionMaterials); } return colorizerPacks; } private static Dictionary<string, GameObject> BuildDyeLookup(ModResourceLoader modResourceLoader) { Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); if (modResourceLoader.items == null) { Debug.LogWarning((object)"ItemSetBuilder: modResourceLoader.items is null."); return dictionary; } foreach (GameObject item in modResourceLoader.items) { if (!((Object)(object)item == (Object)null) && !dictionary.ContainsKey(((Object)item).name)) { dictionary.Add(((Object)item).name, item); } } return dictionary; } private static void AddSimpleSet(ModResourceLoader modResourceLoader, Dictionary<string, GameObject> dyeLookup, string targetName, Material[] bodyMaterials) { for (int i = 0; i < ModResourceLoader.colorNames.Length; i++) { GameObject dyeItem = GetDyeItem(dyeLookup, ModResourceLoader.prefabNames[i]); buildPack(bodyMaterials[i], dyeItem, targetName, ModResourceLoader.colorNames[i]); } } private static void AddComplexSet(ModResourceLoader modResourceLoader, Dictionary<string, GameObject> dyeLookup, string targetName, Material[] bodyMaterials, Material[] rugMaterials, Material[] destructionMaterials) { for (int i = 0; i < ModResourceLoader.colorNames.Length; i++) { GameObject dyeItem = GetDyeItem(dyeLookup, ModResourceLoader.prefabNames[i]); buildPack(bodyMaterials[i], dyeItem, targetName, ModResourceLoader.colorNames[i], rugMaterials[i], destructionMaterials[i]); } } private static GameObject GetDyeItem(Dictionary<string, GameObject> dyeLookup, string dyePrefabName) { if (dyeLookup.TryGetValue(dyePrefabName, out var value)) { return value; } Debug.LogWarning((object)("ItemSetBuilder: dye item not found: " + dyePrefabName)); return null; } private static void buildPack(Material body, GameObject dyeItem, string name, string skin, Material rug = null, Material rugdestruction = null) { colorizerPacks.Add(new ColorizerPack(body, name, dyeItem, skin, rug, rugdestruction)); } public void setupColorizer(GameObject piece) { if ((Object)(object)piece == (Object)null) { Debug.LogWarning((object)"ItemSetBuilder.setupColorizer: piece is null."); return; } BannerColorizer bannerColorizer = piece.GetComponent<BannerColorizer>(); if ((Object)(object)bannerColorizer == (Object)null) { bannerColorizer = piece.AddComponent<BannerColorizer>(); } bannerColorizer.filterPacks(); } } [Serializable] public class ColorizerPack { public Material body; public string buildPieceName; public GameObject dyeItem; public string skin; public Material rugmain; public Material rugdestruction; public ColorizerPack(Material body, string buildPieceName, GameObject dyeItem, string skin, Material rugmain = null, Material rugdestruction = null) { this.buildPieceName = buildPieceName; this.body = body; this.skin = skin; this.dyeItem = dyeItem; this.rugmain = rugmain; this.rugdestruction = rugdestruction; } } public class DatabaseAddMethods { public void AddItems(List<GameObject> items) { foreach (GameObject item in items) { AddItem(item); } } public void AddRecipes(List<Recipe> recipes) { foreach (Recipe recipe in recipes) { AddRecipe(recipe); } } public void AddStatuseffects(List<StatusEffect> statusEffects) { foreach (StatusEffect statusEffect in statusEffects) { AddStatus(statusEffect); } } private bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.m_recipes.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } private void AddStatus(StatusEffect status) { if (!IsObjectDBValid()) { return; } if ((Object)(object)status != (Object)null) { if ((Object)(object)ObjectDB.instance.GetStatusEffect(((object)status).GetHashCode()) == (Object)null) { ObjectDB.instance.m_StatusEffects.Add(status); } } else { Debug.LogError((object)("BalrondBannerColorizer: " + ((Object)status).name + " - Status not found")); } } private void AddRecipe(Recipe recipe) { if (!IsObjectDBValid()) { return; } if ((Object)(object)recipe != (Object)null) { if ((Object)(object)ObjectDB.instance.GetRecipe(recipe.m_item.m_itemData) == (Object)null) { ObjectDB.instance.m_recipes.Add(recipe); } } else { Debug.LogError((object)("BalrondBannerColorizer: " + ((Object)recipe).name + " - Recipe not found")); } } private void AddItem(GameObject newPrefab) { if (!IsObjectDBValid()) { return; } ItemDrop component = newPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { if ((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)newPrefab).name) == (Object)null) { ObjectDB.instance.m_items.Add(newPrefab); Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(ObjectDB.instance); dictionary[((Object)newPrefab).name.GetHashCode()] = newPrefab; } } else { Debug.LogError((object)("BalrondBannerColorizer: " + ((Object)newPrefab).name + " - ItemDrop not found on prefab")); } } } public class JsonLoader { public string defaultPath = string.Empty; public void loadJson() { LoadTranslations(); justDefaultPath(); } public void justDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "BalrondBannerColorizer-translation/"); defaultPath = text; } public void createDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "BalrondBannerColorizer-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("BalrondBannerColorizer: Folder already exists: " + text)); } defaultPath = text; } private string[] jsonFilePath(string folderName, string extension) { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "BalrondBannerColorizer-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("BalrondBannerColorizer: Folder already exists: " + text)); } string[] files = Directory.GetFiles(text, extension); Debug.Log((object)("BalrondBannerColorizer:" + folderName + " Json Files Found: " + files.Length)); return files; } private static void CreateFolder(string path) { try { Directory.CreateDirectory(path); Debug.Log((object)"BalrondBannerColorizer: Folder created successfully."); } catch (Exception ex) { Debug.Log((object)("BalrondBannerColorizer: Error creating folder: " + ex.Message)); } } private void LoadTranslations() { int num = 0; string[] array = jsonFilePath("Translation", "*.json"); foreach (string text in array) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); string json = File.ReadAllText(text); JsonData jsonData = JsonMapper.ToObject(json); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string key in jsonData.Keys) { dictionary[key] = jsonData[key].ToString(); } if (dictionary != null) { BalrondTranslator.translations.Add(fileNameWithoutExtension, dictionary); Debug.Log((object)("BalrondBannerColorizer: Json Files Language: " + fileNameWithoutExtension)); num++; } else { Debug.LogError((object)("BalrondBannerColorizer: Loading FAILED file: " + text)); } } Debug.Log((object)("BalrondBannerColorizer: Translation JsonFiles Loaded: " + num)); } } [BepInPlugin("balrond.astafaraios.BalrondBannerColorizer", "BalrondBannerColorizer", "1.0.7")] public class Launch : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class Object_CopyOtherDB_Path { public static void Postfix() { SetupObjectDbContent(); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_Path { public static void Postfix() { SetupObjectDbContent(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_Path { public static void Prefix(ZNetScene __instance) { if ((Object)(object)__instance == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: No ZNetScene found"); return; } AddMissingPrefabs(__instance); if (!hasSpawned) { SetupDyeTable(__instance); AddDyeTableToHammer(__instance); colorizerPacks = ItemSetBuilder.createColorPacks(modResourceLoader); SetupBuildPieceColorizers(__instance); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) { hasSpawned = true; return; } ShaderReplacment.runMaterialFix(); hasSpawned = true; } } } private readonly Harmony harmony = new Harmony("balrond.astafaraios.BalrondBannerColorizer"); public const string PluginGUID = "balrond.astafaraios.BalrondBannerColorizer"; public const string PluginName = "BalrondBannerColorizer"; public const string PluginVersion = "1.0.7"; public static JsonLoader jsonLoader = new JsonLoader(); public static ModResourceLoader modResourceLoader = new ModResourceLoader(); public static DatabaseAddMethods databaseAddMethods = new DatabaseAddMethods(); public static ItemSetBuilder itemSetBuilder = new ItemSetBuilder(); public static GameObject RootObject; public static GameObject PrefabContainer; public static List<ColorizerPack> colorizerPacks = new List<ColorizerPack>(); public static bool hasSpawned = false; public static string[] buildPieceNames = new string[25] { "piece_banner01", "piece_banner02", "piece_banner03", "piece_banner04", "piece_banner05", "piece_banner06", "piece_banner07", "piece_banner08", "piece_banner09", "piece_banner10", "piece_banner11", "piece_cloth_hanging_door", "piece_cloth_hanging_door_blue", "piece_cloth_hanging_door_blue2", "jute_carpet", "jute_carpet_blue", "crystal_wall_1x1", "darkwood_roof_icorner", "darkwood_roof_icorner_45", "darkwood_roof_ocorner", "darkwood_roof_ocorner_45", "darkwood_roof_top", "darkwood_roof_top_45", "darkwood_roof_45", "darkwood_roof" }; private static readonly Dictionary<string, Func<ModResourceLoader, Material>> DefaultTextureMap = new Dictionary<string, Func<ModResourceLoader, Material>>(StringComparer.Ordinal) { { "piece_banner08", (ModResourceLoader x) => x.banner08yellow }, { "piece_banner05", (ModResourceLoader x) => x.banner05green }, { "piece_banner07", (ModResourceLoader x) => x.banner07blue }, { "piece_banner09", (ModResourceLoader x) => x.banner09purple }, { "piece_banner10", (ModResourceLoader x) => x.banner10orange }, { "piece_banner11", (ModResourceLoader x) => x.banner11white } }; private void Awake() { jsonLoader.loadJson(); createPrefabContainer(); modResourceLoader.loadAssets(); harmony.PatchAll(); } private void OnDestroy() { harmony.UnpatchSelf(); } public void createPrefabContainer() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (!((Object)(object)RootObject != (Object)null) || !((Object)(object)PrefabContainer != (Object)null)) { RootObject = new GameObject("_ValheimReforgedRoot"); Object.DontDestroyOnLoad((Object)(object)RootObject); PrefabContainer = new GameObject("Prefabs"); PrefabContainer.transform.SetParent(RootObject.transform, false); PrefabContainer.SetActive(false); } } public static GameObject cloneMe(GameObject source, string name) { if ((Object)(object)source == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: cloneMe source is null"); return null; } if ((Object)(object)PrefabContainer == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: PrefabContainer is null"); return null; } GameObject val = Object.Instantiate<GameObject>(source, PrefabContainer.transform); ((Object)val).name = name; return val; } private static bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.m_recipes != null && ObjectDB.instance.m_recipes.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } private static void SetupObjectDbContent() { if (IsObjectDBValid()) { databaseAddMethods.AddItems(modResourceLoader.items); List<Recipe> recipes = createRecipesForDye(ObjectDB.instance.m_items); databaseAddMethods.AddRecipes(recipes); } } private static void AddMissingPrefabs(ZNetScene scene) { foreach (GameObject item in modResourceLoader.items) { if ((Object)(object)item != (Object)null && !scene.m_prefabs.Contains(item)) { scene.m_prefabs.Add(item); } } if ((Object)(object)modResourceLoader.dyeTable != (Object)null && !scene.m_prefabs.Contains(modResourceLoader.dyeTable)) { scene.m_prefabs.Add(modResourceLoader.dyeTable); } } private static void SetupDyeTable(ZNetScene scene) { if ((Object)(object)modResourceLoader.dyeTable == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: dyeTable is null"); return; } Piece component = modResourceLoader.dyeTable.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: dyeTable Piece component missing"); return; } List<Requirement> list = new List<Requirement> { createReq("Wood", 5, 0, scene.m_prefabs), createReq("Resin", 5, 0, scene.m_prefabs) }; component.m_resources = list.ToArray(); setupRavenGuide(modResourceLoader.dyeTable, scene.m_prefabs); } private static void AddDyeTableToHammer(ZNetScene scene) { GameObject val = scene.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Hammer"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: Hammer prefab not found"); return; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: Hammer ItemDrop missing"); return; } PieceTable val2 = component.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val2 == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: Hammer build piece table missing"); return; } GameObject val3 = val2.m_pieces.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)modResourceLoader.dyeTable).name); if ((Object)(object)val3 == (Object)null) { val2.m_pieces.Add(modResourceLoader.dyeTable); } } private static void SetupBuildPieceColorizers(ZNetScene scene) { string[] array = buildPieceNames; foreach (string name in array) { GameObject val = scene.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name); if (!((Object)(object)val == (Object)null)) { itemSetBuilder.setupColorizer(val); swapBasicTexture(val); } } } public static void swapBasicTexture(GameObject gameObject) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown if ((Object)(object)gameObject == (Object)null || !DefaultTextureMap.TryGetValue(((Object)gameObject).name, out var value)) { return; } Transform val = gameObject.transform.Find("default"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("BalrondBannerColorizer: default child not found on " + ((Object)gameObject).name)); return; } MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)("BalrondBannerColorizer: MeshRenderer not found on default child of " + ((Object)gameObject).name)); return; } Material val2 = value(modResourceLoader); if ((Object)(object)val2 == (Object)null) { Debug.LogWarning((object)("BalrondBannerColorizer: source material missing for " + ((Object)gameObject).name)); return; } Material sharedMaterial = (((Renderer)component).material = new Material(val2)); ((Renderer)component).sharedMaterial = sharedMaterial; } public static void setupRavenGuide(GameObject gameObject, List<GameObject> gameObjects) { if ((Object)(object)gameObject == (Object)null || gameObjects == null) { return; } Transform val = gameObject.transform.Find("GuidePoint"); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = gameObjects.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "piece_workbench"); if ((Object)(object)val2 == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: Workbench not found for raven guide setup"); return; } Transform val3 = val2.transform.Find("GuidePoint"); if ((Object)(object)val3 == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: Workbench GuidePoint not found"); return; } GuidePoint component = ((Component)val3).GetComponent<GuidePoint>(); GuidePoint component2 = ((Component)val).GetComponent<GuidePoint>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: GuidePoint component missing"); } else if ((Object)(object)component.m_ravenPrefab == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: Raven prefab not found"); } else { component2.m_ravenPrefab = component.m_ravenPrefab; } } public static List<Recipe> createRecipesForDye(List<GameObject> items) { List<Recipe> list = new List<Recipe>(); if (modResourceLoader.items == null || (Object)(object)modResourceLoader.dyeTable == (Object)null) { return list; } CraftingStation component = modResourceLoader.dyeTable.GetComponent<CraftingStation>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)"BalrondBannerColorizer: CraftingStation missing on dyeTable"); return list; } foreach (GameObject item in modResourceLoader.items) { if (!((Object)(object)item == (Object)null)) { ItemDrop component2 = item.GetComponent<ItemDrop>(); if ((Object)(object)component2 == (Object)null) { Debug.LogWarning((object)("BalrondBannerColorizer: ItemDrop missing on " + ((Object)item).name)); continue; } Recipe val = ScriptableObject.CreateInstance<Recipe>(); ((Object)val).name = "Recipe_" + ((Object)item).name; val.m_minStationLevel = 1; val.m_craftingStation = component; val.m_repairStation = component; val.m_item = component2; val.m_resources = createRecipeResource(item, items); list.Add(val); } } return list; } public static Requirement[] createRecipeResource(GameObject item, List<GameObject> items) { List<Requirement> list = new List<Requirement>(); if ((Object)(object)item == (Object)null) { return list.ToArray(); } switch (((Object)item).name) { case "DyeBlack": list.Add(createReq("Coal", 1, 0, items)); break; case "DyeBlue": list.Add(createReq("Blueberries", 2, 0, items)); break; case "DyeGreen": list.Add(createReq("Guck", 1, 0, items)); break; case "DyeOrange": list.Add(createReq("Raspberry", 1, 0, items)); list.Add(createReq("Cloudberry", 1, 0, items)); break; case "DyePurple": list.Add(createReq("Raspberry", 1, 0, items)); list.Add(createReq("Blueberries", 1, 0, items)); break; case "DyeRed": list.Add(createReq("Bloodbag", 1, 0, items)); break; case "DyeWhite": list.Add(createReq("BoneFragments", 2, 0, items)); break; case "DyeYellow": list.Add(createReq("Cloudberry", 2, 0, items)); break; } return list.ToArray(); } public static Requirement createReq(string name, int amount, int amountPerLevel, List<GameObject> items) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Requirement val = new Requirement(); val.m_recover = true; GameObject val2 = FindItem(name, items); if ((Object)(object)val2 == (Object)null) { Debug.LogWarning((object)("BalrondBannerColorizer: Could not create requirement for " + name)); return val; } ItemDrop component = val2.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)("BalrondBannerColorizer: ItemDrop missing for requirement item " + name)); return val; } val.m_resItem = component; val.m_amount = amount; val.m_amountPerLevel = amountPerLevel; return val; } public static GameObject FindItem(string name, List<GameObject> items) { if (items == null) { Debug.LogWarning((object)("BalrondBannerColorizer: item list is null while searching for " + name)); return null; } GameObject val = items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name); if ((Object)(object)val != (Object)null) { return val; } Debug.LogWarning((object)("Item Not Found - " + name + ", Replaced With Wood")); GameObject val2 = items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "Wood"); if ((Object)(object)val2 != (Object)null) { return val2; } Debug.LogWarning((object)("Item Not Found At All - " + name + ", and Wood fallback missing")); return null; } } [HarmonyPatch] internal static class TranslationPatches { [HarmonyPatch(typeof(FejdStartup), "SetupGui")] private class FejdStartup_SetupGUI { private static void Postfix() { string selectedLanguage = Localization.instance.GetSelectedLanguage(); Dictionary<string, string> translations = GetTranslations(selectedLanguage); AddTranslations(translations); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "SetupLanguage")] private class Translation_SetupLanguage { private static void Prefix(Localization __instance, string language) { Dictionary<string, string> translations = GetTranslations(language); AddTranslations(translations, __instance); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "LoadCSV")] private class Translation_LoadCSV { private static void Prefix(Localization __instance, string language) { Dictionary<string, string> translations = GetTranslations(language); AddTranslations(translations, __instance); } } private static Dictionary<string, string> GetTranslations(string language) { Dictionary<string, string> result = BalrondTranslator.getLanguage("English"); if (!string.Equals(language, "English", StringComparison.OrdinalIgnoreCase)) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { result = language2; } else { Debug.Log((object)("BalrondBannerColorizer: Did not find translation file for '" + language + "', loading English")); } } return result; } private static void AddTranslations(Dictionary<string, string> translations, Localization localizationInstance = null) { if (translations == null) { Debug.LogWarning((object)"BalrondBannerColorizer: No translation file found!"); return; } if (localizationInstance != null) { foreach (KeyValuePair<string, string> translation in translations) { localizationInstance.AddWord(translation.Key, translation.Value); } return; } foreach (KeyValuePair<string, string> translation2 in translations) { Localization.instance.AddWord(translation2.Key, translation2.Value); } } } } namespace LitJson2 { internal enum JsonType { None, Object, Array, String, Int, Long, Double, Boolean } internal interface IJsonWrapper : IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable { bool IsArray { get; } bool IsBoolean { get; } bool IsDouble { get; } bool IsInt { get; } bool IsLong { get; } bool IsObject { get; } bool IsString { get; } bool GetBoolean(); double GetDouble(); int GetInt(); JsonType GetJsonType(); long GetLong(); string GetString(); void SetBoolean(bool val); void SetDouble(double val); void SetInt(int val); void SetJsonType(JsonType type); void SetLong(long val); void SetString(string val); string ToJson(); void ToJson(JsonWriter writer); } internal class JsonData : IJsonWrapper, IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable, IEquatable<JsonData> { private IList<JsonData> inst_array; private bool inst_boolean; private double inst_double; private int inst_int; private long inst_long; private IDictionary<string, JsonData> inst_object; private string inst_string; private string json; private JsonType type; private IList<KeyValuePair<string, JsonData>> object_list; public int Count => EnsureCollection().Count; public bool IsArray => type == JsonType.Array; public bool IsBoolean => type == JsonType.Boolean; public bool IsDouble => type == JsonType.Double; public bool IsInt => type == JsonType.Int; public bool IsLong => type == JsonType.Long; public bool IsObject => type == JsonType.Object; public bool IsString => type == JsonType.String; public ICollection<string> Keys { get { EnsureDictionary(); return inst_object.Keys; } } int ICollection.Count => Count; bool ICollection.IsSynchronized => EnsureCollection().IsSynchronized; object ICollection.SyncRoot => EnsureCollection().SyncRoot; bool IDictionary.IsFixedSize => EnsureDictionary().IsFixedSize; bool IDictionary.IsReadOnly => EnsureDictionary().IsReadOnly; ICollection IDictionary.Keys { get { EnsureDictionary(); IList<string> list = new List<string>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Key); } return (ICollection)list; } } ICollection IDictionary.Values { get { EnsureDictionary(); IList<JsonData> list = new List<JsonData>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Value); } return (ICollection)list; } } bool IJsonWrapper.IsArray => IsArray; bool IJsonWrapper.IsBoolean => IsBoolean; bool IJsonWrapper.IsDouble => IsDouble; bool IJsonWrapper.IsInt => IsInt; bool IJsonWrapper.IsLong => IsLong; bool IJsonWrapper.IsObject => IsObject; bool IJsonWrapper.IsString => IsString; bool IList.IsFixedSize => EnsureList().IsFixedSize; bool IList.IsReadOnly => EnsureList().IsReadOnly; object IDictionary.this[object key] { get { return EnsureDictionary()[key]; } set { if (!(key is string)) { throw new ArgumentException("The key has to be a string"); } JsonData value2 = ToJsonData(value); this[(string)key] = value2; } } object IOrderedDictionary.this[int idx] { get { EnsureDictionary(); return object_list[idx].Value; } set { EnsureDictionary(); JsonData value2 = ToJsonData(value); KeyValuePair<string, JsonData> keyValuePair = object_list[idx]; inst_object[keyValuePair.Key] = value2; KeyValuePair<string, JsonData> value3 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value2); object_list[idx] = value3; } } object IList.this[int index] { get { return EnsureList()[index]; } set { EnsureList(); JsonData value2 = ToJsonData(value); this[index] = value2; } } public JsonData this[string prop_name] { get { EnsureDictionary(); return inst_object[prop_name]; } set { EnsureDictionary(); KeyValuePair<string, JsonData> keyValuePair = new KeyValuePair<string, JsonData>(prop_name, value); if (inst_object.ContainsKey(prop_name)) { for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == prop_name) { object_list[i] = keyValuePair; break; } } } else { object_list.Add(keyValuePair); } inst_object[prop_name] = value; json = null; } } public JsonData this[int index] { get { EnsureCollection(); if (type == JsonType.Array) { return inst_array[index]; } return object_list[index].Value; } set { EnsureCollection(); if (type == JsonType.Array) { inst_array[index] = value; } else { KeyValuePair<string, JsonData> keyValuePair = object_list[index]; KeyValuePair<string, JsonData> value2 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value); object_list[index] = value2; inst_object[keyValuePair.Key] = value; } json = null; } } public JsonData() { } public JsonData(bool boolean) { type = JsonType.Boolean; inst_boolean = boolean; } public JsonData(double number) { type = JsonType.Double; inst_double = number; } public JsonData(int number) { type = JsonType.Int; inst_int = number; } public JsonData(long number) { type = JsonType.Long; inst_long = number; } public JsonData(object obj) { if (obj is bool) { type = JsonType.Boolean; inst_boolean = (bool)obj; return; } if (obj is double) { type = JsonType.Double; inst_double = (double)obj; return; } if (obj is int) { type = JsonType.Int; inst_int = (int)obj; return; } if (obj is long) { type = JsonType.Long; inst_long = (long)obj; return; } if (obj is string) { type = JsonType.String; inst_string = (string)obj; return; } throw new ArgumentException("Unable to wrap the given object with JsonData"); } public JsonData(string str) { type = JsonType.String; inst_string = str; } public static implicit operator JsonData(bool data) { return new JsonData(data); } public static implicit operator JsonData(double data) { return new JsonData(data); } public static implicit operator JsonData(int data) { return new JsonData(data); } public static implicit operator JsonData(long data) { return new JsonData(data); } public static implicit operator JsonData(string data) { return new JsonData(data); } public static explicit operator bool(JsonData data) { if (data.type != JsonType.Boolean) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_boolean; } public static explicit operator double(JsonData data) { if (data.type != JsonType.Double) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_double; } public static explicit operator int(JsonData data) { if (data.type != JsonType.Int) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } return data.inst_int; } public static explicit operator long(JsonData data) { if (data.type != JsonType.Long) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } return data.inst_long; } public static explicit operator string(JsonData data) { if (data.type != JsonType.String) { throw new InvalidCastException("Instance of JsonData doesn't hold a string"); } return data.inst_string; } void ICollection.CopyTo(Array array, int index) { EnsureCollection().CopyTo(array, index); } void IDictionary.Add(object key, object value) { JsonData value2 = ToJsonData(value); EnsureDictionary().Add(key, value2); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>((string)key, value2); object_list.Add(item); json = null; } void IDictionary.Clear() { EnsureDictionary().Clear(); object_list.Clear(); json = null; } bool IDictionary.Contains(object key) { return EnsureDictionary().Contains(key); } IDictionaryEnumerator IDictionary.GetEnumerator() { return ((IOrderedDictionary)this).GetEnumerator(); } void IDictionary.Remove(object key) { EnsureDictionary().Remove(key); for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == (string)key) { object_list.RemoveAt(i); break; } } json = null; } IEnumerator IEnumerable.GetEnumerator() { return EnsureCollection().GetEnumerator(); } bool IJsonWrapper.GetBoolean() { if (type != JsonType.Boolean) { throw new InvalidOperationException("JsonData instance doesn't hold a boolean"); } return inst_boolean; } double IJsonWrapper.GetDouble() { if (type != JsonType.Double) { throw new InvalidOperationException("JsonData instance doesn't hold a double"); } return inst_double; } int IJsonWrapper.GetInt() { if (type != JsonType.Int) { throw new InvalidOperationException("JsonData instance doesn't hold an int"); } return inst_int; } long IJsonWrapper.GetLong() { if (type != JsonType.Long) { throw new InvalidOperationException("JsonData instance doesn't hold a long"); } return inst_long; } string IJsonWrapper.GetString() { if (type != JsonType.String) { throw new InvalidOperationException("JsonData instance doesn't hold a string"); } return inst_string; } void IJsonWrapper.SetBoolean(bool val) { type = JsonType.Boolean; inst_boolean = val; json = null; } void IJsonWrapper.SetDouble(double val) { type = JsonType.Double; inst_double = val; json = null; } void IJsonWrapper.SetInt(int val) { type = JsonType.Int; inst_int = val; json = null; } void IJsonWrapper.SetLong(long val) { type = JsonType.Long; inst_long = val; json = null; } void IJsonWrapper.SetString(string val) { type = JsonType.String; inst_string = val; json = null; } string IJsonWrapper.ToJson() { return ToJson(); } void IJsonWrapper.ToJson(JsonWriter writer) { ToJson(writer); } int IList.Add(object value) { return Add(value); } void IList.Clear() { EnsureList().Clear(); json = null; } bool IList.Contains(object value) { return EnsureList().Contains(value); } int IList.IndexOf(object value) { return EnsureList().IndexOf(value); } void IList.Insert(int index, object value) { EnsureList().Insert(index, value); json = null; } void IList.Remove(object value) { EnsureList().Remove(value); json = null; } void IList.RemoveAt(int index) { EnsureList().RemoveAt(index); json = null; } IDictionaryEnumerator IOrderedDictionary.GetEnumerator() { EnsureDictionary(); return new OrderedDictionaryEnumerator(object_list.GetEnumerator()); } void IOrderedDictionary.Insert(int idx, object key, object value) { string text = (string)key; JsonData value2 = (this[text] = ToJsonData(value)); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>(text, value2); object_list.Insert(idx, item); } void IOrderedDictionary.RemoveAt(int idx) { EnsureDictionary(); inst_object.Remove(object_list[idx].Key); object_list.RemoveAt(idx); } private ICollection EnsureCollection() { if (type == JsonType.Array) { return (ICollection)inst_array; } if (type == JsonType.Object) { return (ICollection)inst_object; } throw new InvalidOperationException("The JsonData instance has to be initialized first"); } private IDictionary EnsureDictionary() { if (type == JsonType.Object) { return (IDictionary)inst_object; } if (type != 0) { throw new InvalidOperationException("Instance of JsonData is not a dictionary"); } type = JsonType.Object; inst_object = new Dictionary<string, JsonData>(); object_list = new List<KeyValuePair<string, JsonData>>(); return (IDictionary)inst_object; } private IList EnsureList() { if (type == JsonType.Array) { return (IList)inst_array; } if (type != 0) { throw new InvalidOperationException("Instance of JsonData is not a list"); } type = JsonType.Array; inst_array = new List<JsonData>(); return (IList)inst_array; } private JsonData ToJsonData(object obj) { if (obj == null) { return null; } if (obj is JsonData) { return (JsonData)obj; } return new JsonData(obj); } private static void WriteJson(IJsonWrapper obj, JsonWriter writer) { if (obj == null) { writer.Write(null); } else if (obj.IsString) { writer.Write(obj.GetString()); } else if (obj.IsBoolean) { writer.Write(obj.GetBoolean()); } else if (obj.IsDouble) { writer.Write(obj.GetDouble()); } else if (obj.IsInt) { writer.Write(obj.GetInt()); } else if (obj.IsLong) { writer.Write(obj.GetLong()); } else if (obj.IsArray) { writer.WriteArrayStart(); foreach (object item in (IEnumerable)obj) { WriteJson((JsonData)item, writer); } writer.WriteArrayEnd(); } else { if (!obj.IsObject) { return; } writer.WriteObjectStart(); foreach (DictionaryEntry item2 in (IDictionary)obj) { writer.WritePropertyName((string)item2.Key); WriteJson((JsonData)item2.Value, writer); } writer.WriteObjectEnd(); } } public int Add(object value) { JsonData value2 = ToJsonData(value); json = null; return EnsureList().Add(value2); } public void Clear() { if (IsObject) { ((IDictionary)this).Clear(); } else if (IsArray) { ((IList)this).Clear(); } } public bool Equals(JsonData x) { if (x == null) { return false; } if (x.type != type) { return false; } return type switch { JsonType.None => true, JsonType.Object => inst_object.Equals(x.inst_object), JsonType.Array => inst_array.Equals(x.inst_array), JsonType.String => inst_string.Equals(x.inst_string), JsonType.Int => inst_int.Equals(x.inst_int), JsonType.Long => inst_long.Equals(x.inst_long), JsonType.Double => inst_double.Equals(x.inst_double), JsonType.Boolean => inst_boolean.Equals(x.inst_boolean), _ => false, }; } public JsonType GetJsonType() { return type; } public void SetJsonType(JsonType type) { if (this.type != type) { switch (type) { case JsonType.Object: inst_object = new Dictionary<string, JsonData>(); object_list = new List<KeyValuePair<string, JsonData>>(); break; case JsonType.Array: inst_array = new List<JsonData>(); break; case JsonType.String: inst_string = null; break; case JsonType.Int: inst_int = 0; break; case JsonType.Long: inst_long = 0L; break; case JsonType.Double: inst_double = 0.0; break; case JsonType.Boolean: inst_boolean = false; break; } this.type = type; } } public string ToJson() { if (json != null) { return json; } StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter); jsonWriter.Validate = false; WriteJson(this, jsonWriter); json = stringWriter.ToString(); return json; } public void ToJson(JsonWriter writer) { bool validate = writer.Validate; writer.Validate = false; WriteJson(this, writer); writer.Validate = validate; } public override string ToString() { return type switch { JsonType.Array => "JsonData array", JsonType.Boolean => inst_boolean.ToString(), JsonType.Double => inst_double.ToString(), JsonType.Int => inst_int.ToString(), JsonType.Long => inst_long.ToString(), JsonType.Object => "JsonData object", JsonType.String => inst_string, _ => "Uninitialized JsonData", }; } } internal class OrderedDictionaryEnumerator : IDictionaryEnumerator, IEnumerator { private IEnumerator<KeyValuePair<string, JsonData>> list_enumerator; public object Current => Entry; public DictionaryEntry Entry { get { KeyValuePair<string, JsonData> current = list_enumerator.Current; return new DictionaryEntry(current.Key, current.Value); } } public object Key => list_enumerator.Current.Key; public object Value => list_enumerator.Current.Value; public OrderedDictionaryEnumerator(IEnumerator<KeyValuePair<string, JsonData>> enumerator) { list_enumerator = enumerator; } public bool MoveNext() { return list_enumerator.MoveNext(); } public void Reset() { list_enumerator.Reset(); } } internal class JsonException : ApplicationException { public JsonException() { } internal JsonException(ParserToken token) : base($"Invalid token '{token}' in input string") { } internal JsonException(ParserToken token, Exception inner_exception) : base($"Invalid token '{token}' in input string", inner_exception) { } internal JsonException(int c) : base($"Invalid character '{(char)c}' in input string") { } internal JsonException(int c, Exception inner_exception) : base($"Invalid character '{(char)c}' in input string", inner_exception) { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception inner_exception) : base(message, inner_exception) { } } internal struct PropertyMetadata { public MemberInfo Info; public bool IsField; public Type Type; } internal struct ArrayMetadata { private Type element_type; private bool is_array; private bool is_list; public Type ElementType { get { if (element_type == null) { return typeof(JsonData); } return element_type; } set { element_type = value; } } public bool IsArray { get { return is_array; } set { is_array = value; } } public bool IsList { get { return is_list; } set { is_list = value; } } } internal struct ObjectMetadata { private Type element_type; private bool is_dictionary; private IDictionary<string, PropertyMetadata> properties; public Type ElementType { get { if (element_type == null) { return typeof(JsonData); } return element_type; } set { element_type = value; } } public bool IsDictionary { get { return is_dictionary; } set { is_dictionary = value; } } public IDictionary<string, PropertyMetadata> Properties { get { return properties; } set { properties = value; } } } internal delegate void ExporterFunc(object obj, JsonWriter writer); internal delegate void ExporterFunc<T>(T obj, JsonWriter writer); internal delegate object ImporterFunc(object input); internal delegate TValue ImporterFunc<TJson, TValue>(TJson input); internal delegate IJsonWrapper WrapperFactory(); internal class JsonMapper { private static int max_nesting_depth; private static IFormatProvider datetime_format; private static IDictionary<Type, ExporterFunc> base_exporters_table; private static IDictionary<Type, ExporterFunc> custom_exporters_table; private static IDictionary<Type, IDictionary<Type, ImporterFunc>> base_importers_table; private static IDictionary<Type, IDictionary<Type, ImporterFunc>> custom_importers_table; private static IDictionary<Type, ArrayMetadata> array_metadata; private static readonly object array_metadata_lock; private static IDictionary<Type, IDictionary<Type, MethodInfo>> conv_ops; private static readonly object conv_ops_lock; private static IDictionary<Type, ObjectMetadata> object_metadata; private static readonly object object_metadata_lock; private static IDictionary<Type, IList<PropertyMetadata>> type_properties; private static readonly object type_properties_lock; private static JsonWriter static_writer; private static readonly object static_writer_lock; static JsonMapper() { array_metadata_lock = new object(); conv_ops_lock = new object(); object_metadata_lock = new object(); type_properties_lock = new object(); static_writer_lock = new object(); max_nesting_depth = 100; array_metadata = new Dictionary<Type, ArrayMetadata>(); conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>>(); object_metadata = new Dictionary<Type, ObjectMetadata>(); type_properties = new Dictionary<Type, IList<PropertyMetadata>>(); static_writer = new JsonWriter(); datetime_format = DateTimeFormatInfo.InvariantInfo; base_exporters_table = new Dictionary<Type, ExporterFunc>(); custom_exporters_table = new Dictionary<Type, ExporterFunc>(); base_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>(); custom_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>(); RegisterBaseExporters(); RegisterBaseImporters(); } private static void AddArrayMetadata(Type type) { if (array_metadata.ContainsKey(type)) { return; } ArrayMetadata value = default(ArrayMetadata); value.IsArray = type.IsArray; if (type.GetInterface("System.Collections.IList") != null) { value.IsList = true; } PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name != "Item")) { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(int)) { value.ElementType = propertyInfo.PropertyType; } } } lock (array_metadata_lock) { try { array_metadata.Add(type, value); } catch (ArgumentException) { } } } private static void AddObjectMetadata(Type type) { if (object_metadata.ContainsKey(type)) { return; } ObjectMetadata value = default(ObjectMetadata); if (type.GetInterface("System.Collections.IDictionary") != null) { value.IsDictionary = true; } value.Properties = new Dictionary<string, PropertyMetadata>(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.Name == "Item") { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(string)) { value.ElementType = propertyInfo.PropertyType; } } else { PropertyMetadata value2 = default(PropertyMetadata); value2.Info = propertyInfo; value2.Type = propertyInfo.PropertyType; value.Properties.Add(propertyInfo.Name, value2); } } FieldInfo[] fields = type.GetFields(); foreach (FieldInfo fieldInfo in fields) { PropertyMetadata value3 = default(PropertyMetadata); value3.Info = fieldInfo; value3.IsField = true; value3.Type = fieldInfo.FieldType; value.Properties.Add(fieldInfo.Name, value3); } lock (object_metadata_lock) { try { object_metadata.Add(type, value); } catch (ArgumentException) { } } } private static void AddTypeProperties(Type type) { if (type_properties.ContainsKey(type)) { return; } IList<PropertyMetadata> list = new List<PropertyMetadata>(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name == "Item")) { PropertyMetadata item = default(PropertyMetadata); item.Info = propertyInfo; item.IsField = false; list.Add(item); } } FieldInfo[] fields = type.GetFields(); foreach (FieldInfo info in fields) { PropertyMetadata item2 = default(PropertyMetadata); item2.Info = info; item2.IsField = true; list.Add(item2); } lock (type_properties_lock) { try { type_properties.Add(type, list); } catch (ArgumentException) { } } } private static MethodInfo GetConvOp(Type t1, Type t2) { lock (conv_ops_lock) { if (!conv_ops.ContainsKey(t1)) { conv_ops.Add(t1, new Dictionary<Type, MethodInfo>()); } } if (conv_ops[t1].ContainsKey(t2)) { return conv_ops[t1][t2]; } MethodInfo method = t1.GetMethod("op_Implicit", new Type[1] { t2 }); lock (conv_ops_lock) { try { conv_ops[t1].Add(t2, method); return method; } catch (ArgumentException) { return conv_ops[t1][t2]; } } } private static object ReadValue(Type inst_type, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd) { return null; } Type underlyingType = Nullable.GetUnderlyingType(inst_type); Type type = underlyingType ?? inst_type; if (reader.Token == JsonToken.Null) { if (inst_type.IsClass || underlyingType != null) { return null; } throw new JsonException($"Can't assign null to an instance of type {inst_type}"); } if (reader.Token == JsonToken.Double || reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean) { Type type2 = reader.Value.GetType(); if (type.IsAssignableFrom(type2)) { return reader.Value; } if (custom_importers_table.ContainsKey(type2) && custom_importers_table[type2].ContainsKey(type)) { ImporterFunc importerFunc = custom_importers_table[type