Decompiled source of SkinCloneCompatibility v0.2.1

BepInEx/plugins/SkinCloneCompatibility/SkinCloneCompatibility.dll

Decompiled 15 hours ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using BepInEx;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using RoR2;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SkinCloneCompatibility")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyInformationalVersion("0.2.1")]
[assembly: AssemblyProduct("SkinCloneCompatibility")]
[assembly: AssemblyTitle("SkinCloneCompatibility")]
[assembly: AssemblyVersion("0.2.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 SkinCloneCompatibility
{
	public static class BaseSkinRule
	{
		public static bool Matches(string sourceName, string sourceToken, string displayName, string displayToken)
		{
			if (!string.IsNullOrEmpty(sourceName) && !string.IsNullOrEmpty(sourceToken) && sourceToken == displayToken)
			{
				if (!(displayName == sourceName))
				{
					return displayName == sourceName + "(Clone)";
				}
				return true;
			}
			return false;
		}
	}
	public static class CloneRule
	{
		public static bool Matches(int candidateIndex, int registeredIndex, string candidateToken, string registeredToken, string candidateName, string registeredName)
		{
			if (candidateIndex >= 0 && candidateIndex == registeredIndex && !string.IsNullOrEmpty(candidateToken) && candidateToken == registeredToken)
			{
				return candidateName == registeredName + "(Clone)";
			}
			return false;
		}
	}
	public static class DisplayBasePatchRules
	{
		private static bool LoadLocal(Instruction instruction, int index)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			if (instruction != null && (instruction.OpCode == OpCodes.Ldloc_S || instruction.OpCode == OpCodes.Ldloc))
			{
				object operand = instruction.Operand;
				VariableDefinition val = (VariableDefinition)((operand is VariableDefinition) ? operand : null);
				if (val != null)
				{
					return ((VariableReference)val).Index == index;
				}
			}
			return false;
		}

		public static Instruction FindStore(MethodDefinition method)
		{
			if (!method.HasBody || ((MethodReference)method).Parameters.Count != 0 || ((MemberReference)((MethodReference)method).ReturnType).FullName != "System.Void" || method.Body.Variables.Count <= 11 || ((MemberReference)((VariableReference)method.Body.Variables[5]).VariableType).FullName != "RoR2.ModelSkinController" || ((MemberReference)((VariableReference)method.Body.Variables[7]).VariableType).FullName != "RoR2.ModelSkinController" || ((MemberReference)((VariableReference)method.Body.Variables[9]).VariableType).FullName != "System.Int32" || ((MemberReference)((VariableReference)method.Body.Variables[10]).VariableType).FullName != "RoR2.SkinDef" || ((MemberReference)((VariableReference)method.Body.Variables[11]).VariableType).FullName != "RoR2.SkinDef")
			{
				throw new InvalidOperationException("Unexpected display converter signature or locals: name=" + ((MemberReference)method).Name + " parameters=" + ((MethodReference)method).Parameters.Count + " locals=" + (method.HasBody ? string.Join(";", ((IEnumerable<VariableDefinition>)method.Body.Variables).Select((VariableDefinition v) => ((VariableReference)v).Index + ":" + ((MemberReference)((VariableReference)v).VariableType).FullName)) : "<no body>"));
			}
			Instruction[] array = ((IEnumerable<Instruction>)method.Body.Instructions).Where(delegate(Instruction i)
			{
				//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_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				if (i.OpCode == OpCodes.Stelem_Ref && LoadLocal(i.Previous, 11))
				{
					Instruction previous = i.Previous.Previous;
					OpCode? val = ((previous != null) ? new OpCode?(previous.OpCode) : ((OpCode?)null));
					OpCode ldc_I4_ = OpCodes.Ldc_I4_0;
					if (val.HasValue && val.GetValueOrDefault() == ldc_I4_)
					{
						Instruction previous2 = i.Previous.Previous.Previous;
						val = ((previous2 != null) ? new OpCode?(previous2.OpCode) : ((OpCode?)null));
						ldc_I4_ = OpCodes.Ldfld;
						if (val.HasValue && val.GetValueOrDefault() == ldc_I4_)
						{
							object operand = i.Previous.Previous.Previous.Operand;
							FieldReference val2 = (FieldReference)((operand is FieldReference) ? operand : null);
							if (val2 != null && ((MemberReference)val2).FullName == "RoR2.SkinDef[] RoR2.SkinDef::baseSkins")
							{
								return LoadLocal(i.Previous.Previous.Previous.Previous, 10);
							}
						}
					}
				}
				return false;
			}).ToArray();
			if (array.Length != 1)
			{
				throw new InvalidOperationException("Expected exactly one audited base-skin store");
			}
			Instruction site = array[0];
			if (((IEnumerable<Instruction>)method.Body.Instructions).Any((Instruction i) => i.Operand == site || (i.Operand is Instruction[] source && source.Contains(site))))
			{
				throw new InvalidOperationException("Unexpected branch target at store");
			}
			return site;
		}

		public static void Rewrite(MethodDefinition method, MethodReference helper)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Instruction val = FindStore(method);
			ILProcessor iLProcessor = method.Body.GetILProcessor();
			iLProcessor.InsertBefore(val, Instruction.Create(OpCodes.Ldloc, method.Body.Variables[5]));
			iLProcessor.InsertBefore(val, Instruction.Create(OpCodes.Ldloc, method.Body.Variables[7]));
			iLProcessor.InsertBefore(val, Instruction.Create(OpCodes.Ldloc, method.Body.Variables[9]));
			val.OpCode = OpCodes.Call;
			val.Operand = helper;
			method.Body.MaxStackSize = Math.Max(method.Body.MaxStackSize, 6);
		}
	}
	public static class PatchRules
	{
		private const string Inequality = "System.Boolean UnityEngine.Object::op_Inequality(UnityEngine.Object,UnityEngine.Object)";

		public static Instruction[] FindSites(MethodDefinition method, string owner, int expected)
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if (!method.HasBody || ((MemberReference)((MethodReference)method).ReturnType).FullName != "System.Void" || ((MethodReference)method).Parameters.Count != 3 || ((MemberReference)((ParameterReference)((MethodReference)method).Parameters[1]).ParameterType).FullName != "RoR2.SkinDef" || ((MemberReference)((ParameterReference)((MethodReference)method).Parameters[2]).ParameterType).FullName != "UnityEngine.GameObject")
			{
				throw new InvalidOperationException("Callback signature does not match audited target");
			}
			Instruction[] array = ((IEnumerable<Instruction>)method.Body.Instructions).Where(delegate(Instruction i)
			{
				//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)
				if (i.OpCode == OpCodes.Call)
				{
					object operand = i.Operand;
					MethodReference val3 = (MethodReference)((operand is MethodReference) ? operand : null);
					if (val3 != null)
					{
						return ((MemberReference)val3).FullName == "System.Boolean UnityEngine.Object::op_Inequality(UnityEngine.Object,UnityEngine.Object)";
					}
				}
				return false;
			}).ToArray();
			if (array.Length != expected)
			{
				throw new InvalidOperationException("Unexpected identity comparison count: " + array.Length);
			}
			Instruction[] array2 = array;
			foreach (Instruction obj in array2)
			{
				Instruction previous = obj.Previous;
				object obj2 = ((previous != null) ? previous.Operand : null);
				MethodReference val = (MethodReference)((obj2 is MethodReference) ? obj2 : null);
				Instruction previous2 = obj.Previous;
				OpCode? val2 = ((previous2 != null) ? new OpCode?(previous2.OpCode) : ((OpCode?)null));
				OpCode call = OpCodes.Call;
				if (!val2.HasValue || val2.GetValueOrDefault() != call || val == null || ((MemberReference)((MemberReference)val).DeclaringType).FullName != owner || ((MemberReference)val.ReturnType).FullName != "RoR2.SkinDef" || val.HasThis || val.Parameters.Count != 0 || !((MemberReference)val).Name.StartsWith("get_SkinDef", StringComparison.Ordinal) || !int.TryParse(((MemberReference)val).Name.Substring(11), out var result) || result < 1)
				{
					throw new InvalidOperationException("Unexpected registered-skin getter");
				}
			}
			return array;
		}
	}
	[BepInPlugin("local.skin.clonecompatibility", "Skin Clone Compatibility", "0.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Manipulator <>9__9_0;

			internal void <InstallDisplayBaseFix>b__9_0(ILContext il)
			{
				DisplayBasePatchRules.Rewrite(il.Method, ((MemberReference)il.Method).Module.ImportReference((MethodBase)typeof(Plugin).GetMethod("StoreDisplayBase", BindingFlags.Static | BindingFlags.Public)));
			}
		}

		private readonly ConcurrentQueue<Assembly> pending = new ConcurrentQueue<Assembly>();

		private readonly HashSet<Assembly> inspected = new HashSet<Assembly>();

		private readonly List<ILHook> hooks = new List<ILHook>();

		private readonly HashSet<string> accepted = new HashSet<string>();

		private static Plugin instance;

		private void Awake()
		{
			instance = this;
			AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly item in assemblies)
			{
				pending.Enqueue(item);
			}
			Drain();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Ready. Original files unchanged; audited clone comparisons and display base-skin conversion are patched in memory. Runtime visuals still require verification.");
		}

		private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs e)
		{
			pending.Enqueue(e.LoadedAssembly);
		}

		private void Update()
		{
			Drain();
		}

		private void Drain()
		{
			while (true)
			{
				if (!pending.TryDequeue(out var assembly))
				{
					break;
				}
				if (!inspected.Add(assembly) || assembly.IsDynamic)
				{
					continue;
				}
				if (assembly.GetName().Name == "R2API.Skins")
				{
					InstallDisplayBaseFix(assembly);
				}
				Target[] array = Targets.All.Where((Target t) => t.Assembly == assembly.GetName().Name).ToArray();
				if (array.Length == 0)
				{
					continue;
				}
				try
				{
					string hash;
					using (SHA256 sHA = SHA256.Create())
					{
						using FileStream inputStream = File.OpenRead(assembly.Location);
						hash = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "");
					}
					if (array.Any((Target t) => t.Sha256 != hash))
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("SKIP " + assembly.GetName().Name + " SHA256=" + hash + "; this build has not been audited. Do not combine with the earlier replacement Commando DLL."));
					}
					else
					{
						Target[] array2 = array;
						foreach (Target target in array2)
						{
							Install(assembly, target);
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Could not inspect " + assembly.GetName().Name + ": " + ex));
				}
			}
		}

		private void InstallDisplayBaseFix(Assembly assembly)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			ILHook val = null;
			try
			{
				string text;
				using (SHA256 sHA = SHA256.Create())
				{
					using FileStream inputStream = File.OpenRead(assembly.Location);
					text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "");
				}
				if (text != "9A67B1D407604A5AA3D710DEA3DF248152B62E7D5CA029F80127F96937F47C08")
				{
					throw new InvalidOperationException("R2API.Skins build is not the audited 1.4.11 DLL; SHA256=" + text);
				}
				MethodInfo? method = assembly.GetType("R2API.Skins", throwOnError: true).GetMethod("OnMainMenuInitialized", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					throw new MissingMethodException("R2API.Skins.OnMainMenuInitialized");
				}
				object obj = <>c.<>9__9_0;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						DisplayBasePatchRules.Rewrite(il.Method, ((MemberReference)il.Method).Module.ImportReference((MethodBase)typeof(Plugin).GetMethod("StoreDisplayBase", BindingFlags.Static | BindingFlags.Public)));
					};
					<>c.<>9__9_0 = val2;
					obj = (object)val2;
				}
				val = new ILHook((MethodBase)method, (Manipulator)obj);
				hooks.Add(val);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"PATCH R2API.Skins::OnMainMenuInitialized preserve original base-skin mapping (1 store)");
			}
			catch (Exception ex)
			{
				if (val != null)
				{
					val.Dispose();
				}
				((BaseUnityPlugin)this).Logger.LogError((object)("SKIP display base-skin fix: " + ex));
			}
		}

		public static void StoreDisplayBase(SkinDef[] bases, int slot, SkinDef fallback, ModelSkinController body, ModelSkinController display, int sourceIndex)
		{
			SkinDef val = fallback;
			SkinDef val2 = null;
			SkinDef val3 = null;
			if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)display) && body.skins != null && display.skins != null && sourceIndex >= 0 && sourceIndex < body.skins.Length)
			{
				val2 = body.skins[sourceIndex];
				if (Object.op_Implicit((Object)(object)val2) && val2.baseSkins != null && slot >= 0 && slot < val2.baseSkins.Length)
				{
					val3 = val2.baseSkins[slot];
					int num = (Object.op_Implicit((Object)(object)val3) ? Array.IndexOf(body.skins, val3) : (-1));
					if (num >= 0 && num < display.skins.Length)
					{
						SkinDef val4 = display.skins[num];
						if (Object.op_Implicit((Object)(object)val4) && ((Object)(object)val4 == (Object)(object)val3 || BaseSkinRule.Matches(((Object)val3).name, val3.nameToken, ((Object)val4).name, val4.nameToken)))
						{
							val = val4;
						}
					}
				}
			}
			bases[slot] = val;
			Plugin plugin = instance;
			if ((Object)(object)plugin != (Object)null && (Object)(object)val != (Object)(object)fallback)
			{
				((BaseUnityPlugin)plugin).Logger.LogInfo((object)("BASE INHERIT skin=" + ((Object)val2).name + " intended=" + ((Object)val3).name + " fallback=" + (Object.op_Implicit((Object)(object)fallback) ? ((Object)fallback).name : "<null>") + " mapped=" + ((Object)val).name));
			}
			else if ((Object)(object)plugin != (Object)null && Object.op_Implicit((Object)(object)val3) && (Object)(object)val3 != (Object)(object)fallback && !BaseSkinRule.Matches(((Object)val3).name, val3.nameToken, Object.op_Implicit((Object)(object)fallback) ? ((Object)fallback).name : null, Object.op_Implicit((Object)(object)fallback) ? fallback.nameToken : null))
			{
				((BaseUnityPlugin)plugin).Logger.LogWarning((object)("BASE MAP SKIP skin=" + ((Object)val2).name + " intended=" + ((Object)val3).name + "; keeping converter fallback"));
			}
		}

		private void Install(Assembly assembly, Target target)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			ILHook val = null;
			try
			{
				val = new ILHook((MethodBase)assembly.GetType(target.Type, throwOnError: true).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Single((MethodInfo m) => m.Name == target.Method && m.GetParameters().Length == 3), (Manipulator)delegate(ILContext il)
				{
					Instruction[] array = PatchRules.FindSites(il.Method, target.Type, target.Count);
					MethodReference operand = ((MemberReference)il.Method).Module.ImportReference((MethodBase)typeof(Plugin).GetMethod("AreDifferentSkins", BindingFlags.Static | BindingFlags.Public));
					Instruction[] array2 = array;
					for (int i = 0; i < array2.Length; i++)
					{
						array2[i].Operand = operand;
					}
				});
				hooks.Add(val);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("PATCH " + target.Type + "::" + target.Method + " comparisons=" + target.Count));
			}
			catch (Exception ex)
			{
				if (val != null)
				{
					val.Dispose();
				}
				((BaseUnityPlugin)this).Logger.LogError((object)("SKIP " + target.Type + "::" + target.Method + ": " + ex));
			}
		}

		public static bool AreDifferentSkins(Object candidate, Object registered)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected I4, but got Unknown
			//IL_005c: Expected I4, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected I4, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected I4, but got Unknown
			if (candidate == registered)
			{
				return false;
			}
			if (!Object.op_Implicit(candidate) || !Object.op_Implicit(registered))
			{
				return true;
			}
			SkinDef val = (SkinDef)(object)((candidate is SkinDef) ? candidate : null);
			if (val != null)
			{
				SkinDef val2 = (SkinDef)(object)((registered is SkinDef) ? registered : null);
				if (val2 != null)
				{
					if (!CloneRule.Matches((int)val.skinIndex, (int)val2.skinIndex, val.nameToken, val2.nameToken, ((Object)val).name, ((Object)val2).name))
					{
						return true;
					}
					Plugin plugin = instance;
					if ((Object)(object)plugin != (Object)null && plugin.accepted.Add(val2.nameToken + "|" + (int)val2.skinIndex))
					{
						((BaseUnityPlugin)plugin).Logger.LogInfo((object)("CLONE MATCH index=" + (int)val2.skinIndex + " registered=" + ((Object)val2).name + " candidate=" + ((Object)val).name + " token=" + val2.nameToken));
					}
					return false;
				}
			}
			return true;
		}

		private void OnDestroy()
		{
			AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
			foreach (ILHook hook in hooks)
			{
				hook.Dispose();
			}
			hooks.Clear();
			if (instance == this)
			{
				instance = null;
			}
		}
	}
	public sealed class Target
	{
		public readonly string Assembly;

		public readonly string Type;

		public readonly string Method;

		public readonly string Sha256;

		public readonly int Count;

		public Target(string assembly, string type, string method, int count, string sha256)
		{
			Assembly = assembly;
			Type = type;
			Method = method;
			Count = count;
			Sha256 = sha256;
		}
	}
	internal static class Targets
	{
		internal static readonly Target[] All = new Target[16]
		{
			new Target("FemmeBandit12G", "FemmeBandit12G.FemmeBandit12GPlugin", "SkinDefApply", 4, "826FE2BEF819E7875F3F2AB63DAFA4B85FEB5C7E97F85E68F645BEF2705E578D"),
			new Target("RisqueFemmeBandit12G", "RisqueFemmeBandit12G.RisqueFemmeBandit12GPlugin", "SkinDefApply", 1, "2BE48FF084699FE71E6C80A0B842FE47422A975831538F65332B54F988364E26"),
			new Target("RisqueFemCaptain12G", "RisqueFemCaptain12G.RisqueFemCaptain12GPlugin", "SkinDefApply", 2, "76264ED38A24D4AEE018AB86A526C71D1B166B3B50B72D801D1EC4DCA34B9BB2"),
			new Target("RisqueFemCommando12G", "RisqueFemCommando12G.RisqueFemCommando12GPlugin", "SkinDefApply", 10, "47AC0CD310E381FEEA3BA2F63DF6C83F0A2B24D5AAEFF7208B7DD1A44E38E480"),
			new Target("RisqueFemMerc12G", "RisqueFemMerc12G.RisqueFemMerc12GPlugin", "SkinDefApply", 12, "FC767B33193E12F74A934115ECADEAB0CB1D2E45E10F58A3ECE46D5B418100A7"),
			new Target("RisqueHuntress12G", "RisqueHuntress12G.RisqueHuntress12GPlugin", "SkinDefApply", 4, "5A7B624518CB713B24A78DCC92F10F4D3F6965C6DC45AA1CE10A509FA1788E95"),
			new Target("RisqueRailgunner12G", "RisqueRailgunner12G.RisqueRailgunner12GPlugin", "SkinDefApply", 2, "FED86B990F0767C717056BECBED61879EF656B9F19D40641190538B4B129EC58"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply1", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply2", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply3", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply4", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply5", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply6", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply7", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("ThiccArti12G", "ThiccArti12G.ThiccArti12GPlugin", "SkinDefApply8", 8, "70A2382B49F32DC21FBE8C5E9FA17DD288BCA0E98EBD2BFE25BE9F595D6F5686"),
			new Target("NSFWHuntress", "NSFWHuntress.NSFWHuntressPlugin", "SkinDefApply", 2, "FF87DCC0432D75A88F403CCB14CC3F51274C05D29826418B2EA553494CA1B949")
		};
	}
}