using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AIGraph;
using AK;
using Agents;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using CellMenu;
using CullingSystem;
using EEC.API;
using EEC.Configs;
using EEC.Configs.Customizations;
using EEC.CustomAbilities.Bleed;
using EEC.CustomAbilities.Bleed.Handlers;
using EEC.CustomAbilities.Bleed.Inject;
using EEC.CustomAbilities.DrainStamina;
using EEC.CustomAbilities.EMP;
using EEC.CustomAbilities.EMP.Handlers;
using EEC.CustomAbilities.EMP.Inject;
using EEC.CustomAbilities.Explosion;
using EEC.CustomAbilities.Explosion.Handlers;
using EEC.CustomSettings.CustomProjectiles;
using EEC.CustomSettings.CustomScoutWaves;
using EEC.CustomSettings.CustomTentacles;
using EEC.EnemyCustomizations;
using EEC.EnemyCustomizations.Abilities;
using EEC.EnemyCustomizations.Abilities.Handlers;
using EEC.EnemyCustomizations.Abilities.Inject;
using EEC.EnemyCustomizations.Detections;
using EEC.EnemyCustomizations.EnemyAbilities;
using EEC.EnemyCustomizations.EnemyAbilities.Abilities;
using EEC.EnemyCustomizations.EnemyAbilities.Events;
using EEC.EnemyCustomizations.EnemyAbilities.Handlers;
using EEC.EnemyCustomizations.Models;
using EEC.EnemyCustomizations.Models.Handlers;
using EEC.EnemyCustomizations.Properties;
using EEC.EnemyCustomizations.Shared;
using EEC.EnemyCustomizations.Shared.Handlers;
using EEC.EnemyCustomizations.Shooters;
using EEC.EnemyCustomizations.Shooters.Handlers;
using EEC.EnemyCustomizations.Strikers;
using EEC.Events;
using EEC.Managers;
using EEC.Managers.Assets;
using EEC.Managers.Properties;
using EEC.Networking;
using EEC.Networking.Events;
using EEC.Networking.Replicators;
using EEC.Patches.Handlers;
using EEC.Utils;
using EEC.Utils.Integrations;
using EEC.Utils.Json;
using EEC.Utils.Json.Converters;
using EEC.Utils.Json.Elements;
using EEC.Utils.Unity;
using Enemies;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.InteropTypes.Fields;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using Player;
using SNetwork;
using SemanticVersioning;
using StateMachines;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ExtraEnemyCustomization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.6.0.0")]
[assembly: AssemblyInformationalVersion("1.6.0")]
[assembly: AssemblyProduct("ExtraEnemyCustomization")]
[assembly: AssemblyTitle("ExtraEnemyCustomization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.0.0")]
[module: UnverifiableCode]
namespace EEC
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
internal sealed class CallConstructorOnLoadAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
internal sealed class InjectToIl2CppAttribute : Attribute
{
}
public static class Configuration
{
public const string SECTION_USER = "1. User-End";
public const string SECTION_RUNDEVS = "2. Rundown Developer";
public const string SECTION_LOGGING = "3. Logging";
public const string SECTION_DEV = "4. DEBUG";
public const int CONFIG_VERSION = 1;
private static ConfigEntry<bool> _showMarkerText;
private static ConfigEntry<bool> _showMarkerDistance;
private static ConfigEntry<bool> _showExplosionEffect;
private static ConfigEntry<ShitpostType> _shitpostType;
private static ConfigEntry<bool> _useLiveEdit;
private static ConfigEntry<bool> _linkMTFOHotReload;
private static ConfigEntry<bool> _useDebugLog;
private static ConfigEntry<bool> _useVerboseLog;
private static ConfigEntry<AssetCacheManager.OutputType> _assetCacheBehaviour;
private static ConfigEntry<bool> _dumpConfig;
private static ConfigEntry<bool> _profiler;
private static ConfigFile _currentContext;
public static bool ShowMarkerText { get; private set; }
public static bool ShowMarkerDistance { get; private set; }
public static bool ShowExplosionEffect { get; private set; }
public static ShitpostType ShitpostType { get; private set; }
public static bool UseLiveEdit { get; private set; }
public static bool LinkMTFOHotReload { get; private set; }
public static bool UseDebugLog { get; private set; }
public static bool UseVerboseLog { get; private set; }
public static AssetCacheManager.OutputType AssetCacheBehaviour { get; private set; }
public static bool DumpConfig { get; private set; }
public static bool Profiler { get; private set; }
public static bool CanShitpostOf(ShitpostType type)
{
switch (ShitpostType)
{
case ShitpostType.ForceOff:
return false;
case ShitpostType.Enable:
{
DateTime now = DateTime.Now;
if (now.Month == 4)
{
return now.Day == 1;
}
return false;
}
default:
return ShitpostType.HasFlag(type);
}
}
public static void CreateAndBindAll()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
string text = Path.Combine(Paths.ConfigPath, "EEC.cfg");
ConfigFile context = new ConfigFile(text, true);
if (BindConfigVersion(context).Value < 1)
{
File.Delete(text);
context = new ConfigFile(text, true);
BindConfigVersion(context);
}
BindAll(context);
}
public static void BindAll(ConfigFile context)
{
_currentContext = context;
_showMarkerText = BindUserConfig("Marker Text", "Display Enemy Marker Texts? (if set by rundown devs)", defaultValue: true);
_showMarkerDistance = BindUserConfig("Marker Distance", "Display Enemy Marker Distance? (if set by rundown devs)", defaultValue: true);
_showExplosionEffect = BindUserConfig("Explosion Flash", "(Accessibility) Display Light flash effect for explosion abilities?", defaultValue: true);
_shitpostType = BindUserConfig("Shitposting", "Shitpost mode use comma to enable multiple stuffs", ShitpostType.ForceOff);
ShowMarkerText = _showMarkerText.Value;
ShowMarkerDistance = _showMarkerDistance.Value;
ShowExplosionEffect = _showExplosionEffect.Value;
ShitpostType = _shitpostType.Value;
_useLiveEdit = BindRdwDevConfig("Live Edit", "Reload Config when they are edited while in-game", defaultValue: false);
_linkMTFOHotReload = BindRdwDevConfig("Reload on MTFO HotReload", "Reload Configs when MTFO's HotReload button has pressed?", defaultValue: true);
UseLiveEdit = _useLiveEdit.Value;
LinkMTFOHotReload = _linkMTFOHotReload.Value;
_useDebugLog = BindLoggingConfig("UseDevMessage", "Using Dev Message for Debugging your config?", defaultValue: false);
_useVerboseLog = BindLoggingConfig("Verbose", "Using Much more detailed Message for Debugging?", defaultValue: false);
_assetCacheBehaviour = BindLoggingConfig("Cached Asset Result Output", "How does your cached material/texture result be returned?", AssetCacheManager.OutputType.None);
UseDebugLog = _useDebugLog.Value;
UseVerboseLog = _useVerboseLog.Value;
AssetCacheBehaviour = _assetCacheBehaviour.Value;
_dumpConfig = BindDevConfig("DumpConfig", "Dump Empty Config file?", defaultValue: false);
_profiler = BindDevConfig("Profiler", "Show Profiler Info for Spawned Event", defaultValue: false);
DumpConfig = _dumpConfig.Value;
Profiler = _profiler.Value;
}
private static ConfigEntry<int> BindConfigVersion(ConfigFile context)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
return context.Bind<int>(new ConfigDefinition("Version", "Config Version"), 1, (ConfigDescription)null);
}
private static ConfigEntry<T> BindUserConfig<T>(string name, string description, T defaultValue)
{
return BindItem(_currentContext, "1. User-End", name, description, defaultValue);
}
private static ConfigEntry<T> BindRdwDevConfig<T>(string name, string description, T defaultValue)
{
return BindItem(_currentContext, "2. Rundown Developer", name, description, defaultValue);
}
private static ConfigEntry<T> BindLoggingConfig<T>(string name, string description, T defaultValue)
{
return BindItem(_currentContext, "3. Logging", name, description, defaultValue);
}
private static ConfigEntry<T> BindDevConfig<T>(string name, string description, T defaultValue)
{
return BindItem(_currentContext, "4. DEBUG", name, description, defaultValue);
}
private static ConfigEntry<T> BindItem<T>(ConfigFile context, string section, string name, string description, T defaultValue)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_001b: Expected O, but got Unknown
return context.Bind<T>(new ConfigDefinition(section, name), defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
}
}
[BepInPlugin("GTFO.EECustomization", "EECustom", "1.7.7")]
[BepInProcess("GTFO.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class EntryPoint : BasePlugin
{
public static Harmony HarmonyInstance { get; private set; }
public static string BasePath { get; private set; }
public override void Load()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
Configuration.CreateAndBindAll();
Logger.Initialize();
InjectAllIl2CppType();
CallAllAutoConstructor();
BasePath = Path.Combine(MTFOUtil.CustomPath, "ExtraEnemyCustomization");
HarmonyInstance = new Harmony("EEC.Harmony");
HarmonyInstance.PatchAll();
NetworkManager.Initialize();
ConfigManager.Initialize();
if (Configuration.DumpConfig)
{
ConfigManager.DumpDefault();
}
AssetEvents.AllAssetLoaded += AllAssetLoaded;
AssetCacheManager.OutputMethod = Configuration.AssetCacheBehaviour;
}
private void AllAssetLoaded()
{
SpriteManager.Initialize();
AssetCacheManager.AssetLoaded();
ConfigManager.FireAssetLoaded();
ConfigManager.FirePrefabBuildEventAll(rebuildPrefabs: false);
}
public override bool Unload()
{
UninjectAllIl2CppType();
HarmonyInstance.UnpatchSelf();
ConfigManager.UnloadAllConfig(doClear: true);
return ((BasePlugin)this).Unload();
}
private void InjectAllIl2CppType()
{
Logger.Debug("Injecting IL2CPP Types");
IEnumerable<Type> allHandlers = GetAllHandlers();
Logger.Debug($" - Count: {allHandlers.Count()}");
foreach (Type item in allHandlers)
{
if (!ClassInjector.IsTypeRegisteredInIl2Cpp(item))
{
ClassInjector.RegisterTypeInIl2Cpp(item);
}
}
}
private void CallAllAutoConstructor()
{
Logger.Debug("Calling Necessary Static .ctors");
IEnumerable<Type> allAutoConstructor = GetAllAutoConstructor();
Logger.Debug($" - Count: {allAutoConstructor.Count()}");
foreach (Type item in allAutoConstructor)
{
Logger.Debug("calling ctor of: " + item.Name);
RuntimeHelpers.RunClassConstructor(item.TypeHandle);
}
}
private void UninjectAllIl2CppType()
{
Logger.Debug("Uninjecting IL2CPP Types");
IEnumerable<Type> allHandlers = GetAllHandlers();
Logger.Debug($" - Count: {allHandlers.Count()}");
foreach (Type item in allHandlers)
{
ClassInjector.IsTypeRegisteredInIl2Cpp(item);
}
}
private IEnumerable<Type> GetAllAutoConstructor()
{
return from type in ((object)this).GetType().Assembly.GetTypes()
where type != null && Attribute.IsDefined(type, typeof(CallConstructorOnLoadAttribute))
select type;
}
private IEnumerable<Type> GetAllHandlers()
{
return from type in ((object)this).GetType().Assembly.GetTypes()
where type != null && Attribute.IsDefined(type, typeof(InjectToIl2CppAttribute))
select type;
}
}
public static class AgentExtension
{
public static bool TryCastToEnemyAgent(this Agent agent, out EnemyAgent enemyAgent)
{
return TryCast<EnemyAgent>(agent, (AgentType)1, out enemyAgent);
}
public static bool TryCastToPlayerAgent(this Agent agent, out PlayerAgent playerAgent)
{
return TryCast<PlayerAgent>(agent, (AgentType)0, out playerAgent);
}
private static bool TryCast<T>(Agent agent, AgentType type, out T result) where T : Agent
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)agent == (Object)null) && !((Il2CppObjectBase)agent).WasCollected && agent.Type == type)
{
T val = ((Il2CppObjectBase)agent).TryCast<T>();
if (!((Object)(object)val == (Object)null))
{
result = val;
return true;
}
}
result = default(T);
return false;
}
}
public static class EasingExtension
{
public static float Evaluate(this eEasingType easeType, float progress, bool backward = false)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return Easing.GetEasingValue(easeType, progress, backward);
}
public static Func<float, float, float, float, float> GetEaseFunction(this eEasingType easeType)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected I4, but got Unknown
return (easeType - 1) switch
{
0 => Easing.EaseInQuad,
1 => Easing.EaseOutQuad,
2 => Easing.EaseInOutQuad,
3 => Easing.EaseInCubic,
4 => Easing.EaseOutCubic,
5 => Easing.EaseInOutCubic,
6 => Easing.EaseInQuart,
7 => Easing.EaseOutQuart,
8 => Easing.EaseInOutQuart,
9 => Easing.EaseInQuint,
10 => Easing.EaseOutQuint,
11 => Easing.EaseInOutQuint,
12 => Easing.EaseInSine,
13 => Easing.EaseOutSine,
14 => Easing.EaseInOutSine,
15 => Easing.EaseInExpo,
16 => Easing.EaseOutExpo,
17 => Easing.EaseInOutExpo,
18 => Easing.EaseInCirc,
19 => Easing.EaseOutCirc,
20 => Easing.EaseInOutCirc,
_ => Easing.LinearTween,
};
}
}
public static class EnemyAgentExtension
{
public static void AddOnDeadOnce(this EnemyAgent agent, Action onDead)
{
bool called = false;
agent.OnDeadCallback += Action.op_Implicit((Action)delegate
{
if (!called)
{
onDead?.Invoke();
called = true;
}
});
}
public static T RegisterOrGetProperty<T>(this EnemyAgent agent) where T : class, new()
{
return EnemyProperty<T>.RegisterOrGet(agent);
}
public static bool TryGetProperty<T>(this EnemyAgent agent, out T property) where T : class, new()
{
return EnemyProperty<T>.TryGet(agent, out property);
}
public static bool TryGetSpawnData(this EnemyAgent agent, out pEnemySpawnData spawnData)
{
return EnemySpawnDataManager.TryGet(((Agent)agent).GlobalID, out spawnData);
}
public static bool TryGetEnemyGroup(this EnemyAgent agent, out EnemyGroup group)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
if (!agent.TryGetSpawnData(out var spawnData))
{
group = null;
return false;
}
if (spawnData.groupReplicatorKey == 0)
{
group = null;
return false;
}
IReplicator val = default(IReplicator);
if (SNet_Replication.TryGetReplicator(spawnData.groupReplicatorKey, ref val))
{
group = null;
return false;
}
if (val.ReplicatorSupplier == null)
{
group = null;
return false;
}
group = ((Il2CppObjectBase)val.ReplicatorSupplier).TryCast<EnemyGroup>();
return (Object)(object)group != (Object)null;
}
public static AIG_CourseNode GetSpawnedNode(this EnemyAgent agent)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
pEnemySpawnData spawnData = ((SNet_DynamicReplicator<pEnemySpawnData>)(object)((Il2CppObjectBase)agent.Sync.Replicator).Cast<EnemyReplicator>()).GetSpawnData();
AIG_CourseNode result = default(AIG_CourseNode);
if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref result))
{
return null;
}
return result;
}
}
public static class EnemyDataBlockExtension
{
public static bool TryGetBehaviourBlock(this EnemyDataBlock data, out EnemyBehaviorDataBlock behaviour)
{
if (data == null)
{
behaviour = null;
return false;
}
behaviour = GameDataBlockBase<EnemyBehaviorDataBlock>.GetBlock(data.BehaviorDataId);
return behaviour != null;
}
public static bool TryGetBalancingBlock(this EnemyDataBlock data, out EnemyBalancingDataBlock balancing)
{
if (data == null)
{
balancing = null;
return false;
}
balancing = GameDataBlockBase<EnemyBalancingDataBlock>.GetBlock(data.BalancingDataId);
return balancing != null;
}
}
public static class GameObjectExtension
{
public static bool TryGetComp<T>(this GameObject obj, out T component)
{
component = obj.GetComponent<T>();
return component != null;
}
public static T AddOrGetComponent<T>(this GameObject obj) where T : Component
{
if (!obj.TryGetComp<T>(out var component))
{
return obj.AddComponent<T>();
}
return component;
}
public static GameObject FindChild(this GameObject obj, string name, bool includeInactive = false)
{
foreach (Transform componentsInChild in obj.GetComponentsInChildren<Transform>(includeInactive))
{
if (!(((Object)((Component)componentsInChild).gameObject).name != name))
{
return ((Component)componentsInChild).gameObject;
}
}
return null;
}
public static GameObject RegexFindChild(this GameObject obj, Regex rx, bool includeInactive = false)
{
foreach (Transform componentsInChild in obj.GetComponentsInChildren<Transform>(includeInactive))
{
if (rx.IsMatch(((Object)componentsInChild).name))
{
return ((Component)componentsInChild).gameObject;
}
}
return null;
}
public static GameObject Instantiate(this GameObject obj, Transform toParent, string name)
{
//IL_0018: 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_002d: Unknown result type (might be due to invalid IL or missing references)
GameObject obj2 = Object.Instantiate<GameObject>(obj);
obj2.transform.parent = toParent;
obj2.transform.localPosition = Vector3.zero;
obj2.transform.localRotation = Quaternion.Euler(Vector3.zero);
((Object)obj2).name = name;
return obj2;
}
}
public static class MonoBehaviourExtension
{
public static Coroutine StartCoroutine(this MonoBehaviour self, IEnumerator routine)
{
return self.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(routine));
}
}
public static class ProjectileTargetingExtension
{
public static bool TryGetOwnerEnemyDataID(this ProjectileBase projectile, out uint id)
{
if ((Object)(object)projectile == (Object)null)
{
id = 0u;
return false;
}
return ProjectileOwnerManager.TryGetDataID(((Object)((Component)projectile).gameObject).GetInstanceID(), out id);
}
public static bool TryGetOwnerEnemyDataID(this ProjectileTargeting projectile, out uint id)
{
if ((Object)(object)projectile == (Object)null)
{
id = 0u;
return false;
}
return ProjectileOwnerManager.TryGetDataID(((Object)((Component)projectile).gameObject).GetInstanceID(), out id);
}
public static bool TryGetOwner(this ProjectileBase projectile, out EnemyAgent agent)
{
if ((Object)(object)projectile == (Object)null)
{
agent = null;
return false;
}
return ProjectileOwnerManager.TryGet(((Object)((Component)projectile).gameObject).GetInstanceID(), out agent);
}
public static bool TryGetOwner(this ProjectileTargeting projectile, out EnemyAgent agent)
{
if ((Object)(object)projectile == (Object)null)
{
agent = null;
return false;
}
return ProjectileOwnerManager.TryGet(((Object)((Component)projectile).gameObject).GetInstanceID(), out agent);
}
}
public static class StringExtension
{
public static bool InvariantEquals(this string str, string strToCompare, bool ignoreCase = false)
{
return str.Equals(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
}
public static bool InvariantContains(this string str, string strToCompare, bool ignoreCase = false)
{
return str.Contains(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
}
public static bool InvariantStartsWith(this string str, string strToCompare, bool ignoreCase = false)
{
return str.StartsWith(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
}
public static bool InvariantEndsWith(this string str, string strToCompare, bool ignoreCase = false)
{
return str.EndsWith(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
}
public static bool EqualsAnyIgnoreCase(this string input, params string[] args)
{
return input.EqualsAny(ignoreCase: true, args);
}
public static bool EqualsAny(this string input, bool ignoreCase, params string[] args)
{
StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
foreach (string value in args)
{
if (input.Equals(value, comparisonType))
{
return true;
}
}
return false;
}
public static bool ContainsAnyIgnoreCase(this string input, params string[] args)
{
return input.ContainsAny(ignoreCase: true, args);
}
public static bool ContainsAny(this string input, bool ignoreCase, params string[] args)
{
StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
foreach (string value in args)
{
if (input.Contains(value, comparisonType))
{
return true;
}
}
return false;
}
}
public static class Logger
{
public static ManualLogSource LogInstance { get; private set; }
public static bool UsingDevMessage { get; private set; }
public static bool UsingVerbose { get; private set; }
public static bool DevLogAllowed => UsingDevMessage;
public static bool VerboseLogAllowed
{
get
{
if (UsingDevMessage)
{
return UsingVerbose;
}
return false;
}
}
internal static void Initialize()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
LogInstance = new ManualLogSource("EEC");
Logger.Sources.Add((ILogSource)(object)LogInstance);
UsingDevMessage = Configuration.UseDebugLog;
UsingVerbose = Configuration.UseVerboseLog;
}
public static void Log(string format, params object[] args)
{
Log(string.Format(format, args));
}
public static void Log(string str)
{
ManualLogSource logInstance = LogInstance;
if (logInstance != null)
{
logInstance.Log((LogLevel)8, (object)str);
}
}
public static void Warning(string format, params object[] args)
{
Warning(string.Format(format, args));
}
public static void Warning(string str)
{
ManualLogSource logInstance = LogInstance;
if (logInstance != null)
{
logInstance.Log((LogLevel)4, (object)str);
}
}
public static void Error(string format, params object[] args)
{
Error(string.Format(format, args));
}
public static void Error(string str)
{
ManualLogSource logInstance = LogInstance;
if (logInstance != null)
{
logInstance.Log((LogLevel)2, (object)str);
}
}
public static void Debug(string format, params object[] args)
{
Debug(string.Format(format, args));
}
public static void Debug(string str)
{
if (UsingDevMessage)
{
ManualLogSource logInstance = LogInstance;
if (logInstance != null)
{
logInstance.LogDebug((object)str);
}
}
}
public static void Verbose(string format, params object[] args)
{
Verbose(string.Format(format, args));
}
public static void Verbose(string str)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
if (!UsingDevMessage || !UsingVerbose)
{
return;
}
ManualLogSource logInstance = LogInstance;
if (logInstance != null)
{
bool flag = default(bool);
BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(10, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(str);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (Verbose)");
}
logInstance.LogDebug(val);
}
}
[Conditional("DEBUG")]
[Obsolete("Logger.Dev call will be removed in release mode!")]
public static void Dev(string format, params object[] args)
{
}
[Conditional("DEBUG")]
[Obsolete("Logger.Dev call will be removed in release mode!")]
public static void Dev(string str)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
ManualLogSource logInstance = LogInstance;
if (logInstance != null)
{
LogLevel val = (LogLevel)8;
LogLevel val2 = val;
bool flag = default(bool);
BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(6, 1, val, ref flag);
if (flag)
{
val3.AppendLiteral("[DEV] ");
val3.AppendFormatted<string>(str);
}
logInstance.Log(val2, val3);
}
}
}
}
namespace EEC.Utils
{
public static class EnemyAnimUtil
{
private static readonly Dictionary<EnemyAnimType, int[]> _animHashsLookup;
private static bool _initialized;
static EnemyAnimUtil()
{
_animHashsLookup = new Dictionary<EnemyAnimType, int[]>(Enum.GetValues(typeof(EnemyAnimType)).Length);
}
internal static void Initialize()
{
if (!_initialized)
{
CacheLookup();
_initialized = true;
}
}
private static void CacheLookup()
{
Type typeFromHandle = typeof(EnemyLocomotion);
foreach (EnemyAnimType value in Enum.GetValues(typeof(EnemyAnimType)))
{
switch (value)
{
case EnemyAnimType.Heartbeats:
_animHashsLookup.Add(value, Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)EnemyLocomotion.s_hashHearbeats));
Logger.Verbose($"{value}, {string.Join(" / ", (IEnumerable<int>)EnemyLocomotion.s_hashHearbeats)}");
continue;
case EnemyAnimType.None:
continue;
}
string text = "s_hash" + Enum.GetName(typeof(EnemyAnimType), value);
PropertyInfo property = typeFromHandle.GetProperty(text, BindingFlags.Static | BindingFlags.Public);
if (property == null)
{
Logger.Warning(text + " does not exist!");
}
else if (property.PropertyType == typeof(int))
{
_animHashsLookup.Add(value, new int[1] { (int)property.GetValue(null) });
Logger.Verbose($"{value}, {property.GetValue(null)}");
}
else if (property.PropertyType == typeof(Il2CppStructArray<int>))
{
int[] array = Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)(Il2CppStructArray<int>)property.GetValue(null));
_animHashsLookup.Add(value, array);
Logger.Verbose($"{value}, {string.Join(" / ", array)}");
}
else
{
Logger.Error($"{value} is not a valid hash property!");
}
}
}
public static void DoAnimationLocal(EnemyAgent agent, EnemyAnimType type, float crossfadeTime, bool pauseAI)
{
if (!_initialized)
{
Logger.Error("EnemyAnimUtil.DoAnimation was called too fast before it got cached!");
}
else
{
if (type == EnemyAnimType.None)
{
return;
}
if (!_animHashsLookup.TryGetValue(type, out var value))
{
Logger.Error($"Cannot find AnimationHash with: {type}");
return;
}
int num = ((value.Length > 1) ? Rand.IndexOf(value) : 0);
agent.Locomotion.m_animator.applyRootMotion = true;
agent.Locomotion.m_animator.CrossFadeInFixedTime(value[num], crossfadeTime);
if (pauseAI && ((AgentAI)agent.AI).m_navMeshAgent.isOnNavMesh)
{
((AgentAI)agent.AI).m_navMeshAgent.isStopped = true;
}
}
}
public static void DoAnimation(EnemyAgent agent, EnemyAnimType type, float crossfadeTime, bool pauseAI)
{
if (!_initialized)
{
Logger.Error("EnemyAnimUtil.DoAnimation was called too fast before it got cached!");
}
else if (type != 0)
{
if (!_animHashsLookup.TryGetValue(type, out var value))
{
Logger.Error($"Cannot find AnimationHash with: {type}");
return;
}
int num = ((value.Length > 1) ? Rand.IndexOf(value) : 0);
NetworkManager.EnemyAnim.Send(new EnemyAnimEvent.Packet
{
enemyID = ((Agent)agent).GlobalID,
crossfadeTime = crossfadeTime,
pauseAI = pauseAI,
animHash = value[num]
});
}
}
}
public enum EnemyAnimType : byte
{
None,
MoveOnGround,
Forward,
Right,
ClimbLadder,
GiveBirth,
HitLights_Fwd,
HitLights_Bwd,
HitLights_Rt,
HitLights_Lt,
HitHeavys_Fwd,
HitHeavys_Bwd,
HitHeavys_Rt,
HitHeavys_Lt,
Screams,
ScreamTurns,
HibernationIn,
Heartbeats,
HibernationWakeups,
HibernationWakeupTurns,
AbilityFires,
AbilityUse,
AbilityUseOut,
MeleeWalkSequences,
MeleeSequences,
Melee180Sequences,
JumpStart,
JumpLand
}
public static class EnemyProperty<T> where T : class, new()
{
private static readonly Dictionary<ushort, T> _properties;
public static IEnumerable<T> Properties => _properties.Values;
static EnemyProperty()
{
_properties = new Dictionary<ushort, T>();
EnemyEvents.Despawn += EnemyDespawn;
LevelEvents.LevelCleanup += OnLevelCleanup;
}
private static void EnemyDespawn(EnemyAgent agent)
{
_properties.Remove(((Agent)agent).GlobalID);
}
private static void OnLevelCleanup()
{
_properties.Clear();
}
public static T RegisterOrGet(EnemyAgent agent)
{
T val = RegisterEnemy(agent);
if (val != null)
{
return val;
}
return Get(agent);
}
public static T RegisterEnemy(EnemyAgent agent)
{
ushort globalID = ((Agent)agent).GlobalID;
if (_properties.ContainsKey(globalID))
{
return null;
}
T val = new T();
_properties.Add(globalID, val);
return val;
}
public static T Get(EnemyAgent agent)
{
return Get(((Agent)agent).GlobalID);
}
public static T Get(ushort id)
{
if (_properties.ContainsKey(id))
{
return _properties[id];
}
return null;
}
public static bool TryGet(EnemyAgent agent, out T property)
{
return TryGet(((Agent)agent).GlobalID, out property);
}
public static bool TryGet(ushort id, out T property)
{
return _properties.TryGetValue(id, out property);
}
}
[Obsolete("Will be moved to ExplosionManager")]
public static class ExplosionUtil
{
public static void MakeExplosion(Vector3 position, float damage, float enemyMulti, float minRange, float maxRange)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: 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)
ExplosionData data = default(ExplosionData);
data.position = position;
data.damage = damage;
data.enemyMulti = enemyMulti;
data.minRange = minRange;
data.maxRange = maxRange;
data.lightColor = ExplosionManager.FlashColor;
ExplosionManager.DoExplosion(data);
}
}
public static class PlayerData
{
public static float MaxHealth { get; internal set; } = 25f;
public static float MaxInfection { get; internal set; } = 1f;
}
public static class Rand
{
public const int InclusiveDoublePrecision = 10000;
public const double InclusiveDoubleConversion = 0.0001;
private static readonly Random _rand = new Random();
public static Random CreateInstance()
{
return new Random(_rand.Next());
}
public static T ItemOf<T>(T[] array)
{
return array[IndexOf(array)];
}
public static int IndexOf(Array array)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if (array.Length == 0)
{
throw new ArgumentException("Array Length was zero!", "array");
}
return _rand.Next(0, array.Length);
}
public static int Index(int length)
{
return _rand.Next(0, length);
}
public static int Range(int min, int max)
{
return _rand.Next(min, max);
}
public static float Range(float min, float max)
{
return NextFloat() * (max - min) + min;
}
public static int RangeInclusive(int min, int max)
{
return _rand.Next(min, max + 1);
}
public static float RangeInclusive(float min, float max)
{
return NextFloatInclusive() * (max - min) + min;
}
public static float NextFloatInclusive()
{
return Math.Clamp((float)NextDoubleInclusive(), 0f, 1f);
}
public static double NextDoubleInclusive()
{
return Math.Clamp((double)_rand.Next(0, 10001) * 0.0001, 0.0, 1.0);
}
public static float NextFloat()
{
return (float)_rand.NextDouble();
}
public static bool CanDoBy(float chance01)
{
return NextFloat() <= chance01;
}
public static int NextInt()
{
return _rand.Next();
}
}
public static class RegexUtil
{
private static readonly Regex _vectorRegex = new Regex("-?[0-9.]+");
public static bool TryParseVectorString(string input, out float[] vectorArray)
{
try
{
MatchCollection matchCollection = _vectorRegex.Matches(input);
int count = matchCollection.Count;
if (count < 1)
{
throw new Exception();
}
vectorArray = new float[count];
for (int i = 0; i < count; i++)
{
Match match = matchCollection[i];
vectorArray[i] = float.Parse(match.Value, CultureInfo.InvariantCulture);
}
return true;
}
catch
{
vectorArray = null;
return false;
}
}
}
}
namespace EEC.Utils.Unity
{
[CallConstructorOnLoad]
public static class InLevelCoroutine
{
[InjectToIl2Cpp]
private sealed class InLevelCoroutineHandler : MonoBehaviour
{
}
private static InLevelCoroutineHandler _handler;
static InLevelCoroutine()
{
AssetEvents.AllAssetLoaded += AssetEvents_AllAssetLoaded;
LevelEvents.LevelCleanup += LevelEvents_LevelCleanup;
SNetEvents.PrepareRecall += SNetEvents_PrepareRecall;
}
private static void AssetEvents_AllAssetLoaded()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if ((Object)(object)_handler == (Object)null)
{
GameObject val = new GameObject();
Object.DontDestroyOnLoad((Object)val);
_handler = val.AddComponent<InLevelCoroutineHandler>();
}
}
private static void SNetEvents_PrepareRecall(eBufferType _)
{
StopAll();
}
private static void LevelEvents_LevelCleanup()
{
StopAll();
}
public static Coroutine Start(IEnumerator coroutine)
{
if ((Object)(object)_handler != (Object)null && GameStateManager.IsInExpedition)
{
return ((MonoBehaviour)_handler).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(coroutine));
}
return null;
}
public static void Stop(Coroutine coroutine)
{
if ((Object)(object)_handler != (Object)null && GameStateManager.IsInExpedition)
{
((MonoBehaviour)_handler).StopCoroutine(coroutine);
}
}
public static void StopAll()
{
if ((Object)(object)_handler != (Object)null)
{
((MonoBehaviour)_handler).StopAllCoroutines();
}
}
}
public struct LazyTimer
{
private float _lastTickTime;
private float _durationInv;
public float PassedTime { get; private set; }
public float Duration { get; private set; }
public bool Done => Progress >= 1f;
public float Progress => Mathf.Clamp01(ProgressUnclamped);
public float ProgressUnclamped
{
get
{
if (Duration != 0f)
{
return PassedTime * _durationInv;
}
return 1f;
}
}
public LazyTimer(float duration)
{
PassedTime = 0f;
Duration = duration;
_durationInv = 1f / duration;
_lastTickTime = GetTime();
}
public void Reset(float newDuration = -1f)
{
PassedTime = 0f;
if (newDuration >= 0f)
{
Duration = newDuration;
_durationInv = 1f / newDuration;
}
_lastTickTime = GetTime();
}
public void Tick()
{
float time = GetTime();
float num = time - _lastTickTime;
_lastTickTime = time;
PassedTime += num;
}
public bool TickAndCheckDone()
{
Tick();
return Done;
}
private static float GetTime()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)GameStateManager.CurrentStateName == 10)
{
return Clock.ExpeditionProgressionTime;
}
return Clock.Time;
}
}
public struct Timer
{
private float _durationInv;
public float PassedTime { get; private set; }
public float Duration { get; private set; }
public bool Done => Progress >= 1f;
public float Progress => Mathf.Clamp01(ProgressUnclamped);
public float ProgressUnclamped
{
get
{
if (Duration != 0f)
{
return PassedTime * _durationInv;
}
return 1f;
}
}
public Timer(float duration)
{
PassedTime = 0f;
Duration = duration;
_durationInv = 1f / duration;
}
public void Reset(float newDuration = -1f)
{
PassedTime = 0f;
if (newDuration >= 0f)
{
Duration = newDuration;
_durationInv = 1f / newDuration;
}
}
public void Tick()
{
PassedTime += Time.deltaTime;
}
public void Tick(float deltaTime)
{
PassedTime += deltaTime;
}
public bool TickAndCheckDone()
{
Tick();
return Done;
}
public bool TickAndCheckDone(float deltaTime)
{
Tick(deltaTime);
return Done;
}
}
public struct DoubleTimer
{
private double _durationInv;
public double PassedTime { get; private set; }
public double Duration { get; private set; }
public bool Done => Progress >= 1.0;
public double Progress => Math.Clamp(0.0, 1.0, ProgressUnclamped);
public double ProgressUnclamped
{
get
{
if (Duration != 0.0)
{
return PassedTime * _durationInv;
}
return 1.0;
}
}
public DoubleTimer(double duration)
{
PassedTime = 0.0;
Duration = duration;
_durationInv = 1.0 / duration;
}
public void Reset(double newDuration = -1.0)
{
PassedTime = 0.0;
if (newDuration >= 0.0)
{
Duration = newDuration;
_durationInv = 1.0 / newDuration;
}
}
public void Tick()
{
PassedTime += Time.deltaTime;
}
public bool TickAndCheckDone()
{
Tick();
return Done;
}
}
public static class WaitFor
{
public static readonly WaitForEndOfFrame EndOfFrame = new WaitForEndOfFrame();
public static readonly WaitForFixedUpdate FixedUpdate = new WaitForFixedUpdate();
public static readonly WaitForSecondsCollection Seconds = new WaitForSecondsCollection();
public static readonly WaitForSecondsRealtimeCollection SecondsRealtime = new WaitForSecondsRealtimeCollection();
}
public sealed class WaitForSecondsCollection : WaitForCollection<WaitForSeconds>
{
protected override WaitForSeconds CreateInstance(float time)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
return new WaitForSeconds(time);
}
}
public sealed class WaitForSecondsRealtimeCollection : WaitForCollection<WaitForSecondsRealtime>
{
protected override WaitForSecondsRealtime CreateInstance(float time)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
return new WaitForSecondsRealtime(time);
}
}
public abstract class WaitForCollection<T>
{
private readonly Dictionary<int, T> _lookup = new Dictionary<int, T>(100);
private T _temp;
public T this[float time]
{
get
{
int key = ((!(time <= 0f)) ? Mathf.RoundToInt(time * 1000f) : 0);
if (_lookup.TryGetValue(key, out _temp))
{
return _temp;
}
_temp = CreateInstance(time);
_lookup[key] = _temp;
return _temp;
}
}
protected abstract T CreateInstance(float time);
}
}
namespace EEC.Utils.Json
{
public static class JSON
{
private static readonly JsonSerializerOptions _setting;
static JSON()
{
_setting = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
IncludeFields = false,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
IgnoreReadOnlyProperties = true
};
_setting.Converters.Add(new ColorConverter());
_setting.Converters.Add(new LocalizedTextConverter());
_setting.Converters.Add(new JsonStringEnumConverter());
_setting.Converters.Add(new Vector2Converter());
_setting.Converters.Add(new Vector3Converter());
if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
{
_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
Logger.Log("PartialData Support Found!");
}
}
public static T Deserialize<T>(string json)
{
return JsonSerializer.Deserialize<T>(json, _setting);
}
public static object Deserialize(Type type, string json)
{
return JsonSerializer.Deserialize(json, type, _setting);
}
public static string Serialize(object value, Type type)
{
return JsonSerializer.Serialize(value, type, _setting);
}
}
}
namespace EEC.Utils.Json.Elements
{
[JsonConverter(typeof(AgentModeTargetConverter))]
public struct AgentModeTarget
{
public static readonly AgentModeTarget All = new AgentModeTarget(AgentModeType.Off | AgentModeType.Hibernate | AgentModeType.Agressive | AgentModeType.Scout | AgentModeType.Patrolling);
public static readonly AgentModeTarget Scout = new AgentModeTarget(AgentModeType.Scout);
public static readonly AgentModeTarget Hibernate = new AgentModeTarget(AgentModeType.Hibernate);
public static readonly AgentModeTarget Agressive = new AgentModeTarget(AgentModeType.Agressive);
public static readonly AgentModeTarget None = new AgentModeTarget(AgentModeType.None);
public AgentModeType Mode;
public AgentModeTarget(AgentModeType modes)
{
Mode = modes;
}
public bool IsMatch(EnemyAgent agent)
{
//IL_0011: 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_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected I4, but got Unknown
if ((Object)(object)agent == (Object)null)
{
return false;
}
AgentMode mode = ((AgentAI)agent.AI).Mode;
return (int)mode switch
{
0 => Mode.HasFlag(AgentModeType.Off),
4 => Mode.HasFlag(AgentModeType.Hibernate),
1 => Mode.HasFlag(AgentModeType.Agressive),
3 => Mode.HasFlag(AgentModeType.Scout),
2 => Mode.HasFlag(AgentModeType.Patrolling),
_ => false,
};
}
}
[Flags]
public enum AgentModeType
{
None = 0,
Off = 1,
Hibernate = 2,
Agressive = 4,
Scout = 8,
Patrolling = 0x10
}
public sealed class AgentModeTargetConverter : JsonConverter<AgentModeTarget>
{
private static readonly char[] _separators = new char[2] { ',', '|' };
public override AgentModeTarget Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
{
string @string = reader.GetString();
string[] array = @string.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
if (array.Length == 0)
{
throw new JsonException("There are no entries in " + @string + "! Are you sure it's in right format?");
}
AgentModeType agentModeType = AgentModeType.None;
string[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
switch (array2[i].ToLowerInvariant().Trim())
{
case "off":
case "dead":
agentModeType |= AgentModeType.Off;
break;
case "agressive":
case "combat":
agentModeType |= AgentModeType.Agressive;
break;
case "hibernate":
case "hibernation":
case "hibernating":
case "sleeping":
agentModeType |= AgentModeType.Hibernate;
break;
case "scout":
case "scoutpatrolling":
agentModeType |= AgentModeType.Scout;
break;
case "patrolling":
agentModeType |= AgentModeType.Patrolling;
break;
}
}
return new AgentModeTarget(agentModeType);
}
case JsonTokenType.Number:
Logger.Warning("Found flag number value in AgentModeTarget! : consider changing it to string.");
return new AgentModeTarget((AgentModeType)reader.GetInt32());
default:
throw new JsonException($"Token type: {reader.TokenType} in AgentModeTarget is not supported!");
}
}
public override void Write(Utf8JsonWriter writer, AgentModeTarget value, JsonSerializerOptions options)
{
writer.WriteNumberValue((int)value.Mode);
}
}
[JsonConverter(typeof(BoolBaseConverter))]
public struct BoolBase
{
public static readonly BoolBase False = new BoolBase(BoolMode.False);
public static readonly BoolBase True = new BoolBase(BoolMode.True);
public static readonly BoolBase Unchanged = new BoolBase(BoolMode.Unchanged);
public BoolMode Mode;
public BoolBase(bool mode)
{
Mode = (mode ? BoolMode.True : BoolMode.False);
}
public BoolBase(BoolMode mode)
{
Mode = mode;
}
public bool GetValue(bool originalValue)
{
switch (Mode)
{
case BoolMode.Unchanged:
return originalValue;
case BoolMode.True:
return true;
case BoolMode.False:
return false;
default:
Logger.Error($"BoolBase.GetValue; Got Unknown Mode: {Mode}!\n{Environment.StackTrace}");
return originalValue;
}
}
}
public enum BoolMode
{
False,
True,
Unchanged
}
public sealed class BoolBaseConverter : JsonConverter<BoolBase>
{
public override bool HandleNull => false;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(BoolBase);
}
public override BoolBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
{
string text = reader.GetString().Trim();
if (text.EqualsAnyIgnoreCase("Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
{
return BoolBase.Unchanged;
}
if (bool.TryParse(text, out var result))
{
return new BoolBase(result);
}
throw new JsonException("Cannot parse BoolBase string: " + text + "! Are you sure it's in right format?");
}
case JsonTokenType.True:
return BoolBase.True;
case JsonTokenType.False:
return BoolBase.False;
default:
throw new JsonException($"BoolBaseJson type: {reader.TokenType} is not implemented!");
}
}
public override void Write(Utf8JsonWriter writer, BoolBase value, JsonSerializerOptions options)
{
switch (value.Mode)
{
case BoolMode.True:
writer.WriteBooleanValue(value: true);
break;
case BoolMode.False:
writer.WriteBooleanValue(value: false);
break;
case BoolMode.Unchanged:
writer.WriteStringValue("Unchanged");
break;
}
writer.WriteCommentValue("BoolBase");
}
}
public sealed class CurveWrapper : Collection<CurveKeyFrame>
{
public const int KEYFRAME_FRAMECOUNT = 20;
public const float KEYFRAME_PROGRESS_INV = 0.05f;
public static readonly CurveWrapper Empty = new CurveWrapper();
private static readonly List<Keyframe> _keys = new List<Keyframe>();
public bool HasSetting => base.Count >= 2;
public bool TryBuildCurve(out AnimationCurve curve)
{
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Expected O, but got Unknown
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
if (base.Count < 2)
{
curve = null;
return false;
}
CurveKeyFrame[] array = this.OrderBy((CurveKeyFrame x) => x.Time).ToArray();
_keys.Clear();
for (int i = 0; i < base.Count - 1; i++)
{
CurveKeyFrame curveKeyFrame = array[i];
CurveKeyFrame curveKeyFrame2 = array[i + 1];
if (curveKeyFrame.Time > 1f || curveKeyFrame.Time < 0f)
{
Logger.Error($"CurveWrapper Time '{curveKeyFrame.Time}' was invalid!, must be range of 0.0 ~ 1.0");
curve = null;
return false;
}
float num = curveKeyFrame2.Time - curveKeyFrame.Time;
float num2 = curveKeyFrame2.Value - curveKeyFrame.Value;
float num3 = num2 / num;
for (int j = 0; j < 20; j++)
{
float num4 = 0.05f * (float)j;
float time = curveKeyFrame.Time + num * num4;
float value = curveKeyFrame.Value + num2 * curveKeyFrame.OutEaseType.Evaluate(num4);
List<Keyframe> keys = _keys;
Keyframe item = default(Keyframe);
((Keyframe)(ref item)).time = time;
((Keyframe)(ref item)).value = value;
((Keyframe)(ref item)).inTangent = num3;
((Keyframe)(ref item)).outTangent = num3;
keys.Add(item);
}
}
curve = new AnimationCurve(_keys.ToArray());
return true;
}
}
public struct CurveKeyFrame
{
public float Time { get; set; }
public float Value { get; set; }
public eEasingType OutEaseType { get; set; }
}
[JsonConverter(typeof(EventWrapperConverter))]
public sealed class EventWrapper : IDisposable
{
private string _json;
private WardenObjectiveEventData _cached;
public EventWrapper(string json)
{
_json = json;
}
public void Cache()
{
_cached = JSON.Deserialize<WardenObjectiveEventData>(_json);
_json = string.Empty;
}
public WardenObjectiveEventData ToEvent()
{
if (_cached == null)
{
Cache();
}
return _cached;
}
public void Dispose()
{
_json = null;
_cached = null;
}
}
internal sealed class EventWrapperConverter : JsonConverter<EventWrapper>
{
public override bool HandleNull => false;
public override EventWrapper Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartObject)
{
using (JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader))
{
return new EventWrapper(jsonDocument.RootElement.ToString());
}
}
throw new JsonException($"{reader.TokenType} is not supported for EventWrapperValue!");
}
public override void Write(Utf8JsonWriter writer, EventWrapper value, JsonSerializerOptions options)
{
}
}
[JsonConverter(typeof(ValueBaseConverter))]
public struct ValueBase
{
public static readonly ValueBase Unchanged = new ValueBase(1f, ValueMode.Rel, fromDefault: true);
public static readonly ValueBase Zero = new ValueBase(0f, ValueMode.Abs, fromDefault: false);
public float Value;
public ValueMode Mode;
public bool FromDefault;
public ValueBase(float value = 1f, ValueMode mode = ValueMode.Rel, bool fromDefault = true)
{
Value = value;
Mode = mode;
FromDefault = fromDefault;
}
public float GetAbsValue(float maxValue, float currentValue)
{
if (Mode == ValueMode.Rel)
{
if (FromDefault)
{
return currentValue * Value;
}
return maxValue * Value;
}
return Value;
}
public float GetAbsValue(float baseValue)
{
if (Mode == ValueMode.Rel)
{
return baseValue * Value;
}
return Value;
}
public int GetAbsValue(int maxValue, int currentValue)
{
return (int)Math.Round(GetAbsValue((float)maxValue, (float)currentValue));
}
public int GetAbsValue(int baseValue)
{
return (int)Math.Round(GetAbsValue((float)baseValue));
}
public override string ToString()
{
return $"[Mode: {Mode}, Value: {Value}]";
}
}
public enum ValueMode
{
Rel,
Abs
}
public sealed class ValueBaseConverter : JsonConverter<ValueBase>
{
public override bool HandleNull => false;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ValueBase);
}
public override ValueBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.Number:
return new ValueBase(reader.GetSingle(), ValueMode.Abs);
case JsonTokenType.StartObject:
{
ValueBase result3 = default(ValueBase);
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return result3;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string? @string = reader.GetString();
reader.Read();
switch (@string.ToLowerInvariant())
{
case "value":
result3.Value = reader.GetSingle();
break;
case "mode":
{
if (Enum.TryParse<ValueMode>(reader.GetString(), out var result4))
{
result3.Mode = result4;
}
break;
}
case "fromdefault":
result3.FromDefault = reader.GetBoolean();
break;
}
}
throw new JsonException("Expected EndObject token");
}
case JsonTokenType.String:
{
string text = reader.GetString().Trim();
bool fromDefault = false;
if (text.EndsWith("of default", StringComparison.OrdinalIgnoreCase))
{
fromDefault = true;
string text2 = text;
text = text2.Substring(0, text2.Length - 10).TrimEnd();
}
if (text.InvariantEndsWith("%"))
{
string text2 = text;
if (float.TryParse(text2.Substring(0, text2.Length - 1).TrimEnd(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result))
{
return new ValueBase(result / 100f, ValueMode.Rel, fromDefault);
}
}
else
{
if (text.EqualsAnyIgnoreCase("Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
{
return new ValueBase(1f, ValueMode.Rel, fromDefault: false);
}
if (float.TryParse(text, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result2))
{
return new ValueBase(result2, ValueMode.Abs);
}
}
throw new JsonException("Cannot parse ValueBase string: " + text + "! Are you sure it's in right format?");
}
default:
throw new JsonException($"ValueBaseJson type: {reader.TokenType} is not implemented!");
}
}
public override void Write(Utf8JsonWriter writer, ValueBase value, JsonSerializerOptions options)
{
switch (value.Mode)
{
case ValueMode.Rel:
{
if (Mathf.Approximately(value.Value, 1f))
{
writer.WriteStringValue("Unchanged");
break;
}
string format = (value.FromDefault ? "{0}% of default" : "{0}%");
writer.WriteStringValue(string.Format(format, value.Value * 100f));
break;
}
case ValueMode.Abs:
writer.WriteStringValue(value.Value.ToString());
break;
}
writer.WriteCommentValue("ValueBase");
}
}
}
namespace EEC.Utils.Json.Converters
{
public sealed class ColorConverter : JsonConverter<Color>
{
public override bool HandleNull => false;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Color);
}
public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: 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_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
Color color = default(Color);
float result = 1f;
switch (reader.TokenType)
{
case JsonTokenType.StartObject:
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return color * result;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string? @string = reader.GetString();
reader.Read();
switch (@string.ToLowerInvariant())
{
case "r":
color.r = reader.GetSingle();
break;
case "g":
color.g = reader.GetSingle();
break;
case "b":
color.b = reader.GetSingle();
break;
case "a":
color.a = reader.GetSingle();
break;
case "multiplier":
result = reader.GetSingle();
break;
}
}
throw new JsonException("Expected EndObject token");
case JsonTokenType.String:
{
string text = reader.GetString().Trim();
string[] array = text.Split("*");
string text2;
switch (array.Length)
{
case 1:
result = 1f;
text2 = array[0].Trim();
break;
case 2:
if (!float.TryParse(array[1].Trim(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result))
{
throw new JsonException("Color multiplier is not valid number! (*): " + text);
}
text2 = array[0].Trim();
break;
default:
throw new JsonException("Color format has more than two Mutiplier (*): " + text);
}
if (ColorUtility.TryParseHtmlString(text2, ref color))
{
return color * result;
}
if (TryParseColor(text, out color))
{
return color * result;
}
throw new JsonException("Color format is not right: " + text);
}
default:
throw new JsonException($"ColorJson type: {reader.TokenType} is not implemented!");
}
}
private static bool TryParseColor(string input, out Color color)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_004a: Unknown result type (might be due to invalid IL or missing references)
if (!RegexUtil.TryParseVectorString(input, out var vectorArray))
{
color = Color.white;
return false;
}
if (vectorArray.Length < 3)
{
color = Color.white;
return false;
}
float num = 1f;
if (vectorArray.Length > 3)
{
num = vectorArray[3];
}
color = new Color(vectorArray[0], vectorArray[1], vectorArray[2], num);
return true;
}
public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
writer.WriteStringValue("#" + ColorUtility.ToHtmlStringRGBA(value));
}
}
public sealed class LocalizedTextConverter : JsonConverter<LocalizedText>
{
public override bool HandleNull => false;
public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
switch (reader.TokenType)
{
case JsonTokenType.String:
{
string @string = reader.GetString();
if (!MTFOPartialDataUtil.TryGetId(@string, out var id))
{
return new LocalizedText
{
Id = 0u,
UntranslatedText = @string
};
}
return new LocalizedText
{
Id = id,
UntranslatedText = null
};
}
case JsonTokenType.Number:
return new LocalizedText
{
Id = reader.GetUInt32(),
UntranslatedText = null
};
default:
throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
}
}
public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<LocalizedText>(writer, value, options);
}
}
public sealed class Vector2Converter : JsonConverter<Vector2>
{
public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//IL_0002: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
Vector2 vector = default(Vector2);
switch (reader.TokenType)
{
case JsonTokenType.StartObject:
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return vector;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string? @string = reader.GetString();
reader.Read();
string text2 = @string.ToLowerInvariant();
if (!(text2 == "x"))
{
if (text2 == "y")
{
vector.y = reader.GetSingle();
}
}
else
{
vector.x = reader.GetSingle();
}
}
throw new JsonException("Expected EndObject token");
case JsonTokenType.String:
{
string text = reader.GetString().Trim();
if (TryParseVector2(text, out vector))
{
return vector;
}
throw new JsonException("Vector2 format is not right: " + text);
}
default:
throw new JsonException($"Vector2Json type: {reader.TokenType} is not implemented!");
}
}
private static bool TryParseVector2(string input, out Vector2 vector)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if (!RegexUtil.TryParseVectorString(input, out var vectorArray))
{
vector = Vector2.zero;
return false;
}
if (vectorArray.Length < 2)
{
vector = Vector2.zero;
return false;
}
vector = new Vector2(vectorArray[0], vectorArray[1]);
return true;
}
public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
writer.WriteStringValue($"({value.x} {value.y})");
}
}
public sealed class Vector3Converter : JsonConverter<Vector3>
{
public override bool HandleNull => false;
public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//IL_0002: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
Vector3 vector = default(Vector3);
switch (reader.TokenType)
{
case JsonTokenType.StartObject:
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return vector;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string? @string = reader.GetString();
reader.Read();
switch (@string.ToLowerInvariant())
{
case "x":
vector.x = reader.GetSingle();
break;
case "y":
vector.y = reader.GetSingle();
break;
case "z":
vector.z = reader.GetSingle();
break;
}
}
throw new JsonException("Expected EndObject token");
case JsonTokenType.String:
{
string text = reader.GetString().Trim();
if (TryParseVector3(text, out vector))
{
return vector;
}
throw new JsonException("Vector3 format is not right: " + text);
}
default:
throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!");
}
}
private static bool TryParseVector3(string input, out Vector3 vector)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if (!RegexUtil.TryParseVectorString(input, out var vectorArray))
{
vector = Vector3.zero;
return false;
}
if (vectorArray.Length < 3)
{
vector = Vector3.zero;
return false;
}
vector = new Vector3(vectorArray[0], vectorArray[1], vectorArray[2]);
return true;
}
public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
writer.WriteStringValue($"({value.x} {value.y} {value.z})");
}
}
}
namespace EEC.Utils.Integrations
{
public static class MTFOPartialDataUtil
{
public delegate bool TryGetDelegate(string guid, out uint id);
public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";
private static readonly TryGetDelegate _tryGetIDDelegate;
public static JsonConverter PersistentIDConverter { get; private set; }
public static JsonConverter LocalizedTextConverter { get; private set; }
public static bool IsLoaded { get; private set; }
public static bool Initialized { get; private set; }
public static string PartialDataPath { get; private set; }
public static string ConfigPath { get; private set; }
static MTFOPartialDataUtil()
{
PersistentIDConverter = null;
LocalizedTextConverter = null;
IsLoaded = false;
Initialized = false;
PartialDataPath = string.Empty;
ConfigPath = string.Empty;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
{
return;
}
try
{
Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type[] types = obj.GetTypes();
Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
if ((object)type == null)
{
throw new Exception("Unable to Find PersistentIDConverter Class");
}
Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class");
PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
if ((object)property == null)
{
throw new Exception("Unable to Find Property: Initialized");
}
if ((object)property2 == null)
{
throw new Exception("Unable to Find Property: PartialDataPath");
}
if ((object)property3 == null)
{
throw new Exception("Unable to Find Field: ConfigPath");
}
Initialized = (bool)property.GetValue(null);
PartialDataPath = (string)property2.GetValue(null);
ConfigPath = (string)property3.GetValue(null);
_tryGetIDDelegate = (TryGetDelegate)(types.First((Type t) => t.Name == "PersistentIDManager") ?? throw new Exception("Unable to Find PersistentIDManager Class")).GetMethod("TryGetId", BindingFlags.Static | BindingFlags.Public).CreateDelegate(typeof(TryGetDelegate));
PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
IsLoaded = true;
}
catch (Exception value2)
{
Logger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
}
}
public static bool TryGetId(string guid, out uint id)
{
if (!IsLoaded)
{
id = 0u;
return false;
}
if (!Initialized)
{
id = 0u;
return false;
}
if (_tryGetIDDelegate == null)
{
id = 0u;
return false;
}
return _tryGetIDDelegate(guid, out id);
}
}
public static class MTFOUtil
{
public const string PLUGIN_GUID = "com.dak.MTFO";
public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;
public static readonly Version MTFO_FORBID;
public static readonly Version MTFO_V5;
public static string GameDataPath { get; private set; }
public static string CustomPath { get; private set; }
public static bool HasCustomContent { get; private set; }
public static bool IsLoaded { get; private set; }
public static bool HasHotReload { get; private set; }
public static FieldInfo HotReloaderField { get; private set; }
public static event Action HotReloaded;
static MTFOUtil()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
MTFO_FORBID = new Version("4.2.0", false);
MTFO_V5 = new Version("4.3.5", false);
GameDataPath = string.Empty;
CustomPath = string.Empty;
HasCustomContent = false;
IsLoaded = false;
HasHotReload = false;
HotReloaderField = null;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
{
return;
}
Version version = value.Metadata.Version;
if (version >= MTFO_V5)
{
InitMTFO_V5(value);
return;
}
if (version > MTFO_FORBID)
{
InitMTFO_V4(value);
return;
}
throw new Exception("You are using unsupported version of MTFO!");
}
private static void InitMTFO_V4(PluginInfo info)
{
try
{
Assembly obj = ((info == null) ? null : info.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
if ((object)field == null)
{
throw new Exception("Unable to Find Field: GameDataPath");
}
if ((object)field2 == null)
{
throw new Exception("Unable to Find Field: CustomPath");
}
if ((object)field3 == null)
{
throw new Exception("Unable to Find Field: HasCustomContent");
}
GameDataPath = (string)field.GetValue(null);
CustomPath = (string)field2.GetValue(null);
HasCustomContent = (bool)field3.GetValue(null);
IsLoaded = true;
}
catch (Exception value)
{
Logger.Error($"Exception thrown while reading path from DataDumper (MTFO V{info.Metadata.Version}): \n{value}");
}
}
private static void InitMTFO_V5(PluginInfo info)
{
try
{
Assembly obj = ((info == null) ? null : info.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type[] types = obj.GetTypes();
Type obj2 = types.First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
PropertyInfo? property = obj2.GetProperty("IsHotReloadEnabled", BindingFlags.Static | BindingFlags.Public);
if ((object)field == null)
{
throw new Exception("Unable to Find Field: GameDataPath");
}
if ((object)field2 == null)
{
throw new Exception("Unable to Find Field: CustomPath");
}
if ((object)field3 == null)
{
throw new Exception("Unable to Find Field: HasCustomContent");
}
if ((object)field3 == null)
{
throw new Exception("Unable to Find Field: HasCustomContent");
}
if ((object)property == null)
{
throw new Exception("Unable to Find Property: IsHotReloadEnabled");
}
GameDataPath = (string)field.GetValue(null);
CustomPath = (string)field2.GetValue(null);
HasCustomContent = (bool)field3.GetValue(null);
HasHotReload = (bool)property.GetValue(null);
if (HasHotReload)
{
HotReloaderField = (types.First((Type t) => t.Name == "HotReloader") ?? throw new Exception("Unable to Find HotReloader Class")).GetField("Current", BindingFlags.Static | BindingFlags.Public) ?? throw new Exception("Unable to Find Field: Current");
}
IsLoaded = true;
}
catch (Exception value)
{
Logger.Error($"Exception thrown while reading metadata from MTFO (V{info.Metadata.Version}): \n{value}");
}
}
internal static void OnHotReloaded(int _)
{
MTFOUtil.HotReloaded?.Invoke();
}
}
}
namespace EEC.Utils.Integrations.Inject
{
[HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")]
internal static class Inject_CM_PageRundown_New
{
private static bool _isInjected;
[HarmonyWrapSafe]
internal static void Postfix()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
if (_isInjected)
{
return;
}
object obj = MTFOUtil.HotReloaderField?.GetValue(null) ?? null;
if (obj != null)
{
FieldInfo field = obj.GetType().GetField("button", BindingFlags.Instance | BindingFlags.NonPublic);
if ((object)field != null)
{
((CM_Item)field.GetValue(obj)).OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)MTFOUtil.OnHotReloaded);
_isInjected = true;
}
}
}
}
}
namespace EEC.Patches
{
[CallConstructorOnLoad]
public static class PatchManager
{
static PatchManager()
{
ConfigManager.EnemyPrefabBuilt += PrefabBuilt;
}
private static void PrefabBuilt(EnemyAgent agent, EnemyDataBlock enemyData)
{
if (ConfigManager.Global.UsingFlyerStuckCheck && enemyData.TryGetBehaviourBlock(out var behaviour) && behaviour.IsFlyer)
{
((Component)agent).gameObject.AddComponent<FlyerStuckHandler>().Agent.Value = agent;
Logger.Debug($"Added Flyer Check to {((GameDataBlockBase<EnemyDataBlock>)(object)enemyData).persistentID}");
}
}
}
}
namespace EEC.Patches.Inject
{
[HarmonyPatch(typeof(Dam_SyncedDamageBase))]
internal static class Inject_Patch_HealerEnemies
{
[HarmonyPatch("TentacleAttackDamage")]
[HarmonyPrefix]
[HarmonyWrapSafe]
internal static bool Pre_TentacleDamage(float dam, Dam_SyncedDamageBase __instance)
{
return DoHealer(dam, __instance);
}
[HarmonyPatch("MeleeDamage")]
[HarmonyPrefix]
[HarmonyWrapSafe]
internal static bool Pre_PunchDamage(float dam, Dam_SyncedDamageBase __instance)
{
return DoHealer(dam, __instance);
}
[HarmonyPatch("ExplosionDamage")]
[HarmonyPrefix]
[HarmonyWrapSafe]
internal static bool Pre_ExplosionDamage(float dam, Dam_SyncedDamageBase __instance)
{
return DoHealer(dam, __instance);
}
[HarmonyPatch("ShooterProjectileDamage")]
[HarmonyPrefix]
[HarmonyWrapSafe]
internal static bool Pre_ShooterProjectileDamage(float dam, Dam_SyncedDamageBase __instance)
{
return DoHealer(dam, __instance);
}
private static bool DoHealer(float dam, Dam_SyncedDamageBase damBase)
{
if (dam >= 0f)
{
return true;
}
if (SNet.IsMaster)
{
float num = Math.Abs(dam);
damBase.SendSetHealth(Math.Min(damBase.Health + num, damBase.HealthMax));
}
return false;
}
}
}
namespace EEC.Patches.Handlers
{
[InjectToIl2Cpp]
internal sealed class FlyerStuckHandler : MonoBehaviour
{
public Il2CppReferenceField<EnemyAgent> Agent;
public float UpdateInterval = float.MaxValue;
public int RetryCount = int.MaxValue;
private EnemyAgent _agent;
private Vector3 _firstPosition;
private Vector2 _lastGoalXZ;
private Timer _timer;
private int _tryCount = -1;
private bool _shouldCheck = true;
private void Start()
{
if (!SNet.IsMaster)
{
((Behaviour)this).enabled = false;
return;
}
_agent = Il2CppReferenceField<EnemyAgent>.op_Implicit(Agent);
if ((Object)(object)_agent == (Object)null)
{
((Behaviour)this).enabled = false;
return;
}
if (!_agent.EnemyBehaviorData.IsFlyer)
{
((Behaviour)this).enabled = false;
return;
}
UpdateInterval = ConfigManager.Global.FlyerStuck_Interval;
RetryCount = ConfigManager.Global.FlyerStuck_Retry;
}
private void FixedUpdate()
{
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: 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_001c: Invalid comparison between Unknown and I4
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
if (_shouldCheck)
{
if ((int)((AgentAI)_agent.AI).Mode != 1 || !_timer.TickAndCheckDone())
{
return;
}
_timer.Reset(UpdateInterval);
if (_tryCount == -1)
{
_firstPosition = _agent.Position;
_tryCount = 0;
}
else if (Vector3.Distance(_firstPosition, _agent.Position) < 0.1f)
{
_tryCount++;
if (_tryCount >= RetryCount)
{
Logger.Debug("Flyer was stuck in Place!");
((Agent)_agent).m_replicator.Despawn();
}
}
else
{
_shouldCheck = false;
}
return;
}
Vector3 navmeshAgentGoal = _agent.AI.NavmeshAgentGoal;
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(navmeshAgentGoal.x, navmeshAgentGoal.z);
Vector2 val2 = val - _lastGoalXZ;
if (((Vector2)(ref val2)).sqrMagnitude < 0.1f)
{
if (((MachineState<EB_StateBase>)(object)((StateMachine<EB_StateBase>)(object)_agent.AI.m_behaviour).CurrentState).ENUM_ID == 5)
{
_tryCount = -1;
_shouldCheck = true;
}
}
else
{
_tryCount = -1;
_shouldCheck = false;
}
_lastGoalXZ = val;
}
private void OnDestroy()
{
Agent = null;
}
}
[Flags]
public enum ShitpostType
{
ForceOff = -1,
Enable = 0,
Dinnerbone = 1
}
}
namespace EEC.Patches.Handlers.Yes.Yes.Yes.Yes
{
[CallConstructorOnLoad]
public static class Shitpost2022
{
static Shitpost2022()
{
if (Configuration.CanShitpostOf(ShitpostType.Dinnerbone))
{
EnemyEvents.Spawned += EnemyEvents_Spawned;
}
}
private static void EnemyEvents_Spawned(EnemyAgent agent)
{
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
NavMarker marker = GuiManager.NavMarkerLayer.PlaceCustomMarker((NavMarkerOption)16, agent.ModelRef.m_markerTagAlign, "<alpha=#44>Dinnerbone", 0f, false);
marker.SetVisualStates((NavMarkerOption)0, (NavMarkerOption)0, (NavMarkerOption)0, (NavMarkerOption)0);
marker.m_titleSubObj.SetEnabled(false);
marker.SetPinEnabled(false);
((MonoBehaviour)(object)agent.AI).StartCoroutine(UpdateMarker(agent, marker));
agent.AddOnDeadOnce(delegate
{
GuiManager.NavMarkerLayer.RemoveMarker(marker);
});
Transform boneTransform = agent.Anim.GetBoneTransform((HumanBodyBones)0);
if ((Object)(object)boneTransform != (Object)null)
{
BoneOffsetHandler boneOffsetHandler = ((Component)boneTransform).gameObject.AddComponent<BoneOffsetHandler>();
boneOffsetHandler.Animator = Il2CppReferenceField<Animator>.op_Implicit(agent.Anim);
boneOffsetHandler.RotationOffset = Il2CppValueField<Vector3>.op_Implicit(new Vector3(0f, 180f, 0f));
}
else
{
agent.MainModelTransform.Rotate(Vector3.forward, 180f);
}
}
private static IEnumerator UpdateMarker(EnemyAgent agent, NavMarker marker)
{
WaitForSeconds yielder = WaitFor.Seconds[0.25f];
bool enabled = false;
yield return yielder;
while (((Agent)agent).Alive)
{
if ((int)marker.m_currentState == 2)
{
Vector3 val = agent.Position - ((Component)CameraManager.GetCurrentCamera()).transform.position;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
if (!enabled && sqrMagnitude <= 64f)
{
marker.m_titleSubObj.SetEnabled(true);
enabled = true;
}
else if (enabled && sqrMagnitude > 64f)
{
marker.m_titleSubObj.SetEnabled(false);
enabled = false;
}
}
else if (enabled)
{
marker.m_titleSubObj.SetEnabled(false);
enabled = false;
}
yield return yielder;
}
}
}
}
namespace EEC.Networking
{
public static class NetworkManager
{
public const ulong LOWEST_STEAMID64 = 76561197960265729uL;
public static EnemyAgentModeReplicator EnemyAgentModeState { get; private set; } = new EnemyAgentModeReplicator();
public static EnemyHealthInfoReplicator EnemyHealthState { get; private set; } = new EnemyHealthInfoReplicator();
public static EnemyAnimEvent EnemyAnim { get; private set; } = new EnemyAnimEvent();
internal static void Initialize()
{
EnemyEvents.Spawned += EnemySpawned;
EnemyEvents.Despawn += EnemyDespawn;
EnemyAgentModeState.Initialize();
EnemyHealthState.Initialize();
EnemyAnim.Setup();
}
private static void EnemySpawned(EnemyAgent agent)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (agent.TryGetSpawnData(out var spawnData))
{
EnemyAgentModeReplicator.State state = default(EnemyAgentModeReplicator.State);
state.mode = spawnData.mode;
EnemyAgentModeReplicator.State startState = state;
EnemyAgentModeState.Register(((Agent)agent).GlobalID, startState, delegate(EnemyAgentModeReplicator.State newState)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
ConfigManager.FireAgentModeChangedEvent(agent, newState.mode);
});
}
EnemyHealthInfoReplicator.State state2 = default(EnemyHealthInfoReplicator.State);
state2.maxHealth = ((Dam_SyncedDamageBase)agent.Damage).HealthMax;
state2.health = ((Dam_SyncedDamageBase)agent.Damage).Health;
EnemyHealthInfoReplicator.State startState2 = state2;
EnemyHealthState.Register(((Agent)agent).GlobalID, startState2, delegate(EnemyHealthInfoReplicator.State newState)
{
EnemyDamageEvents.OnHealthUpdated(agent, newState.maxHealth, newState.health);
});
((MonoBehaviour)(object)agent.AI).StartCoroutine(CheckHealth(agent));
}
private static IEnumerator CheckHealth(EnemyAgent agent)
{
WaitForFixedUpdate fixedUpdateYielder = WaitFor.FixedUpdate;
float health = ((Dam_SyncedDamageBase)agent.Damage).Health;
while (true)
{
if (SNet.IsMaster)
{
float health2 = ((Dam_SyncedDamageBase)agent.Damage).Health;
if (!Mathf.Approximately(health, health2))
{
EnemyHealthState.UpdateInfo(agent);
health = health2;
}
}
yield return fixedUpdateYielder;
}
}
private static void EnemyDespawn(EnemyAgent agent)
{
EnemyAgentModeState.Deregister(((Agent)agent).GlobalID);
}
}
public delegate void SNetRecallEvent(eBufferType bufferType);
public delegate void SNetPlayerEvent(SNet_Player player);
public delegate void SNetPlayerEventWithReason(SNet_Player player, SNet_PlayerEventReason reason);
public static class SNetEvents
{
public static event SNetPlayerEvent AgentSpawned;
public static event SNetRecallEvent PrepareRecall;
public static event SNetRecallEvent RecallComplete;
internal static void OnAgentSpawned(SNet_Player player)
{
SNetEvents.AgentSpawned?.Invoke(player);
}
internal static void OnPrepareRecall(eBufferType bufferType)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
SNetEvents.PrepareRecall?.Invoke(bufferType);
}
internal static void OnRecallComplete(eBufferType bufferType)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
SNetEvents.RecallComplete?.Invoke(bufferType);
}
}
internal struct ReplicatorPayload
{
public ushort key;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public byte[] stateBytes;
public void Serialize<T>(T stateData) where T : struct
{
int num = Marshal.SizeOf(stateData);
if (num >= 30)
{
throw new ArgumentException("StateData Exceed size of 30 : Unable to Serialize", "T");
}
byte[] destination = new byte[30];
IntPtr intPtr = Marshal.AllocHGlobal(num);
Marshal.StructureToPtr(stateData, intPtr, fDeleteOld: false);
Marshal.Copy(intPtr, destination, 0, num);
Marshal.FreeHGlobal(intPtr);
stateBytes = destination;
}
public T Deserialize<T>()
{
int num = Marshal.SizeOf(typeof(T));
if (num > stateBytes.Length)
{
throw new ArgumentException("StateData Exceed size of 30 : Unable to Deserialize", "T");
}
IntPtr intPtr = Marshal.AllocHGlobal(num);
Marshal.Copy(stateBytes, 0, intPtr, num);
T result = (T)Marshal.PtrToStructure(intPtr, typeof(T));
Marshal.FreeHGlobal(intPtr);
return result;
}
}
public sealed class StateContext<S> where S : struct
{
public bool Registered;
public Action<S> OnStateChanged;
public S State;
}
public abstract class StateReplicator<S> where S : struct
{
private static readonly Dictionary<ushort, StateContext<S>> _lookup = new Dictionary<ushort, StateContext<S>>(500);
private bool _isInitialized;
public abstract bool ClearOnLevelCleanup { get; }
public abstract string GUID { get; }
public bool IsSetup => _isInitialized;
public string SetStateName { get; private set; } = string.Empty;
public string ChangeRequestName { get; private set; } = string.Empty;
public void Initialize()
{
if (!_isInitialized)
{
SNetEvents.AgentSpawned += SNetEvents_AgentSpawned;
if (ClearOnLevelCleanup)
{
LevelEvents.LevelCleanup += Clear;
}
SetStateName = "EECRp" + GUID + "S";
ChangeRequestName = "EECRp" + GUID + "R";
NetworkAPI.RegisterEvent<ReplicatorPayload>(SetStateName, (Action<ulong, ReplicatorPayload>)ReceiveSetState_FromMaster);
NetworkAPI.RegisterEvent<ReplicatorPayload>(ChangeRequestName, (Action<ulong, ReplicatorPayload>)ReceiveSetState_FromClient);
_isInitialized = true;
}
}
private void SNetEvents_AgentSpawned(SNet_Player player)
{
if (!SNet.IsMaster)
{
return;
}
foreach (KeyValuePair<ushort, StateContext<S>> item in _lookup)
{
ReplicatorPayload replicatorPayload = default(ReplicatorPayload);
replicatorPayload.key = item.Key;
ReplicatorPayload replicatorPayload2 = replicatorPayload;
replicatorPayload2.Serialize(item.Value.State);
NetworkAPI.InvokeEvent<ReplicatorPayload>(SetStateName, replicatorPayload2, player, (SNet_ChannelType)2);
}
}
public void Register(ushort id, S startState, Action<S> onChanged = null)
{
if (TryGetContext(id, out var context))
{
if (context.Registered)
{
return;
}
context.Registered = true;
context.OnStateChanged = onChanged;
}
else
{
context = new StateContext<S>
{
Registered = true,
OnStateChanged = onChanged,
State = startState
};
_lookup[id] = context;
}
context.OnStateChanged?.Invoke(context.State);
OnStateChange(id, context.State);
}
public void Deregister(ushort id)
{
if (TryGetContext(id, out var context) && context.Registered)
{
_lookup.Remove(id);
}
}
private void Clear()
{
_lookup.Clear();
}
public void SetState(ushort id, S state)
{
if (TryGetContext(id, out var context) && context.Registered)
{
ReplicatorPayload replicatorPayload = default(ReplicatorPayload);
replicatorPayload.key = id;
ReplicatorPayload replicatorPayload2 = replicatorPayload;
replicatorPayload2.Serialize(state);
if (SNet.IsMaster)
{
NetworkAPI.InvokeEvent<ReplicatorPayload>(SetStateName, replicatorPayload2, (SNet_ChannelType)2);
context.State = state;
ReceiveSetState_FromMaster(SNet.Master.Lookup, replicatorPayload2);
}
else if (SNet.HasMaster)
{
NetworkAPI.InvokeEvent<ReplicatorPayload>(ChangeRequestName, replicatorPayload2, SNet.Master, (SNet_ChannelType)2);
context.State = state;
}
}
}
public bool TryGetState(ushort id, out S state)
{
if (!TryGetContext(id, out var context) || !context.Registered)
{
Logger.Warning($"KEY: {id} has not registered; backing to Default");
state = default(S);
return false;
}
state = context.State;
return true;
}
private void ReceiveSetState_FromMaster(ulong sender, ReplicatorPayload statePacket)
{
ushort key = statePacket.key;
S val = statePacket.Deserialize<S>();
if (TryGetContext(key, out var context))
{
context.State = val;
if (context.Registered)
{
context.OnStateChanged?.Invoke(val);
OnStateChange(key, val);
}
}
else
{
_lookup[key] = new StateContext<S>
{
Registered = false,
State = val
};
}
}
private void ReceiveSetState_FromClient(ulong sender, ReplicatorPayload statePacket)
{
if (SNet.IsMaster)
{
SetState(statePacket.key, statePacket.Deserialize<S>());
}
}
public bool TryGetContext(ushort id, out StateContext<S> context)
{
return _lookup.TryGetValue(id, out context);
}
public virtual void OnStateChange(ushort id, S newState)
{
}
}
public abstract class SyncedEvent<T> where T : struct
{
public delegate void ReceiveHandler(T packet);
private bool _isSetup;
public abstract string GUID { get; }
public bool IsSetup => _isSetup;
public string EventName { get; private set; } = string.Empty;
public event ReceiveHandler OnReceive;
public event ReceiveHandler OnReceiveLocal;
public void Setup()
{
if (!_isSetup)
{
EventName = "EEC" + GUID;
NetworkAPI.RegisterEvent<T>(EventName, (Action<ulong, T>)ReceiveClient_Callback);
_isSetup = true;
}
}
public void Send(T packetData, SNet_Player target = null)
{
if ((Object)(object)target != (Object)null)
{
NetworkAPI.InvokeEvent<T>(EventName, packetData, target, (SNet_ChannelType)2);
}
else
{
NetworkAPI.InvokeEvent<T>(EventName, packetData, (SNet_ChannelType)2);
}
ReceiveLocal_Callback(packetData);
}
private void ReceiveLocal_Callback(T packet)
{
ReceiveLocal(packet);
this.OnReceiveLocal?.Invoke(packet);
Receive(packet);
this.OnReceive?.Invoke(packet);
}
private void ReceiveClient_Callback(ulong sender, T packet)
{
Receive(packet);
this.OnReceive?.Invoke(packet);
}
protected virtual void ReceiveLocal(T packet)
{
}
protected virtual void Receive(T packet)
{
}
}
internal struct SyncedPlayerEventPayload
{
public ulong lookup;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public byte[] packetBytes;
public void Serialize<T>(T packet) where T : struct
{
int num = Marshal.SizeOf(packet);
if (num >= 30)
{
throw new ArgumentException("PacketData Exceed size of 30 : Unable to Serialize", "T");
}
byte[] destination = new byte[30];
IntPtr intPtr = Marshal.AllocHGlobal(num);
Marshal.StructureToPtr(packet, intPtr, fDeleteOld: false);
Marshal.Copy(intPtr, destination, 0, num);
Marshal.FreeHGlobal(intPtr);
packetBytes = destination;
}
public T Deserialize<T>()
{
int num = Marshal.SizeOf(typeof(T));
if (num > packetBytes.Length)
{
throw new ArgumentException("Packet Exceed size of 30 : Unable to Deserialize", "T");
}
IntPtr intPtr = Marshal.AllocHGlobal(num);
Marshal.Copy(packetBytes, 0, intPtr, num);
T result = (T)Marshal.PtrToStructure(intPtr, typeof(T));
Marshal.FreeHGlobal(intPtr);
return result;
}
public bool TryGetPlayer(out SNet_Player player)
{
if (lookup == 0L)
{
player = null;
return false;
}
if (lookup < 76561197960265729L)
{
return SNet.Core.TryGetPlayerBot((int)lookup - 1, ref player);
}
return SNet.Core.TryGetPlayer(lookup, ref player, false);
}
}
public abstract class SyncedPlayerEvent<T> where T : struct
{
public delegate void ReceiveHandler(T packet, SNet_Player receivedPlayer);
private bool _isSetup;
public abstract string GUID { get; }
public abstract bool SendToTargetOnly { get; }
public abstract bool AllowBots { get; }
public bool IsSetup => _isSetup;
public string EventName { get; private set; } = string.Empty;
public event ReceiveHandler OnReceive;
public void Setup()
{
if (!_isSetup)
{
EventName = "EECp" + GUID;
NetworkAPI.RegisterEvent<SyncedPlayerEventPayload>(EventName, (Action<ulong, SyncedPlayerEventPayload>)Received_Callback);
_isSetup = true;
}
}
public bool TryGetPlayerAgent(SNet_Player player, out PlayerAgent agent)
{
if (!player.HasPlayerAgent)
{
agent = null;
return false;
}
agent = ((Il2CppObjectBase)player.m_playerAgent).TryCast<PlayerAgent>();
return (Object)(object)agent != (Object)null;
}
public void SendToPlayers(T packetData, params PlayerAgent[] agents)
{
foreach (PlayerAgent val in agents)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Owner == (Object)null))
{
SendToPlayer(packetData, val.Owner);
}
}
}
public void SendToPlayers(T packetData, params SNet_Player[] players)
{
foreach (SNet_Player player in players)
{
SendToPlayer(packetData, player);
}
}
public void SendToPlayer(T packetData, PlayerAgent agent)
{
if (!((Object)(object)agent == (Object)null) && !((Object)(object)agent.Owner == (Object)null))
{
SendToPlayer(packetData, agent.Owner);
}
}
public void SendToPlayer(T packetData, SNet_Player player)
{
if ((Object)(object)player == (Object)null)
{
Logger.Error(GetType().Name + " - SyncedPlayerEvent player was null!");
return;
}
if (player.Lookup == 0L)
{
Logger.Error(GetType().Name + " - SyncedPlayerEvent lookup for player was 0!");
return;
}
SyncedPlayerEventPayload syncedPlayerEventPayload = default(SyncedPlayerEventPayload);
syncedPlayerEventPayload.lookup = player.Lookup;
SyncedPlayerEventPayload syncedPlayerEventPayload2 = syncedPlayerEventPayload;
syncedPlayerEventPayload2.Serialize(packetData);
if (player.IsBot)
{
if (AllowBots)
{
if (SNet.IsMaster)
{
Received_Callback(SNet.Master.Lookup, syncedPlayerEventPayload2);
}
else if (SNet.HasMaster)
{
NetworkAPI.InvokeEvent<SyncedPlayerEventPayload>(EventName, syncedPlayerEventPayload2, SNet.Master, (SNet_ChannelType)2);
}
}
}
else if (player.IsLocal)
{
Received_Callback(player.Lookup, syncedPlayerEventPayload2);
}
else if (SendToTargetOnly)
{
NetworkAPI.InvokeEvent<SyncedPlayerEventPayload>(EventName, syncedPlayerEventPayload2, player, (SNet_ChannelType)2);
}
else
{
NetworkAPI.InvokeEvent<SyncedPlayerEventPayload>(EventName, syncedPlayerEventPayload2, (SNet_ChannelType)2);
}
}
private void Received_Callback(ulong sender, SyncedPlayerEventPayload payload)
{
if (payload.TryGetPlayer(out var player) && (player.IsBot ? AllowBots : (player.IsLocal || !SendToTargetOnly)))
{
Received(payload.Deserialize<T>(), player);
}
}
private void Received(T packet, SNet_Player receivedPlayer)
{
Receive(packet, receivedPlayer);
this.OnReceive?.Invoke(packet, receivedPlayer);
}
protected virtual void Receive(T packet, SNet_Player receivedPlayer)
{
}
}
}
namespace EEC.Networking.Replicators
{
public sealed class EnemyAgentModeReplicator : StateReplicator<EnemyAgentModeReplicator.State>
{
public struct State
{
public AgentMode mode;
}
public override bool ClearOnLevelCleanup => true;
public override string GUID => "EMD";
public void SetState(ushort id, AgentMode newMode)
{
//IL_000c: 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)
base.SetState(id, new State
{
mode = newMode
});
}
}
public sealed class EnemyHealthInfoReplicator : StateReplicator<EnemyHealthInfoReplicator.State>
{
public struct State
{
public float maxHealth;
public float health;
}
public override bool ClearOnLevelCleanup => true;
public override string GUID => "EHI";
public void UpdateInfo(EnemyAgent agent)
{
SetState(((Agent)agent).GlobalID, new State
{
maxHealth = ((Dam_SyncedDamageBase)agent.Damage).HealthMa