using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using AIGraph;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.IL2CPP;
using BepInEx.IL2CPP.Hook;
using BepInEx.IL2CPP.Utils;
using BepInEx.Logging;
using GTFO.API.Attributes;
using GTFO.API.Components;
using GTFO.API.Extensions;
using GTFO.API.Impl;
using GTFO.API.JSON;
using GTFO.API.JSON.Converters;
using GTFO.API.Native;
using GTFO.API.Resources;
using GTFO.API.Utilities;
using GTFO.API.Utilities.Impl;
using GTFO.API.Wrappers;
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.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using ItemSetup;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;
using UnityEngine.Analytics;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("GTFO-API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.1")]
[assembly: AssemblyInformationalVersion("0.3.1+git4b21c34-main")]
[assembly: AssemblyProduct("GTFO-API")]
[assembly: AssemblyTitle("GTFO-API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.1.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace GTFO.API
{
internal static class APILogger
{
private static readonly ManualLogSource _logger;
static APILogger()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
_logger = new ManualLogSource("GTFO-API");
Logger.Sources.Add((ILogSource)(object)_logger);
}
private static string Format(string module, object msg)
{
return $"[{module}]: {msg}";
}
public static void Info(string module, object data)
{
_logger.LogMessage((object)Format(module, data));
}
public static void Verbose(string module, object data)
{
}
public static void Debug(string module, object data)
{
_logger.LogDebug((object)Format(module, data));
}
public static void Warn(string module, object data)
{
_logger.LogWarning((object)Format(module, data));
}
public static void Error(string module, object data)
{
_logger.LogError((object)Format(module, data));
}
}
[API("Asset")]
public static class AssetAPI
{
internal static ConcurrentDictionary<string, Object> s_RegistryCache = new ConcurrentDictionary<string, Object>();
public static ApiStatusInfo Status => APIStatus.Asset;
public static event Action OnStartupAssetsLoaded;
public static event Action OnAssetBundlesLoaded;
public static event Action OnImplReady;
public static bool ContainsAsset(string assetName)
{
string text = assetName.ToUpper();
if (!APIStatus.Asset.Ready)
{
return s_RegistryCache.ContainsKey(text);
}
return AssetShardManager.s_loadedAssetsLookup.ContainsKey(text);
}
public static Object GetLoadedAsset(string path)
{
string text = path.ToUpper();
APILogger.Verbose("Asset", "Requested Asset: " + text);
try
{
if (!APIStatus.Asset.Ready && s_RegistryCache.TryGetValue(text, out var value))
{
return value;
}
return AssetShardManager.GetLoadedAsset(text, false);
}
catch
{
return null;
}
}
public static TAsset GetLoadedAsset<TAsset>(string path) where TAsset : Object
{
Object loadedAsset = GetLoadedAsset(path);
if (loadedAsset == null)
{
return default(TAsset);
}
return ((Il2CppObjectBase)loadedAsset).Cast<TAsset>();
}
public static void RegisterAsset(string name, Object gameObject)
{
string text = name.ToUpper();
if (!APIStatus.Asset.Ready)
{
if (s_RegistryCache.ContainsKey(text))
{
throw new ArgumentException("The asset with " + text + " has already been registered.", "name");
}
s_RegistryCache.TryAdd(text, gameObject);
}
else
{
AssetAPI_Impl.Instance.RegisterAsset(text, gameObject);
}
}
public static void RegisterAssetBundle(AssetBundle bundle)
{
string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)bundle.AllAssetNames());
APILogger.Verbose("Asset", "Bundle names: [" + string.Join(", ", array) + "]");
string[] array2 = array;
foreach (string text in array2)
{
Object val = bundle.LoadAsset(text);
if (val != (Object)null)
{
RegisterAsset(text, val);
}
else
{
APILogger.Warn("Asset", "Skipping asset " + text);
}
}
}
public static void LoadAndRegisterAssetBundle(string pathToBundle)
{
AssetBundle obj = AssetBundle.LoadFromFile(pathToBundle);
if ((Object)(object)obj == (Object)null)
{
throw new Exception("Failed to load asset bundle");
}
RegisterAssetBundle(obj);
}
public static void LoadAndRegisterAssetBundle(byte[] bundleBytes)
{
AssetBundle obj = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(bundleBytes));
if ((Object)(object)obj == (Object)null)
{
throw new Exception("Failed to load asset bundle");
}
RegisterAssetBundle(obj);
}
public static Object InstantiateAsset(string assetName, string copyName)
{
if (ContainsAsset(copyName))
{
throw new ArgumentException("The asset you're trying to copy into is already registered", "copyName");
}
RegisterAsset(copyName, Object.Instantiate(GetLoadedAsset(assetName) ?? throw new ArgumentException("Couldn't find an asset with the name '" + assetName + "'", "assetName")));
return GetLoadedAsset(copyName);
}
public static TAsset InstantiateAsset<TAsset>(string assetName, string copyName) where TAsset : Object
{
Object obj = InstantiateAsset(assetName, copyName);
if (obj == null)
{
return default(TAsset);
}
return ((Il2CppObjectBase)obj).Cast<TAsset>();
}
public static bool TryInstantiateAsset<TAsset>(string assetName, string copyName, out TAsset clonedObj) where TAsset : Object
{
Object obj = InstantiateAsset(assetName, copyName);
clonedObj = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<TAsset>() : default(TAsset));
return (Object)(object)clonedObj != (Object)null;
}
private static void OnAssetsLoaded()
{
if (!APIStatus.Asset.Created)
{
APIStatus.CreateApi<AssetAPI_Impl>("Asset");
}
AssetAPI.OnStartupAssetsLoaded?.Invoke();
}
internal static void InvokeImplReady()
{
AssetAPI.OnImplReady?.Invoke();
}
internal static void Setup()
{
AssetShardManager.OnStartupAssetsLoaded += Action.op_Implicit((Action)OnAssetsLoaded);
OnImplReady += LoadAssetBundles;
}
private static void LoadAssetBundles()
{
string path = Path.Combine(Paths.ConfigPath, "Assets", "AssetBundles");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
if (files.Length == 0)
{
return;
}
for (int i = 0; i < files.Length; i++)
{
try
{
LoadAndRegisterAssetBundle(files[i]);
}
catch (Exception ex)
{
APILogger.Warn("AssetAPI", $"Failed to load asset bundle '{files[i]}' ({ex.Message})");
}
}
AssetAPI.OnAssetBundlesLoaded?.Invoke();
}
}
[API("GameData")]
public class GameDataAPI
{
public static ApiStatusInfo Status => APIStatus.GameData;
public static event Action OnGameDataInitialized;
static GameDataAPI()
{
Status.Created = true;
Status.Ready = true;
}
internal static void InvokeGameDataInit()
{
GameDataAPI.OnGameDataInitialized?.Invoke();
}
}
[API("Il2Cpp")]
public static class Il2CppAPI
{
public static ApiStatusInfo Status => APIStatus.Il2Cpp;
static Il2CppAPI()
{
Status.Created = true;
Status.Ready = true;
}
public unsafe static void InjectWithInterface<T>() where T : Il2CppObjectBase
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
List<INativeClassStruct> list = new List<INativeClassStruct>();
foreach (Il2CppInterfaceAttribute item in GetCustomAttributesInType<T, Il2CppInterfaceAttribute>())
{
Il2CppClass* ptr = (Il2CppClass*)(void*)(IntPtr)typeof(Il2CppClassPointerStore<>).MakeGenericType(item.Type).GetField("NativeClassPtr").GetValue(null);
IL2CPP.il2cpp_runtime_class_init((IntPtr)ptr);
list.Add(UnityVersionHandler.Wrap(ptr));
}
RegisterTypeOptions val = new RegisterTypeOptions();
val.set_LogSuccess(true);
val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(list.ToArray()));
ClassInjector.RegisterTypeInIl2Cpp<T>(val);
}
public unsafe static void* GetIl2CppMethod<T>(string methodName, string returnTypeName, bool isGeneric, params string[] argTypes) where T : Il2CppObjectBase
{
void** ptr = (void**)IL2CPP.GetIl2CppMethod(Il2CppClassPointerStore<T>.NativeClassPtr, isGeneric, methodName, returnTypeName, argTypes).ToPointer();
if (ptr == null)
{
return ptr;
}
return *ptr;
}
public unsafe static TDelegate GetIl2CppMethod<T, TDelegate>(string methodName, string returnTypeName, bool isGeneric, params string[] argTypes) where T : Il2CppObjectBase where TDelegate : Delegate
{
void* il2CppMethod = GetIl2CppMethod<T>(methodName, returnTypeName, isGeneric, argTypes);
if (il2CppMethod == null)
{
return null;
}
return Marshal.GetDelegateForFunctionPointer<TDelegate>((IntPtr)il2CppMethod);
}
public unsafe static INativeDetour CreateGenericDetour<TClass, TDelegate>(string methodName, string returnType, string[] paramTypes, Type[] genericArguments, TDelegate to, out TDelegate original) where TClass : Object where TDelegate : Delegate
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
IntPtr nativeClassPtr = Il2CppClassPointerStore<TClass>.NativeClassPtr;
if (nativeClassPtr == IntPtr.Zero)
{
throw new ArgumentException(typeof(TClass).Name + " does not exist in il2cpp domain");
}
return INativeDetour.CreateAndApply<TDelegate>(UnityVersionHandler.Wrap((Il2CppMethodInfo*)(void*)IL2CPP.il2cpp_method_get_from_reflection(((Il2CppObjectBase)new MethodInfo(IL2CPP.il2cpp_method_get_object(IL2CPP.GetIl2CppMethod(nativeClassPtr, true, methodName, returnType, paramTypes), nativeClassPtr)).MakeGenericMethod(((IEnumerable<Type>)genericArguments).Select((Func<Type, Type>)Il2CppType.From).ToArray())).Pointer)).MethodPointer, to, ref original);
}
private static IEnumerable<TAttribute> GetCustomAttributesInType<T, TAttribute>() where TAttribute : Attribute
{
Type attributeType = typeof(TAttribute);
return typeof(T).GetCustomAttributes(attributeType, inherit: true).Union(typeof(T).GetInterfaces().SelectMany((Type interfaceType) => interfaceType.GetCustomAttributes(attributeType, inherit: true))).Distinct()
.Cast<TAttribute>();
}
}
[API("Network")]
public static class NetworkAPI
{
internal class CachedEvent
{
public string EventName { get; set; }
public Type Type { get; set; }
public object OnReceive { get; set; }
}
internal static ConcurrentDictionary<string, CachedEvent> s_EventCache = new ConcurrentDictionary<string, CachedEvent>();
public static ApiStatusInfo Status => APIStatus.Network;
public static bool IsEventRegistered(string eventName)
{
return NetworkAPI_Impl.Instance.EventExists(eventName);
}
public static void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct
{
if (!APIStatus.Network.Ready)
{
if (s_EventCache.ContainsKey(eventName))
{
throw new ArgumentException("An event with the name " + eventName + " has already been registered.", "eventName");
}
s_EventCache.TryAdd(eventName, new CachedEvent
{
EventName = eventName,
Type = typeof(T),
OnReceive = onReceive
});
}
else
{
NetworkAPI_Impl.Instance.RegisterEvent(eventName, onReceive);
}
}
public static void InvokeEvent<T>(string eventName, T payload, SNet_ChannelType channelType = 2) where T : struct
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
SNet_SendGroup val = default(SNet_SendGroup);
SNet_SendQuality val2 = default(SNet_SendQuality);
int num = default(int);
SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
SNet.Core.SendBytes(MakeBytes(eventName, payload), val, val2, num);
}
public static void InvokeEvent<T>(string eventName, T payload, SNet_Player target, SNet_ChannelType channelType = 2) where T : struct
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
SNet_SendGroup val = default(SNet_SendGroup);
SNet_SendQuality val2 = default(SNet_SendQuality);
int num = default(int);
SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, target);
}
public static void InvokeEvent<T>(string eventName, T payload, List<SNet_Player> targets, SNet_ChannelType channelType = 2) where T : struct
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
SNet_SendGroup val = default(SNet_SendGroup);
SNet_SendQuality val2 = default(SNet_SendQuality);
int num = default(int);
SNet.GetSendSettings(ref channelType, ref val, ref val2, ref num);
SNet.Core.SendBytes(MakeBytes(eventName, payload), val2, num, targets.ToIl2Cpp());
}
private static Il2CppStructArray<byte> MakeBytes<T>(string eventName, T payload) where T : struct
{
return Il2CppStructArray<byte>.op_Implicit(NetworkAPI_Impl.Instance.MakePacketBytes(eventName, payload));
}
}
[API("Prefab")]
public static class PrefabAPI
{
private static Shader s_CustomGearShader;
private static readonly Dictionary<uint, Action<SyringeFirstPerson>> s_SyringeActions = new Dictionary<uint, Action<SyringeFirstPerson>>();
public static ApiStatusInfo Status => APIStatus.Prefab;
private static Shader CustomGearShader
{
get
{
if ((Object)(object)s_CustomGearShader == (Object)null)
{
s_CustomGearShader = Shader.Find("Cell/Player/CustomGearShader");
}
return s_CustomGearShader;
}
}
public static void CreateConsumable(string assetName, bool enableEmissive = false)
{
Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
GameObject val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
if ((Object)(object)val == (Object)null)
{
throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName");
}
ItemEquippable obj = val.AddComponent<ItemEquippable>();
obj.m_isFirstPerson = false;
((Item)obj).m_itemModelHolder = val.transform;
ReplaceShaderInAssetMaterials(val, CustomGearShader, enableEmissive ? "ENABLE_EMISSIVE" : null);
}
public static void CreateConsumablePickup(string assetName, bool enableEmissive = false)
{
Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
GameObject val = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
if ((Object)(object)val == (Object)null)
{
throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName");
}
BoxCollider componentInChildren = val.GetComponentInChildren<BoxCollider>();
if ((Object)(object)componentInChildren == (Object)null)
{
throw new Exception("The Consumable Pickup prefab doesn't contain a BoxCollider for interaction");
}
GameObject gameObject = ((Component)componentInChildren).gameObject;
gameObject.layer = LayerMask.NameToLayer("Interaction");
Interact_Pickup_PickupItem val2 = gameObject.AddComponent<Interact_Pickup_PickupItem>();
((Interact_Base)val2).m_colliderToOwn = (Collider)(object)componentInChildren;
ConsumablePickup_Core obj = val.AddComponent<ConsumablePickup_Core>();
obj.m_syncComp = (Component)(object)val.AddComponent<LG_PickupItem_Sync>();
obj.m_interactComp = (Component)(object)val2;
ReplaceShaderInAssetMaterials(val, CustomGearShader, enableEmissive ? "ENABLE_EMISSIVE" : null);
}
public static void CreateConsumableInstance<T>(string assetName) where T : ConsumableInstance
{
Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
GameObject obj = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
if ((Object)(object)obj == (Object)null)
{
throw new ArgumentException("Couldn't find a game object asset with the name " + assetName, "assetName");
}
if (!ClassInjector.IsTypeRegisteredInIl2Cpp<T>())
{
ClassInjector.RegisterTypeInIl2Cpp<T>();
}
obj.layer = LayerMask.NameToLayer("Debris");
Rigidbody component = obj.GetComponent<Rigidbody>();
obj.AddComponent<ColliderMaterial>().PhysicsBody = component ?? throw new Exception("The Consumable Instance prefab doesn't contain a Rigidbody");
obj.AddComponent<T>();
}
public static void CreateGearComponent(string assetName, bool enableEmissive = false)
{
Object loadedAsset = AssetAPI.GetLoadedAsset(assetName);
GameObject obj = ((loadedAsset != null) ? ((Il2CppObjectBase)loadedAsset).TryCast<GameObject>() : null) ?? null;
if ((Object)(object)obj == (Object)null)
{
throw new ArgumentException("Couldnt find a game object asset with the name " + assetName, "assetName");
}
obj.layer = LayerMask.NameToLayer("FirstPersonItem");
ReplaceShaderInAssetMaterials(obj, CustomGearShader, "ENABLE_FPS_RENDERING", enableEmissive ? "ENABLE_EMISSIVE" : null);
}
public static void CreateSyringe(uint itemPersistentId, Action<SyringeFirstPerson> onUse)
{
if (s_SyringeActions.ContainsKey(itemPersistentId))
{
throw new ArgumentException($"{itemPersistentId} is already registered with a syringe action.");
}
s_SyringeActions.Add(itemPersistentId, onUse);
}
internal static bool OnSyringeUsed(SyringeFirstPerson syringe)
{
if (s_SyringeActions.TryGetValue(((GameDataBlockBase<ItemDataBlock>)(object)((Item)syringe).ItemDataBlock).persistentID, out var value))
{
value(syringe);
return true;
}
return false;
}
private static void ReplaceShaderInAssetMaterials(GameObject asset, Shader newShader, params string[] addedKeywords)
{
addedKeywords = addedKeywords.Where((string x) => !string.IsNullOrEmpty(x)).ToArray();
foreach (MeshRenderer componentsInChild in asset.GetComponentsInChildren<MeshRenderer>(true))
{
foreach (Material item in (Il2CppArrayBase<Material>)(object)((Renderer)componentsInChild).materials)
{
item.shader = newShader;
if (addedKeywords.Length != 0)
{
string[] array = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)item.shaderKeywords);
int num = array.Length;
Array.Resize(ref array, array.Length + addedKeywords.Length);
for (int i = 0; i < addedKeywords.Length; i++)
{
array[num + i] = addedKeywords[i];
}
item.shaderKeywords = Il2CppStringArray.op_Implicit(array);
}
}
}
}
}
[BepInPlugin("dev.gtfomodding.gtfo-api", "GTFO-API", "0.3.1")]
internal class EntryPoint : BasePlugin
{
private Harmony m_Harmony;
public override void Load()
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
APILogger.Verbose("Core", "Registering API Implementations");
ClassInjector.RegisterTypeInIl2Cpp<NetworkAPI_Impl>();
ClassInjector.RegisterTypeInIl2Cpp<AssetAPI_Impl>();
APILogger.Verbose("Core", "Registering Wrappers");
ClassInjector.RegisterTypeInIl2Cpp<ItemWrapped>();
APILogger.Verbose("Core", "Registering Utilities Implementations");
ClassInjector.RegisterTypeInIl2Cpp<ThreadDispatcher_Impl>();
ClassInjector.RegisterTypeInIl2Cpp<CoroutineDispatcher_Impl>();
APILogger.Verbose("Core", "Applying Patches");
m_Harmony = new Harmony("dev.gtfomodding.gtfo-api");
m_Harmony.PatchAll();
AssetAPI.Setup();
APILogger.Verbose("Core", "Plugin Load Complete");
APILogger.Warn("GTFO-API", "Syringes are currently disabled in this version");
}
}
[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
[CompilerGenerated]
internal static class VersionInfo
{
public const string RootNamespace = "GTFO.API";
public const string Version = "0.3.1";
public const string VersionPrerelease = null;
public const string VersionMetadata = "git4b21c34-main";
public const string SemVer = "0.3.1+git4b21c34-main";
public const string GitRevShort = "4b21c34";
public const string GitRevLong = "4b21c34e6e7b0ca87cc4ae60bd12120654e36fe1";
public const string GitBranch = "main";
public const string GitTag = "0.3.0";
public const bool GitIsDirty = false;
}
}
namespace GTFO.API.Wrappers
{
public class ItemWrapped : Item
{
private static readonly Item__Get_pItemData Get_pItemDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Get_pItemData>("Get_pItemData", "Player.pItemData", isGeneric: false, Array.Empty<string>());
private static readonly Item__Set_pItemData Set_pItemDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Set_pItemData>("Set_pItemData", "System.Void", isGeneric: false, new string[1] { "Player.pItemData" });
private static readonly Item__GetCustomData GetCustomDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetCustomData>("GetCustomData", "Player.pItemData_Custom", isGeneric: false, Array.Empty<string>());
private static readonly Item__SetCustomData SetCustomDataBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SetCustomData>("SetCustomData", "System.Void", isGeneric: false, new string[2] { "Player.pItemData_Custom", "System.Boolean" });
private static readonly Item__OnCustomDataUpdated OnCustomDataUpdatedBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnCustomDataUpdated>("OnCustomDataUpdated", "System.Void", isGeneric: false, new string[1] { "Player.pItemData_Custom" });
private static readonly Item__Awake AwakeBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Awake>("Awake", "System.Void", isGeneric: false, Array.Empty<string>());
private static readonly Item__OnDespawn OnDespawnBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnDespawn>("OnDespawn", "System.Void", isGeneric: false, Array.Empty<string>());
private static readonly Item__Setup SetupBase = Il2CppAPI.GetIl2CppMethod<Item, Item__Setup>("Setup", "System.Void", isGeneric: false, new string[1] { "GameData.ItemDataBlock" });
private static readonly Item__OnGearSpawnComplete OnGearSpawnCompleteBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnGearSpawnComplete>("OnGearSpawnComplete", "System.Void", isGeneric: false, Array.Empty<string>());
private static readonly Item__OnPickUp OnPickUpBase = Il2CppAPI.GetIl2CppMethod<Item, Item__OnPickUp>("OnPickUp", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });
private static readonly Item__SetupBaseModel SetupBaseModelBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SetupBaseModel>("SetupBaseModel", "System.Void", isGeneric: false, new string[1] { "ItemSetup.ItemModelSetup" });
private static readonly Item__SyncedTurnOn SyncedTurnOnBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTurnOn>("SyncedTurnOn", "System.Void", isGeneric: false, new string[2] { "Player.PlayerAgent", "AIGraph.AIG_CourseNode" });
private static readonly Item__SyncedTurnOff SyncedTurnOffBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTurnOff>("SyncedTurnOff", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });
private static readonly Item__SyncedTrigger SyncedTriggerBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTrigger>("SyncedTrigger", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });
private static readonly Item__SyncedTriggerSecondary SyncedTriggerSecondaryBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedTriggerSecondary>("SyncedTriggerSecondary", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });
private static readonly Item__SyncedThrow SyncedThrowBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedThrow>("SyncedThrow", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });
private static readonly Item__SyncedPickup SyncedPickupBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedPickup>("SyncedPickup", "System.Void", isGeneric: false, new string[1] { "Player.PlayerAgent" });
private static readonly Item__SyncedSetKeyValue SyncedSetKeyValueBase = Il2CppAPI.GetIl2CppMethod<Item, Item__SyncedSetKeyValue>("SyncedSetKeyValue", "System.Void", isGeneric: false, new string[2] { "System.Int32", "System.Single" });
private static readonly Item__GetPickupInteraction GetPickupInteractionBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetPickupInteraction>("GetPickupInteraction", "Interact_Base", isGeneric: false, Array.Empty<string>());
private static readonly Item__GetItem GetItemBase = Il2CppAPI.GetIl2CppMethod<Item, Item__GetItem>("GetItem", "Item", isGeneric: false, Array.Empty<string>());
public ItemWrapped(IntPtr hdl)
: base(hdl)
{
}
public unsafe override pItemData Get_pItemData()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
pItemData* retstr = (pItemData*)stackalloc pItemData[1];
return *Get_pItemDataBase(retstr, ((Il2CppObjectBase)this).Pointer.ToPointer());
}
public unsafe override void Set_pItemData(pItemData data)
{
Set_pItemDataBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &data);
}
public unsafe override pItemData_Custom GetCustomData()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
return *GetCustomDataBase(((Il2CppObjectBase)this).Pointer.ToPointer());
}
public unsafe override void SetCustomData(pItemData_Custom custom, bool sync)
{
SetCustomDataBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &custom, sync);
}
public unsafe override void OnCustomDataUpdated(pItemData_Custom customDataCopy)
{
OnCustomDataUpdatedBase(((Il2CppObjectBase)this).Pointer.ToPointer(), &customDataCopy);
}
public unsafe override void Awake()
{
AwakeBase(((Il2CppObjectBase)this).Pointer.ToPointer());
}
public unsafe override void OnDespawn()
{
OnDespawnBase(((Il2CppObjectBase)this).Pointer.ToPointer());
}
public unsafe override void Setup(ItemDataBlock data)
{
SetupBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)data).Pointer.ToPointer());
}
public unsafe override void OnGearSpawnComplete()
{
OnGearSpawnCompleteBase(((Il2CppObjectBase)this).Pointer.ToPointer());
}
public unsafe override void OnPickUp(PlayerAgent player)
{
OnPickUpBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)player).Pointer.ToPointer());
}
public unsafe override void SetupBaseModel(ItemModelSetup setup)
{
SetupBaseModelBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)setup).Pointer.ToPointer());
}
public unsafe override void SyncedTurnOn(PlayerAgent agent, AIG_CourseNode courseNode)
{
SyncedTurnOnBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer(), ((Il2CppObjectBase)courseNode).Pointer.ToPointer());
}
public unsafe override void SyncedTurnOff(PlayerAgent agent)
{
SyncedTurnOffBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
}
public unsafe override void SyncedTrigger(PlayerAgent agent)
{
SyncedTriggerBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
}
public unsafe override void SyncedTriggerSecondary(PlayerAgent agent)
{
SyncedTriggerSecondaryBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
}
public unsafe override void SyncedThrow(PlayerAgent agent)
{
SyncedThrowBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
}
public unsafe override void SyncedPickup(PlayerAgent agent)
{
SyncedPickupBase(((Il2CppObjectBase)this).Pointer.ToPointer(), ((Il2CppObjectBase)agent).Pointer.ToPointer());
}
public unsafe override void SyncedSetKeyValue(int key, float value)
{
SyncedSetKeyValueBase(((Il2CppObjectBase)this).Pointer.ToPointer(), key, value);
}
public unsafe override Interact_Base GetPickupInteraction()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
return new Interact_Base((IntPtr)GetPickupInteractionBase(((Il2CppObjectBase)this).Pointer.ToPointer()));
}
public unsafe override Item GetItem()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
return new Item((IntPtr)GetItemBase(((Il2CppObjectBase)this).Pointer.ToPointer()));
}
}
public unsafe delegate pItemData* Item__Get_pItemData(pItemData* retstr, void* _this);
public unsafe delegate void Item__Set_pItemData(void* _this, void* data);
public unsafe delegate pItemData_Custom* Item__GetCustomData(void* _this);
public unsafe delegate void Item__SetCustomData(void* _this, pItemData_Custom* custom, bool sync);
public unsafe delegate void Item__OnCustomDataUpdated(void* _this, pItemData_Custom* customDataCopy);
public unsafe delegate void Item__Awake(void* _this);
public unsafe delegate void Item__OnDespawn(void* _this);
public unsafe delegate void Item__Setup(void* _this, void* data);
public unsafe delegate void Item__OnGearSpawnComplete(void* _this);
public unsafe delegate void Item__OnPickUp(void* _this, void* player);
public unsafe delegate void Item__SetupBaseModel(void* _this, void* setup);
public unsafe delegate void Item__SyncedTurnOn(void* _this, void* agent, void* courseNode);
public unsafe delegate void Item__SyncedTurnOff(void* _this, void* agent);
public unsafe delegate void Item__SyncedTrigger(void* _this, void* agent);
public unsafe delegate void Item__SyncedTriggerSecondary(void* _this, void* agent);
public unsafe delegate void Item__SyncedThrow(void* _this, void* agent);
public unsafe delegate void Item__SyncedPickup(void* _this, void* agent);
public unsafe delegate void Item__SyncedSetKeyValue(void* _this, int key, float value);
public unsafe delegate void* Item__GetPickupInteraction(void* _this);
public unsafe delegate void* Item__GetItem(void* _this);
[Il2CppInterface(typeof(iTerminalItem))]
public interface iTerminalItemWrapper
{
uint TerminalItemId { get; set; }
string TerminalItemKey { get; set; }
string OverrideCode { get; set; }
Vector3 LocatorBeaconPosition { get; set; }
AIG_CourseNode SpawnNode { get; set; }
bool ShowInFloorInventory { get; set; }
string FloorItemLocation { get; set; }
eFloorInventoryObjectType FloorItemType { get; set; }
eFloorInventoryObjectStatus FloorItemStatus { get; set; }
Func<List<string>, List<string>> OnWantDetailedInfo { get; set; }
void Setup(string key);
List<string> GetDetailedInfo(List<string> defaultDetails);
void PlayPing();
}
[Il2CppInterface(typeof(iResourcePackReceiver))]
public interface iResourcePackReceiverWrapper
{
bool IsLocallyOwned { get; }
string InteractionName { get; }
bool NeedHealth();
bool NeedDisinfection();
bool NeedWeaponAmmo();
bool NeedToolAmmo();
void GiveAmmoRel(float ammoStandardRel, float ammoSpecialRel, float ammoClassRel);
void GiveHealth(float health);
void GiveDisinfection(float disinfection);
}
[Il2CppInterface(typeof(iPlayerPingTarget))]
public interface iPlayerPingTargetWrapper
{
eNavMarkerStyle PingTargetStyle { get; set; }
}
[Il2CppInterface(typeof(iWardenObjectiveItem))]
public interface iWardenObjectiveItemWrapper
{
LG_LayerType OriginLayer { get; }
AIG_CourseNode SpawnNode { get; }
string PublicName { get; }
Transform transform { get; }
bool ObjectiveItemSolved { get; }
ePickupItemStatus PickupItemStatus { get; }
PlayerAgent PickedUpByPlayer { get; }
void ActivateWardenObjectiveItem();
void DeactivateWardenObjectiveItem();
}
}
namespace GTFO.API.Utilities
{
public static class CoroutineDispatcher
{
public static void StartCoroutine(IEnumerator routine)
{
CoroutineDispatcher_Impl.Instance.RunCoroutine(routine);
}
public static void StartInLevelCoroutine(IEnumerator routine)
{
CoroutineDispatcher_Impl.Instance.RunInLevelCoroutine(routine);
}
}
public delegate void LiveEditEventHandler(LiveEditEventArgs e);
public class LiveEditEventArgs
{
public LiveEditEventType Type { get; set; }
public string FullPath { get; set; }
public string FileName { get; set; }
}
public enum LiveEditEventType
{
Created,
Deleted,
Renamed,
Changed
}
public static class LiveEdit
{
internal const int RETRY_COUNT = 5;
internal const float RETRY_INTERVAL = 0.1f;
internal static readonly List<LiveEditListener> s_Listeners = new List<LiveEditListener>();
public static LiveEditListener CreateListener(string path, string filter, bool includeSubDir)
{
LiveEditListener liveEditListener = new LiveEditListener(path, filter, includeSubDir);
s_Listeners.Add(liveEditListener);
return liveEditListener;
}
public static void TryReadFileContent(string filepath, Action<string> onReaded)
{
CoroutineDispatcher.StartCoroutine(GetFileStream(filepath, 5, 0.1f, delegate(FileStream stream)
{
try
{
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
onReaded?.Invoke(streamReader.ReadToEnd());
}
catch
{
}
}));
}
private static IEnumerator GetFileStream(string filepath, int retryCount, float retryInterval, Action<FileStream> onFileStreamOpened)
{
retryCount = Math.Max(retryCount, 1);
retryInterval = Math.Max(retryInterval, 0f);
WaitForSecondsRealtime wait = new WaitForSecondsRealtime(retryInterval);
for (int i = 0; i < retryCount; i++)
{
try
{
FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
onFileStreamOpened?.Invoke(fileStream);
fileStream.Close();
break;
}
catch
{
}
yield return wait;
}
}
}
public sealed class LiveEditListener : IDisposable
{
private FileSystemWatcher m_Watcher;
private bool m_Allocated = true;
private float m_ChangedCooldownTimer;
public float FileChangedEventCooldown { get; set; } = 0.05f;
public event LiveEditEventHandler FileChanged;
public event LiveEditEventHandler FileDeleted;
public event LiveEditEventHandler FileCreated;
public event LiveEditEventHandler FileRenamed;
private LiveEditListener()
{
}
internal LiveEditListener(string path, string filter, bool includeSubDir)
{
LiveEditListener liveEditListener = this;
m_Watcher = new FileSystemWatcher
{
Path = path,
Filter = filter,
IncludeSubdirectories = includeSubDir,
NotifyFilter = (NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime)
};
m_Watcher.Deleted += delegate(object sender, FileSystemEventArgs e)
{
FileSystemEventArgs e5 = e;
ThreadDispatcher.Dispatch(delegate
{
liveEditListener.FileDeleted?.Invoke(CreateArgs(e5, LiveEditEventType.Deleted));
});
};
m_Watcher.Created += delegate(object sender, FileSystemEventArgs e)
{
FileSystemEventArgs e4 = e;
ThreadDispatcher.Dispatch(delegate
{
liveEditListener.FileCreated?.Invoke(CreateArgs(e4, LiveEditEventType.Created));
});
};
m_Watcher.Renamed += delegate(object sender, RenamedEventArgs e)
{
RenamedEventArgs e3 = e;
ThreadDispatcher.Dispatch(delegate
{
liveEditListener.FileRenamed?.Invoke(CreateArgs(e3, LiveEditEventType.Renamed));
});
};
m_Watcher.Changed += delegate(object sender, FileSystemEventArgs e)
{
FileSystemEventArgs e2 = e;
ThreadDispatcher.Dispatch(delegate
{
float time = Time.time;
if (!(liveEditListener.m_ChangedCooldownTimer > time))
{
liveEditListener.m_ChangedCooldownTimer = time + liveEditListener.FileChangedEventCooldown;
liveEditListener.FileChanged?.Invoke(CreateArgs(e2, LiveEditEventType.Changed));
}
});
};
m_Watcher.Error += delegate(object sender, ErrorEventArgs e)
{
APILogger.Error("LiveEdit", $"Path: {path} error reported! - {e.GetException()}");
};
StartListen();
}
private static LiveEditEventArgs CreateArgs(FileSystemEventArgs args, LiveEditEventType type)
{
return new LiveEditEventArgs
{
FullPath = args.FullPath,
FileName = Path.GetFileName(args.FullPath),
Type = type
};
}
public void Dispose()
{
if (m_Allocated)
{
LiveEdit.s_Listeners.Remove(this);
m_Allocated = false;
}
if (m_Watcher != null)
{
StopListen();
this.FileChanged = null;
this.FileDeleted = null;
this.FileCreated = null;
this.FileRenamed = null;
m_Watcher.Dispose();
}
m_Watcher = null;
}
public void StopListen()
{
if (m_Watcher != null)
{
m_Watcher.EnableRaisingEvents = false;
}
}
public void StartListen()
{
if (m_Watcher != null)
{
m_Watcher.EnableRaisingEvents = true;
}
}
}
internal static class MemoryUtils
{
private static byte[] _trampolineShellcode = new byte[12]
{
72, 184, 0, 0, 0, 0, 0, 0, 0, 0,
255, 208
};
public unsafe static void* FindSignatureInBlock(void* block, ulong blockSize, string pattern, string mask, ulong sigOffset = 0uL)
{
return FindSignatureInBlock(block, blockSize, pattern.ToCharArray(), mask.ToCharArray(), sigOffset);
}
public unsafe static void* FindSignatureInBlock(void* block, ulong blockSize, char[] pattern, char[] mask, ulong sigOffset = 0uL)
{
for (ulong num = 0uL; num < blockSize; num++)
{
bool flag = true;
for (uint num2 = 0u; num2 < mask.Length; num2++)
{
if (*(byte*)((long)num + (long)block + num2) != (byte)pattern[num2] && mask[num2] != '?')
{
flag = false;
break;
}
}
if (flag)
{
return (void*)((ulong)((long)num + (long)block) + sigOffset);
}
}
return null;
}
public unsafe static byte[] MakeTrampoline(void* destination)
{
byte[] array = new byte[_trampolineShellcode.Length];
Array.Copy(_trampolineShellcode, 0, array, 0, _trampolineShellcode.Length);
fixed (byte* ptr = array)
{
*(long*)(ptr + 2) = (long)destination;
}
return array;
}
public unsafe static void CreateTrampolineBetween(void* start, void* end, void* destination)
{
ulong num = (ulong)end - (ulong)start;
if (num < (ulong)_trampolineShellcode.Length)
{
throw new Exception("Trampoline block size is not enough to create.");
}
uint flNewProtect = default(uint);
if (!Kernel32.VirtualProtect(start, num, 64u, &flNewProtect))
{
throw new Exception("Failed to change protection of trampoline block.");
}
APILogger.Verbose("MemoryUtils", "NOPing trampoline block");
for (ulong num2 = 0uL; num2 < num; num2++)
{
*(sbyte*)((ulong)start + num2) = -112;
}
APILogger.Verbose("MemoryUtils", "Creating trampoline shellcode");
byte[] array = MakeTrampoline(destination);
APILogger.Verbose("MemoryUtils", "Writing trampoline shellcode");
for (ulong num3 = 0uL; num3 < (ulong)array.Length; num3++)
{
*(byte*)((ulong)start + num3) = array[num3];
}
if (!Kernel32.VirtualProtect(start, num, flNewProtect, &flNewProtect))
{
throw new Exception("Failed to revert trampoline block protection.");
}
}
}
public class PersistentData<T> where T : PersistentData<T>, new()
{
private const string VERSION_REGEX = "\"PersistentDataVersion\": \"(.+?)\"";
private static T s_CurrentData;
public static T CurrentData
{
get
{
if (s_CurrentData != null)
{
return s_CurrentData;
}
s_CurrentData = Load();
return s_CurrentData;
}
set
{
s_CurrentData = value;
}
}
protected static string persistentPath => Path.Combine(Paths.PluginPath, "PersistentData", typeof(T).Assembly.GetName().Name, typeof(T).Name + ".json");
public virtual string PersistentDataVersion { get; set; } = "1.0.0";
public static T Load()
{
return Load(persistentPath);
}
public static T Load(string path)
{
T val = new T();
if (File.Exists(path))
{
string text = File.ReadAllText(path);
T val2;
try
{
val2 = GTFO.API.JSON.JsonSerializer.Deserialize<T>(text);
}
catch (JsonException)
{
APILogger.Warn("JSON", "Failed to deserialize " + typeof(T).Name + ", replacing with default");
string text2 = "FAILED";
Match match = Regex.Match(text, "\"PersistentDataVersion\": \"(.+?)\"");
if (match.Success)
{
text2 = match.Groups[1].Value + "-FAILED";
}
File.WriteAllText(Path.ChangeExtension(path, null) + "-" + text2 + ".json", text);
val2 = new T();
val2.Save(path);
}
if (val2.PersistentDataVersion != val.PersistentDataVersion)
{
val2.Save(Path.ChangeExtension(path, null) + "-" + val2.PersistentDataVersion + ".json");
val.Save(path);
}
else
{
val = val2;
}
}
else
{
val.Save(path);
}
return val;
}
public void Save()
{
Save(persistentPath);
}
public void Save(string path)
{
string contents = GTFO.API.JSON.JsonSerializer.Serialize((T)this);
string directoryName = Path.GetDirectoryName(path);
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
File.WriteAllText(path, contents);
}
}
public static class RegexUtils
{
private static readonly Regex s_VectorRegex = new Regex("-?[0-9.]+");
public static bool TryParseVectorString(string input, out float[] vectorArray)
{
try
{
MatchCollection matchCollection = s_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;
}
}
}
public static class StringUtils
{
private static readonly uint[] _lookup32 = ((Func<uint[]>)delegate
{
uint[] array = new uint[256];
for (int i = 0; i < 256; i++)
{
string text = i.ToString("X2");
if (BitConverter.IsLittleEndian)
{
array[i] = text[0] + ((uint)text[1] << 16);
}
else
{
array[i] = text[1] + ((uint)text[0] << 16);
}
}
return array;
})();
private unsafe static readonly uint* _lookup32Ptr = (uint*)(void*)GCHandle.Alloc(_lookup32, GCHandleType.Pinned).AddrOfPinnedObject();
public unsafe static string FromByteArrayAsHex(byte[] bytes)
{
char[] array = new char[bytes.Length * 2];
fixed (byte* ptr3 = bytes)
{
fixed (char* ptr = array)
{
uint* ptr2 = (uint*)ptr;
for (int i = 0; i < bytes.Length; i++)
{
ptr2[i] = _lookup32Ptr[(int)ptr3[i]];
}
}
}
return new string(array);
}
}
public static class ThreadDispatcher
{
public static void Dispatch(Action action)
{
ThreadDispatcher_Impl.Instance.EnqueueAction(action);
}
}
}
namespace GTFO.API.Utilities.Impl
{
internal class CoroutineDispatcher_Impl : MonoBehaviour
{
private bool m_HasInLevelCoroutines;
private readonly List<Coroutine> m_InLevelCoroutines;
private static CoroutineDispatcher_Impl s_Instance;
public static CoroutineDispatcher_Impl Instance
{
get
{
if ((Object)(object)s_Instance == (Object)null)
{
CoroutineDispatcher_Impl coroutineDispatcher_Impl = Object.FindObjectOfType<CoroutineDispatcher_Impl>();
if ((Object)(object)coroutineDispatcher_Impl != (Object)null)
{
s_Instance = coroutineDispatcher_Impl;
}
}
return s_Instance;
}
}
static CoroutineDispatcher_Impl()
{
AssetAPI.OnStartupAssetsLoaded += OnAssetsLoaded;
}
private static void OnAssetsLoaded()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
if (!((Object)(object)s_Instance != (Object)null))
{
GameObject val = new GameObject();
CoroutineDispatcher_Impl coroutineDispatcher_Impl = val.AddComponent<CoroutineDispatcher_Impl>();
((Object)val).name = "GTFO-API Coroutine Dispatcher";
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)val);
s_Instance = coroutineDispatcher_Impl;
}
}
private void Update()
{
if (m_HasInLevelCoroutines && !GameStateManager.IsInExpedition)
{
m_InLevelCoroutines.ForEach(delegate(Coroutine coroutine)
{
((MonoBehaviour)this).StopCoroutine(coroutine);
});
m_HasInLevelCoroutines = false;
}
}
[HideFromIl2Cpp]
internal void RunCoroutine(IEnumerator routine)
{
MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine);
}
[HideFromIl2Cpp]
internal void RunInLevelCoroutine(IEnumerator routine)
{
if (!GameStateManager.IsInExpedition)
{
APILogger.Error("CoroutineDispatcher", "Cannot run InLevelCoroutine while you're not in level!");
return;
}
Coroutine item = MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, routine);
m_InLevelCoroutines.Add(item);
m_HasInLevelCoroutines = true;
}
}
internal class ThreadDispatcher_Impl : MonoBehaviour
{
private readonly Queue<Action> s_ActionQueue = new Queue<Action>();
private static ThreadDispatcher_Impl s_Instance;
public static ThreadDispatcher_Impl Instance
{
get
{
if ((Object)(object)s_Instance == (Object)null)
{
ThreadDispatcher_Impl threadDispatcher_Impl = Object.FindObjectOfType<ThreadDispatcher_Impl>();
if ((Object)(object)threadDispatcher_Impl != (Object)null)
{
s_Instance = threadDispatcher_Impl;
}
}
return s_Instance;
}
}
public ThreadDispatcher_Impl(IntPtr intPtr)
: base(intPtr)
{
}
static ThreadDispatcher_Impl()
{
AssetAPI.OnStartupAssetsLoaded += OnAssetsLoaded;
}
private static void OnAssetsLoaded()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
if (!((Object)(object)s_Instance != (Object)null))
{
GameObject val = new GameObject();
ThreadDispatcher_Impl threadDispatcher_Impl = val.AddComponent<ThreadDispatcher_Impl>();
((Object)val).name = "GTFO-API Thread Dispatcher";
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)val);
s_Instance = threadDispatcher_Impl;
}
}
[HideFromIl2Cpp]
internal void EnqueueAction(Action action)
{
lock (s_ActionQueue)
{
s_ActionQueue.Enqueue(action);
}
}
internal void Update()
{
lock (s_ActionQueue)
{
while (s_ActionQueue.Count > 0)
{
s_ActionQueue.Dequeue()?.Invoke();
}
}
}
}
}
namespace GTFO.API.Resources
{
public class ApiStatusInfo
{
public bool Created { get; internal set; }
public bool Ready { get; internal set; }
}
public static class APIStatus
{
private static GameObject s_ScriptHolder;
public static ApiStatusInfo Asset { get; internal set; } = new ApiStatusInfo();
public static ApiStatusInfo GameData { get; internal set; } = new ApiStatusInfo();
public static ApiStatusInfo Il2Cpp { get; internal set; } = new ApiStatusInfo();
public static ApiStatusInfo Network { get; internal set; } = new ApiStatusInfo();
public static ApiStatusInfo Prefab { get; internal set; } = new ApiStatusInfo();
internal static GameObject ScriptHolder
{
get
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
if ((Object)(object)s_ScriptHolder == (Object)null)
{
s_ScriptHolder = new GameObject();
((Object)s_ScriptHolder).name = "GTFO-API Script Holder";
((Object)s_ScriptHolder).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)s_ScriptHolder);
}
return s_ScriptHolder;
}
}
internal static void CreateApi<T>(string apiName) where T : Component
{
ApiStatusInfo apiStatusInfo = (ApiStatusInfo)(typeof(APIStatus).GetProperty(apiName)?.GetValue(null));
if (apiStatusInfo == null)
{
throw new ArgumentException("Couldn't find API status for " + apiName, "apiName");
}
if (!apiStatusInfo.Created && !((Object)(object)ScriptHolder.GetComponent<T>() != (Object)null))
{
APILogger.Verbose("Core", "Creating API " + apiName);
ScriptHolder.AddComponent<T>();
apiStatusInfo.Created = true;
}
}
}
internal static class RuntimeData
{
public static Dictionary<InventorySlot, string[]> BotFavorites;
}
public static class ShaderConstants
{
public const string CUSTOM_GEAR_SHADER = "Cell/Player/CustomGearShader";
}
public static class NetworkConstants
{
public const string Magic = "GAPI_KSQK";
public const byte MagicSize = 9;
public const ulong VersionSignature = 18374688137539712817uL;
}
}
namespace GTFO.API.Patches
{
[HarmonyPatch(typeof(AssetShardManager))]
internal class AssetShardManager_Patches
{
[HarmonyPatch("Setup")]
[HarmonyWrapSafe]
[HarmonyPostfix]
public static void Setup_Postfix()
{
if (!APIStatus.Asset.Created)
{
APIStatus.CreateApi<AssetAPI_Impl>("Asset");
}
}
}
[HarmonyPatch(typeof(GameDataInit))]
internal class GameDataInit_Patches
{
private struct PluginWhitelistInfo
{
public string GUID;
public string Name;
public string Version;
public string Checksum;
}
private static PluginWhitelistInfo[] FetchPluginWhitelist()
{
using HttpClient httpClient = new HttpClient();
using Stream stream = httpClient.GetStreamAsync("https://raw.githubusercontent.com/GTFO-Modding/GTFO-API-PluginWhitelist/main/whitelist.txt").GetAwaiter().GetResult();
using StreamReader streamReader = new StreamReader(stream);
string[] array = streamReader.ReadToEnd().Split('\n', StringSplitOptions.RemoveEmptyEntries);
PluginWhitelistInfo[] array2 = new PluginWhitelistInfo[array.Length];
for (int i = 0; i < array2.Length; i++)
{
string[] array3 = array[i].Split(":");
array2[i] = new PluginWhitelistInfo
{
GUID = array3[0],
Name = array3[1],
Version = array3[2],
Checksum = array3[3].TrimEnd('\r')
};
}
return array2;
}
[HarmonyPatch("Initialize")]
[HarmonyWrapSafe]
[HarmonyPostfix]
public static void Initialize_Postfix()
{
Analytics.enabled = false;
try
{
PluginWhitelistInfo[] array = FetchPluginWhitelist();
if (array.Length == 0)
{
throw null;
}
foreach (PluginInfo loadedPlugin in ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.Values)
{
if (loadedPlugin.Metadata.GUID == "dev.gtfomodding.gtfo-api")
{
continue;
}
using SHA256 sHA = SHA256.Create();
string s = $"{loadedPlugin.Metadata.GUID}|{loadedPlugin.Metadata.Version}|{loadedPlugin.Metadata.Name}|{Path.GetFileName(loadedPlugin.Location)}|{loadedPlugin.Instance.GetType().Assembly.FullName}";
byte[] bytes = Encoding.UTF8.GetBytes(s);
sHA.TransformBlock(bytes, 0, bytes.Length, null, 0);
byte[] array2 = File.ReadAllBytes(loadedPlugin.Location);
sHA.TransformFinalBlock(array2, 0, array2.Length);
string checksum = StringUtils.FromByteArrayAsHex(sHA.Hash);
if (!array.Any((PluginWhitelistInfo x) => x.Name == loadedPlugin.Metadata.Name && x.GUID == loadedPlugin.Metadata.GUID && x.Version == ((object)loadedPlugin.Metadata.Version).ToString() && x.Checksum == checksum))
{
throw null;
}
}
}
catch
{
goto IL_01be;
}
goto IL_02c6;
IL_01be:
GameSetupDataBlock block = GameDataBlockBase<GameSetupDataBlock>.GetBlock(1u);
if (block == null || block.RundownIdToLoad != 1)
{
APILogger.Verbose("GameDataInit_Patches", $"RundownIdToLoad was {block.RundownIdToLoad}. Setting to 1");
GameDataBlockBase<RundownDataBlock>.RemoveBlockByID(1u);
RundownDataBlock block2 = GameDataBlockBase<RundownDataBlock>.GetBlock(block.RundownIdToLoad);
if (block2 != null)
{
((GameDataBlockBase<RundownDataBlock>)(object)block2).persistentID = 1u;
((GameDataBlockBase<RundownDataBlock>)(object)block2).name = "MOVEDBYAPI_" + ((GameDataBlockBase<RundownDataBlock>)(object)block2).name;
block2.UseTierUnlockRequirements = false;
RemoveRequirementFromList(block2.TierA);
RemoveRequirementFromList(block2.TierB);
RemoveRequirementFromList(block2.TierC);
RemoveRequirementFromList(block2.TierD);
RemoveRequirementFromList(block2.TierE);
GameDataBlockBase<RundownDataBlock>.RemoveBlockByID(block.RundownIdToLoad);
GameDataBlockBase<RundownDataBlock>.AddBlock(block2, -1);
block.RundownIdToLoad = 1u;
}
else
{
APILogger.Error("GameDataInit_Patches", "GameSetupDataBlock points to an invalid Rundown Id");
}
}
goto IL_02c6;
IL_02c6:
GameDataAPI.InvokeGameDataInit();
if (!APIStatus.Network.Created)
{
APIStatus.CreateApi<NetworkAPI_Impl>("Network");
}
}
private static void RemoveRequirementFromList(List<ExpeditionInTierData> list)
{
//IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Invalid comparison between Unknown and I4
Enumerator<ExpeditionInTierData> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
ExpeditionInTierData current = enumerator.Current;
if (current.Enabled)
{
eExpeditionAccessibility accessibility = current.Accessibility;
if ((int)accessibility == 0 || accessibility - 4 <= 1)
{
current.Accessibility = (eExpeditionAccessibility)2;
}
}
}
}
}
[HarmonyPatch(typeof(GearManager))]
internal static class GearManager_Patches
{
private unsafe delegate IntPtr ReadFromDiskDelegate(IntPtr path, byte* createNew, Il2CppMethodInfo* methodInfo);
private unsafe delegate void SaveToDiskDelegate(IntPtr path, IntPtr obj, Il2CppMethodInfo* methodInfo);
private static bool m_PatchApplied;
private static INativeDetour s_ReadFromDiskDetour;
private static ReadFromDiskDelegate s_ReadFromDiskOriginal;
private static INativeDetour s_SaveToDiskDetour;
private static SaveToDiskDelegate s_SaveToDiskOriginal;
private static string FavoritesDirectory => Path.Combine(Paths.ConfigPath, "Favorites");
private static string FavoritePath => Path.Combine(FavoritesDirectory, "Gear.json");
private static string BotFavoritePath => Path.Combine(FavoritesDirectory, "BotGear.json");
[HarmonyPatch("Setup")]
[HarmonyWrapSafe]
[HarmonyPrefix]
private unsafe static void Setup_Prefix()
{
if (!m_PatchApplied)
{
if (!Directory.Exists(FavoritesDirectory))
{
Directory.CreateDirectory(FavoritesDirectory);
}
string methodName = "SaveToDisk";
APILogger.Verbose("GearManager_Patches", "Applying ReadFromDisk Patch");
s_ReadFromDiskDetour = Il2CppAPI.CreateGenericDetour<CellJSON, ReadFromDiskDelegate>("ReadFromDisk", "T", new string[2]
{
typeof(string).FullName,
typeof(bool).MakeByRefType().FullName
}, new Type[1] { typeof(GearFavoritesData) }, (ReadFromDiskDelegate)Patch_ReadFromDisk, out s_ReadFromDiskOriginal);
APILogger.Verbose("GearManager_Patches", "Applying SaveToDisk Patch");
s_SaveToDiskDetour = Il2CppAPI.CreateGenericDetour<CellJSON, SaveToDiskDelegate>(methodName, typeof(void).FullName, new string[2]
{
typeof(string).FullName,
"T"
}, new Type[1] { typeof(GearFavoritesData) }, (SaveToDiskDelegate)Patch_SaveToDisk, out s_SaveToDiskOriginal);
m_PatchApplied = true;
}
}
private unsafe static IntPtr Patch_ReadFromDisk(IntPtr path, byte* createNew, Il2CppMethodInfo* methodInfo)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
string text = String.op_Implicit(new String(path));
if (text.EndsWith("GTFO_Favorites.txt", StringComparison.OrdinalIgnoreCase))
{
return s_ReadFromDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(FavoritePath), createNew, methodInfo);
}
if (text.EndsWith("GTFO_BotFavorites.txt", StringComparison.OrdinalIgnoreCase))
{
return s_ReadFromDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(BotFavoritePath), createNew, methodInfo);
}
return s_ReadFromDiskOriginal(path, createNew, methodInfo);
}
private unsafe static void Patch_SaveToDisk(IntPtr path, IntPtr favData, Il2CppMethodInfo* methodInfo)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
string text = String.op_Implicit(new String(path));
if (text.EndsWith("GTFO_Favorites.txt", StringComparison.OrdinalIgnoreCase))
{
s_SaveToDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(FavoritePath), favData, methodInfo);
}
else if (text.EndsWith("GTFO_BotFavorites.txt", StringComparison.OrdinalIgnoreCase))
{
s_SaveToDiskOriginal(IL2CPP.ManagedStringToIl2Cpp(BotFavoritePath), favData, methodInfo);
if (File.Exists(text))
{
File.Delete(text);
}
}
else
{
s_SaveToDiskOriginal(path, favData, methodInfo);
}
}
}
[HarmonyPatch(typeof(SNet_Replication))]
internal class SNet_Replication_Patches
{
[HarmonyPatch("RecieveBytes")]
[HarmonyWrapSafe]
[HarmonyPrefix]
public static bool RecieveBytes_Prefix(Il2CppStructArray<byte> bytes, uint size, ulong messagerID)
{
if (size < 12)
{
return true;
}
byte[] array = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)bytes);
ushort num = BitConverter.ToUInt16(array, 0);
if (NetworkAPI_Impl.Instance.m_ReplicatorKey == num)
{
string @string = Encoding.ASCII.GetString(array, 2, 9);
if (@string != "GAPI_KSQK")
{
APILogger.Verbose("NetworkApi", $"Received invalid magic from {messagerID} ({@string} != {9}).");
return true;
}
ulong num2 = BitConverter.ToUInt64(array, 11);
if ((num2 & 0xFF00000000000000uL) != 18374686479671623680uL)
{
APILogger.Verbose("NetworkApi", $"Received invalid version signature from {messagerID}.");
return true;
}
if (num2 != NetworkAPI_Impl.Instance.m_Signature)
{
APILogger.Error("NetworkApi", $"Received incompatible version signature, cannot unmask packet. Is {messagerID} on the same version?. ({num2} != {NetworkAPI_Impl.Instance.m_Signature})");
return false;
}
ushort num3 = BitConverter.ToUInt16(array, 19);
string string2 = Encoding.UTF8.GetString(array, 21, num3);
if (!NetworkAPI.IsEventRegistered(string2))
{
APILogger.Error("NetworkApi", $"{messagerID} invoked an event {string2} which isn't registered.");
return false;
}
NetworkAPI_Impl.Instance.HandlePacket(string2, messagerID, array, 21 + num3);
return false;
}
return true;
}
}
}
namespace GTFO.API.Patches.Native
{
internal class SyringeFirstPerson_Patch : NativePatch<SyringeFirstPerson_Patch.SyringeUsedDelegate>
{
[UnmanagedFunctionPointer(CallingConvention.FastCall)]
public unsafe delegate eSyringeType SyringeUsedDelegate(void* pSyringe);
public unsafe override void* MethodPtr => Il2CppAPI.GetIl2CppMethod<_ApplySyringe_d__18>("MoveNext", "System.Boolean", isGeneric: false, Array.Empty<string>());
public override string JmpStartSig => "Æ\u0081\u00b4\0\0\0\u0001\u008b\u0087Ð\u0001\0\0\u0085À";
public override string JmpStartMask => "xxxxxxxxxxxxxxx";
public override byte[] CodeCave => new byte[10] { 198, 129, 180, 0, 0, 0, 1, 72, 137, 249 };
public override uint TrampolineSize => 13u;
public unsafe override SyringeUsedDelegate To => OnSyringeApplyEffect;
public unsafe static eSyringeType OnSyringeApplyEffect(void* pSyringe)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
SyringeFirstPerson val = new SyringeFirstPerson(new IntPtr(pSyringe));
if (PrefabAPI.OnSyringeUsed(val))
{
return (eSyringeType)(-1);
}
return val.m_type;
}
}
}
namespace GTFO.API.Native
{
internal static class Kernel32
{
[DllImport("kernel32.dll")]
public unsafe static extern void* VirtualAlloc(void* lpAddress, ulong dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public unsafe static extern bool VirtualProtect(void* lpAddress, ulong dwSize, uint flNewProtect, uint* lpflOldProtect);
}
internal static class MSVCRT
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern void* memcpy(void* destination, void* source, long num);
}
public abstract class NativePatch<T> where T : Delegate
{
private static readonly byte[] s_CodeCaveHeader = new byte[4] { 72, 131, 236, 40 };
private static readonly byte[] s_CodeCaveFooter = new byte[17]
{
72, 184, 0, 0, 0, 0, 0, 0, 0, 0,
255, 208, 72, 131, 196, 40, 195
};
public abstract byte[] CodeCave { get; }
public unsafe abstract void* MethodPtr { get; }
public abstract string JmpStartSig { get; }
public abstract string JmpStartMask { get; }
public abstract uint TrampolineSize { get; }
public abstract T To { get; }
public unsafe virtual void Apply()
{
void* ptr = MemoryUtils.FindSignatureInBlock(MethodPtr, 4096uL, JmpStartSig, JmpStartMask, 0uL);
void* end = (void*)((ulong)ptr + (ulong)TrampolineSize);
void* ptr2 = Kernel32.VirtualAlloc(null, (ulong)(s_CodeCaveHeader.Length + CodeCave.Length + s_CodeCaveFooter.Length), 12288u, 64u);
fixed (byte* source = s_CodeCaveHeader)
{
MSVCRT.memcpy(ptr2, source, s_CodeCaveHeader.Length);
}
fixed (byte* source2 = CodeCave)
{
MSVCRT.memcpy((void*)((ulong)ptr2 + (ulong)s_CodeCaveHeader.Length), source2, CodeCave.Length);
}
void* ptr3 = (void*)((long)ptr2 + (long)s_CodeCaveHeader.Length + CodeCave.Length);
fixed (byte* source3 = s_CodeCaveFooter)
{
MSVCRT.memcpy(ptr3, source3, s_CodeCaveFooter.Length);
}
*(long*)((ulong)ptr3 + 2uL) = Marshal.GetFunctionPointerForDelegate(To).ToInt64();
APILogger.Verbose("NativePatch", $"Method: 0x{MethodPtr:X2}, Trampoline: 0x{ptr:X2}, Code Cave: 0x{ptr2:X2}");
MemoryUtils.CreateTrampolineBetween(ptr, end, ptr2);
}
}
}
namespace GTFO.API.JSON
{
public static class JsonSerializer
{
private static JsonSerializerOptions s_DefaultSerializerSettings;
public static JsonSerializerOptions DefaultSerializerSettings
{
get
{
if (s_DefaultSerializerSettings == null)
{
s_DefaultSerializerSettings = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
IncludeFields = false,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
IgnoreReadOnlyProperties = true
};
s_DefaultSerializerSettings.Converters.Add(new JsonStringEnumConverter());
s_DefaultSerializerSettings.Converters.Add(new Vector2Converter());
s_DefaultSerializerSettings.Converters.Add(new Vector3Converter());
s_DefaultSerializerSettings.Converters.Add(new ColorConverter());
}
return s_DefaultSerializerSettings;
}
}
public static string Serialize(object value, JsonSerializerOptions options = null)
{
if (options == null)
{
options = DefaultSerializerSettings;
}
return System.Text.Json.JsonSerializer.Serialize(value, options);
}
public static T Deserialize<T>(string json, JsonSerializerOptions options = null)
{
if (options == null)
{
options = DefaultSerializerSettings;
}
return System.Text.Json.JsonSerializer.Deserialize<T>(json, options);
}
}
}
namespace GTFO.API.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 (!RegexUtils.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 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 (!RegexUtils.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 (!RegexUtils.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 GTFO.API.Extensions
{
public static class ListExtensions
{
public static List<T> ToIl2Cpp<T>(this List<T> list)
{
List<T> val = new List<T>(list.Count);
for (int i = 0; i < list.Count; i++)
{
val.Add(list[i]);
}
return val;
}
}
}
namespace GTFO.API.Components
{
public class ConsumableInstance : ItemWrapped
{
public ConsumableInstance(IntPtr hdl)
: base(hdl)
{
}
}
}
namespace GTFO.API.Attributes
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
internal class APIAttribute : Attribute
{
public string Name;
public APIAttribute(string name)
{
Name = name;
}
}
[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
internal class Il2CppInterfaceAttribute : Attribute
{
public Type Type;
public Il2CppInterfaceAttribute(Type type)
{
Type = type;
}
}
}
namespace GTFO.API.Impl
{
internal class AssetAPI_Impl : MonoBehaviour
{
private static AssetAPI_Impl s_Instance;
public static AssetAPI_Impl Instance
{
get
{
if ((Object)(object)s_Instance == (Object)null)
{
AssetAPI_Impl assetAPI_Impl = Object.FindObjectOfType<AssetAPI_Impl>();
if ((Object)(object)assetAPI_Impl != (Object)null)
{
s_Instance = assetAPI_Impl;
}
}
return s_Instance;
}
}
public AssetAPI_Impl(IntPtr intPtr)
: base(intPtr)
{
}
private void Awake()
{
s_Instance = this;
APIStatus.Asset.Ready = true;
foreach (KeyValuePair<string, Object> item in AssetAPI.s_RegistryCache)
{
RegisterAsset(item.Key, item.Value);
}
AssetAPI.s_RegistryCache.Clear();
AssetAPI.InvokeImplReady();
}
public void RegisterAsset(string name, Object gameObject)
{
string text = name.ToUpper();
if (AssetShardManager.s_loadedAssetsLookup.ContainsKey(text))
{
throw new ArgumentException("The asset with " + name + " has already been registered.", "name");
}
APILogger.Verbose("AssetAPI_Impl", "Registering asset: " + name);
AssetShardManager.s_loadedAssetsLookup.Add(text, gameObject);
}
}
internal interface INetworkingEventInfo
{
string Name { get; }
Type EventType { get; }
int EventTypeSize { get; }
byte[] EventNameBytes { get; }
void InvokeOnReceive(ulong sender, object payload);
}
internal class NetworkingEventInfo<T> : INetworkingEventInfo where T : struct
{
public string Name { get; set; }
public Action<ulong, T> OnReceive { get; set; }
public Type EventType { get; set; }
public int EventTypeSize { get; set; }
public byte[] EventNameBytes { get; set; }
public void InvokeOnReceive(ulong sender, object payload)
{
if (payload is T)
{
T arg = (T)payload;
OnReceive?.Invoke(sender, arg);
}
}
}
internal class NetworkAPI_Impl : MonoBehaviour
{
public ushort m_ReplicatorKey = 65533;
public ulong m_Signature = 18374688137539712817uL;
private readonly Dictionary<string, INetworkingEventInfo> m_Events = new Dictionary<string, INetworkingEventInfo>();
private static readonly byte[] s_MagicBytes = Encoding.ASCII.GetBytes("GAPI_KSQK");
private static NetworkAPI_Impl s_Instance;
public static NetworkAPI_Impl Instance
{
get
{
if ((Object)(object)s_Instance == (Object)null)
{
NetworkAPI_Impl networkAPI_Impl = Object.FindObjectOfType<NetworkAPI_Impl>();
if ((Object)(object)networkAPI_Impl != (Object)null)
{
s_Instance = networkAPI_Impl;
}
}
return s_Instance;
}
}
public NetworkAPI_Impl(IntPtr intPtr)
: base(intPtr)
{
}
private void Awake()
{
s_Instance = this;
APIStatus.Network.Ready = true;
foreach (KeyValuePair<string, NetworkAPI.CachedEvent> item in NetworkAPI.s_EventCache)
{
typeof(NetworkAPI_Impl).GetMethod("RegisterEvent").MakeGenericMethod(item.Value.Type).Invoke(this, new object[2]
{
item.Key,
item.Value.OnReceive
});
}
NetworkAPI.s_EventCache.Clear();
}
internal unsafe static void XORPacket(ref byte[] packetBytes, ulong versionSig, int offset)
{
fixed (byte* ptr = packetBytes)
{
XORPacketImpl(ptr + offset, (uint)(packetBytes.Length - offset), (byte*)(&versionSig));
}
}
internal unsafe static void XORPacketImpl(byte* pPacket, uint packetLength, byte* pVersion)
{
for (int i = 0; i < packetLength; i++)
{
pPacket[i] ^= pVersion[i % 8];
}
}
[HideFromIl2Cpp]
public void HandlePacket(string eventName, ulong senderId, byte[] packetData, int startIndex = 0)
{
INetworkingEventInfo networkingEventInfo = m_Events[eventName];
Type eventType = networkingEventInfo.EventType;
XORPacket(ref packetData, m_Signature, startIndex);
int num = Marshal.SizeOf(eventType);
IntPtr intPtr = Marshal.AllocHGlobal(num);
Marshal.Copy(packetData, startIndex, intPtr, num);
object payload = Marshal.PtrToStructure(intPtr, eventType);
Marshal.FreeHGlobal(intPtr);
networkingEventInfo.InvokeOnReceive(senderId, payload);
}
[HideFromIl2Cpp]
public void RegisterEvent<T>(string eventName, Action<ulong, T> onReceive) where T : struct
{
if (EventExists(eventName))
{
throw new ArgumentException($"Type {typeof(T)} is a generic and cannot be registered.", "eventName");
}
if (typeof(T).IsGenericType)
{
throw new ArgumentException("Generic type is not allowed to register", "T");
}
NetworkingEventInfo<T> value = new NetworkingEventInfo<T>
{
Name = eventName,
OnReceive = onReceive,
EventType = typeof(T),
EventTypeSize = Marshal.SizeOf<T>(),
EventNameBytes = Encoding.UTF8.GetBytes(eventName)
};
m_Events.Add(eventName, value);
}
[HideFromIl2Cpp]
public bool EventExists(string eventName)
{
return m_Events.ContainsKey(eventName);
}
[HideFromIl2Cpp]
public byte[] MakePacketBytes<T>(string eventName, T payload) where T : struct
{
if (!m_Events.TryGetValue(eventName, out var value))
{
throw new ArgumentException("An event with the name " + eventName + " was not registered.", "eventName");
}
if (value.EventType != typeof(T))
{
throw new ArgumentException("Payload type was incorrect! expecting: " + typeof(T).FullName, "eventName");
}
byte[] eventNameBytes = value.EventNameBytes;
int num = 21 + eventNameBytes.Length + value.EventTypeSize;
IntPtr intPtr;
IntPtr intPtr2 = (intPtr = Marshal.AllocHGlobal(num));
Marshal.WriteInt16(intPtr, (short)m_ReplicatorKey);
intPtr += 2;
Marshal.Copy(s_MagicBytes, 0, intPtr, 9);
intPtr += 9;
Marshal.WriteInt64(intPtr, (long)m_Signature);
intPtr += 8;
Marshal.WriteInt16(intPtr, (short)eventNameBytes.Length);
intPtr += 2;
Marshal.Copy(eventNameBytes, 0, intPtr, eventNameBytes.Length);
intPtr += eventNameBytes.Length;
Marshal.StructureToPtr(payload, intPtr, fDeleteOld: true);
byte[] packetBytes = new byte[num];
Marshal.Copy(intPtr2, packetBytes, 0, num);
Marshal.FreeHGlobal(intPtr2);
XORPacket(ref packetBytes, m_Signature, 21 + eventNameBytes.Length);
return packetBytes;
}
}
}