using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppLudiq;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using ModelSwapLib;
using ModelSwapLib.Managers;
using ModelSwapLib.ObjectTracking;
using ModelSwapLib.Swapper;
using ModelSwapLib.Swapper.Modules;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "ModelSwapLib", "2.1.0", "CocoPopEater", null)]
[assembly: MelonGame("Keepsake Games", "Jump Space")]
[assembly: MelonColor(255, 0, 255, 0)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ModelSwapLib")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b61ef0eb25c6152fc962dc129c4d3eb812aa5bee")]
[assembly: AssemblyProduct("ModelSwapLib")]
[assembly: AssemblyTitle("ModelSwapLib")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ModelSwapLib
{
public class Core : MelonMod
{
public override void OnInitializeMelon()
{
BundleManager.GetInstance().InitializeBundles();
TrackingManager.Initialize();
ConsoleUtils.Msg("Initialized");
}
public override void OnDeinitializeMelon()
{
BundleManager.GetInstance().Shutdown();
}
public override void OnSceneWasInitialized(int buildIndex, string sceneName)
{
TrackingManager.RebuildAllTrackingIds();
}
}
internal static class ConsoleUtils
{
internal static void Msg(string message)
{
Melon<Core>.Logger.Msg(message);
}
internal static void Warning(string message)
{
Melon<Core>.Logger.Warning(message);
}
internal static void Error(string message)
{
Melon<Core>.Logger.Error(message);
}
internal static void BigError(string message)
{
Melon<Core>.Logger.BigError(message);
}
}
public static class MeshUtils
{
public static Mesh MoveMesh(Mesh mesh, float x, float z, float y)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
return MoveMesh(mesh, new Vector3(x, y, z));
}
public static Mesh MoveMesh(Mesh mesh, Vector3 pos)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
Vector3[] array = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)mesh.vertices);
Vector3[] array2 = (Vector3[])(object)new Vector3[((Il2CppArrayBase<Vector3>)(object)mesh.vertices).Length];
for (int i = 0; i < array.Length; i++)
{
array2[i] = pos + array[i];
}
mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(array2);
return mesh;
}
public static Mesh RotateMesh(Mesh mesh, float x, float y, float z)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Quaternion qAngle = Quaternion.Euler(x, y, z);
return RotateMesh(mesh, qAngle);
}
public static Mesh RotateMesh(Mesh mesh, Quaternion qAngle)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
Vector3[] array = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)mesh.vertices);
Vector3[] array2 = (Vector3[])(object)new Vector3[((Il2CppArrayBase<Vector3>)(object)mesh.vertices).Length];
for (int i = 0; i < array.Length; i++)
{
array2[i] = qAngle * array[i];
}
mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(array2);
return mesh;
}
public static Mesh ScaleMesh(Mesh mesh, float x, float y, float z)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
return ScaleMesh(mesh, new Vector3(x, y, z));
}
public static Mesh ScaleMesh(Mesh mesh, Vector3 scale)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
Vector3[] array = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)mesh.vertices);
Vector3[] array2 = (Vector3[])(object)new Vector3[((Il2CppArrayBase<Vector3>)(object)mesh.vertices).Length];
for (int i = 0; i < array.Length; i++)
{
Vector3 val = array[i];
array2[i] = new Vector3(val.x * scale.x, val.y * scale.y, val.z * scale.z);
}
mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(array2);
return mesh;
}
}
}
namespace ModelSwapLib.ObjectTracking
{
internal static class TrackingManager
{
private static bool Initialized;
private static HashSet<int> _trackedIds;
private static Dictionary<string, HashSet<int>> _nameMap;
internal static IEnumerable<int> TrackedIds => _trackedIds;
internal static Dictionary<string, HashSet<int>> NameMap => _nameMap;
internal static void Initialize()
{
if (!Initialized)
{
ConsoleUtils.Msg("Initializing tracking manager...");
_trackedIds = new HashSet<int>();
_nameMap = new Dictionary<string, HashSet<int>>();
Initialized = true;
}
}
internal static IEnumerable<GameObject> GetObjectsFromNames(IEnumerable<string> names)
{
List<GameObject> list = new List<GameObject>();
foreach (string name in names)
{
list.AddRange(GetObjectsFromName(name));
}
return list;
}
internal static IEnumerable<GameObject> GetObjectsFromName(string name)
{
List<GameObject> list = new List<GameObject>();
try
{
_nameMap.TryGetValue(name, out var value);
foreach (int item in value)
{
Object obj = Object.FindObjectFromInstanceID(item);
GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
if (!Object.op_Implicit((Object)(object)val))
{
ForceObjectReprocess(name, item);
}
else if (((Object)val).name != name)
{
ForceObjectReprocess(name, item);
}
else
{
list.Add(val);
}
}
}
catch (Exception)
{
}
return list;
}
private static void ForceObjectReprocess(string apparentName, int objectId)
{
RemoveTrackingDetails(apparentName, objectId);
Object val = Object.FindObjectFromInstanceID(objectId);
if (Object.op_Implicit(val))
{
GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null);
if (val2 != null)
{
AddTrackingDetails(val2);
}
}
}
internal static IEnumerable<int> GetObjectIdsByName(string name)
{
try
{
_nameMap.TryGetValue(name, out var value);
return value;
}
catch (Exception)
{
return Enumerable.Empty<int>();
}
}
internal static IEnumerable<int> GetAllObjectsFromNames(IEnumerable<string> names)
{
List<int> list = new List<int>();
foreach (string name in names)
{
try
{
list.AddRange(GetObjectIdsByName(name));
}
catch (Exception)
{
}
}
return list;
}
internal static void RebuildAllTrackingIds()
{
_trackedIds.Clear();
_nameMap.Clear();
foreach (GameObject item in ((IEnumerable<GameObject>)Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0)).ToList())
{
AddTrackingDetails(item);
}
}
internal static void AddTrackingDetails(GameObject gameObject)
{
AddTrackingDetails(((Object)gameObject).name, ((Object)gameObject).GetInstanceID());
MelonCoroutines.Start(ObjectActionManager.GetInstance().HandleObject(gameObject));
}
private static void AddTrackingDetails(string name, int trackingId)
{
if (!_trackedIds.Contains(trackingId))
{
_trackedIds.Add(trackingId);
if (!_nameMap.TryGetValue(name, out var value))
{
_nameMap.Add(name, new HashSet<int>(new <>z__ReadOnlySingleElementList<int>(trackingId)));
return;
}
value.Add(trackingId);
_nameMap[name] = value;
}
}
internal static void RemoveTrackingDetails(GameObject gameObject)
{
RemoveTrackingDetails(((Object)gameObject).name, ((Object)gameObject).GetInstanceID());
}
private static void RemoveTrackingDetails(string name, int trackingId)
{
if (_nameMap.TryGetValue(name, out var value))
{
value.Remove(trackingId);
_trackedIds.Remove(trackingId);
}
}
}
}
namespace ModelSwapLib.Swapper
{
public class ObjectActionManager
{
private static ObjectActionManager instance;
private Dictionary<string, List<Swapper>> ObjectActions = new Dictionary<string, List<Swapper>>();
private Dictionary<Guid, Swapper> SwapperCache = new Dictionary<Guid, Swapper>();
private HashSet<string> SkipCache = new HashSet<string>();
private ObjectActionManager()
{
instance = this;
}
public static ObjectActionManager GetInstance()
{
if (instance == null)
{
instance = new ObjectActionManager();
}
return instance;
}
internal IEnumerator HandleObject(GameObject obj)
{
if (!Object.op_Implicit((Object)(object)obj) || SkipCache.Contains(((Object)obj).name))
{
yield break;
}
if (!ObjectActions.TryGetValue(((Object)obj).name, out var actions))
{
SkipCache.Add(((Object)obj).name);
yield break;
}
if (actions == null || actions.Count == 0)
{
SkipCache.Add(((Object)obj).name);
yield break;
}
yield return (object)new WaitForEndOfFrame();
if (!Object.op_Implicit((Object)(object)obj))
{
yield break;
}
foreach (Swapper item in actions)
{
item.RunAllModules(obj);
item.DeactivateObjects();
}
}
public Guid RegisterSwapper(Swapper swapper)
{
if (!swapper.Validate())
{
return Guid.Empty;
}
foreach (string objectName in swapper.ObjectNames)
{
ObjectActions.TryGetValue(objectName, out var value);
if (value == null)
{
value = new List<Swapper>();
value.Add(swapper);
ObjectActions[objectName] = value;
}
else if (!value.Contains(swapper))
{
value.Add(swapper);
}
}
SwapperCache.Add(swapper.SwapperGuid, swapper);
foreach (GameObject objectsFromName in TrackingManager.GetObjectsFromNames(swapper.ObjectNames))
{
swapper.RunAllModules(objectsFromName);
}
swapper.DeactivateObjects();
foreach (string objectName2 in swapper.ObjectNames)
{
if (SkipCache.Contains(objectName2))
{
SkipCache.Remove(objectName2);
}
}
return swapper.SwapperGuid;
}
public void ClearSkipCache()
{
SkipCache.Clear();
TrackingManager.RebuildAllTrackingIds();
}
public Swapper GetSwapper(Guid swapperGuid)
{
return SwapperCache.GetValueOrDefault(swapperGuid, null);
}
public void UnregisterSwapper(Guid swapperGuid)
{
if (!(swapperGuid == Guid.Empty))
{
UnregisterSwapper(SwapperCache.GetValueOrDefault(swapperGuid, null));
}
}
public void UnregisterSwapper(Swapper swapper)
{
if (swapper == null || !swapper.Validate())
{
return;
}
foreach (KeyValuePair<string, List<Swapper>> objectAction in ObjectActions)
{
List<Swapper> value = objectAction.Value;
if (value.Contains(swapper))
{
value.Remove(swapper);
}
}
SwapperCache.Remove(swapper.SwapperGuid);
}
}
public class Swapper
{
public string ModName { get; set; }
public string SwapperName { get; set; } = "Default Name";
public List<string> ObjectNames { get; set; }
public string BundleName { get; set; }
public List<IAssetModule> AssetModules { get; set; }
public List<ITransformModule> TransformModules { get; set; }
public List<string> Deactivations { get; set; }
public Guid SwapperGuid { get; internal set; }
public Swapper(string modName, string swapperName, List<string> objectNames, string bundleName, List<IAssetModule> assetModules, List<ITransformModule> transformModules, List<string> deactivations)
{
ModName = modName;
SwapperName = swapperName;
ObjectNames = objectNames;
BundleName = bundleName;
AssetModules = assetModules;
TransformModules = transformModules;
Deactivations = deactivations;
}
public Swapper()
{
}
internal void RunAllModules(GameObject target)
{
if (!Object.op_Implicit((Object)(object)target))
{
return;
}
if (AssetModules != null)
{
AssetBundle bundle = BundleManager.GetInstance().GetBundle(this);
if ((Object)(object)bundle == (Object)null)
{
ConsoleUtils.Error("Failed to load AssetBundle from Mod:Swapper : " + ModName + ":" + SwapperName);
}
else
{
foreach (IAssetModule assetModule in AssetModules)
{
assetModule.Apply(target, bundle);
}
}
}
if (TransformModules == null)
{
return;
}
foreach (ITransformModule transformModule in TransformModules)
{
transformModule.Apply(target);
}
}
internal void DeactivateObjects()
{
if (Deactivations == null || Deactivations.Count == 0)
{
return;
}
foreach (GameObject objectsFromName in TrackingManager.GetObjectsFromNames(Deactivations))
{
objectsFromName.SetActive(false);
}
}
internal Guid GenerateSwapperGuid()
{
if (SwapperGuid == Guid.Empty)
{
SwapperGuid = Guid.NewGuid();
}
return SwapperGuid;
}
public bool Validate()
{
if (string.IsNullOrEmpty(ModName))
{
return false;
}
if (ObjectNames == null || ObjectNames.Count == 0)
{
return false;
}
if (AssetModules != null && AssetModules.Count > 0)
{
if (BundleName == null)
{
return false;
}
if (!BundleName.EndsWith(".bundle"))
{
BundleName += ".bundle";
}
}
else
{
if (TransformModules == null || TransformModules.Count == 0)
{
return false;
}
if (Deactivations == null || Deactivations.Count == 0)
{
return false;
}
}
GenerateSwapperGuid();
return true;
}
}
public class SwapperBuilder
{
private string ModName;
private string SwapperName;
private List<string> ObjectNames = new List<string>();
private string BundleName;
private List<IAssetModule> AssetModules;
private List<ITransformModule> TransformModules;
private List<string> Deactivations;
public SwapperBuilder(string ModName)
{
this.ModName = ModName;
}
public SwapperBuilder()
{
}
public SwapperBuilder SetModName(string ModName)
{
this.ModName = ModName;
return this;
}
public SwapperBuilder SetSwapperName(string SwapperName)
{
this.SwapperName = SwapperName;
return this;
}
public SwapperBuilder AddObjectName(string ObjectName)
{
ObjectNames.Add(ObjectName);
return this;
}
public SwapperBuilder AddObjectNames(List<string> BundleNames)
{
ObjectNames.AddRange(BundleNames);
return this;
}
public SwapperBuilder SetBundleName(string BundleName)
{
this.BundleName = BundleName;
return this;
}
public SwapperBuilder AddAssetModule(IAssetModule assetModule)
{
if (AssetModules == null)
{
AssetModules = new List<IAssetModule>();
}
AssetModules.Add(assetModule);
return this;
}
public SwapperBuilder AddAssetModules(List<IAssetModule> assetModules)
{
if (AssetModules == null)
{
AssetModules = new List<IAssetModule>();
}
AssetModules.AddRange(assetModules);
return this;
}
public SwapperBuilder AddTransformModule(ITransformModule transformModule)
{
if (TransformModules == null)
{
TransformModules = new List<ITransformModule>();
}
TransformModules.Add(transformModule);
return this;
}
public SwapperBuilder AddTransformModules(List<ITransformModule> transformModules)
{
if (TransformModules == null)
{
TransformModules = new List<ITransformModule>();
}
TransformModules.AddRange(transformModules);
return this;
}
public SwapperBuilder AddDeactivation(string deactivation)
{
if (Deactivations == null)
{
Deactivations = new List<string>();
}
Deactivations.Add(deactivation);
return this;
}
public SwapperBuilder AddDeactivations(List<string> deactivations)
{
if (Deactivations == null)
{
Deactivations = new List<string>();
}
Deactivations.AddRange(deactivations);
return this;
}
public Swapper Build()
{
if (ModName == null)
{
return null;
}
if (ObjectNames == null || ObjectNames.Count == 0)
{
return null;
}
if (BundleName == null && AssetModules != null && AssetModules.Count > 0)
{
return null;
}
if ((AssetModules == null || AssetModules.Count == 0) && (TransformModules == null || TransformModules.Count == 0) && (Deactivations == null || Deactivations.Count == 0))
{
return null;
}
return new Swapper(ModName, SwapperName, ObjectNames, BundleName, AssetModules, TransformModules, Deactivations);
}
}
}
namespace ModelSwapLib.Swapper.Modules
{
public class ColorDetailModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public ColorDetailModule(string assetPath)
{
AssetPath = assetPath;
}
public ColorDetailModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Color Detail Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (materials == null || ((Il2CppArrayBase<Material>)(object)materials).Length == 0)
{
return;
}
foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
{
if (item.HasProperty("_ColorDetailLookup"))
{
item.SetTexture("_ColorDetailLookup", (Texture)(object)val);
}
}
}
}
public class ColorMainModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public ColorMainModule(string assetPath)
{
}
public ColorMainModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Color Main Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (materials == null || ((Il2CppArrayBase<Material>)(object)materials).Length == 0)
{
return;
}
foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
{
if (item.HasProperty("_ColorMainLookup"))
{
item.SetTexture("_ColorMainLookup", (Texture)(object)val);
}
}
}
}
public class ColorSecondaryModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public ColorSecondaryModule(string assetPath)
{
AssetPath = assetPath;
}
public ColorSecondaryModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Color Secondary Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (materials == null || ((Il2CppArrayBase<Material>)(object)materials).Length == 0)
{
return;
}
foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
{
if (item.HasProperty("_ColorSecondaryLookup"))
{
item.SetTexture("_ColorSecondaryLookup", (Texture)(object)val);
}
}
}
}
public class EmmisionsModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public EmmisionsModule(string assetPath)
{
AssetPath = assetPath;
}
public EmmisionsModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Emissions Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (materials == null || ((Il2CppArrayBase<Material>)(object)materials).Length == 0)
{
return;
}
foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
{
if (item.HasProperty("_T3"))
{
item.SetTexture("_T3", (Texture)(object)val);
}
}
}
}
public class MeshFilterModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public MeshFilterModule(string assetPath)
{
AssetPath = assetPath;
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Mesh val = bundle.LoadAsset<Mesh>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Mesh: " + AssetPath);
return;
}
MeshFilter component = obj.GetComponent<MeshFilter>();
if (!((Object)(object)component == (Object)null))
{
component.mesh = val;
}
}
}
[Obsolete("This class is deprecated. Use SkinnedMeshModule instead")]
public class MeshModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public MeshModule(string assetPath)
{
AssetPath = assetPath;
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Mesh val = bundle.LoadAsset<Mesh>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Mesh: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if (!((Object)(object)component == (Object)null))
{
component.sharedMesh = val;
}
}
}
public class MetallicModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public MetallicModule(string assetPath)
{
AssetPath = assetPath;
}
public MetallicModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Metallic Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (materials == null || ((Il2CppArrayBase<Material>)(object)materials).Length == 0)
{
return;
}
foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
{
if (item.HasProperty("_M"))
{
item.SetTexture("_M", (Texture)(object)val);
}
}
}
}
public class NormalsModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public NormalsModule(string assetPath)
{
AssetPath = assetPath;
}
public NormalsModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Normals Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (materials == null || ((Il2CppArrayBase<Material>)(object)materials).Length == 0)
{
return;
}
foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
{
if (item.HasProperty("_T2"))
{
item.SetTexture("_T2", (Texture)(object)val);
}
}
}
}
public class SkinnedMeshModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public SkinnedMeshModule(string assetPath)
{
AssetPath = assetPath;
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Mesh val = bundle.LoadAsset<Mesh>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Mesh: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if (!((Object)(object)component == (Object)null))
{
component.sharedMesh = val;
}
}
}
public class Texture2DModule : IAssetModule, IModule
{
public string AssetPath { get; set; }
public Texture2DModule(string assetPath)
{
AssetPath = assetPath;
}
public Texture2DModule()
{
}
public void Apply(GameObject obj, AssetBundle bundle)
{
Texture2D val = bundle.LoadAsset<Texture2D>(AssetPath);
if ((Object)(object)val == (Object)null)
{
ConsoleUtils.Error("Failed to load Main Texture2D: " + AssetPath);
return;
}
SkinnedMeshRenderer component = obj.GetComponent<SkinnedMeshRenderer>();
if (!((Object)(object)component == (Object)null))
{
Il2CppReferenceArray<Material> materials = ((Renderer)component).materials;
if (((Il2CppArrayBase<Material>)(object)materials)[0].HasProperty("_T1"))
{
((Il2CppArrayBase<Material>)(object)materials)[0].SetTexture("_T1", (Texture)(object)val);
}
}
}
}
public interface IAssetModule : IModule
{
string AssetPath { get; set; }
void Apply(GameObject obj, AssetBundle bundle);
void ApplyAll(IEnumerable<GameObject> objects, AssetBundle assetBundle)
{
foreach (GameObject @object in objects)
{
Apply(@object, assetBundle);
}
}
}
public interface IModule
{
}
public interface ITransformModule : IModule
{
void Apply(GameObject obj);
void ApplyAll(IEnumerable<GameObject> objects)
{
foreach (GameObject @object in objects)
{
Apply(@object);
}
}
}
}
namespace ModelSwapLib.Swapper.Modules.ITransformModules
{
public class MoveMeshModule : ITransformModule, IModule
{
private Vector3 vector;
public MoveMeshModule(float xDist, float yDist, float zDist)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
vector = new Vector3(xDist, yDist, zDist);
}
public MoveMeshModule(Vector3 vector)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
this.vector = vector;
}
public void Apply(GameObject gameObject)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
SkinnedMeshRenderer component = gameObject.GetComponent<SkinnedMeshRenderer>();
if (!((Object)(object)component == (Object)null))
{
Mesh val = new Mesh();
component.BakeMesh(val);
if (!((Object)(object)val == (Object)null))
{
val = MeshUtils.MoveMesh(val, vector);
component.sharedMesh = val;
}
}
}
}
public class RotateMeshModule : ITransformModule, IModule
{
private Vector3 vector;
public RotateMeshModule(float xRot, float yRot, float zRot)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
vector = new Vector3(xRot, yRot, zRot);
}
public RotateMeshModule(Vector3 vector)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
this.vector = vector;
}
public void Apply(GameObject gameObject)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
SkinnedMeshRenderer component = gameObject.GetComponent<SkinnedMeshRenderer>();
if (!((Object)(object)component == (Object)null))
{
Mesh val = new Mesh();
component.BakeMesh(val);
if (!((Object)(object)val == (Object)null))
{
val = MeshUtils.RotateMesh(val, vector.x, vector.y, vector.z);
component.sharedMesh = val;
}
}
}
}
public class ScaleMeshModule : ITransformModule, IModule
{
private Vector3 vector;
public ScaleMeshModule(float xScale, float yScale, float zScale)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
vector = new Vector3(xScale, yScale, zScale);
}
public ScaleMeshModule(Vector3 vector)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
this.vector = vector;
}
public void Apply(GameObject gameObject)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
SkinnedMeshRenderer component = gameObject.GetComponent<SkinnedMeshRenderer>();
if (!((Object)(object)component == (Object)null))
{
Mesh val = new Mesh();
component.BakeMesh(val);
if (!((Object)(object)val == (Object)null))
{
val = MeshUtils.ScaleMesh(val, vector);
component.sharedMesh = val;
}
}
}
}
}
namespace ModelSwapLib.Managers
{
public class BundleManager
{
private static BundleManager _instance;
private readonly Dictionary<string, AssetBundle> _bundles = new Dictionary<string, AssetBundle>();
private BundleManager()
{
_instance = this;
}
public static BundleManager GetInstance()
{
if (_instance == null)
{
_instance = new BundleManager();
}
return _instance;
}
internal void InitializeBundles()
{
_bundles.Clear();
string modsDirectory = MelonEnvironment.ModsDirectory;
FindBundlesRecursive(modsDirectory);
}
private void FindBundlesRecursive(string rootDir)
{
string[] files = Directory.GetFiles(rootDir);
foreach (string text in files)
{
if (text.EndsWith(".bundle"))
{
string fileName = Path.GetFileName(text);
ConsoleUtils.Msg("Found Bundle: " + fileName);
_bundles.Add(fileName, AssetBundle.LoadFromFile(text));
}
}
files = Directory.GetDirectories(rootDir);
foreach (string text2 in files)
{
if (new DirectoryInfo(text2).LinkTarget == null)
{
FindBundlesRecursive(text2);
}
}
}
internal AssetBundle GetBundle(ModelSwapLib.Swapper.Swapper swapper)
{
string key = ((!swapper.BundleName.EndsWith(".bundle")) ? (swapper.BundleName + ".bundle") : swapper.BundleName);
_bundles.TryGetValue(key, out var value);
if ((Object)(object)value != (Object)null)
{
return value;
}
return null;
}
internal void Shutdown()
{
foreach (AssetBundle value in _bundles.Values)
{
try
{
if (value != null)
{
value.Unload(true);
}
}
catch (Exception)
{
}
}
_bundles.Clear();
}
}
}
namespace ModelSwapLib.Harmony
{
[HarmonyPatch]
public class HarmonyPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
{
typeof(Object),
typeof(Transform),
typeof(bool)
})]
[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
{
typeof(Object),
typeof(Vector3),
typeof(Quaternion)
})]
[HarmonyPatch(typeof(Object), "Instantiate", new Type[]
{
typeof(Object),
typeof(Vector3),
typeof(Quaternion),
typeof(Transform)
})]
private static void InstantiatePostfix(ref Object __result)
{
if (__result == (Object)null)
{
return;
}
GameObject val = ComponentHolderProtocol.GameObject(__result);
if ((Object)(object)val == (Object)null)
{
return;
}
TrackingManager.AddTrackingDetails(val);
Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(val.GetComponentsInChildren<Transform>());
foreach (Transform val2 in array)
{
if (!((Object)(object)((Component)val2).gameObject == __result))
{
TrackingManager.AddTrackingDetails(((Component)val2).gameObject);
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object) })]
private static void Prefix_Object(Object obj)
{
if (Object.op_Implicit(obj))
{
GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
if (val != null)
{
TrackingManager.RemoveTrackingDetails(val);
}
}
}
}
}
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
{
object IEnumerator.Current => _item;
T IEnumerator<T>.Current => _item;
public Enumerator(T item)
{
_item = item;
}
bool IEnumerator.MoveNext()
{
if (!_moveNextCalled)
{
return _moveNextCalled = true;
}
return false;
}
void IEnumerator.Reset()
{
_moveNextCalled = false;
}
void IDisposable.Dispose()
{
}
}
int ICollection.Count => 1;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object IList.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => 1;
T IReadOnlyList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
}
int ICollection<T>.Count => 1;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlySingleElementList(T item)
{
_item = item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection.CopyTo(Array array, int index)
{
array.SetValue(_item, index);
}
int IList.Add(object value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object value)
{
return EqualityComparer<T>.Default.Equals(_item, (T)value);
}
int IList.IndexOf(object value)
{
if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
{
return -1;
}
return 0;
}
void IList.Insert(int index, object value)
{
throw new NotSupportedException();
}
void IList.Remove(object value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return EqualityComparer<T>.Default.Equals(_item, item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
array[arrayIndex] = _item;
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
if (!EqualityComparer<T>.Default.Equals(_item, item))
{
return -1;
}
return 0;
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}