Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of IDRSJsonLoader v1.0.3
plugins/IDRSJsonLoader/IDRSJsonLoader.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HG.Coroutines; using HG.Reflection; using IDRSJsonLoader.Models; using R2API; using RoR2; using UnityEngine; using UnityEngine.AddressableAssets; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace IDRSJsonLoader { public delegate void ParseCallback(ItemDisplayRuleSet idrs); [BepInPlugin("com.KingEnderBrine.IDRSJsonLoader", "IDRS Json Loader", "1.0.3")] public class IDRSJsonLoaderPlugin : BaseUnityPlugin { public const string Guid = "com.KingEnderBrine.IDRSJsonLoader"; public const string Name = "IDRS Json Loader"; public const string Version = "1.0.3"; private static readonly List<DelayedReplacementInfo> delayedReplacementInfos = new List<DelayedReplacementInfo>(); internal static IDRSJsonLoaderPlugin Instance { get; private set; } internal static ManualLogSource InstanceLogger { get { IDRSJsonLoaderPlugin instance = Instance; if (instance == null) { return null; } return ((BaseUnityPlugin)instance).Logger; } } private void Awake() { Instance = this; string[] files = Directory.GetFiles(Paths.PluginPath, "*.idrsjson", SearchOption.AllDirectories); foreach (string text in files) { try { ParseAndUpdate(File.ReadAllText(text), null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Couldn't load file " + text)); ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } } public static void ParseAndUpdate(string json, ParseCallback beforeGenerateRuntimeValues) { DelayedReplacementInfo item = new DelayedReplacementInfo { exportIdrs = JsonUtility.FromJson<ExportItemDisplayRuleSet>(json), beforeGenerateRuntimeValues = beforeGenerateRuntimeValues }; delayedReplacementInfos.Add(item); } public static void ParseAndUpdate(string json, ItemDisplayRuleSet idrs, ParseCallback beforeGenerateRuntimeValues) { DelayedReplacementInfo item = new DelayedReplacementInfo { exportIdrs = JsonUtility.FromJson<ExportItemDisplayRuleSet>(json), idrs = idrs, beforeGenerateRuntimeValues = beforeGenerateRuntimeValues }; delayedReplacementInfos.Add(item); } [SystemInitializer(new Type[] { typeof(ItemDisplayRuleSet), typeof(BodyCatalog), typeof(SkinCatalog) })] internal static IEnumerator Init() { Dictionary<string, AssetBundle> assetBundles = AssetBundle.GetAllLoadedAssetBundles().ToDictionary((AssetBundle b) => ((Object)b).name); Dictionary<ItemDisplayRuleSet, AssetsInfo> dictionary = new Dictionary<ItemDisplayRuleSet, AssetsInfo>(); Dictionary<SkinDef, AssetsInfo> dictionary2 = new Dictionary<SkinDef, AssetsInfo>(); AssetsInfo value2; foreach (DelayedReplacementInfo delayedReplacementInfo in delayedReplacementInfos) { ExportItemDisplayRuleSet exportIdrs = delayedReplacementInfo.exportIdrs; if (!Object.op_Implicit((Object)(object)delayedReplacementInfo.idrs) && !string.IsNullOrEmpty(exportIdrs.bodyName)) { GameObject val = BodyCatalog.FindBodyPrefab(exportIdrs.bodyName); if (Object.op_Implicit((Object)(object)val)) { CharacterBody component = val.GetComponent<CharacterBody>(); ModelLocator component2 = val.GetComponent<ModelLocator>(); object obj; if (component2 == null) { obj = null; } else { Transform modelTransform = component2.modelTransform; obj = ((modelTransform != null) ? ((Component)modelTransform).GetComponent<CharacterModel>() : null); } CharacterModel val2 = (CharacterModel)obj; if (Object.op_Implicit((Object)(object)val2)) { delayedReplacementInfo.characterModel = val2; if (!Object.op_Implicit((Object)(object)val2.itemDisplayRuleSet)) { val2.itemDisplayRuleSet = ScriptableObject.CreateInstance<ItemDisplayRuleSet>(); } if (!string.IsNullOrEmpty(exportIdrs.skinName)) { SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(component.bodyIndex); delayedReplacementInfo.skinDef = ((IEnumerable<SkinDef>)bodySkinDefs).FirstOrDefault((Func<SkinDef, bool>)((SkinDef s) => ((Object)s).name == exportIdrs.skinName)); } else { delayedReplacementInfo.idrs = val2.itemDisplayRuleSet; } } } } AssetsInfo value = null; if (Object.op_Implicit((Object)(object)delayedReplacementInfo.idrs)) { if (!dictionary.TryGetValue(delayedReplacementInfo.idrs, out value)) { value = (dictionary[delayedReplacementInfo.idrs] = new AssetsInfo()); } } else if (Object.op_Implicit((Object)(object)delayedReplacementInfo.skinDef) && !dictionary2.TryGetValue(delayedReplacementInfo.skinDef, out value)) { value = (dictionary2[delayedReplacementInfo.skinDef] = new AssetsInfo()); } if (value == null) { continue; } value2 = value; if (value2.characterModel == null) { value2.characterModel = delayedReplacementInfo.characterModel; } for (int num = 0; num < exportIdrs.itemGroups.Count; num++) { ExportKeyAssetRuleGroup exportKeyAssetRuleGroup = exportIdrs.itemGroups[num]; ItemDef itemDef = ItemCatalog.GetItemDef(ItemCatalog.FindItemIndex(exportKeyAssetRuleGroup.name)); if (Object.op_Implicit((Object)(object)itemDef)) { value.groups[(Object)(object)itemDef] = exportKeyAssetRuleGroup; } } for (int num2 = 0; num2 < exportIdrs.equipmentGroups.Count; num2++) { ExportKeyAssetRuleGroup exportKeyAssetRuleGroup2 = exportIdrs.equipmentGroups[num2]; EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(EquipmentCatalog.FindEquipmentIndex(exportKeyAssetRuleGroup2.name)); if (Object.op_Implicit((Object)(object)equipmentDef)) { value.groups[(Object)(object)equipmentDef] = exportKeyAssetRuleGroup2; } } } ParallelCoroutine assetsCoroutine = null; Object key2; ExportKeyAssetRuleGroup value4; foreach (KeyValuePair<ItemDisplayRuleSet, AssetsInfo> item in dictionary) { item.Deconstruct(out var key, out value2); ItemDisplayRuleSet val3 = key; AssetsInfo assetsInfo3 = value2; HashSet<string> addedChildren = new HashSet<string>(0); for (int num3 = 0; num3 < val3.keyAssetRuleGroups.Length; num3++) { Object keyAsset = val3.keyAssetRuleGroups[num3].keyAsset; if (!Object.op_Implicit(keyAsset) || !assetsInfo3.groups.Remove(keyAsset, out var value3)) { continue; } IEnumerator enumerator3 = MapGroup(val3, num3, keyAsset, value3, assetBundles, assetsInfo3.characterModel, addedChildren); if (enumerator3.MoveNext()) { if (assetsCoroutine == null) { assetsCoroutine = new ParallelCoroutine(); } assetsCoroutine.Add(enumerator3); } } if (assetsInfo3.groups.Count == 0) { continue; } int num4 = val3.keyAssetRuleGroups.Length; Array.Resize(ref val3.keyAssetRuleGroups, val3.keyAssetRuleGroups.Length + assetsInfo3.groups.Count); foreach (KeyValuePair<Object, ExportKeyAssetRuleGroup> group in assetsInfo3.groups) { group.Deconstruct(out key2, out value4); Object keyAsset2 = key2; ExportKeyAssetRuleGroup exportGroup = value4; IEnumerator enumerator5 = MapGroup(val3, num4++, keyAsset2, exportGroup, assetBundles, assetsInfo3.characterModel, addedChildren); if (enumerator5.MoveNext()) { if (assetsCoroutine == null) { assetsCoroutine = new ParallelCoroutine(); } assetsCoroutine.Add(enumerator5); } } } foreach (KeyValuePair<SkinDef, AssetsInfo> item2 in dictionary2) { item2.Deconstruct(out var key3, out value2); SkinDef skinDef = key3; AssetsInfo assetsInfo4 = value2; if (assetsInfo4.groups.Count == 0) { continue; } HashSet<string> addedChildren2 = new HashSet<string>(0); foreach (KeyValuePair<Object, ExportKeyAssetRuleGroup> group2 in assetsInfo4.groups) { group2.Deconstruct(out key2, out value4); Object keyAsset3 = key2; ExportKeyAssetRuleGroup exportGroup2 = value4; IEnumerator enumerator7 = MapGroup(skinDef, keyAsset3, exportGroup2, assetBundles, assetsInfo4.characterModel, addedChildren2); if (enumerator7.MoveNext()) { if (assetsCoroutine == null) { assetsCoroutine = new ParallelCoroutine(); } assetsCoroutine.Add(enumerator7); } } } if (assetsCoroutine != null) { while (assetsCoroutine.MoveNext()) { yield return null; } } ParallelCoroutine idrsCoroutine = new ParallelCoroutine(); foreach (DelayedReplacementInfo delayedReplacementInfo2 in delayedReplacementInfos) { if (Object.op_Implicit((Object)(object)delayedReplacementInfo2.idrs)) { delayedReplacementInfo2.beforeGenerateRuntimeValues?.Invoke(delayedReplacementInfo2.idrs); idrsCoroutine.Add(delayedReplacementInfo2.idrs.GenerateRuntimeValuesAsync()); } } while (idrsCoroutine.MoveNext()) { yield return null; } delayedReplacementInfos.Clear(); } private static IEnumerator MapGroup(ItemDisplayRuleSet idrs, int index, Object keyAsset, ExportKeyAssetRuleGroup exportGroup, Dictionary<string, AssetBundle> assetBundles, CharacterModel characterModel, HashSet<string> addedChildren) { ParallelCoroutine coroutine = null; KeyAssetRuleGroup group = new KeyAssetRuleGroup { displayRuleGroup = { rules = (ItemDisplayRule[])(object)new ItemDisplayRule[exportGroup.rules.Count] }, keyAsset = keyAsset }; for (int i = 0; i < exportGroup.rules.Count; i++) { IEnumerator enumerator = MapRule(group.displayRuleGroup.rules, i, exportGroup.rules[i], assetBundles, characterModel, addedChildren); if (enumerator.MoveNext()) { if (coroutine == null) { coroutine = new ParallelCoroutine(); } coroutine.Add(enumerator); } } if (coroutine != null) { while (coroutine.MoveNext()) { yield return null; } } idrs.keyAssetRuleGroups[index] = group; } private static IEnumerator MapGroup(SkinDef skinDef, Object keyAsset, ExportKeyAssetRuleGroup exportGroup, Dictionary<string, AssetBundle> assetBundles, CharacterModel characterModel, HashSet<string> addedChildren) { ParallelCoroutine coroutine = null; DisplayRuleGroup group = new DisplayRuleGroup { rules = (ItemDisplayRule[])(object)new ItemDisplayRule[exportGroup.rules.Count] }; for (int i = 0; i < exportGroup.rules.Count; i++) { IEnumerator enumerator = MapRule(group.rules, i, exportGroup.rules[i], assetBundles, characterModel, addedChildren); if (enumerator.MoveNext()) { if (coroutine == null) { coroutine = new ParallelCoroutine(); } coroutine.Add(enumerator); } } if (coroutine != null) { while (coroutine.MoveNext()) { yield return null; } } SkinIDRS.AddGroupOverride(skinDef, keyAsset, group); } private static IEnumerator MapRule(ItemDisplayRule[] rules, int index, ExportItemDisplayRule exportRule, Dictionary<string, AssetBundle> assetBundles, CharacterModel characterModel, HashSet<string> addedChildren) { string text = exportRule.childName; if (!string.IsNullOrEmpty(exportRule.childPath) && Object.op_Implicit((Object)(object)characterModel)) { text = StringHelpers.ChildNameFromPath(exportRule.childPath); if (!addedChildren.Contains(text)) { addedChildren.Add(text); Transform val = ((Component)characterModel).transform.Find(exportRule.childPath); if (Object.op_Implicit((Object)(object)val)) { ((Component)characterModel).GetComponent<ChildLocator>().AddChild(text, val); } } } ItemDisplayRule rule = new ItemDisplayRule { childName = text, followerPrefabAddress = new AssetReferenceGameObject(exportRule.guid ?? ""), limbMask = exportRule.limbMask, localAngles = exportRule.localAngles, localPos = exportRule.localPos, localScale = exportRule.localScale, ruleType = exportRule.ruleType }; if (!string.IsNullOrEmpty(exportRule.assetBundle)) { if (assetBundles.TryGetValue(exportRule.assetBundle, out var value)) { AssetBundleRequest request = value.LoadAssetAsync<GameObject>(exportRule.assetPath); while (!((AsyncOperation)request).isDone) { yield return null; } Object asset = request.asset; rule.followerPrefab = (GameObject)(object)((asset is GameObject) ? asset : null); } else { InstanceLogger.LogError((object)("AssetBundle " + exportRule.assetBundle + " was not found.")); } } rules[index] = rule; } } public static class StringHelpers { public static readonly string NamePostfix = "|IJL"; public static string ChildNameFromPath(string path) { string fileName = Path.GetFileName(path); return $"{fileName}_{(uint)GetStableHashCode(path)}{NamePostfix}"; } public static int GetStableHashCode(string str) { int num = 5381; int num2 = num; for (int i = 0; i < str.Length && str[i] != 0; i += 2) { num = ((num << 5) + num) ^ str[i]; if (i == str.Length - 1 || str[i + 1] == '\0') { break; } num2 = ((num2 << 5) + num2) ^ str[i + 1]; } return num + num2 * 1566083941; } } } namespace IDRSJsonLoader.Models { internal class AssetsInfo { public Dictionary<Object, ExportKeyAssetRuleGroup> groups = new Dictionary<Object, ExportKeyAssetRuleGroup>(); public CharacterModel characterModel; } internal class DelayedReplacementInfo { public ExportItemDisplayRuleSet exportIdrs; public ParseCallback beforeGenerateRuntimeValues; public ItemDisplayRuleSet idrs; public SkinDef skinDef; public CharacterModel characterModel; } [Serializable] public class ExportItemDisplayRule { public string guid; public string assetBundle; public string assetPath; public Vector3 localScale; public Vector3 localPos; public Vector3 localAngles; public string childName; public string childPath; public LimbFlags limbMask; public ItemDisplayRuleType ruleType; } [Serializable] public class ExportItemDisplayRuleSet { public string bodyName; public string skinName; public List<ExportKeyAssetRuleGroup> itemGroups = new List<ExportKeyAssetRuleGroup>(); public List<ExportKeyAssetRuleGroup> equipmentGroups = new List<ExportKeyAssetRuleGroup>(); } [Serializable] public class ExportKeyAssetRuleGroup { public string name; public List<ExportItemDisplayRule> rules = new List<ExportItemDisplayRule>(); } }