using System;
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;
using System.Security.Permissions;
using System.Text.Json;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CustomEnemyAnimationsAPI.JSON;
using CustomEnemyAnimationsAPI.Manager;
using CustomEnemyAnimationsAPI.Patches;
using CustomEnemyAnimationsAPI.Util;
using Enemies;
using GTFO.API;
using GameData;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CustomEnemyAnimationsAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CustomEnemyAnimationsAPI")]
[assembly: AssemblyTitle("CustomEnemyAnimationsAPI")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[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 CustomEnemyAnimationsAPI
{
[BepInPlugin("HatsuneFucker.CustomEnemyAnimations", "CustomEnemyAnimations", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class EntryPoint : BasePlugin
{
private Harmony _Harmony;
public override void Load()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
_Harmony = new Harmony("CustomEnemyAnimations");
_Harmony.PatchAll(typeof(EnemyLocomotionPatches));
Logger.Info("CustomEnemyAnimations has been installed");
AssetAPI.OnImplReady += delegate
{
CustomFolder.CheckCustomFile();
};
}
public override bool Unload()
{
_Harmony.UnpatchSelf();
return ((BasePlugin)this).Unload();
}
}
internal static class Logger
{
private static readonly ManualLogSource _Logger;
static Logger()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
_Logger = new ManualLogSource("CustomEnemyAnimations");
Logger.Sources.Add((ILogSource)(object)_Logger);
}
private static string Format(object msg)
{
return msg.ToString();
}
public static void Info(BepInExInfoLogInterpolatedStringHandler handler)
{
_Logger.LogInfo(handler);
}
public static void Info(string str)
{
_Logger.LogMessage((object)str);
}
public static void Info(object data)
{
_Logger.LogMessage((object)Format(data));
}
public static void Debug(BepInExDebugLogInterpolatedStringHandler handler)
{
_Logger.LogDebug(handler);
}
public static void Debug(string str)
{
_Logger.LogDebug((object)str);
}
public static void Debug(object data)
{
_Logger.LogDebug((object)Format(data));
}
public static void Error(BepInExErrorLogInterpolatedStringHandler handler)
{
_Logger.LogError(handler);
}
public static void Error(string str)
{
_Logger.LogError((object)str);
}
public static void Error(object data)
{
_Logger.LogError((object)Format(data));
}
public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler)
{
_Logger.LogFatal(handler);
}
public static void Fatal(string str)
{
_Logger.LogFatal((object)str);
}
public static void Fatal(object data)
{
_Logger.LogFatal((object)Format(data));
}
public static void Warn(BepInExWarningLogInterpolatedStringHandler handler)
{
_Logger.LogWarning(handler);
}
public static void Warn(string str)
{
_Logger.LogWarning((object)str);
}
public static void Warn(object data)
{
_Logger.LogWarning((object)Format(data));
}
[Conditional("DEBUG")]
public static void DebugOnly(object data)
{
}
}
}
namespace CustomEnemyAnimationsAPI.Util
{
public static class MtfoUtils
{
public static string CustomPath { get; private set; }
public static string Version { get; private set; }
public static bool PluginExists { get; private set; }
static MtfoUtils()
{
CustomPath = string.Empty;
Version = string.Empty;
PluginExists = false;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var info))
{
return;
}
PluginExists = true;
try
{
Assembly? assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => !x.IsDynamic && x.Location == info.Location);
if (assembly == null)
{
throw new Exception("couldn't locate the MTFO assembly");
}
Type[] types = assembly.GetTypes();
Type type = types.FirstOrDefault((Type x) => x.Name == "ConfigManager");
Type? type2 = types.FirstOrDefault((Type x) => x.Name == "MTFO");
if (type2 == null)
{
throw new Exception("couldn't locate MTFO's EntryPoint");
}
if (type == null)
{
throw new Exception("couldn't locate MTFO's ConfigManager");
}
FieldInfo? field = type2.GetField("VERSION", BindingFlags.Static | BindingFlags.Public);
FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
if (field == null)
{
throw new Exception("couldn't locate MTFO's Version");
}
if (field2 == null)
{
throw new Exception("couldn't locate MTFO's CustomPath");
}
CustomPath = (string)field2.GetValue(null);
Version = (string)field.GetValue(null);
types.FirstOrDefault((Type x) => x.Name == "HotReloader");
}
catch (Exception ex)
{
Logger.Error(ex.ToString());
}
}
}
}
namespace CustomEnemyAnimationsAPI.Patches
{
internal class EnemyLocomotionPatches
{
[HarmonyPatch(typeof(EnemyLocomotion), "InitController")]
[HarmonyPostfix]
internal static void OverrideController(EnemyLocomotion __instance, AnimatorControllerHandleName handle, bool enableAnimator)
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Expected O, but got Unknown
if (!enableAnimator || !((Object)(object)__instance.AnimHandle.AnimatorController != (Object)null))
{
return;
}
bool flag = default(bool);
foreach (CustomDataBlock.CustomAnimations animation in CustomDataBlock.animationList)
{
if (!animation.Enabled)
{
continue;
}
switch (animation.Target.Mode)
{
case "PersistentID":
ApplyAnimation.PersistentIDs(handle, __instance.m_animator, __instance.m_agent.EnemyDataID, animation);
continue;
case "NameContains":
ApplyAnimation.NameContains(handle, __instance.m_animator, ((GameDataBlockBase<EnemyDataBlock>)(object)__instance.m_agent.EnemyData).name, animation);
continue;
case "NameEquals":
ApplyAnimation.NameEquals(handle, __instance.m_animator, ((GameDataBlockBase<EnemyDataBlock>)(object)__instance.m_agent.EnemyData).name, animation);
continue;
case "Everything":
ApplyAnimation.Everything(handle, __instance.m_animator, animation);
continue;
}
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(27, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(animation.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has an invalid Mode of '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(animation.Target.Mode);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'!");
}
Logger.Error(val);
}
}
}
}
namespace CustomEnemyAnimationsAPI.Manager
{
public class ApplyAnimation
{
internal static void PersistentIDs(AnimatorControllerHandleName animatorEnum, Animator enemyAnimator, uint enemyPersistentID, CustomDataBlock.CustomAnimations customAnimationDB)
{
if (!customAnimationDB.Target.PersistentIDs.Contains(enemyPersistentID))
{
return;
}
foreach (CustomDataBlock.ControllerSwap animatorOverrideController in customAnimationDB.AnimatorOverrideControllers)
{
if (((object)(AnimatorControllerHandleName)(ref animatorEnum)).ToString() == animatorOverrideController.DefaultController)
{
int index = Random.Range(0, animatorOverrideController.OverrideControllers.Count);
enemyAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)AssetAPI.GetLoadedAsset<AnimatorOverrideController>(animatorOverrideController.OverrideControllers[index]);
}
}
}
internal static void NameContains(AnimatorControllerHandleName animatorEnum, Animator enemyAnimator, string enemyName, CustomDataBlock.CustomAnimations customAnimationDB)
{
if (!enemyName.Contains(customAnimationDB.Target.NameParam))
{
return;
}
foreach (CustomDataBlock.ControllerSwap animatorOverrideController in customAnimationDB.AnimatorOverrideControllers)
{
if (((object)(AnimatorControllerHandleName)(ref animatorEnum)).ToString() == animatorOverrideController.DefaultController)
{
int index = Random.Range(0, animatorOverrideController.OverrideControllers.Count);
enemyAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)AssetAPI.GetLoadedAsset<AnimatorOverrideController>(animatorOverrideController.OverrideControllers[index]);
}
}
}
internal static void NameEquals(AnimatorControllerHandleName animatorEnum, Animator enemyAnimator, string enemyName, CustomDataBlock.CustomAnimations customAnimationDB)
{
if (!(customAnimationDB.Target.NameParam == enemyName))
{
return;
}
foreach (CustomDataBlock.ControllerSwap animatorOverrideController in customAnimationDB.AnimatorOverrideControllers)
{
if (((object)(AnimatorControllerHandleName)(ref animatorEnum)).ToString() == animatorOverrideController.DefaultController)
{
int index = Random.Range(0, animatorOverrideController.OverrideControllers.Count);
enemyAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)AssetAPI.GetLoadedAsset<AnimatorOverrideController>(animatorOverrideController.OverrideControllers[index]);
}
}
}
internal static void Everything(AnimatorControllerHandleName animatorEnum, Animator enemyAnimator, CustomDataBlock.CustomAnimations customAnimationDB)
{
foreach (CustomDataBlock.ControllerSwap animatorOverrideController in customAnimationDB.AnimatorOverrideControllers)
{
if (((object)(AnimatorControllerHandleName)(ref animatorEnum)).ToString() == animatorOverrideController.DefaultController)
{
int index = Random.Range(0, animatorOverrideController.OverrideControllers.Count);
enemyAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)AssetAPI.GetLoadedAsset<AnimatorOverrideController>(animatorOverrideController.OverrideControllers[index]);
}
}
}
}
internal class CustomFolder
{
private static string dir;
public static void CheckCustomFile()
{
if (MtfoUtils.PluginExists)
{
dir = Path.Combine(MtfoUtils.CustomPath, "CustomEnemyAnimations");
}
if (!dir.Contains("BepInEx"))
{
Logger.Warn("No MTFO was found, using assembly path...");
dir = Path.Combine(Paths.PluginPath, "HatsuneFucker39-CustomEnemyAnimationsAPI");
}
if (!File.Exists(Path.Combine(dir, "CustomAnimations.json")))
{
CreateDefaultJson();
}
else
{
ParseCustomJson();
}
}
public static void CreateDefaultJson()
{
Logger.Debug("Creating default json");
if (dir.Contains("BepInEx"))
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
File.WriteAllText(Path.Combine(dir, "CustomAnimations.json"), "[\r\n {\r\n \"Name\": \"\",\r\n \"Enabled\": false,\r\n \"Target\": {\r\n \"Mode\": \"\",\r\n \"PersistentIDs\": [],\r\n \"NameParam\": \"\",\r\n \"NameIgnoreCase\": false\r\n },\r\n \"AnimatorOverrideControllers\": [\r\n {\r\n \"DefaultController\": \"\",\r\n \"OverrideControllers\": []\r\n }\r\n ]\r\n }\r\n]");
}
}
internal static void ParseCustomJson()
{
CustomDataBlock.animationList = JsonSerializer.Deserialize<List<CustomDataBlock.CustomAnimations>>(File.ReadAllText(Path.Combine(dir, "CustomAnimations.json")));
}
}
}
namespace CustomEnemyAnimationsAPI.JSON
{
internal class CustomDataBlock
{
public class CustomAnimations
{
public string Name { get; set; }
public bool Enabled { get; set; }
public Target Target { get; set; }
public List<ControllerSwap> AnimatorOverrideControllers { get; set; }
}
public class Target
{
public string Mode { get; set; }
public List<uint> PersistentIDs { get; set; }
public string NameParam { get; set; }
public bool NameIgnoreCase { get; set; }
}
public class ControllerSwap
{
public string DefaultController { get; set; }
public List<string> OverrideControllers { get; set; }
}
public static List<CustomAnimations> animationList = new List<CustomAnimations>();
}
public class EmptyDataBlock
{
public const string CustomAnimationsDataBlock = "[\r\n {\r\n \"Name\": \"\",\r\n \"Enabled\": false,\r\n \"Target\": {\r\n \"Mode\": \"\",\r\n \"PersistentIDs\": [],\r\n \"NameParam\": \"\",\r\n \"NameIgnoreCase\": false\r\n },\r\n \"AnimatorOverrideControllers\": [\r\n {\r\n \"DefaultController\": \"\",\r\n \"OverrideControllers\": []\r\n }\r\n ]\r\n }\r\n]";
}
}