Decompiled source of CommandoInChief v0.3.2

CommandoInChief.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace CommandoInChief;

[BepInPlugin("com.mally.commando_in_chief", "Commando in Chief", "1.0.0")]
public class CommandoInChiefPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.mally.commando_in_chief";

	public const string PluginName = "Commando in Chief";

	public const string PluginVersion = "1.0.0";

	private const string SkinNameToken = "CHIEFMANDO_SKIN_MASTERCHIEF_NAME";

	private const string SkinDisplayName = "Master Chief";

	private const int ExpectedBoneCount = 78;

	private void Awake()
	{
		SetupLanguage();
		try
		{
			AddSkin();
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Failed to add the Master Chief skin to Commando: " + ex));
		}
	}

	private void SetupLanguage()
	{
		try
		{
			string root = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language");
			string text = Path.Combine(root, "en");
			string path = Path.Combine(text, "CommandoInChief.json");
			if (!File.Exists(path))
			{
				Directory.CreateDirectory(text);
				File.WriteAllText(path, "{\n  \"strings\": {\n    \"CHIEFMANDO_SKIN_MASTERCHIEF_NAME\": \"Master Chief\"\n  }\n}\n");
			}
			Language.collectLanguageRootFolders += delegate(List<string> folders)
			{
				folders.Add(root);
			};
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not register language folder: " + ex.Message));
		}
		Language.onCurrentLanguageChanged += delegate
		{
			Language currentLanguage = Language.currentLanguage;
			if (currentLanguage != null)
			{
				currentLanguage.SetStringByToken("CHIEFMANDO_SKIN_MASTERCHIEF_NAME", "Master Chief");
			}
		};
	}

	private void AddSkin()
	{
		//IL_0005: 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)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Expected O, but got Unknown
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		GameObject obj = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Commando/CommandoBody.prefab").WaitForCompletion();
		GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Commando/CommandoDisplay.prefab").WaitForCompletion();
		if (!Object.op_Implicit((Object)(object)obj))
		{
			throw new Exception("CommandoBody prefab not found");
		}
		GameObject gameObject = ((Component)obj.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController component = gameObject.GetComponent<ModelSkinController>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			throw new Exception("Commando model has no ModelSkinController");
		}
		SkinnedMeshRenderer val2 = ((IEnumerable<SkinnedMeshRenderer>)gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name == "CommandoMesh"));
		MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>(true);
		MeshRenderer val3 = ((IEnumerable<MeshRenderer>)componentsInChildren).FirstOrDefault((Func<MeshRenderer, bool>)((MeshRenderer r) => ((Object)r).name == "GunMesh.001"));
		MeshRenderer val4 = ((IEnumerable<MeshRenderer>)componentsInChildren).FirstOrDefault((Func<MeshRenderer, bool>)((MeshRenderer r) => ((Object)r).name == "GunMesh"));
		if (!Object.op_Implicit((Object)(object)val2))
		{
			throw new Exception("Could not find Commando's body renderer (CommandoMesh)");
		}
		if (val2.bones.Length != 78)
		{
			throw new Exception("Commando's skeleton has " + val2.bones.Length + " bones, expected " + 78 + ". The game's Commando rig changed; the Chief model needs re-rigging.");
		}
		Mesh mesh = LoadMesh("Commando.cmesh", "meshCommandoChief");
		Mesh mesh2 = LoadMesh("SMG.cmesh", "meshCommandoChiefSMG");
		Texture2D tex = LoadTexture("ChiefPalette.png", pixelArt: true);
		Texture2D tex2 = LoadTexture("smg_diffuse.png", pixelArt: true);
		Texture2D val5 = LoadTexture("SkinIcon.png", pixelArt: false);
		Material val6 = null;
		try
		{
			val6 = Addressables.LoadAssetAsync<Material>((object)"RoR2/Base/Commando/matCommandoDualies.mat").WaitForCompletion();
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not load Commando's material, falling back to HGStandard: " + ex.Message));
		}
		if (!Object.op_Implicit((Object)(object)val6))
		{
			val6 = new Material(Addressables.LoadAssetAsync<Shader>((object)"RoR2/Base/Shaders/HGStandard.shader").WaitForCompletion());
		}
		Material material = MakeMaterial(val6, "matCommandoChief", tex, Color.white);
		Material material2 = MakeMaterial(val6, "matCommandoChiefSMG", tex2, new Color(0.8f, 0.8f, 0.8f, 1f));
		List<RendererInfo> list = new List<RendererInfo>();
		List<MeshReplacement> list2 = new List<MeshReplacement>();
		if (Object.op_Implicit((Object)(object)val3))
		{
			list.Add(MakeRendererInfo((Renderer)(object)val3, material2));
			list2.Add(new MeshReplacement
			{
				renderer = (Renderer)(object)val3,
				mesh = mesh2
			});
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Left gun renderer not found; left gun will keep its default look.");
		}
		if (Object.op_Implicit((Object)(object)val4))
		{
			list.Add(MakeRendererInfo((Renderer)(object)val4, material2));
			list2.Add(new MeshReplacement
			{
				renderer = (Renderer)(object)val4,
				mesh = mesh2
			});
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Right gun renderer not found; right gun will keep its default look.");
		}
		list.Add(MakeRendererInfo((Renderer)(object)val2, material));
		list2.Add(new MeshReplacement
		{
			renderer = (Renderer)(object)val2,
			mesh = mesh
		});
		SkinDefParams val7 = ScriptableObject.CreateInstance<SkinDefParams>();
		((Object)val7).name = "skinCommandoChiefParams";
		val7.rendererInfos = list.ToArray();
		val7.meshReplacements = list2.ToArray();
		val7.gameObjectActivations = (GameObjectActivation[])(object)new GameObjectActivation[0];
		val7.projectileGhostReplacements = (ProjectileGhostReplacement[])(object)new ProjectileGhostReplacement[0];
		val7.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[0];
		val7.lightReplacements = (LightInfo[])(object)new LightInfo[0];
		SkinDef val8 = ScriptableObject.CreateInstance<SkinDef>();
		((Object)val8).name = "skinCommandoChief";
		val8.nameToken = "CHIEFMANDO_SKIN_MASTERCHIEF_NAME";
		val8.icon = Sprite.Create(val5, new Rect(0f, 0f, (float)((Texture)val5).width, (float)((Texture)val5).height), new Vector2(0.5f, 0.5f));
		val8.rootObject = gameObject;
		val8.baseSkins = (SkinDef[])(object)((component.skins.Length == 0) ? new SkinDef[0] : new SkinDef[1] { component.skins[0] });
		val8.skinDefParams = val7;
		val8.rendererInfos = (RendererInfo[])(object)new RendererInfo[0];
		val8.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[0];
		val8.gameObjectActivations = (GameObjectActivation[])(object)new GameObjectActivation[0];
		val8.projectileGhostReplacements = (ProjectileGhostReplacement[])(object)new ProjectileGhostReplacement[0];
		val8.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[0];
		component.skins = component.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
		if (Object.op_Implicit((Object)(object)val))
		{
			ModelSkinController componentInChildren = val.GetComponentInChildren<ModelSkinController>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren) && (Object)(object)componentInChildren != (Object)(object)component && !componentInChildren.skins.Contains(val8))
			{
				componentInChildren.skins = componentInChildren.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { val8 }).ToArray();
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Added Master Chief skin to Commando.");
	}

	private static RendererInfo MakeRendererInfo(Renderer renderer, Material material)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: 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)
		return new RendererInfo
		{
			renderer = renderer,
			defaultMaterial = material,
			defaultShadowCastingMode = (ShadowCastingMode)1,
			ignoreOverlays = false,
			hideOnDeath = false,
			ignoresMaterialOverrides = false
		};
	}

	private static Material MakeMaterial(Material baseMat, string name, Texture2D tex, Color color)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		Material val = new Material(baseMat)
		{
			name = name
		};
		val.SetTexture("_MainTex", (Texture)(object)tex);
		val.SetTexture("_NormalTex", (Texture)null);
		val.SetTexture("_EmTex", (Texture)null);
		val.SetColor("_EmColor", Color.black);
		val.SetColor("_Color", color);
		return val;
	}

	private static Stream OpenResource(string fileName)
	{
		Assembly assembly = typeof(CommandoInChiefPlugin).Assembly;
		string text = assembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(fileName, StringComparison.OrdinalIgnoreCase));
		if (text == null)
		{
			throw new Exception("Missing embedded resource " + fileName);
		}
		return assembly.GetManifestResourceStream(text);
	}

	private static Texture2D LoadTexture(string fileName, bool pixelArt)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		byte[] array;
		using (Stream stream = OpenResource(fileName))
		{
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			array = memoryStream.ToArray();
		}
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, !pixelArt);
		ImageConversion.LoadImage(val, array);
		((Object)val).name = Path.GetFileNameWithoutExtension(fileName);
		((Texture)val).wrapMode = (TextureWrapMode)1;
		((Texture)val).filterMode = (FilterMode)(!pixelArt);
		return val;
	}

	private static Mesh LoadMesh(string fileName, string meshName)
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Expected O, but got Unknown
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		using Stream input = OpenResource(fileName);
		using BinaryReader binaryReader = new BinaryReader(input);
		if (new string(binaryReader.ReadChars(4)) != "CMC1")
		{
			throw new Exception("Bad mesh data in " + fileName);
		}
		int num = binaryReader.ReadInt32();
		Vector3[] array = (Vector3[])(object)new Vector3[num];
		Vector3[] array2 = (Vector3[])(object)new Vector3[num];
		Vector4[] array3 = (Vector4[])(object)new Vector4[num];
		Vector2[] array4 = (Vector2[])(object)new Vector2[num];
		for (int i = 0; i < num; i++)
		{
			array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int j = 0; j < num; j++)
		{
			array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int k = 0; k < num; k++)
		{
			array3[k] = new Vector4(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int l = 0; l < num; l++)
		{
			array4[l] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		Mesh val = new Mesh
		{
			name = meshName
		};
		val.indexFormat = (IndexFormat)(num > 65535);
		val.vertices = array;
		val.normals = array2;
		val.tangents = array3;
		val.uv = array4;
		if (binaryReader.ReadInt32() != 0)
		{
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num];
			for (int m = 0; m < num; m++)
			{
				int boneIndex = binaryReader.ReadInt32();
				int boneIndex2 = binaryReader.ReadInt32();
				int boneIndex3 = binaryReader.ReadInt32();
				int boneIndex4 = binaryReader.ReadInt32();
				float weight = binaryReader.ReadSingle();
				float weight2 = binaryReader.ReadSingle();
				float weight3 = binaryReader.ReadSingle();
				float weight4 = binaryReader.ReadSingle();
				int num2 = m;
				BoneWeight val2 = default(BoneWeight);
				((BoneWeight)(ref val2)).boneIndex0 = boneIndex;
				((BoneWeight)(ref val2)).boneIndex1 = boneIndex2;
				((BoneWeight)(ref val2)).boneIndex2 = boneIndex3;
				((BoneWeight)(ref val2)).boneIndex3 = boneIndex4;
				((BoneWeight)(ref val2)).weight0 = weight;
				((BoneWeight)(ref val2)).weight1 = weight2;
				((BoneWeight)(ref val2)).weight2 = weight3;
				((BoneWeight)(ref val2)).weight3 = weight4;
				array5[num2] = val2;
			}
			int num3 = binaryReader.ReadInt32();
			Matrix4x4[] array6 = (Matrix4x4[])(object)new Matrix4x4[num3];
			for (int n = 0; n < num3; n++)
			{
				Matrix4x4 val3 = default(Matrix4x4);
				for (int num4 = 0; num4 < 4; num4++)
				{
					for (int num5 = 0; num5 < 4; num5++)
					{
						((Matrix4x4)(ref val3))[num4, num5] = binaryReader.ReadSingle();
					}
				}
				array6[n] = val3;
			}
			val.boneWeights = array5;
			val.bindposes = array6;
		}
		int num6 = binaryReader.ReadInt32();
		int[] array7 = new int[num6];
		for (int num7 = 0; num7 < num6; num7++)
		{
			array7[num7] = binaryReader.ReadInt32();
		}
		val.SetTriangles(array7, 0);
		val.RecalculateBounds();
		return val;
	}
}