Decompiled source of TakeyPlush v1.13.0
com.github.zehsteam.TakeyGokuBracken.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using GokuBracken.Core; using GokuBracken.Scripts; using Hallucinoceps; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Steamworks; using Unity.Netcode; using UnityEngine; using com.github.zehsteam.TakeyGokuBracken.Data; using com.github.zehsteam.TakeyGokuBracken.Dependencies; using com.github.zehsteam.TakeyGokuBracken.Dependencies.GokuBrackenProxy; using com.github.zehsteam.TakeyGokuBracken.Dependencies.GokuBrackenProxy.Patches; using com.github.zehsteam.TakeyGokuBracken.MonoBehaviours; using com.github.zehsteam.TakeyGokuBracken.NetcodePatcher; using com.github.zehsteam.TakeyGokuBracken.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.zehsteam.TakeyGokuBracken")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Adds 2 scrap and 1 enemy reskin. Requires the GokuBracken mod to be installed for most features. (This mod is included with the TakeyPlush mod)")] [assembly: AssemblyFileVersion("1.4.0.0")] [assembly: AssemblyInformationalVersion("1.4.0+118102ffa96c047aa0286cfa3b1a2fb77f5cfdc1")] [assembly: AssemblyProduct("TakeyGokuBracken")] [assembly: AssemblyTitle("com.github.zehsteam.TakeyGokuBracken")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace com.github.zehsteam.TakeyGokuBracken { public static class Api { public static Dictionary<FlowermanAI, TakeyGokuBrackenBehaviour> EnemyControllerPairs => FlowermanAIPatch.EnemyControllerPairs; public static int TakeyGokuBrackenMaxSpawnCount => Plugin.ConfigManager.TakeyGokuBracken_MaxSpawnCount.Value; public static int TakeyGokuBrackenSpawnChance => Plugin.ConfigManager.TakeyGokuBracken_SpawnChance.Value; public static int TakeyGokuBrackenSpawnCount => FlowermanAIPatch.TakeyGokuBrackenSpawnCount; public static bool ForceTakeyGokuBrackenSpawns { get { return FlowermanAIPatch.ForceTakeyGokuBrackenSpawns; } set { FlowermanAIPatch.ForceTakeyGokuBrackenSpawns = value; } } public static int ForceTakeyGokuBrackenMaxSpawnCount { get { return FlowermanAIPatch.ForceTakeyGokuBrackenMaxSpawnCount; } set { FlowermanAIPatch.ForceTakeyGokuBrackenMaxSpawnCount = value; } } public static bool SetTakeyGokuBrackenOnServer(FlowermanAI flowermanAI) { return Plugin.Instance.SetTakeyGokuBrackenOnServer(flowermanAI); } } internal static class ConfigHelper { public static void SetModIcon(Sprite sprite) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SetModIcon(sprite); } } public static void SetModDescription(string description) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SetModDescription(description); } } public static void SkipAutoGen() { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SkipAutoGen(); } } public static void AddButton(string section, string name, string description, string buttonText, Action callback) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.AddButton(section, name, description, buttonText, callback); } } public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (configFile == null) { configFile = ((BaseUnityPlugin)Plugin.Instance).Config; } ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>()))); if (settingChanged != null) { configEntry.SettingChanged += delegate { settingChanged?.Invoke(configEntry.Value); }; } if (LethalConfigProxy.Enabled) { LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart); } return configEntry; } public static Dictionary<ConfigDefinition, string> GetOrphanedConfigEntries(ConfigFile configFile = null) { if (configFile == null) { configFile = ((BaseUnityPlugin)Plugin.Instance).Config; } PropertyInfo property = ((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); return (Dictionary<ConfigDefinition, string>)property.GetValue(configFile, null); } public static void SetConfigEntryValue<T>(ConfigEntry<T> configEntry, string value) { if (typeof(T) == typeof(int) && int.TryParse(value, out var result)) { configEntry.Value = (T)(object)result; return; } if (typeof(T) == typeof(float) && float.TryParse(value, out var result2)) { configEntry.Value = (T)(object)result2; return; } if (typeof(T) == typeof(double) && double.TryParse(value, out var result3)) { configEntry.Value = (T)(object)result3; return; } if (typeof(T) == typeof(bool) && bool.TryParse(value, out var result4)) { configEntry.Value = (T)(object)result4; return; } if (typeof(T) == typeof(string)) { configEntry.Value = (T)(object)value; return; } throw new InvalidOperationException($"Unsupported type: {typeof(T)}"); } public static void ClearUnusedEntries(ConfigFile configFile = null) { if (configFile == null) { configFile = ((BaseUnityPlugin)Plugin.Instance).Config; } Dictionary<ConfigDefinition, string> orphanedConfigEntries = GetOrphanedConfigEntries(configFile); if (orphanedConfigEntries != null) { orphanedConfigEntries.Clear(); configFile.Save(); } } } internal class ConfigManager { public ConfigEntry<bool> ExtendedLogging { get; private set; } public ConfigEntry<bool> EnablePlushies { get; private set; } public ConfigEntry<int> TakeyGokuBracken_MaxSpawnCount { get; private set; } public ConfigEntry<int> TakeyGokuBracken_SpawnChance { get; private set; } public ItemConfigData SmolTakeyGokuPlushie { get; private set; } public ItemConfigData TakeyGokuPlushie { get; private set; } public ConfigManager() { BindConfigs(); MigrateOldConfigSettings(); ConfigHelper.ClearUnusedEntries(); } private void BindConfigs() { ConfigHelper.SkipAutoGen(); ExtendedLogging = ConfigHelper.Bind("General", "ExtendedLogging", defaultValue: false, requiresRestart: false, "Enable extended logging."); EnablePlushies = ConfigHelper.Bind("General", "EnablePlushies", defaultValue: false, requiresRestart: false, "Enable plushies without needing the GokuBracken mod installed."); EnablePlushies.SettingChanged += EnablePlushies_SettingChanged; TakeyGokuBracken_MaxSpawnCount = ConfigHelper.Bind("Takey Goku Bracken", "MaxSpawnCount", 999, requiresRestart: false, "Takey Goku Bracken max spawn count."); TakeyGokuBracken_SpawnChance = ConfigHelper.Bind("Takey Goku Bracken", "SpawnChance", 25, requiresRestart: false, "The percent chance a Goku Bracken turns into a Takey Goku Bracken."); SmolTakeyGokuPlushie = new ItemConfigData(Content.SmolTakeyGokuPlushie, "Smol Takey Goku Plushie", 10, twoHanded: false, 6, 80, 250); TakeyGokuPlushie = new ItemConfigData(Content.TakeyGokuPlushie, "Takey Goku Plushie", 10, twoHanded: true, 69, 255, 525); } private void EnablePlushies_SettingChanged(object sender, EventArgs e) { foreach (ItemConfigData instance in ItemConfigData.Instances) { instance.RefreshConfigData(); } } private void MigrateOldConfigSettings() { foreach (KeyValuePair<ConfigDefinition, string> orphanedConfigEntry in ConfigHelper.GetOrphanedConfigEntries()) { MigrateOldConfigSetting(orphanedConfigEntry.Key.Section, orphanedConfigEntry.Key.Key, orphanedConfigEntry.Value); } } private void MigrateOldConfigSetting(string section, string key, string value) { if (section == "General Settings") { if (!(key == "ExtendedLogging")) { if (key == "EnablePlushies") { ConfigHelper.SetConfigEntryValue<bool>(EnablePlushies, value); } } else { ConfigHelper.SetConfigEntryValue<bool>(ExtendedLogging, value); } } if (!(section == "Takey Goku Bracken Settings")) { return; } if (!(key == "MaxSpawnCount")) { if (key == "SpawnChance") { ConfigHelper.SetConfigEntryValue<int>(TakeyGokuBracken_SpawnChance, value); } } else { ConfigHelper.SetConfigEntryValue<int>(TakeyGokuBracken_MaxSpawnCount, value); } } } internal static class Content { public static GameObject NetworkHandlerPrefab { get; private set; } public static GameObject TakeyGokuBrackenControllerPrefab { get; private set; } public static Item SmolTakeyGokuPlushie { get; private set; } public static Item TakeyGokuPlushie { get; private set; } public static HallucinocepsAssets HallucinocepsAssets { get; private set; } public static Sprite ModIcon { get; private set; } public static void Load() { LoadAssetsFromAssetBundle(); } private static void LoadAssetsFromAssetBundle() { AssetBundle val = LoadAssetBundle("takeygokubracken_assets"); if (!((Object)(object)val == (Object)null)) { NetworkHandlerPrefab = LoadAssetFromAssetBundle<GameObject>("NetworkHandler", val); NetworkHandlerPrefab.AddComponent<PluginNetworkBehaviour>(); TakeyGokuBrackenControllerPrefab = LoadAssetFromAssetBundle<GameObject>("TakeyGokuBrackenController", val); SmolTakeyGokuPlushie = LoadAssetFromAssetBundle<Item>("SmolTakeyGokuPlushie", val); TakeyGokuPlushie = LoadAssetFromAssetBundle<Item>("TakeyGokuPlushie", val); HallucinocepsAssets = LoadAssetFromAssetBundle<HallucinocepsAssets>("HallucinocepsAssets", val); ModIcon = LoadAssetFromAssetBundle<Sprite>("ModIcon", val); Plugin.Logger.LogInfo((object)"Successfully loaded assets from AssetBundle!"); } } private static AssetBundle LoadAssetBundle(string fileName) { try { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location); string text = Path.Combine(directoryName, fileName); return AssetBundle.LoadFromFile(text); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to load AssetBundle \"{fileName}\". {arg}"); } return null; } private static T LoadAssetFromAssetBundle<T>(string name, AssetBundle assetBundle) where T : Object { if (string.IsNullOrWhiteSpace(name)) { Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace.")); return default(T); } if ((Object)(object)assetBundle == (Object)null) { Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null.")); return default(T); } T val = assetBundle.LoadAsset<T>(name); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name.")); return default(T); } return val; } } internal static class ItemHelper { public static void RegisterScrap(Item item, int rarity, bool twoHanded, int carryWeight, int minValue, int maxValue) { if ((Object)(object)item == (Object)null) { Plugin.Logger.LogError((object)"Failed to register scrap item. Item is null."); return; } item.twoHanded = twoHanded; item.weight = (float)carryWeight / 105f + 1f; item.minValue = minValue; item.maxValue = maxValue; Utilities.FixMixerGroups(item.spawnPrefab); NetworkPrefabs.RegisterNetworkPrefab(item.spawnPrefab); Items.RegisterScrap(item, rarity, (LevelTypes)(-1)); Plugin.Logger.LogInfo((object)$"Registered \"{item.itemName}\" scrap item. (Rarity: {rarity}, TwoHanded: {twoHanded}, CarryWeight: {carryWeight}, MinValue: {minValue}, MaxValue: {maxValue})"); } public static void RegisterScrap(ItemConfigData itemConfigData) { RegisterScrap(itemConfigData.Item, itemConfigData.SpawnWeightValue, itemConfigData.TwoHanded.Value, itemConfigData.CarryWeight.Value, itemConfigData.MinValue.Value, itemConfigData.MaxValue.Value); } public static void UpdateScrapRarity(Item item, int rarity) { if ((Object)(object)item == (Object)null) { Plugin.Logger.LogError((object)"Failed to update scrap item rarity. Item is null."); return; } if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.Logger.LogError((object)"Failed to update scrap item rarity. StartOfRound instance is null."); return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { foreach (SpawnableItemWithRarity item2 in val.spawnableScrap) { if (!((Object)(object)item2.spawnableItem != (Object)(object)item)) { item2.rarity = rarity; Plugin.Logger.LogInfo((object)$"Updated \"{item.itemName}\" scrap item rarity to {rarity} on \"{val.PlanetName}\"."); } } } } public static void UpdateScrapRarity(ItemConfigData itemConfigData) { UpdateScrapRarity(itemConfigData.Item, itemConfigData.SpawnWeightValue); } public static void UpdateItemProperties(Item item, bool twoHanded, int carryWeight, int minValue, int maxValue) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { Plugin.Logger.LogError((object)"Failed to update item properties. Item is null."); return; } item.twoHanded = twoHanded; item.weight = (float)carryWeight / 105f + 1f; item.minValue = minValue; item.maxValue = maxValue; Plugin.Logger.LogInfo((object)$"Updated \"{item.itemName}\" item properties. (TwoHanded: {twoHanded}, CarryWeight: {carryWeight}, MinValue: {minValue}, MaxValue: {maxValue})"); if (NetworkUtils.IsServer) { PluginNetworkBehaviour.Instance.UpdateItemPropertiesClientRpc(item.itemName, twoHanded, carryWeight, minValue, maxValue); } } public static void UpdateItemProperties(string itemName, bool twoHanded, int carryWeight, int minValue, int maxValue) { if (!TryGetItem(itemName, out var item, matchCase: false)) { Plugin.Logger.LogError((object)("Failed to update item properties. Item is null. (ItemName: " + itemName + ")")); } else { UpdateItemProperties(item, twoHanded, carryWeight, minValue, maxValue); } } public static void UpdateItemProperties(ItemConfigData itemConfigData) { UpdateItemProperties(itemConfigData.Item, itemConfigData.TwoHanded.Value, itemConfigData.CarryWeight.Value, itemConfigData.MinValue.Value, itemConfigData.MaxValue.Value); } public static Item GetItem(string itemName, bool matchCase = true) { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.Logger.LogError((object)"Failed to get item by name. StartOfRound instance is null."); return null; } StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture); foreach (Item items in StartOfRound.Instance.allItemsList.itemsList) { if (items.itemName.Equals(itemName, comparisonType)) { return items; } } return null; } public static bool TryGetItem(string itemName, out Item item, bool matchCase = true) { item = GetItem(itemName, matchCase); return (Object)(object)item != (Object)null; } public static List<Item> GetItems(string[] itemNames, bool matchCase = true) { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.Logger.LogError((object)"Failed to get items by names. StartOfRound instance is null."); return new List<Item>(); } List<Item> list = new List<Item>(); foreach (string itemName in itemNames) { if (TryGetItem(itemName, out var item, matchCase)) { list.Add(item); } } return list; } } internal static class ModpackSaveSystem { public const string FileName = "TakeyGokuBracken_SaveData.json"; private static JObject _saveFileObject; public static string FilePath { get { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Config.ConfigFilePath); return Path.Combine(directoryName, "TakeyGokuBracken_SaveData.json"); } } public static bool FileExists => File.Exists(FilePath); public static void Initialize() { if (!FileExists) { WriteFile(JObject.Parse("{}")); } _saveFileObject = ReadFile(); } public static bool ContainsKey(string key) { return _saveFileObject.ContainsKey(key); } public static T ReadValue<T>(string key, T defaultValue = default(T)) { //IL_001e: Expected O, but got Unknown JToken val = default(JToken); if (_saveFileObject.TryGetValue(key, ref val)) { try { return val.ToObject<T>(); } catch (JsonException val2) { JsonException val3 = val2; Plugin.Logger.LogError((object)("JSON Conversion Error: " + ((Exception)(object)val3).Message)); } catch (ArgumentNullException ex) { Plugin.Logger.LogError((object)("Argument Null Error: " + ex.Message)); } catch (Exception ex2) { Plugin.Logger.LogError((object)("Unexpected Error: " + ex2.Message)); } return defaultValue; } return defaultValue; } public static void WriteValue<T>(string key, T value) { JToken val = JToken.FromObject((object)value); if (_saveFileObject.ContainsKey(key)) { _saveFileObject[key] = val; } else { _saveFileObject.Add(key, val); } WriteFile(_saveFileObject); } private static JObject ReadFile() { try { using FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite); using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); return JObject.Parse(streamReader.ReadToEnd()); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to read save file. {arg}"); } return null; } private static bool WriteFile(JObject jObject) { try { using FileStream stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); using StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8); streamWriter.WriteLine(((object)jObject).ToString()); return true; } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to write save file. {arg}"); } return false; } } internal static class NetworkUtils { public static bool IsServer { get { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return NetworkManager.Singleton.IsServer; } } public static bool IsHost { get { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return NetworkManager.Singleton.IsHost; } } public static ulong GetLocalClientId() { return NetworkManager.Singleton.LocalClientId; } public static bool IsLocalClientId(ulong clientId) { return clientId == GetLocalClientId(); } } internal static class PlayerUtils { public static ulong GetLocalClientId() { return NetworkManager.Singleton.LocalClientId; } public static ulong GetLocalPlayerId() { return GetLocalPlayerScript().playerClientId; } public static bool IsLocalPlayerId(ulong playerId) { return playerId == GetLocalPlayerId(); } public static PlayerControllerB GetLocalPlayerScript() { return GameNetworkManager.Instance.localPlayerController; } } [BepInPlugin("com.github.zehsteam.TakeyGokuBracken", "TakeyGokuBracken", "1.4.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.github.zehsteam.TakeyGokuBracken"); internal static Plugin Instance; internal static ManualLogSource Logger; internal static ConfigManager ConfigManager; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } Logger = Logger.CreateLogSource("com.github.zehsteam.TakeyGokuBracken"); Logger.LogInfo((object)"TakeyGokuBracken has awoken!"); _harmony.PatchAll(typeof(GameNetworkManagerPatch)); _harmony.PatchAll(typeof(StartOfRoundPatch)); _harmony.PatchAll(typeof(FlowermanAIPatch)); _harmony.PatchAll(typeof(PlayerControllerBPatch)); if (GokuBrackenProxy.Enabled) { GokuBrackenProxy.PatchAll(_harmony); } Content.Load(); ConfigManager = new ConfigManager(); ModpackSaveSystem.Initialize(); FlowermanAIPatch.Reset(); ConfigHelper.SetModIcon(Content.ModIcon); ConfigHelper.SetModDescription("Adds 2 scrap and 1 enemy reskin. Requires the GokuBracken mod to be installed for most features. (This mod is included with the TakeyPlush mod)"); RegisterScrapItems(); NetcodePatcherAwake(); } private void NetcodePatcherAwake() { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); Type[] types = executingAssembly.GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { try { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { try { methodInfo.Invoke(null, null); } catch (TargetInvocationException ex) { Logger.LogWarning((object)("Failed to invoke method " + methodInfo.Name + ": " + ex.Message)); } } } catch (Exception ex2) { Logger.LogWarning((object)("Error processing method " + methodInfo.Name + " in type " + type.Name + ": " + ex2.Message)); } } } } catch (Exception ex3) { Logger.LogError((object)("An error occurred in NetcodePatcherAwake: " + ex3.Message)); } } public void OnLocalDisconnect() { FlowermanAIPatch.Reset(); } public void OnShipHasLeft() { FlowermanAIPatch.DespawnAllControllers(); FlowermanAIPatch.Reset(); ForceDespawnAllTakeyGokuBrackenControllersOnServer(); } private void RegisterScrapItems() { ItemHelper.RegisterScrap(ConfigManager.SmolTakeyGokuPlushie); ItemHelper.RegisterScrap(ConfigManager.TakeyGokuPlushie); } public bool SetTakeyGokuBrackenOnServer(FlowermanAI flowermanAI) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (!NetworkUtils.IsServer) { return false; } if ((Object)(object)flowermanAI == (Object)null) { Logger.LogError((object)"Failed to set Takey Goku Bracken on server. FlowermanAI is null."); return false; } NetworkObject component = ((Component)flowermanAI).GetComponent<NetworkObject>(); if (GokuBrackenProxy.Enabled && !GokuBrackenProxy.IsGokuBracken(flowermanAI)) { Logger.LogError((object)$"Failed to set Takey Goku Bracken on server. Enemy is not a Goku Bracken. (NetworkObject: {component.NetworkObjectId})"); return false; } if (Utils.IsTakeyGokuBracken(flowermanAI)) { Logger.LogWarning((object)$"Warning: Failed to set Takey Goku Bracken on server. Enemy is already a Takey Goku Bracken. (NetworkObject: {component.NetworkObjectId})"); return false; } SpawnTakeyGokuControllerOnServer(((Component)component).transform); PluginNetworkBehaviour.Instance.SetTakeyGokuClientRpc(NetworkObjectReference.op_Implicit(component)); SetTakeyGokuBrackenOnLocalClient(component); LogInfoExtended($"Spawned Takey Goku Bracken. (NetworkObject: {component.NetworkObjectId})"); return true; } public void SetTakeyGokuBrackenOnLocalClient(NetworkObject enemyNetworkObject) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) if (!GokuBrackenProxy.Enabled) { return; } FlowermanAI val = default(FlowermanAI); if ((Object)(object)enemyNetworkObject == (Object)null) { Logger.LogError((object)"Failed to set Takey Goku Bracken on local client. Enemy NetworkObject is null."); } else if (((Component)enemyNetworkObject).TryGetComponent<FlowermanAI>(ref val)) { if (GokuBrackenProxy.Enabled && !GokuBrackenProxy.IsGokuBracken(val)) { Logger.LogError((object)$"Failed to set Takey Goku Bracken on local client. Enemy \"{((Object)((Component)enemyNetworkObject).gameObject).name}\" is not a Goku Bracken. (NetworkObject: {enemyNetworkObject.NetworkObjectId})"); return; } if (!FlowermanAIPatch.EnemyControllerPairs.ContainsKey(val)) { try { Transform val2 = ((Component)enemyNetworkObject).transform.Find("TakeyGokuBrackenController(Clone)"); val2.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); FlowermanAIPatch.AddEnemyControllerPair(val, ((Component)val2).GetComponent<TakeyGokuBrackenBehaviour>()); LogInfoExtended($"Initialized Takey Goku Bracken on local client. (NetworkObject: {enemyNetworkObject.NetworkObjectId})"); return; } catch (Exception arg) { Logger.LogError((object)$"Failed to set Takey Goku Bracken on local client. (NetworkObject: {enemyNetworkObject.NetworkObjectId})\n\n{arg}"); return; } } Logger.LogWarning((object)$"Failed to set Takey Goku Bracken on local client. Enemy is already a Takey Goku Bracken. (NetworkObject: {enemyNetworkObject.NetworkObjectId})"); } else { Logger.LogError((object)$"Failed to set Takey Goku Bracken on local client. Could not find FlowermanAI. (NetworkObject: {enemyNetworkObject.NetworkObjectId})"); } } private NetworkObject SpawnTakeyGokuControllerOnServer(Transform parentTransform) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!NetworkUtils.IsServer) { return null; } GameObject val = Object.Instantiate<GameObject>(Content.TakeyGokuBrackenControllerPrefab, Vector3.zero, Quaternion.identity, parentTransform); NetworkObject component = val.GetComponent<NetworkObject>(); component.Spawn(true); val.transform.SetParent(parentTransform); return component; } private void ForceDespawnAllTakeyGokuBrackenControllersOnServer() { if (!NetworkUtils.IsServer) { return; } TakeyGokuBrackenBehaviour[] array = Object.FindObjectsByType<TakeyGokuBrackenBehaviour>((FindObjectsSortMode)0); if (array.Length == 0) { return; } Transform[] array2 = (from x in array select ((Component)x).transform.parent into x where (Object)(object)x != (Object)null select x).ToArray(); Transform[] array3 = array2; NetworkObject val2 = default(NetworkObject); foreach (Transform val in array3) { if (((Component)val).TryGetComponent<NetworkObject>(ref val2)) { if (!val2.IsSpawned) { Logger.LogError((object)"Failed to force despawn Takey Goku Bracken controller. NetworkObject is not spawned."); break; } val2.Despawn(true); LogInfoExtended("Force despawned Takey Goku Bracken controller."); } else { Logger.LogError((object)"Failed to force despawn Takey Goku Bracken controller. NetworkObject is null."); } } } public void LogInfoExtended(object data) { LogExtended((LogLevel)16, data); } public void LogExtended(LogLevel level, object data) { //IL_0022: 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) if (ConfigManager == null || ConfigManager.ExtendedLogging == null) { Logger.Log(level, data); } else if (ConfigManager.ExtendedLogging.Value) { Logger.Log(level, data); } } } internal static class SteamUtils { public static bool IsLocalPlayerTakerst() { return IsLocalPlayer("Takerst", 76561197980238122uL); } public static bool IsLocalPlayer(string username, ulong steamId) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!SteamClient.IsValid) { return false; } if (!SteamClient.IsLoggedOn) { return false; } if (SteamClient.Name.Equals(username, StringComparison.OrdinalIgnoreCase)) { return true; } if (SteamId.op_Implicit(SteamClient.SteamId) == steamId) { return true; } return false; } } public static class Utils { public static bool RandomPercent(float percent) { if (percent <= 0f) { return false; } if (percent >= 100f) { return true; } return Random.value * 100f <= percent; } public static bool IsTakeyGokuBracken(FlowermanAI flowermanAI) { return (Object)(object)((Component)flowermanAI).GetComponentInChildren<TakeyGokuBrackenBehaviour>() != (Object)null; } public static bool IsTakeyGokuBracken(FlowermanAI flowermanAI, out TakeyGokuBrackenBehaviour behaviour) { behaviour = ((Component)flowermanAI).GetComponentInChildren<TakeyGokuBrackenBehaviour>(); return (Object)(object)behaviour != (Object)null; } public static int GetRandomIndexFromWeightList(List<int> weightList) { List<(int, int)> list = new List<(int, int)>(); for (int i = 0; i < weightList.Count; i++) { int num = weightList[i]; if (num > 0) { list.Add((i, num)); } } int num2 = 0; foreach (var item4 in list) { int item = item4.Item2; num2 += item; } if (num2 == 0) { return -1; } int num3 = Random.Range(0, num2); int num4 = 0; foreach (var item5 in list) { int item2 = item5.Item1; int item3 = item5.Item2; num4 += item3; if (num3 < num4) { return item2; } } throw new InvalidOperationException("Weights are not properly specified."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.TakeyGokuBracken"; public const string PLUGIN_NAME = "TakeyGokuBracken"; public const string PLUGIN_VERSION = "1.4.0"; } } namespace com.github.zehsteam.TakeyGokuBracken.Patches { [HarmonyPatch(typeof(FlowermanAI))] internal static class FlowermanAIPatch { public static int TakeyGokuBrackenSpawnCount = 0; public static bool ForceTakeyGokuBrackenSpawns = false; public static int ForceTakeyGokuBrackenMaxSpawnCount = -1; public static Dictionary<FlowermanAI, TakeyGokuBrackenBehaviour> EnemyControllerPairs { get; private set; } = new Dictionary<FlowermanAI, TakeyGokuBrackenBehaviour>(); public static void Reset() { EnemyControllerPairs = new Dictionary<FlowermanAI, TakeyGokuBrackenBehaviour>(); TakeyGokuBrackenSpawnCount = 0; ForceTakeyGokuBrackenSpawns = false; ForceTakeyGokuBrackenMaxSpawnCount = -1; } public static void AddEnemyControllerPair(FlowermanAI flowermanAI, TakeyGokuBrackenBehaviour controllerScript) { EnemyControllerPairs.Add(flowermanAI, controllerScript); } public static void DespawnAllControllers() { if (!NetworkUtils.IsServer) { return; } foreach (TakeyGokuBrackenBehaviour value in EnemyControllerPairs.Values) { DespawnController(value); } EnemyControllerPairs.Clear(); Plugin.Instance.LogInfoExtended("Finished despawning all Takey Goku Bracken controllers."); } public static void DespawnController(FlowermanAI flowermanAI) { if (!NetworkUtils.IsServer) { return; } NetworkObject component = ((Component)flowermanAI).GetComponent<NetworkObject>(); TakeyGokuBrackenBehaviour value; if ((Object)(object)component == (Object)null) { Plugin.Logger.LogError((object)"Failed to despawn Takey Goku Bracken controller. Enemy NetworkObject is null."); } else if (EnemyControllerPairs.TryGetValue(flowermanAI, out value)) { try { DespawnController(value); EnemyControllerPairs.Remove(flowermanAI); Plugin.Instance.LogInfoExtended($"Despawned Takey Goku Bracken controller (NetworkObjectId: {component.NetworkObjectId})."); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to despawn Takey Goku Bracken controller. (NetworkObjectId: {component.NetworkObjectId}).\n\n{arg}"); } } } public static void DespawnController(TakeyGokuBrackenBehaviour controllerScript) { if (NetworkUtils.IsServer) { NetworkObject component = ((Component)controllerScript).GetComponent<NetworkObject>(); if ((Object)(object)component == (Object)null) { Plugin.Logger.LogError((object)"Failed to despawn Takey Goku Bracken controller. NetworkObject is null."); } else if (!component.IsSpawned) { Plugin.Logger.LogError((object)"Failed to despawn Takey Goku Bracken controller. NetworkObject is not spawned."); } else { component.Despawn(true); } } } [HarmonyPatch("Start")] [HarmonyPostfix] [HarmonyPriority(0)] private static void StartPatch(ref FlowermanAI __instance) { if (NetworkUtils.IsServer) { ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(LateStartCO(__instance)); } } private static IEnumerator LateStartCO(FlowermanAI flowermanAI) { yield return null; TrySpawnTakeyGokuBracken(flowermanAI); } private static bool TrySpawnTakeyGokuBracken(FlowermanAI flowermanAI) { int num = Plugin.ConfigManager.TakeyGokuBracken_MaxSpawnCount.Value; int value = Plugin.ConfigManager.TakeyGokuBracken_SpawnChance.Value; if (ForceTakeyGokuBrackenMaxSpawnCount > -1) { num = ForceTakeyGokuBrackenMaxSpawnCount; } if (!ForceTakeyGokuBrackenSpawns) { if (TakeyGokuBrackenSpawnCount >= num) { return false; } if (!Utils.RandomPercent(value)) { return false; } } return Plugin.Instance.SetTakeyGokuBrackenOnServer(flowermanAI); } [HarmonyPatch("KillEnemy")] [HarmonyPrefix] private static void KillEnemyPatch(ref FlowermanAI __instance, bool destroy) { if (NetworkUtils.IsServer && Utils.IsTakeyGokuBracken(__instance) && destroy) { DespawnController(__instance); } } [HarmonyPatch("KillPlayerAnimationServerRpc")] [HarmonyPrefix] private static void KillPlayerAnimationServerRpcPatch(ref FlowermanAI __instance) { if (Utils.IsTakeyGokuBracken(__instance, out var behaviour)) { behaviour.SetRandomCrackNeckSFXOnServer(); } } } [HarmonyPatch(typeof(GameNetworkManager))] internal static class GameNetworkManagerPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { AddNetworkPrefabs(); } private static void AddNetworkPrefabs() { AddNetworkPrefab(Content.NetworkHandlerPrefab); AddNetworkPrefab(Content.TakeyGokuBrackenControllerPrefab); } private static void AddNetworkPrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { Plugin.Logger.LogError((object)"Failed to register network prefab. GameObject is null."); return; } NetworkManager.Singleton.AddNetworkPrefab(prefab); Plugin.Logger.LogInfo((object)("Registered \"" + ((Object)prefab).name + "\" network prefab.")); } } [HarmonyPatch(typeof(PlayerControllerB))] internal static class PlayerControllerBPatch { private static bool _ignoreNextFallDamage; private static Coroutine _ignoreNextFallCancelCheck; [HarmonyPatch("PlayerHitGroundEffects")] [HarmonyPrefix] private static void PlayerHitGroundEffectsPatch(ref PlayerControllerB __instance) { if (!((Object)(object)__instance != (Object)(object)PlayerUtils.GetLocalPlayerScript()) && _ignoreNextFallDamage) { _ignoreNextFallDamage = false; if (__instance.fallValueUncapped < -39f) { __instance.fallValueUncapped = -39f; } if (__instance.fallValue < -38f) { __instance.fallValue = -38f; } Plugin.Instance.LogInfoExtended("Local player ignored fall damage."); } } public static void IgnoreNextFallDamage() { _ignoreNextFallDamage = true; if (_ignoreNextFallCancelCheck != null) { ((MonoBehaviour)StartOfRound.Instance).StopCoroutine(_ignoreNextFallCancelCheck); } _ignoreNextFallCancelCheck = ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(IgnoreNextFallCancelCheck()); } private static IEnumerator IgnoreNextFallCancelCheck() { PlayerControllerB playerScript = PlayerUtils.GetLocalPlayerScript(); if ((Object)(object)playerScript == (Object)null) { _ignoreNextFallDamage = false; yield break; } yield return (object)new WaitForSeconds(1f); if (_ignoreNextFallDamage && playerScript.thisController.isGrounded) { yield return (object)new WaitForSeconds(0.1f); Plugin.Instance.LogInfoExtended("Cancelled local player ignored fall damage."); _ignoreNextFallDamage = false; } } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch() { SpawnNetworkHandler(); } private static void SpawnNetworkHandler() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (NetworkUtils.IsServer) { GameObject val = Object.Instantiate<GameObject>(Content.NetworkHandlerPrefab, Vector3.zero, Quaternion.identity); val.GetComponent<NetworkObject>().Spawn(false); } } [HarmonyPatch("Start")] [HarmonyPostfix] [HarmonyPriority(300)] private static void StartPatch() { foreach (ItemConfigData instance in ItemConfigData.Instances) { instance.RefreshConfigData(); } if (GokuBrackenProxy.Enabled && HallucinocepsProxy.Enabled) { HallucinocepsProxy.AddHallucinationSounds(); } } [HarmonyPatch("OnClientConnect")] [HarmonyPrefix] private static void OnClientConnectPatch(ref ulong clientId) { SendConfigsToNewConnectedPlayer(clientId); } private static void SendConfigsToNewConnectedPlayer(ulong clientId) { if (!NetworkUtils.IsServer) { return; } Plugin.Logger.LogInfo((object)$"Sending item config data to client: {clientId}"); foreach (ItemConfigData instance in ItemConfigData.Instances) { instance.SendConfigDataToClient(clientId); } } [HarmonyPatch("ShipHasLeft")] [HarmonyPostfix] private static void ShipHasLeftPatch() { Plugin.Instance.OnShipHasLeft(); } [HarmonyPatch("OnLocalDisconnect")] [HarmonyPrefix] private static void OnLocalDisconnectPatch() { Plugin.Instance.OnLocalDisconnect(); } } } namespace com.github.zehsteam.TakeyGokuBracken.MonoBehaviours { public abstract class AdvancedGrabbableObject : GrabbableObject { public int UniqueId { get; private set; } public string SaveKey => string.Format("{0}_{1}", "AdvancedGrabbableObject", UniqueId); public virtual void Awake() { if (NetworkUtils.IsServer) { UniqueId = Random.Range(0, 1000000); } } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); if (NetworkUtils.IsServer) { NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected; } } public override void OnNetworkDespawn() { ((NetworkBehaviour)this).OnNetworkDespawn(); if (NetworkUtils.IsServer) { NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnected; } } protected virtual void OnClientConnected(ulong clientId) { } public override int GetItemDataToSave() { return UniqueId; } public override void LoadItemSaveData(int saveData) { ((GrabbableObject)this).LoadItemSaveData(saveData); UniqueId = saveData; } protected override void __initializeVariables() { ((GrabbableObject)this).__initializeVariables(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "AdvancedGrabbableObject"; } } public class AdvancedNoisemakerProp : AdvancedGrabbableObject { [Space(20f)] [Header("Advanced Noisemaker Prop")] [Space(5f)] public AudioSourceGroup NoiseAudio; public AudioClipGroupWithWeight[] NoiseSFX = Array.Empty<AudioClipGroupWithWeight>(); [Space(10f)] public float NoiseRange = 65f; public float MaxLoudness = 1f; public float MinLoudness = 0.95f; public float MinPitch = 1f; public float MaxPitch = 1f; [Space(10f)] public bool UseDynamicCooldown; public bool CancelActiveSFXOnItemActivate; public override void ItemActivate(bool used, bool buttonDown = true) { if (NoiseSFX.Length != 0) { int randomIndexFromWeightList = Utils.GetRandomIndexFromWeightList(NoiseSFX.Select((AudioClipGroupWithWeight x) => x.Weight).ToList()); PlaySound(randomIndexFromWeightList); } } public void PlaySound(int index) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (NoiseSFX.Length != 0) { PlaySoundServerRpc(index); PlaySoundOnLocalClient(index); } } [ServerRpc(RequireOwnership = false)] protected void PlaySoundServerRpc(int index, ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1516145776u, serverRpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, index); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 1516145776u, serverRpcParams, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId)) { PlaySoundClientRpc(index, senderClientId); } } } [ClientRpc] protected void PlaySoundClientRpc(int index, ulong senderClientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3699628756u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, index); BytePacker.WriteValueBitPacked(val2, senderClientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3699628756u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !NetworkUtils.IsLocalClientId(senderClientId)) { PlaySoundOnLocalClient(index); } } } public void PlaySoundOnLocalClient(int index) { AudioClipGroup audioClipGroup = ((index >= 0 && index < NoiseSFX.Length) ? NoiseSFX[index] : null); PlaySoundOnLocalClient(audioClipGroup); OnPlaySoundFromIndex(index); } protected virtual void OnPlaySoundFromIndex(int index) { } public float PlaySoundOnLocalClient(AudioClip audioClip, AudioClip audioClipFar, bool stopPreviousSFX = false) { return PlaySoundOnLocalClient(new AudioClipGroup(audioClip, audioClipFar), stopPreviousSFX); } public float PlaySoundOnLocalClient(AudioClipGroup audioClipGroup, bool stopPreviousSFX = false) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (audioClipGroup == null || (Object)(object)audioClipGroup.AudioClip == (Object)null) { return 0f; } float num = (float)Random.Range((int)(MinLoudness * 100f), (int)(MaxLoudness * 100f)) / 100f; float pitch = (float)Random.Range((int)(MinPitch * 100f), (int)(MaxPitch * 100f)) / 100f; if (CancelActiveSFXOnItemActivate || stopPreviousSFX) { NoiseAudio.Stop(); } if (UseDynamicCooldown && !CancelActiveSFXOnItemActivate) { ((GrabbableObject)this).currentUseCooldown = audioClipGroup.Length; } NoiseAudio.Pitch = pitch; NoiseAudio.PlayOneShot(audioClipGroup, num); WalkieTalkie.TransmitOneShotAudio(NoiseAudio.AudioSource, audioClipGroup.AudioClip, num); RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, NoiseRange, num, 0, ((GrabbableObject)this).isInElevator && StartOfRound.Instance.hangarDoorsClosed, 0); if (MinLoudness >= 0.6f && (Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null) { ((GrabbableObject)this).playerHeldBy.timeSinceMakingLoudNoise = 0f; } return audioClipGroup.Length; } protected override void __initializeVariables() { base.__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_AdvancedNoisemakerProp() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(1516145776u, new RpcReceiveHandler(__rpc_handler_1516145776)); NetworkManager.__rpc_func_table.Add(3699628756u, new RpcReceiveHandler(__rpc_handler_3699628756)); } private static void __rpc_handler_1516145776(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0040: 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_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int index = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref index); ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((AdvancedNoisemakerProp)(object)target).PlaySoundServerRpc(index, server); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3699628756(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int index = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref index); ulong senderClientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref senderClientId); target.__rpc_exec_stage = (__RpcExecStage)2; ((AdvancedNoisemakerProp)(object)target).PlaySoundClientRpc(index, senderClientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "AdvancedNoisemakerProp"; } } public class AdvancedRandomPeriodicAudioPlayer : NetworkBehaviour { public AudioSourceGroup NoiseAudio = null; public AudioClipGroup[] NoiseSFX = Array.Empty<AudioClipGroup>(); public float MinInterval = 0f; public float MaxInterval = 0f; public float PercentChance = 0f; private float _timer = 0f; private float _interval = 0f; private void Start() { SetRandomInterval(); } private void Update() { if (!NetworkUtils.IsServer) { return; } if (_timer >= _interval) { _timer = 0f; SetRandomInterval(); if (Utils.RandomPercent(PercentChance)) { PlaySoundServerRpc(Random.Range(0, NoiseSFX.Length)); } } else { _timer += Time.deltaTime; } } private void SetRandomInterval() { _interval = Random.Range(MinInterval, MaxInterval); } [ServerRpc(RequireOwnership = false)] private void PlaySoundServerRpc(int index) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4251847043u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, index); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4251847043u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { PlaySoundClientRpc(index); } } } [ClientRpc] private void PlaySoundClientRpc(int index) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1611995967u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, index); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1611995967u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost)) { NoiseAudio.PlayOneShot(NoiseSFX[index]); } } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_AdvancedRandomPeriodicAudioPlayer() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(4251847043u, new RpcReceiveHandler(__rpc_handler_4251847043)); NetworkManager.__rpc_func_table.Add(1611995967u, new RpcReceiveHandler(__rpc_handler_1611995967)); } private static void __rpc_handler_4251847043(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int index = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref index); target.__rpc_exec_stage = (__RpcExecStage)1; ((AdvancedRandomPeriodicAudioPlayer)(object)target).PlaySoundServerRpc(index); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1611995967(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int index = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref index); target.__rpc_exec_stage = (__RpcExecStage)2; ((AdvancedRandomPeriodicAudioPlayer)(object)target).PlaySoundClientRpc(index); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "AdvancedRandomPeriodicAudioPlayer"; } } internal class PluginNetworkBehaviour : NetworkBehaviour { public static PluginNetworkBehaviour Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { Instance = this; } } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { if (((NetworkBehaviour)this).IsServer) { ((NetworkBehaviour)this).NetworkObject.Despawn(true); } } else { Instance = this; } } [ClientRpc] public void UpdateItemPropertiesClientRpc(string itemName, bool twoHanded, int carryWeight, int minValue, int maxValue, ClientRpcParams clientRpcParams = default(ClientRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2102329058u, clientRpcParams, (RpcDelivery)0); bool flag = itemName != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(itemName, false); } ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref twoHanded, default(ForPrimitives)); BytePacker.WriteValueBitPacked(val, carryWeight); BytePacker.WriteValueBitPacked(val, minValue); BytePacker.WriteValueBitPacked(val, maxValue); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2102329058u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !NetworkUtils.IsServer) { ItemHelper.UpdateItemProperties(itemName, twoHanded, carryWeight, minValue, maxValue); } } [ClientRpc] public void SetTakeyGokuClientRpc(NetworkObjectReference enemyReference) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3517081936u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref enemyReference, default(ForNetworkSerializable)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3517081936u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !NetworkUtils.IsServer) { NetworkObject takeyGokuBrackenOnLocalClient = default(NetworkObject); if (((NetworkObjectReference)(ref enemyReference)).TryGet(ref takeyGokuBrackenOnLocalClient, (NetworkManager)null)) { Plugin.Instance.SetTakeyGokuBrackenOnLocalClient(takeyGokuBrackenOnLocalClient); } else { Plugin.Instance.SetTakeyGokuBrackenOnLocalClient(null); } } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_PluginNetworkBehaviour() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(2102329058u, new RpcReceiveHandler(__rpc_handler_2102329058)); NetworkManager.__rpc_func_table.Add(3517081936u, new RpcReceiveHandler(__rpc_handler_3517081936)); } private static void __rpc_handler_2102329058(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); string itemName = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref itemName, false); } bool twoHanded = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref twoHanded, default(ForPrimitives)); int carryWeight = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref carryWeight); int minValue = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref minValue); int maxValue = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref maxValue); ClientRpcParams client = rpcParams.Client; target.__rpc_exec_stage = (__RpcExecStage)2; ((PluginNetworkBehaviour)(object)target).UpdateItemPropertiesClientRpc(itemName, twoHanded, carryWeight, minValue, maxValue, client); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3517081936(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { NetworkObjectReference takeyGokuClientRpc = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref takeyGokuClientRpc, default(ForNetworkSerializable)); target.__rpc_exec_stage = (__RpcExecStage)2; ((PluginNetworkBehaviour)(object)target).SetTakeyGokuClientRpc(takeyGokuClientRpc); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "PluginNetworkBehaviour"; } } public class TakeyGokuBrackenBehaviour : NetworkBehaviour { public Material clothesMaterial = null; public Material headMaterial = null; public AudioClip[] takeyFoundSFX = Array.Empty<AudioClip>(); public AudioClip[] takeyCrackNeckSFX = Array.Empty<AudioClip>(); public AudioClip ChaseSFX; public AudioSource DeathAudio; private FlowermanAI _flowermanAI; private ScanNodeProperties _scanNodeProperties; private PlayAudioAnimationEvent _playAudioAnimationEvent; private float _timer = 0f; public FlowermanAI FlowermanAI { get { if ((Object)(object)_flowermanAI == (Object)null) { _flowermanAI = ((Component)((Component)this).transform.parent).GetComponent<FlowermanAI>(); } return _flowermanAI; } } public ScanNodeProperties ScanNodeProperties { get { if ((Object)(object)_scanNodeProperties == (Object)null) { _scanNodeProperties = ((Component)FlowermanAI).GetComponentInChildren<ScanNodeProperties>(); } return _scanNodeProperties; } } public PlayAudioAnimationEvent PlayAudioAnimationEvent { get { if ((Object)(object)_playAudioAnimationEvent == (Object)null) { _playAudioAnimationEvent = ((Component)FlowermanAI).GetComponentInChildren<PlayAudioAnimationEvent>(); } return _playAudioAnimationEvent; } } private void Start() { //IL_0007: 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) ((Component)this).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); if (!((Object)(object)FlowermanAI == (Object)null) && GokuBrackenProxy.Enabled) { SetMaterials(); SetScanNodeProperties("Takey Goku"); FlowermanAI.creatureAngerVoice.clip = ChaseSFX; if (NetworkUtils.IsServer) { SetSFXOnServer(); } ((MonoBehaviour)this).StartCoroutine(ForceSetMaterials()); } } private IEnumerator ForceSetMaterials() { yield return null; SetMaterials(); for (int i = 0; i < 10; i++) { yield return (object)new WaitForSeconds(0.1f); SetMaterials(); } } private void Update() { if (NetworkUtils.IsServer && GokuBrackenProxy.Enabled) { if (_timer >= 20f) { _timer = 0f; SetRandomFoundSFXOnServer(); } _timer += Time.deltaTime; } } private void SetMaterials() { for (int i = 0; i < ((Component)FlowermanAI).transform.childCount; i++) { Transform child = ((Component)FlowermanAI).transform.GetChild(i); string[] array = new string[4] { "Base Goku", "God Goku", "SSJ Goku", "SSB Goku" }; string[] array2 = array; foreach (string value in array2) { if (((Object)child).name.Equals(value, StringComparison.OrdinalIgnoreCase)) { SetMaterialsOnBaseGoku(child); } } } } private void SetMaterialsOnBaseGoku(Transform baseGokuTransform) { SkinnedMeshRenderer componentInChildren = ((Component)baseGokuTransform.GetChild(0)).GetComponentInChildren<SkinnedMeshRenderer>(true); if ((Object)(object)componentInChildren != (Object)null) { SetSkinnedMeshRendererMaterials(componentInChildren, clothesMaterial, headMaterial); } } private void SetSkinnedMeshRendererMaterials(SkinnedMeshRenderer skinnedMeshRenderer, Material material1, Material material2) { Material[] sharedMaterials = ((Renderer)skinnedMeshRenderer).sharedMaterials; sharedMaterials[0] = material1; sharedMaterials[1] = material2; ((Renderer)skinnedMeshRenderer).sharedMaterials = sharedMaterials; } private void SetSFXOnServer() { SetRandomCrackNeckSFXOnServer(); SetRandomFoundSFXOnServer(); } public void SetRandomCrackNeckSFXOnServer() { if (NetworkUtils.IsServer) { int crackNeckSFXClientRpc = Random.Range(0, takeyCrackNeckSFX.Length); SetCrackNeckSFXClientRpc(crackNeckSFXClientRpc); } } [ClientRpc] private void SetCrackNeckSFXClientRpc(int index) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2929643050u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, index); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2929643050u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && GokuBrackenProxy.Enabled) { AudioClip val3 = takeyCrackNeckSFX[index]; FlowermanAI.crackNeckSFX = val3; FlowermanAI.crackNeckAudio.clip = val3; } } } public void SetRandomFoundSFXOnServer() { if (NetworkUtils.IsServer) { int foundSFXClientRpc = Random.Range(0, takeyFoundSFX.Length); SetFoundSFXClientRpc(foundSFXClientRpc); } } [ClientRpc] private void SetFoundSFXClientRpc(int index) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3425590996u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, index); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3425590996u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && GokuBrackenProxy.Enabled) { PlayAudioAnimationEvent.audioClip = takeyFoundSFX[index]; } } } private void SetScanNodeProperties(string headerText) { ScanNodeProperties.headerText = headerText; } public void OnDeath() { if (GokuBrackenProxy.Enabled && GokuBrackenProxy.UseDeathSound()) { DeathAudio.Play(); } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_TakeyGokuBrackenBehaviour() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(2929643050u, new RpcReceiveHandler(__rpc_handler_2929643050)); NetworkManager.__rpc_func_table.Add(3425590996u, new RpcReceiveHandler(__rpc_handler_3425590996)); } private static void __rpc_handler_2929643050(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int crackNeckSFXClientRpc = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref crackNeckSFXClientRpc); target.__rpc_exec_stage = (__RpcExecStage)2; ((TakeyGokuBrackenBehaviour)(object)target).SetCrackNeckSFXClientRpc(crackNeckSFXClientRpc); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3425590996(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int foundSFXClientRpc = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref foundSFXClientRpc); target.__rpc_exec_stage = (__RpcExecStage)2; ((TakeyGokuBrackenBehaviour)(object)target).SetFoundSFXClientRpc(foundSFXClientRpc); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "TakeyGokuBrackenBehaviour"; } } public class TakeyGokuPlushBehaviour : AdvancedNoisemakerProp { protected override void __initializeVariables() { base.__initializeVariables(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "TakeyGokuPlushBehaviour"; } } } namespace com.github.zehsteam.TakeyGokuBracken.Dependencies { internal static class HallucinocepsProxy { public const string PLUGIN_GUID = "PloufJPEG.Hallucinoceps"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("PloufJPEG.Hallucinoceps"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddHallucinationSounds() { try { List<AudioClip> list = CompanyCreaturesNetworker.instance.hallucinationSounds.ToList(); AudioClip[] hallucinationSounds = Content.HallucinocepsAssets.HallucinationSounds; foreach (AudioClip item in hallucinationSounds) { if (!list.Contains(item)) { list.Add(item); } } CompanyCreaturesNetworker.instance.hallucinationSounds = list.ToArray(); Plugin.Logger.LogInfo((object)"Added hallucination sounds to the Hallucinoceps mod."); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to add hallucination sounds to the Hallucinoceps mod. {arg}"); } } } internal static class LethalConfigProxy { public const string PLUGIN_GUID = "ainavt.lc.lethalconfig"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SetModIcon(Sprite sprite) { LethalConfigManager.SetModIcon(sprite); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SetModDescription(string description) { LethalConfigManager.SetModDescription(description); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SkipAutoGen() { LethalConfigManager.SkipAutoGen(); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig<T>(ConfigEntry<T> configEntry, bool requiresRestart = false) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues; if (acceptableValues != null) { if (acceptableValues is AcceptableValueRange<float> || acceptableValues is AcceptableValueRange<int>) { AddConfigSlider<T>(configEntry, requiresRestart); return; } if (acceptableValues is AcceptableValueList<string>) { AddConfigDropdown<T>(configEntry, requiresRestart); return; } } if (!(configEntry is ConfigEntry<string> val)) { if (!(configEntry is ConfigEntry<bool> val2)) { if (!(configEntry is ConfigEntry<float> val3)) { if (!(configEntry is ConfigEntry<int> val4)) { throw new NotSupportedException($"Unsupported type: {typeof(T)}"); } LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(val4, requiresRestart)); } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(val3, requiresRestart)); } } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(val2, requiresRestart)); } } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(val, requiresRestart)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfigSlider<T>(ConfigEntry<T> configEntry, bool requiresRestart = false) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if (!(configEntry is ConfigEntry<float> val)) { if (!(configEntry is ConfigEntry<int> val2)) { throw new NotSupportedException($"Slider not supported for type: {typeof(T)}"); } LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(val2, requiresRestart)); } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(val, requiresRestart)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfigDropdown<T>(ConfigEntry<T> configEntry, bool requiresRestart = false) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (configEntry is ConfigEntry<string> val) { LethalConfigManager.AddConfigItem((BaseConfigItem)new TextDropDownConfigItem(val, requiresRestart)); return; } throw new NotSupportedException($"Dropdown not supported for type: {typeof(T)}"); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddButton(string section, string name, string description, string buttonText, Action callback) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate { callback?.Invoke(); })); } } } namespace com.github.zehsteam.TakeyGokuBracken.Dependencies.GokuBrackenProxy { internal static class GokuBrackenProxy { public const string PLUGIN_GUID = "Vulf.GokuBracken"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("Vulf.GokuBracken"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void PatchAll(Harmony harmony) { harmony.PatchAll(typeof(GokuControllerPatch)); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static bool IsGokuBracken(FlowermanAI flowermanAI) { if ((Object)(object)flowermanAI == (Object)null) { return false; } return (Object)(object)((Component)flowermanAI).GetComponentInChildren<GokuController>() != (Object)null; } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static bool UseDeathSound() { try { return ConfigManager.UseDeathSound.Value; } catch { Plugin.Logger.LogError((object)"Failed to check if GokuBracken has UseDeathSound enabled."); } return true; } } } namespace com.github.zehsteam.TakeyGokuBracken.Dependencies.GokuBrackenProxy.Patches { [HarmonyPatch(typeof(GokuController))] internal static class GokuControllerPatch { [HarmonyPatch("KillGoku")] [HarmonyPostfix] private static void KillGokuPatch(ref GokuController __instance) { if (FlowermanAIPatch.EnemyControllerPairs.TryGetValue(__instance.FlowermanAI, out var value)) { AudioSource componentInChildren = __instance.BaseGokuObject.GetComponentInChildren<AudioSource>(); if ((Object)(object)componentInChildren != (Object)null) { Object.Destroy((Object)(object)((Component)componentInChildren).gameObject); } value.OnDeath(); } } } } namespace com.github.zehsteam.TakeyGokuBracken.Data { [Serializable] public class AudioClipGroup { public AudioClip AudioClip; public AudioClip AudioClipFar; public float Length => AudioClip.length; public AudioClipGroup(AudioClip audioClip, AudioClip audioClipFar) { AudioClip = audioClip; AudioClipFar = audioClipFar; } } [Serializable] public class AudioClipGroupWithWeight : AudioClipGroup { [Range(0f, 100f)] public int Weight = 10; public AudioClipGroupWithWeight(AudioClip audioClip, AudioClip audioClipFar, int weight = 10) : base(audioClip, audioClipFar) { Weight = weight; } } [Serializable] public class AudioClipGroupWithData<T> : AudioClipGroup { public T Data; public AudioClipGroupWithData(AudioClip audioClip, AudioClip audioClipFar, T data) : base(audioClip, audioClipFar) { Data = data; } } [Serializable] public class AudioSourceGroup { public AudioSource AudioSource; public AudioSource AudioSourceFar; public bool IsPlaying => AudioSource.isPlaying; public float Volume { get { return AudioSource.volume; } set { AudioSource.volume = value; AudioSourceFar.volume = value; } } public float Pitch { get { return AudioSource.pitch; } set { AudioSource.pitch = value; AudioSourceFar.pitch = value; } } public AudioSourceGroup(AudioSource audioSource, AudioSource audioSourceFar) { AudioSource = audioSource; AudioSourceFar = audioSourceFar; } public void Play() { AudioSource.Play(); AudioSourceFar.Play(); } public float PlayOneShot(AudioClipGroup audioClipGroup, float volumeScale = 1f) { if (audioClipGroup == null) { return 0f; } float result = 0f; if ((Object)(object)audioClipGroup.AudioClip != (Object)null) { result = audioClipGroup.AudioClip.length; AudioSource.PlayOneShot(audioClipGroup.AudioClip, volumeScale); } if ((Object)(object)audioClipGroup.AudioClipFar != (Object)null) { AudioSourceFar.PlayOneShot(audioClipGroup.AudioClipFar, volumeScale); } return result; } public void Pause() { AudioSource.Pause(); AudioSourceFar.Pause(); } public void Stop() { AudioSource.Stop(); AudioSourceFar.Stop(); } } [CreateAssetMenu(fileName = "HallucinocepsAssets", menuName = "TakeyGokuBracken/HallucinocepsAssets")] public class HallucinocepsAssets : ScriptableObject { public AudioClip[] HallucinationSounds = Array.Empty<AudioClip>(); } public class ItemConfigData { public static List<ItemConfigData> Instances { get; private set; } = new List<ItemConfigData>(); public ConfigEntry<int> SpawnWeight { get; private set; } public ConfigEntry<bool> TwoHanded { get; private set; } public ConfigEntry<int> CarryWeight { get; private set; } public ConfigEntry<int> MinValue { get; private set; } public ConfigEntry<int> MaxValue { get; private set; } public int SpawnWeightValue { get { if (!GokuBrackenProxy.Enabled && !Plugin.ConfigManager.EnablePlushies.Value) { return 0; } return SpawnWeight.Value; } } public Item Item { get; private set; } public ItemConfigData(Item item, string section, int rarity, bool twoHanded, int carryWeight, int minValue, int maxValue) { Instances.Add(this); Item = item; Bind(section, rarity, twoHanded, carryWeight, minValue, maxValue); MigrateOldConfigSettings(); } private void Bind(string section, int rarity, bool twoHanded, int carryWeight, int minValue, int maxValue) { if (!((Object)(object)Item == (Object)null)) { SpawnWeight = ConfigHelper.Bind(section, "SpawnWeight", rarity, requiresRestart: false, Item.itemName + " spawn chance weight."); TwoHanded = ConfigHelper.Bind(section, "TwoHanded", twoHanded, requiresRestart: false, "If enabled, " + Item.itemName + " will be two-handed."); CarryWeight = ConfigHelper.Bind(section, "CarryWeight", carryWeight, requiresRestart: false, Item.itemName + " carry weight in pounds."); MinValue = ConfigHelper.Bind(section, "MinValue", minValue, requiresRestart: false, Item.itemName + " min scrap value."); MaxValue = ConfigHelper.Bind(section, "MaxValue", maxValue, requiresRestart: false, Item.itemName + " max scrap value."); SpawnWeight.SettingChanged += SpawnWeight_SettingsChanged; TwoHanded.SettingChanged += Properties_SettingsChanged; CarryWeight.SettingChanged += Properties_SettingsChanged; MinValue.SettingChanged += Properties_SettingsChanged; MaxValue.SettingChanged += Properties_SettingsChanged; } } private void MigrateOldConfigSettings() { foreach (KeyValuePair<ConfigDefinition, string> orphanedConfigEntry in ConfigHelper.GetOrphanedConfigEntries()) { MigrateOldConfigSetting(orphanedConfigEntry.Key.Section, orphanedConfigEntry.Key.Key, orphanedConfigEntry.Value); } } private void MigrateOldConfigSetting(string section, string key, string value) { if (section == ((ConfigEntryBase)SpawnWeight).Definition.Section + " Settings") { switch (key) { case "SpawnWeight": ConfigHelper.SetConfigEntryValue<int>(SpawnWeight, value); break; case "TwoHanded": ConfigHelper.SetConfigEntryValue<bool>(TwoHanded, value); break; case "CarryWeight": ConfigHelper.SetConfigEntryValue<int>(CarryWeight, value); break; case "MinValue": ConfigHelper.SetConfigEntryValue<int>(MinValue, value); break; case "MaxValue": ConfigHelper.SetConfigEntryValue<int>(MaxValue, value); break; } } } public void RefreshConfigData() { if (NetworkUtils.IsServer) { Plugin.Instance.LogInfoExtended("Refreshing \"" + Item.itemName + "\" config data."); ItemHelper.UpdateScrapRarity(this); ItemHelper.UpdateItemProperties(this); } } public void SendConfigDataToClient(ulong clientId) { //IL_0014: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (NetworkUtils.IsServer) { ClientRpcParams val = default(ClientRpcParams); val.Send = new ClientRpcSendParams { TargetClientIds = new <>z__ReadOnlySingleElementList<ulong>(clientId) }; ClientRpcParams clientRpcParams = val; Plugin.Instance.LogInfoExtended($"Sending \"{Item.itemName}\" config data to client: {clientId}"); PluginNetworkBehaviour.Instance.UpdateItemPropertiesClientRpc(Item.itemName, TwoHanded.Value, CarryWeight.Value, MinValue.Value, MaxValue.Value, clientRpcParams); } } private void SpawnWeight_SettingsChanged(object sender, EventArgs e) { if (NetworkUtils.IsServer) { ItemHelper.UpdateScrapRarity(this); } } private void Properties_SettingsChanged(object sender, EventArgs e) { if (NetworkUtils.IsServer) { ItemHelper.UpdateItemProperties(this); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { return !_moveNextCalled && (_moveNextCalled = true); } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { return (!EqualityComparer<T>.Default.Equals(_item, (T)value)) ? (-1) : 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return (!EqualityComparer<T>.Default.Equals(_item, item)) ? (-1) : 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace com.github.zehsteam.TakeyGokuBracken.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }
com.github.zehsteam.TakeyPlush.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DigitalRuby.ThunderAndLightning; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLib.Extras; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using ProfanityFilter; using Steamworks; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Networking; using com.github.zehsteam.TakeyPlush.Data; using com.github.zehsteam.TakeyPlush.Dependencies; using com.github.zehsteam.TakeyPlush.Enums; using com.github.zehsteam.TakeyPlush.Helpers; using com.github.zehsteam.TakeyPlush.MonoBehaviours; using com.github.zehsteam.TakeyPlush.NetcodePatcher; using com.github.zehsteam.TakeyPlush.Patches; using com.github.zehsteam.ZombiesPlush.MonoBehaviours; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.zehsteam.TakeyPlush")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Adds 3 scrap, 1 store item, and 1 decor. The Smol Takey plushie has over 20 variants with each one having a unique appearence, special abilities, and interactions. There are more secrets to be discovered \ud83d\ude08")] [assembly: AssemblyFileVersion("1.13.0.0")] [assembly: AssemblyInformationalVersion("1.13.0+d81a5e894bd6ac71bce0d401501fc8190b506d7d")] [assembly: AssemblyProduct("TakeyPlush")] [assembly: AssemblyTitle("com.github.zehsteam.TakeyPlush")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.13.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace com.github.zehsteam.TakeyPlush { internal class ConfigManager { public ConfigEntry<bool> ExtendedLogging { get; private set; } public ConfigEntry<bool> ExtraFeatures_Enabled { get; private set; } public ConfigEntry<float> ExtraFeatures_SpecialSporeLizardSoundsChance { get; private set; } public ConfigEntry<bool> ExtraFeatures_EnableSpecialKidnapperFoxSounds { get; private set; } public ConfigEntry<float> ExtraFeatures_BunkerSpiderReskinChance { get; private set; } public ConfigEntry<float> ExtraFeatures_ButlerReskinChance { get; private set; } public ItemConfigData SmolTakey { get; private set; } public ConfigEntry<float> SmolTakey_JetpackChance { get; private set; } public ItemConfigData TakeyBox { get; private set; } public ConfigEntry<bool> TakeyBox_NegativeEffectsEnabled { get; private set; } public ConfigEntry<float> TakeyBox_NegativeEffectsChance { get; private set; } public ItemConfigData TakeyMug { get; private set; } public UnlockableItemConfigData TakeyMugShelf { get; private set; } public ConfigEntry<float> Takeypack_MusicVolume { get; private set; } public ConfigEntry<float> Takeypack_JetpackReplaceChance { get; private set; } public ConfigEntry<bool> TwitchIntegration_Enabled { get; private set; } public ConfigEntry<string> TwitchIntegration_Username { get; private set; } public ConfigEntry<bool> ALOOVariantTTS_Enabled { get; private set; } public ConfigEntry<float> ALOOVariantTTS_Cooldown { get; private set; } public ConfigEntry<float> ALOOVariantTTS_VoiceVolumeAmplificationDB { get; private set; } public ConfigEntry<float> ALOOVariantTTS_MinSoundDistance { get; private set; } public ConfigEntry<float> ALOOVariantTTS_MaxSoundDistance { get; private set; } public ConfigEntry<bool> ALOOVariantTTS_ProfanityFilterEnabled { get; private set; } public ConfigManager() { BindConfigs(); SetupChangedEvents(); MigrateOldConfigSettings(); ConfigHelper.ClearUnusedEntries(); } private void BindConfigs() { ConfigHelper.SkipAutoGen(); ExtendedLogging = ConfigHelper.Bind("General", "ExtendedLogging", defaultValue: false, requiresRestart: false, "Enable extended logging."); ExtraFeatures_Enabled = ConfigHelper.Bind("Extra Features", "Enabled", defaultValue: false, requiresRestart: false, "Enabled all the extra features."); ExtraFeatures_SpecialSporeLizardSoundsChance = ConfigHelper.Bind("Extra Features", "SpecialSporeLizardSoundsChance", 5f, requiresRestart: false, "The percent chance the Spore Lizard spawns with special sounds. (Requires Extra Features to be enabled)"); ExtraFeatures_EnableSpecialKidnapperFoxSounds = ConfigHelper.Bind("Extra Features", "EnableSpecialKidnapperFoxSounds", defaultValue: true, requiresRestart: false, "If enabled, the Kidnapper Fox will have some special sounds. (Requires Extra Features to be enabled)"); ExtraFeatures_BunkerSpiderReskinChance = ConfigHelper.Bind("Extra Features", "BunkerSpiderReskinChance", 50f, requiresRestart: false, "The percent chance the Bunker Spider gets a special reskin. (Requires Extra Features to be enabled)"); ExtraFeatures_ButlerReskinChance = ConfigHelper.Bind("Extra Features", "ButlerReskinChance", 50f, requiresRestart: false, "The percent chance the Butler gets a special reskin. (Requires Extra Features to be enabled)"); SmolTakey = new ItemConfigData(Content.SmolTakey, "Smol Takey", 20, twoHanded: false, 6, 80, 250); SmolTakey_JetpackChance = ConfigHelper.Bind("Smol Takey", "JetpackChance", 10f, requiresRestart: false, "The percent chance Smol Takey will start flying with his jetpack after you try picking him up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); TakeyBox = new ItemConfigData(Content.TakeyBox, "Takey Box", 10, twoHanded: false, 19, 30, 70); TakeyBox_NegativeEffectsEnabled = ConfigHelper.Bind("Takey Box", "NegativeEffectsEnabled", defaultValue: false, requiresRestart: false, "If enabled, the Takey Box will have a chance of giving a negative effect after opening."); TakeyBox_NegativeEffectsChance = ConfigHelper.Bind("Takey Box", "NegativeEffectsChance", 25f, requiresRestart: false, "The percent chance to give a negative effect after opening the Takey Box."); TakeyMug = new ItemConfigData(Content.TakeyMug, "Takey Mug", 10, twoHanded: false, 5, 60, 170); TakeyMugShelf = new UnlockableItemConfigData(Content.TakeyMugShelf, "Takey Mug Shelf", 0, unlockAtStart: false); Takeypack_MusicVolume = ConfigHelper.Bind("Takeypack", "MusicVolume", 75f, requiresRestart: false, "The music volume of the Takeypack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); Takeypack_JetpackReplaceChance = ConfigHelper.Bind("Takeypack", "JetpackReplaceChance", 25f, requiresRestart: false, "The percent chance a bought Jetpack from the store becomes a Takeypack."); TwitchIntegration_Enabled = ConfigHelper.Bind("Twitch Integration", "Enabled", defaultValue: false, requiresRestart: false, "Enable events from Twitch chat."); TwitchIntegration_Username = ConfigHelper.Bind("Twitch Integration", "Username", "", requiresRestart: false, "Your Twitch username."); ConfigHelper.AddButton("Twitch Integration", "Refresh Connection", "Click to refresh the connection to Twitch.", "Refresh", TwitchIntegration_Refresh_OnButtonClicked); ALOOVariantTTS_Enabled = ConfigHelper.Bind("ALOO Variant TTS", "Enabled", defaultValue: true, requiresRestart: false, "If enabled, will allow chat from Twitch to send TTS messages through the ALOO Takey's phone. (Requires Twitch Integration to be enabled)"); ALOOVariantTTS_Cooldown = ConfigHelper.Bind("ALOO Variant TTS", "Cooldown", 60f, requiresRestart: false, "The cooldown between TTS messages in seconds."); ConfigHelper.AddButton("ALOO Variant TTS", "Reset TTS Cooldown", "Click to reset the cooldown.", "Reset Cooldown", TakeyALOOVariant.ResetTTSCooldown_OnButtonClicked); ALOOVariantTTS_VoiceVolumeAmplificationDB = ConfigHelper.Bind("ALOO Variant TTS", "VoiceVolumeAmplificationDB", 10f, requiresRestart: false, "Boost the TTS voice volume in decibels (dB). Increase for louder sound, with 10 dB roughly doubling the perceived loudness.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 20f)); ALOOVariantTTS_MinSoundDistance = ConfigHelper.Bind("ALOO Variant TTS", "MinSoundDistance", 4f, requiresRestart: false, "The min sound distance of the TTS voice and phone sfx.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f)); ALOOVariantTTS_MaxSoundDistance = ConfigHelper.Bind("ALOO Variant TTS", "MaxSoundDistance", 16f, requiresRestart: false, "The max sound distance of the TTS voice and phone sfx.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f)); ALOOVariantTTS_ProfanityFilterEnabled = ConfigHelper.Bind("ALOO Variant TTS", "ProfanityFilterEnabled", defaultValue: true, requiresRestart: false, "If enabled, TTS messages will filter out profanity."); } private void SetupChangedEvents() { TakeyBox_NegativeEffectsEnabled.SettingChanged += com.github.zehsteam.TakeyPlush.MonoBehaviours.TakeyBox.OnSettingsChanged; TakeyBox_NegativeEffectsChance.SettingChanged += com.github.zehsteam.TakeyPlush.MonoBehaviours.TakeyBox.OnSettingsChanged; Takeypack_MusicVolume.SettingChanged += TakeypackItem.OnMusicValuesChanged; TwitchIntegration_Enabled.SettingChanged += TwitchIntegrationEnabled_SettingChanged; TwitchIntegration_Username.SettingChanged += TwitchIntegrationUsername_SettingChanged; ALOOVariantTTS_MinSoundDistance.SettingChanged += TakeyALOOVariant.OnSoundDistanceChanged; ALOOVariantTTS_MaxSoundDistance.SettingChanged += TakeyALOOVariant.OnSoundDistanceChanged; } private void TwitchIntegrationEnabled_SettingChanged(object sender, EventArgs e) { if (TwitchIntegration_Enabled.Value) { if (NetworkUtils.IsServer) { TwitchChat.StartReading(); } } else { TwitchChat.StopReading(); } } private void TwitchIntegrationUsername_SettingChanged(object sender, EventArgs e) { if (NetworkUtils.IsServer && TwitchIntegration_Enabled.Value) { TwitchChat.StartReading(); } } private void TwitchIntegration_Refresh_OnButtonClicked() { if (TwitchIntegration_Enabled.Value) { if (NetworkUtils.IsServer) { TwitchChat.StartReading(); } } else { TwitchChat.StopReading(); } } private void MigrateOldConfigSettings() { foreach (KeyValuePair<ConfigDefinition, string> orphanedConfigEntry in ConfigHelper.GetOrphanedConfigEntries()) { MigrateOldConfigSetting(orphanedConfigEntry.Key.Section, orphanedConfigEntry.Key.Key, orphanedConfigEntry.Value); } } private void MigrateOldConfigSetting(string section, string key, string value) { if (section == "Smol Takey Plushie Settings") { switch (key) { case "SpawnWeight": ConfigHelper.SetConfigEntryValue<int>(SmolTakey.SpawnWeight, value); break; case "TwoHanded": ConfigHelper.SetConfigEntryValue<bool>(SmolTakey.TwoHanded, value); break; case "CarryWeight": ConfigHelper.SetConfigEntryValue<int>(SmolTakey.CarryWeight, value); break; case "MinValue": ConfigHelper.SetConfigEntryValue<int>(SmolTakey.MinValue, value); break; case "MaxValue": ConfigHelper.SetConfigEntryValue<int>(SmolTakey.MaxValue, value); break; } } if (section == "Takeypack Settings") { if (key == "ReplaceChance") { ConfigHelper.SetConfigEntryValue<float>(Takeypack_JetpackReplaceChance, value); } } if (section == "Extra Features Settings") { switch (key) { case "Enabled": ConfigHelper.SetConfigEntryValue<bool>(ExtraFeatures_Enabled, value); break; case "SpecialSporeLizardSoundsChance": ConfigHelper.SetConfigEntryValue<float>(ExtraFeatures_SpecialSporeLizardSoundsChance, value); break; case "EnableSpecialKidnapperFoxSounds": ConfigHelper.SetConfigEntryValue<bool>(ExtraFeatures_EnableSpecialKidnapperFoxSounds, value); break; case "BunkerSpiderReskinChance": ConfigHelper.SetConfigEntryValue<float>(ExtraFeatures_BunkerSpiderReskinChance, value); break; case "ButlerReskinChance": ConfigHelper.SetConfigEntryValue<float>(ExtraFeatures_ButlerReskinChance, value); break; } } if (section == "Smol Takey Settings") { if (key == "JetpackChance") { ConfigHelper.SetConfigEntryValue<float>(SmolTakey_JetpackChance, value); } } if (section == "Takey Box Settings") { if (!(key == "NegativeEffectsEnabled")) { if (key == "NegativeEffectsChance") { ConfigHelper.SetConfigEntryValue<float>(TakeyBox_NegativeEffectsChance, value); } } else { ConfigHelper.SetConfigEntryValue<bool>(TakeyBox_NegativeEffectsEnabled, value); } } if (section == "Takeypack Settings") { if (!(key == "MusicVolume")) { if (key == "JetpackReplaceChance") { ConfigHelper.SetConfigEntryValue<float>(Takeypack_JetpackReplaceChance, value); } } else { ConfigHelper.SetConfigEntryValue<float>(Takeypack_MusicVolume, value); } } if (section == "Twitch Integration Settings") { if (!(key == "Enabled")) { if (key == "Username") { ConfigHelper.SetConfigEntryValue<string>(TwitchIntegration_Username, value); } } else { ConfigHelper.SetConfigEntryValue<bool>(TwitchIntegration_Enabled, value); } } if (section == "ALOO Variant TTS Settings") { switch (key) { case "Enabled": ConfigHelper.SetConfigEntryValue<bool>(ALOOVariantTTS_Enabled, value); break; case "Cooldown": ConfigHelper.SetConfigEntryValue<float>(ALOOVariantTTS_Cooldown, value); break; case "VoiceVolumeAmplificationDB": ConfigHelper.SetConfigEntryValue<float>(ALOOVariantTTS_VoiceVolumeAmplificationDB, value); break; case "MinSoundDistance": ConfigHelper.SetConfigEntryValue<float>(ALOOVariantTTS_MinSoundDistance, value); break; case "MaxSoundDistance": ConfigHelper.SetConfigEntryValue<float>(ALOOVariantTTS_MaxSoundDistance, value); break; case "ProfanityFilterEnabled": ConfigHelper.SetConfigEntryValue<bool>(ALOOVariantTTS_ProfanityFilterEnabled, value); break; } } } public void TrySetCustomSettings() { TrySetCustomSettingsForSpecialUsers(); TrySetCustomSettingsForTakerst(); } public void TrySetCustomSettingsForSpecialUsers() { PlayerData localClientPlayerData = SteamUtils.GetLocalClientPlayerData(); if (localClientPlayerData != null) { if (!string.IsNullOrWhiteSpace(localClientPlayerData.TwitchUsername)) { TwitchIntegration_Username.Value = localClientPlayerData.TwitchUsername; } if (!ModpackSaveSystem.ReadValue("EnabledExtraFeatures", defaultValue: false)) { ModpackSaveSystem.WriteValue("EnabledExtraFeatures", value: true); ExtraFeatures_Enabled.Value = true; } } } public void TrySetCustomSettingsForTakerst() { if (SteamUtils.IsLocalClient(PlayerName.Takerst) && !ModpackSaveSystem.ReadValue("SetUnlockAtStart", defaultValue: false)) { ModpackSaveSystem.WriteValue("SetUnlockAtStart", value: true); TakeyMugShelf.UnlockAtStart.Value = true; } } } internal static class Content { public static GameObject NetworkHandlerPrefab { get; private set; } public static GameObject PartyExplosionPrefab { get; private set; } public static GameObject TakeyALOOEventReceiverPrefab { get; private set; } public static GameObject CuteSandSpiderPrefab { get; private set; } public static GameObject TakeyButlerControllerPrefab { get; private set; } public static Item SmolTakey { get; private set; } public static Item TakeyBox { get; private set; } public static Item TakeyMug { get; private set; } public static TakeyVariantDataList TakeyVariantDataList { get; private set; } public static Item Takeypack { get; private set; } public static TerminalNode Takeypack_TerminalNode { get; private set; } public static UnlockableItemDef TakeyMugShelf { get; private set; } public static TerminalNode TakeyMugShelf_TerminalNode { get; private set; } public static AudioClip BlubbersYameteKudasaiSFX { get; private set; } public static AudioClip BushWolfHit1SFX { get; private set; } public static AudioClip BushWolfHit2SFX { get; private set; } public static AudioClip BushWolfHit3SFX { get; private set; } public static AudioClip BushWolfDogHit1SFX { get; private set; } public static AudioClip BushWolfDogHit2SFX { get; private set; } public static void Load() { LoadAssetsFromAssetBundle(); } private static void LoadAssetsFromAssetBundle() { AssetBundle val = LoadAssetBundle("takeyplush_assets"); if (!((Object)(object)val == (Object)null)) { NetworkHandlerPrefab = LoadAssetFromAssetBundle<GameObject>("NetworkHandler", val); NetworkHandlerPrefab.AddComponent<PluginNetworkBehaviour>(); PartyExplosionPrefab = LoadAssetFromAssetBundle<GameObject>("PartyExplosion", val); TakeyALOOEventReceiverPrefab = LoadAssetFromAssetBundle<GameObject>("TakeyALOOEventReceiver", val); CuteSandSpiderPrefab = LoadAssetFromAssetBundle<GameObject>("CuteSandSpider", val); TakeyButlerControllerPrefab = LoadAssetFromAssetBundle<GameObject>("TakeyButlerController", val); SmolTakey = LoadAssetFromAssetBundle<Item>("SmolTakey", val); TakeyBox = LoadAssetFromAssetBundle<Item>("TakeyBox", val); TakeyMug = LoadAssetFromAssetBundle<Item>("TakeyMug", val); TakeyVariantDataList = LoadAssetFromAssetBundle<TakeyVariantDataList>("TakeyVariantDataList", val); Takeypack = LoadAssetFromAssetBundle<Item>("TakeypackItem", val); Takeypack_TerminalNode = LoadAssetFromAssetBundle<TerminalNode>("TiTerminalNode", val); TakeyMugShelf = LoadAssetFromAssetBundle<UnlockableItemDef>("TakeyMugShelf", val); TakeyMugShelf_TerminalNode = LoadAssetFromAssetBundle<TerminalNode>("TakeyMugShelfBuy", val); BlubbersYameteKudasaiSFX = LoadAssetFromAssetBundle<AudioClip>("BlubbersYameteKudasaiSFX", val); BushWolfHit1SFX = LoadAssetFromAssetBundle<AudioClip>("BushWolfHit1SFX", val); BushWolfHit2SFX = LoadAssetFromAssetBundle<AudioClip>("BushWolfHit2SFX", val); BushWolfHit3SFX = LoadAssetFromAssetBundle<AudioClip>("BushWolfHit3SFX", val); BushWolfDogHit1SFX = LoadAssetFromAssetBundle<AudioClip>("BushWolfDogHit1SFX", val); BushWolfDogHit2SFX = LoadAssetFromAssetBundle<AudioClip>("BushWolfDogHit2SFX", val); Plugin.Logger.LogInfo((object)"Successfully loaded assets from AssetBundle!"); } } private static AssetBundle LoadAssetBundle(string fileName) { try { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location); string text = Path.Combine(directoryName, fileName); return AssetBundle.LoadFromFile(text); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to load AssetBundle \"{fileName}\". {arg}"); } return null; } private static T LoadAssetFromAssetBundle<T>(string name, AssetBundle assetBundle) where T : Object { if (string.IsNullOrWhiteSpace(name)) { Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace.")); return default(T); } if ((Object)(object)assetBundle == (Object)null) { Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null.")); return default(T); } T val = assetBundle.LoadAsset<T>(name); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name.")); return default(T); } return val; } } public static class Events { internal static Action OnProfitQuotaFulfilled { get; set; } internal static Action<PlayerControllerB, PlayerDeathReason> OnPlayerDied { get; set; } internal static Action OnShipArrive { get; set; } internal static Action OnShipLeave { get; set; } internal static Action<List<Item>> OnItemsOrdered { get; set; } public static Action OnDinkDonkScrapEaterSpawned { get; set; } internal static Action<GrabbableObject> OnNewScrapCollected { get; set; } internal static Action<int, int> OnTimeChanged { get; set; } internal static Action<string> OnALOOTTSMessage { get; set; } internal static Action<GrabbableObject> OnGrabItem { get; set; } internal static Action<GrabbableObject> OnDiscardItem { get; set; } internal static Action<MaskedPlayerEnemy> OnMaskedEnteredShip { get; set; } internal static Action<ForestGiantAI> OnForestGiantSpawned { get; set; } internal static Action<ForestGiantAI> OnForestGiantNearMain { get; set; } internal static void Initialize() { TwitchChat.OnMessage = (Action<TwitchMessage>)Delegate.Combine(TwitchChat.OnMessage, new Action<TwitchMessage>(OnTwitchChatMessage)); } private static void OnTwitchChatMessage(TwitchMessage twitchMessage) { if (twitchMessage.Message.StartsWith("ALOO") && twitchMessage.Message.Length > 4) { OnALOOTTSMessage?.Invoke(twitchMessage.Message); } } } internal static class ModpackSaveSystem { public const string FileName = "TakeyPlush_SaveData.json"; private static JObject _saveFileObject; public static string FilePath { get { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Config.ConfigFilePath); return Path.Combine(directoryName, "TakeyPlush_SaveData.json"); } } public static bool FileExists => File.Exists(FilePath); public static void Initialize() { if (!FileExists) { WriteFile(JObject.Parse("{}")); } _saveFileObject = ReadFile(); } public static bool ContainsKey(string key) { return _saveFileObject.ContainsKey(key); } public static T ReadValue<T>(string key, T defaultValue = default(T)) { //IL_001e: Expected O, but got Unknown JToken val = default(JToken); if (_saveFileObject.TryGetValue(key, ref val)) { try { return val.ToObject<T>(); } catch (JsonException val2) { JsonException val3 = val2; Plugin.Logger.LogError((object)("JSON Conversion Error: " + ((Exception)(object)val3).Message)); } catch (ArgumentNullException ex) { Plugin.Logger.LogError((object)("Argument Null Error: " + ex.Message)); } catch (Exception ex2) { Plugin.Logger.LogError((object)("Unexpected Error: " + ex2.Message)); } return defaultValue; } return defaultValue; } public static void WriteValue<T>(string key, T value) { JToken val = JToken.FromObject((object)value); if (_saveFileObject.ContainsKey(key)) { _saveFileObject[key] = val; } else { _saveFileObject.Add(key, val); } WriteFile(_saveFileObject); } private static JObject ReadFile() { try { using FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite); using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); return JObject.Parse(streamReader.ReadToEnd()); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to read save file. {arg}"); } return null; } private static bool WriteFile(JObject jObject) { try { using FileStream stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); using StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8); streamWriter.WriteLine(((object)jObject).ToString()); return true; } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to write save file. {arg}"); } return false; } } internal static class NetworkUtils { public static bool IsServer { get { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return NetworkManager.Singleton.IsServer; } } public static bool IsHost { get { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return NetworkManager.Singleton.IsHost; } } public static ulong GetLocalClientId() { return NetworkManager.Singleton.LocalClientId; } public static bool IsLocalClientId(ulong clientId) { return clientId == GetLocalClientId(); } public static bool IsNetworkPrefab(GameObject prefab) { foreach (NetworkPrefab prefab2 in NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs) { if ((Object)(object)prefab2.Prefab == (Object)(object)prefab) { return true; } } return false; } } internal static class PlayerUtils { public static PlayerControllerB GetLocalPlayerScript() { if ((Object)(object)GameNetworkManager.Instance == (Object)null) { return null; } return GameNetworkManager.Instance.localPlayerController; } public static bool IsLocalPlayer(PlayerControllerB playerScript) { return (Object)(object)playerScript == (Object)(object)GetLocalPlayerScript(); } public static bool IsLocalPlayer(PlayerName playerName) { return SteamUtils.IsLocalClient(playerName); } public static bool IsLocalPlayer(PlayerName[] playerNames) { foreach (PlayerName playerName in playerNames) { if (SteamUtils.IsLocalClient(playerName)) { return true; } } return false; } public static bool IsPlayer(PlayerControllerB playerScript, PlayerName playerName) { if ((Object)(object)playerScript == (Object)null) { return false; } return SteamUtils.IsPlayer(playerName, playerScript.playerUsername, playerScript.playerSteamId); } public static bool HasPlayer(PlayerName playerName) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB playerScript in allPlayerScripts) { if (IsPlayer(playerScript, playerName)) { return true; } } return false; } public static PlayerControllerB GetPlayerScript(PlayerName playerName) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (IsPlayer(val, playerName)) { return val; } } return null; } public static bool IsPlayerNearby(Vector3 position, float range, bool inShip = false) { //IL_002c: 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) PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if ((!inShip || val.isInHangarShipRoom) && Vector3.Distance(position, ((Component)val).gameObject.transform.position) <= range) { return true; } } return false; } public static bool IsLootNearPlayer(PlayerControllerB playerScript, float radius) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)playerScript == (Object)null) { return false; } GrabbableObject[] array = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); foreach (GrabbableObject val in array) { if (val.isInFactory && !val.isHeld && val.itemProperties.isScrap && Vector3.Distance(((Component)playerScript).transform.position, ((Component)val).transform.position) <= radius) { return true; } } return false; } public static PlayerControllerB GetPlayerScriptByClientId(ulong clientId) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.actualClientId == clientId) { return val; } } return null; } public static int PlayersAliveCount() { int num = 0; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.isPlayerControlled && !val.isPlayerDead) { num++; } } return num; } } [BepInPlugin("com.github.zehsteam.TakeyPlush", "TakeyPlush", "1.13.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.github.zehsteam.TakeyPlush"); internal static Plugin Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static ConfigManager ConfigManager { get; private set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } Logger = Logger.CreateLogSource("com.github.zehsteam.TakeyPlush"); Logger.LogInfo((object)"TakeyPlush has awoken!"); _harmony.PatchAll(typeof(GameNetworkManagerPatch)); _harmony.PatchAll(typeof(StartOfRoundPatch)); _harmony.PatchAll(typeof(RoundManagerPatch)); _harmony.PatchAll(typeof(TimeOfDayPatch)); _harmony.PatchAll(typeof(HUDManagerPatch)); _harmony.PatchAll(typeof(ShipBuildModeManagerPatch)); _harmony.PatchAll(typeof(TerminalPatch)); _harmony.PatchAll(typeof(ItemDropshipPatch)); _harmony.PatchAll(typeof(PlayerControllerBPatch)); _harmony.PatchAll(typeof(HoarderBugAIPatch)); _harmony.PatchAll(typeof(BaboonBirdAIPatch)); _harmony.PatchAll(typeof(PufferAIPatch)); _harmony.PatchAll(typeof(BushWolfEnemyPatch)); _harmony.PatchAll(typeof(MouthDogAIPatch)); _harmony.PatchAll(typeof(MaskedPlayerEnemyPatch)); _harmony.PatchAll(typeof(ForestGiantAIPatch)); _harmony.PatchAll(typeof(SandSpiderAIPatch)); _harmony.PatchAll(typeof(ButlerEnemyAIPatch)); _harmony.PatchAll(typeof(GrabbableObjectPatch)); _harmony.PatchAll(typeof(JetpackItemPatch)); Content.Load(); ConfigManager = new ConfigManager(); ModpackSaveSystem.Initialize(); SteamUtils.Initialize(); Events.Initialize(); MaskedPlayerEnemyPatch.Initialize(); ForestGiantAIPatch.Initialize(); SandSpiderAIPatch.Initialize(); ButlerEnemyAIPatch.Initialize(); RegisterScrapItems(); RegisterShopItems(); RegisterUnlockableItems(); NetcodePatcherAwake(); } private void NetcodePatcherAwake() { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); Type[] types = executingAssembly.GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { try { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { try { methodInfo.Invoke(null, null); } catch (TargetInvocationException ex) { Logger.LogWarning((object)("Failed to invoke method " + methodInfo.Name + ": " + ex.Message)); } } } catch (Exception ex2) { Logger.LogWarning((object)("Error processing method " + methodInfo.Name + " in type " + type.Name + ": " + ex2.Message)); } } } } catch (Exception ex3) { Logger.LogError((object)("An error occurred in NetcodePatcherAwake: " + ex3.Message)); } } private void RegisterScrapItems() { ItemHelper.RegisterScrap(ConfigManager.SmolTakey); ItemHelper.RegisterScrap(ConfigManager.TakeyBox); ItemHelper.RegisterScrap(ConfigManager.TakeyMug); } private void RegisterShopItems() { ShopHelper.RegisterShopItem(Content.Takeypack, 900, Content.Takeypack_TerminalNode); } private void RegisterUnlockableItems() { UnlockableItemHelper.RegisterUnlockable(ConfigManager.TakeyMugShelf, Content.TakeyMugShelf_TerminalNode); } public void LogInfoExtended(object data) { LogExtended((LogLevel)16, data); } public void LogMessageExtended(object data) { LogExtended((LogLevel)8, data); } public void LogExtended(LogLevel level, object data) { //IL_0022: 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) if (ConfigManager == null || ConfigManager.ExtendedLogging == null) { Logger.Log(level, data); } else if (ConfigManager.ExtendedLogging.Value) { Logger.Log(level, data); } } } internal static class SaveSystem { public static void SaveData<T>(string key, T data) { ES3.Save<T>(GetBaseKey() + "." + key, data, GetCurrentSaveFilePath()); } public static T LoadData<T>(string key, T defaultValue = default(T)) { return ES3.Load<T>(GetBaseKey() + "." + key, GetCurrentSaveFilePath(), defaultValue); } private static string GetBaseKey() { return MethodBase.GetCurrentMethod().DeclaringType.Namespace; } private static string GetCurrentSaveFilePath() { return GameNetworkManager.Instance.currentSaveFileName; } } internal enum PlayerName { Takerst, ZombiesAteMyChannel, WolfsMyChocolate, Hiccubz, Lunxara, PANDAM0NIEM, Jxshkins, SpookyTug, Raqaizal, MaestroSpooks, VanoraDarkWolf, TetraFlash, XSuperBeefyx, Ariesgoddess168, LustStings, TIMETELL, IElucian, Irishdev13, CritHaxXoG, Oopsmyleg, Reapermitsuki, Yinisin, AGlitchedNpc } internal static class SteamUtils { public static List<PlayerData> PlayersData { get; private set; } = new List<PlayerData>(); public static void Initialize() { List<PlayerData> list = new List<PlayerData>(23); list.Add(new PlayerData(PlayerName.Takerst, "Takerst", 76561197980238122uL, "Takerst")); list.Add(new PlayerData(PlayerName.ZombiesAteMyChannel, "ZombieAteMyChannel", 76561197990822861uL, "ZombiesAteMyChannel")); list.Add(new PlayerData(PlayerName.WolfsMyChocolate, new string[2] { "WolfsMyChocolate", "wolfyfook" }, new ulong[2] { 76561199112488706uL, 76561199589529626uL }, "WolfsMyChocolate")); list.Add(new PlayerData(PlayerName.Hiccubz, "Hiccubz", 76561199090697084uL, "Hiccubz")); list.Add(new PlayerData(PlayerName.Lunxara, "Lunxara", 76561198086325047uL, "Lunxara")); list.Add(new PlayerData(PlayerName.PANDAM0NIEM, "PANDAM0NIEM", 76561199169070660uL, "PANDAM0NIEM")); list.Add(new PlayerData(PlayerName.Jxshkins, "jxshkins", 76561199004549621uL, "Jxshkins")); list.Add(new PlayerData(PlayerName.SpookyTug, "SpookyTug", 76561198053549767uL, "SpookyTug")); list.Add(new PlayerData(PlayerName.Raqaizal, "Raqaizal", 76561198047992629uL, "raqaizal1")); list.Add(new PlayerData(PlayerName.MaestroSpooks, "MaestroSpooks", 76561198150757587uL, "MaestroSpooks")); list.Add(new PlayerData(PlayerName.VanoraDarkWolf, "Vanora", 76561198064529684uL, "VanoraDarkWolf")); list.Add(new PlayerData(PlayerName.TetraFlash, "TetraFlash", 76561197993458924uL, "TetraFlash")); list.Add(new PlayerData(PlayerName.XSuperBeefyx, "xSuperBeefyx", 76561197964982016uL, "xSuperBeefyx")); list.Add(new PlayerData(PlayerName.Ariesgoddess168, "NewAgeAries", 76561198174632877uL, "Ariesgoddess168")); list.Add(new PlayerData(PlayerName.LustStings, "lustings", 76561198053068793uL, "LustStings")); list.Add(new PlayerData(PlayerName.TIMETELL, "TIMETELL", 76561197967817500uL, "TIMETELL")); list.Add(new PlayerData(PlayerName.IElucian, "iElucian", 76561197962979730uL, "ielucian")); list.Add(new PlayerData(PlayerName.Irishdev13, "TTV_Irishdev13", 76561198123000350uL, "Irishdev13")); list.Add(new PlayerData(PlayerName.CritHaxXoG, "CritHaxXoG", 76561198993712632uL, "CritHaxXoG")); list.Add(new PlayerData(PlayerName.Oopsmyleg, "Oopsmyleg", 76561198113371889uL, "Oopsmyleg")); list.Add(new PlayerData(PlayerName.Reapermitsuki, "reaper-mitsuki", 76561198281494776uL, "reapermitsuki")); list.Add(new PlayerData(PlayerName.Yinisin, "Yinisin", 76561199582073183uL, "yinisin")); list.Add(new PlayerData(PlayerName.AGlitchedNpc, "a glitched npc", 76561198984467725uL, "a_glitched_npc")); PlayersData = list; } public static bool TryGetLocalClientTwitchUsername(out string twitchUsername) { twitchUsername = string.Empty; PlayerData localClientPlayerData = GetLocalClientPlayerData(); if (localClientPlayerData == null) { return false; } twitchUsername = localClientPlayerData.TwitchUsername; return true; } public static bool IsPlayer(PlayerName playerName, string username, ulong steamId) { return GetPlayerData(playerName)?.IsPlayer(username, steamId) ?? false; } public static PlayerData GetLocalClientPlayerData() { foreach (PlayerData playersDatum in PlayersData) { if (playersDatum.IsLocalClient()) { return playersDatum; } } return null; } public static PlayerData GetPlayerData(PlayerName playerName) { foreach (PlayerData playersDatum in PlayersData) { if (playersDatum.PlayerName == playerName) { return playersDatum; } } return null; } public static bool IsLocalClient(PlayerName playerName) { return GetPlayerData(playerName)?.IsLocalClient() ?? false; } public static bool IsLocalClient(string username, ulong steamId) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!SteamClient.IsValid) { return false; } if (!SteamClient.IsLoggedOn) { return false; } if (SteamClient.Name.Equals(username, StringComparison.OrdinalIgnoreCase)) { return true; } if (SteamId.op_Implicit(SteamClient.SteamId) == steamId) { return true; } return false; } } internal class PlayerData { public PlayerName PlayerName { get; private set; } public string[] Username { get; private set; } public ulong[] SteamId { get; private set; } public string TwitchUsername { get; private set; } public PlayerData(PlayerName playerName, string username, ulong steamId, string twitchUsername) { PlayerName = playerName; Username = new string[1] { username }; SteamId = new ulong[1] { steamId }; TwitchUsername = twitchUsername; } public PlayerData(PlayerName playerName, string[] username, ulong[] steamId, string twitchUsername) { PlayerName = playerName; Username = username; SteamId = steamId; TwitchUsername = twitchUsername; } public bool IsLocalClient() { for (int i = 0; i < Username.Length; i++) { if (SteamUtils.IsLocalClient(Username[i], SteamId[i])) { return true; } } return false; } public bool IsPlayer(string username, ulong steamId) { for (int i = 0; i < Username.Length; i++) { if (Username[i].Equals(username, StringComparison.OrdinalIgnoreCase)) { return true; } if (SteamId[i] == steamId) { return true; } } return false; } } internal static class TextToSpeech { private const string _apiUrl = "https://api.streamelements.com/kappa/v2/speech"; public static string[] Voices = new string[2] { "Brian", "Salli" }; public static void GetAudioClip(string voice, string text, Action<AudioClip> onClipReady) { Utils.StartCoroutine(GetAudioClipFromAPI(voice, text, onClipReady)); } private static IEnumerator GetAudioClipFromAPI(string voice, string text, Action<AudioClip> onClipReady) { string url = "https://api.streamelements.com/kappa/v2/speech?voice=" + voice + "&text=" + UnityWebRequest.EscapeURL(text); Plugin.Instance.LogInfoExtended("[TextToSpeech] Sending GET request to " + url); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, (AudioType)13); try { yield return www.SendWebRequest(); if ((int)www.result == 2 || (int)www.result == 3) { Plugin.Logger.LogError((object)("[TextToSpeech] Error fetching TTS audio: " + www.error)); onClipReady(null); } else { AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www); onClipReady(audioClip); } } finally { ((IDisposable)www)?.Dispose(); } } public static string GetRandomVoice() { return Voices[Random.Range(0, Voices.Length)]; } } internal static class TwitchChat { public const string TwitchServer = "irc.chat.twitch.tv"; public const int TwitchPort = 6667; private static TcpClient _tcpClient; private static NetworkStream _stream; private static StreamReader _reader; private static StreamWriter _writer; private static CancellationTokenSource _cts; public static string TwitchChannel => ("#" + Plugin.ConfigManager.TwitchIntegration_Username.Value).Trim(); public static bool IsReading { get; private set; } public static bool IsBusy { get; private set; } public static DateTime? TimeStartedReading { get; private set; } public static Action<TwitchMessage> OnMessage { get; set; } public static async Task StartReading() { Plugin.Instance.LogMessageExtended("[TwitchChat] Trying to start reading."); if (TwitchChannel == "#") { Plugin.Instance.LogMessageExtended("[TwitchChat] Twitch username is empty!"); return; } if (IsBusy) { Plugin.Instance.LogMessageExtended("[TwitchChat] Process is busy."); return; } if (IsReading) { Plugin.Instance.LogMessageExtended("[TwitchChat] You are already reading."); await StopReading(); } IsBusy = true; _cts = new CancellationTokenSource(); CancellationToken token = _cts.Token; try { _tcpClient = new TcpClient("irc.chat.twitch.tv", 6667); _stream = _tcpClient.GetStream(); _reader = new StreamReader(_stream); _writer = new StreamWriter(_stream) { AutoFlush = true }; await _writer.WriteLineAsync("PASS 1337"); await _writer.WriteLineAsync("NICK justinfan123"); await _writer.WriteLineAsync("JOIN " + TwitchChannel); Plugin.Instance.LogMessageExtended("[TwitchChat] Started reading."); IsReading = true; TimeStartedReading = DateTime.Now; } catch (Exception ex2) { Exception ex = ex2; Plugin.Logger.LogError((object)$"[TwitchChat] Failed to start reading Twitch chat. {ex}"); } finally { IsBusy = false; } await Task.Run(async delegate { try { while (!token.IsCancellationRequested) { string message = await _reader.ReadLineAsync(); if (message != null) { if (message.StartsWith("PING")) { Plugin.Instance.LogMessageExtended(message); await _writer.WriteLineAsync("PONG " + message.Split(' ')[1]); Plugin.Instance.LogMessageExtended("[TwitchChat] Responded with PONG to keep connection alive."); } else { ParseMessage(message); } } } } catch (TaskCanceledException) { Plugin.Logger.LogError((object)"[TwitchChat] StartReading task canceled."); } catch (Exception ex5) { Exception ex3 = ex5; if (Plugin.ConfigManager.TwitchIntegration_Enabled.Value) { Plugin.Logger.LogError((object)$"[TwitchChat] StartReading task failed. {ex3}"); } } finally { IsReading = false; } }, token); } public static async Task StopReading() { Plugin.Instance.LogMessageExtended("[TwitchChat] Trying to stop reading."); if (!IsReading || IsBusy) { Plugin.Instance.LogMessageExtended("[TwitchChat] Not reading or busy. No need to stop or wait for the current process."); return; } IsBusy = true; if (_cts != null) { _cts.Cancel(); try { } catch (TaskCanceledException) { } finally { IsReading = false; TimeStartedReading = null; _reader?.Close(); _writer?.Close(); _stream?.Close(); _tcpClient?.Close(); Plugin.Instance.LogMessageExtended("[TwitchChat] Stopped reading."); } } IsBusy = false; } private static void ParseMessage(string message) { if (message.StartsWith(":tmi.twitch.tv") || message.StartsWith(":justinfan123")) { Plugin.Instance.LogMessageExtended(message); } else if (message.StartsWith(":")) { string[] array = message.Split(' '); string text = array[0].Substring(1).Split('!')[0]; string text2 = array[2]; string text3 = message.Substring(message.IndexOf(text2) + text2.Length + 2); Plugin.Instance.LogMessageExtended($"[TwitchChat] [{DateTime.Now:HH:mm}] info: [{text2}] <{text}>: {text3}"); if (Plugin.ConfigManager.TwitchIntegration_Enabled.Value) { OnMessage?.Invoke(new TwitchMessage(text, text3)); } } } } public struct TwitchMessage { public string Sender; public string Message; public TwitchMessage(string sender, string message) { Sender = sender; Message = message; } } internal static class Utils { public static bool RandomPercent(float percent) { if (percent <= 0f) { return false; } if (percent >= 100f) { return true; } return Random.value * 100f <= percent; } public static void CreateExplosion(Vector3 explosionPosition, bool spawnExplosionEffect = false, int damage = 20, float minDamageRange = 0f, float maxDamageRange = 6.4f, int enemyHitForce = 6, CauseOfDeath causeOfDeath = 3, PlayerControllerB attacker = null) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) Plugin.Logger.LogInfo((object)$"Spawning explosion at pos: {explosionPosition}"); Transform val = null; if ((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer.transform != (Object)null) { val = RoundManager.Instance.mapPropsContainer.transform; } if (spawnExplosionEffect) { Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, explosionPosition, Quaternion.Euler(-90f, 0f, 0f), val).SetActive(true); } float num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, explosionPosition); if (num < 14f) { HUDManager.Instance.ShakeCamera((ScreenShakeType)1); } else if (num < 25f) { HUDManager.Instance.ShakeCamera((ScreenShakeType)0); } Collider[] array = Physics.OverlapSphere(explosionPosition, maxDamageRange, 2621448, (QueryTriggerInteraction)2); PlayerControllerB val2 = null; for (int i = 0; i < array.Length; i++) { float num2 = Vector3.Distance(explosionPosition, ((Component)array[i]).transform.position); if (num2 > 4f && Physics.Linecast(explosionPosition, ((Component)array[i]).transform.position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1)) { continue; } if (((Component)array[i]).gameObject.layer == 3) { val2 = ((Component)array[i]).gameObject.GetComponent<PlayerControllerB>(); if ((Object)(object)val2 != (Object)null && ((NetworkBehaviour)val2).IsOwner) { float num3 = 1f - Mathf.Clamp01((num2 - minDamageRange) / (maxDamageRange - minDamageRange)); val2.DamagePlayer((int)((float)damage * num3), true, true, causeOfDeath, 0, false, default(Vector3)); } } else if (((Component)array[i]).gameObject.layer == 21) { Landmine componentInChildren = ((Component)array[i]).gameObject.GetComponentInChildren<Landmine>(); if ((Object)(object)componentInChildren != (Object)null && !componentInChildren.hasExploded && num2 < 6f) { Plugin.Logger.LogInfo((object)"Setting off other mine"); ((MonoBehaviour)componentInChildren).StartCoroutine(componentInChildren.TriggerOtherMineDelayed(componentInChildren)); } } else if (((Component)array[i]).gameObject.layer == 19) { EnemyAICollisionDetect componentInChildren2 = ((Component)array[i]).gameObject.GetComponentInChildren<EnemyAICollisionDetect>(); if ((Object)(object)componentInChildren2 != (Object)null && ((NetworkBehaviour)componentInChildren2.mainScript).IsOwner && num2 < 4.5f) { componentInChildren2.mainScript.HitEnemyOnLocalClient(enemyHitForce, default(Vector3), attacker, false, -1); } } } int num4 = ~LayerMask.GetMask(new string[1] { "Room" }); num4 = ~LayerMask.GetMask(new string[1] { "Colliders" }); array = Physics.OverlapSphere(explosionPosition, 10f, num4); for (int j = 0; j < array.Length; j++) { Rigidbody component = ((Component)array[j]).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.AddExplosionForce(70f, explosionPosition, 10f); } } } public static int GetRandomIndexFromWeightList(List<int> weightList) { List<(int, int)> list = new List<(int, int)>(); for (int i = 0; i < weightList.Count; i++) { int num = weightList[i]; if (num > 0) { list.Add((i, num)); } } int num2 = 0; foreach (var item4 in list) { int item = item4.Item2; num2 += item; } if (num2 == 0) { return -1; } int num3 = Random.Range(0, num2); int num4 = 0; foreach (var item5 in list) { int item2 = item5.Item1; int item3 = item5.Item2; num4 += item3; if (num3 < num4) { return item2; } } throw new InvalidOperationException("Weights are not properly specified."); } public static string GetEnumName<T>(T e) where T : Enum { return Enum.GetName(typeof(T), e) ?? string.Empty; } public static Transform GetHangarShipTransform() { if ((Object)(object)StartOfRound.Instance == (Object)null) { return null; } return StartOfRound.Instance.elevatorTransform; } public static Vector3 GetHangarShipCenter() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Transform hangarShipTransform = GetHangarShipTransform(); if ((Object)(object)hangarShipTransform == (Object)null) { return Vector3.zero; } return hangarShipTransform.position + new Vector3(1.47f, 0f, -6.68f); } public static bool HasBeehivesOnShip(bool inShipRoom = false) { return GetBeehivesOnShipCount(inShipRoom) > 0; } public static int GetBeehivesOnShipCount(bool inShipRoom = false) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) int num = 0; Vector3 hangarShipCenter = GetHangarShipCenter(); GrabbableObject[] array = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); foreach (GrabbableObject val in array) { if (!(((Component)val).transform.position.y < hangarShipCenter.y) && val.itemProperties.itemName.Equals("Hive", StringComparison.OrdinalIgnoreCase) && inShipRoom == val.isInShipRoom && Vector3.Distance(hangarShipCenter, ((Component)val).transform.position) <= 25f) { num++; } } return num; } public static bool CollectedAllScrap() { GrabbableObject[] array = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); foreach (GrabbableObject val in array) { if (val.itemProperties.isScrap && !val.isInShipRoom) { return false; } } return true; } public static void SpawnExplosionForce(Vector3 position, float physicsForce, bool fallDamage = false) { //IL_0015: 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_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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript(); if (physicsForce > 0f && Vector3.Distance(((Component)localPlayerScript).transform.position, position) < 35f && !Physics.Linecast(position, ((Component)localPlayerScript).transform.position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1)) { float num = Vector3.Distance(((Component)localPlayerScript).transform.position, position); Vector3 val = Vector3.Normalize(((Component)localPlayerScript).transform.position + Vector3.up * num - position) / (num * 0.35f) * physicsForce; if (((Vector3)(ref val)).magnitude > 2f) { if (((Vector3)(ref val)).magnitude > 10f) { localPlayerScript.CancelSpecialTriggerAnimations(); } if (localPlayerScript.inVehicleAnimation) { Vector3 val2 = localPlayerScript.externalForceAutoFade + val; if (!(((Vector3)(ref val2)).magnitude > 50f)) { goto IL_0135; } } localPlayerScript.externalForceAutoFade += val; if (!fallDamage) { PlayerControllerBPatch.IgnoreNextFallDamage(); } } } goto IL_0135; IL_0135: VehicleController val3 = Object.FindObjectOfType<VehicleController>(); if ((Object)(object)val3 != (Object)null && !val3.magnetedToShip && physicsForce > 0f && Vector3.Distance(((Component)val3).transform.position, position) < 35f) { val3.mainRigidbody.AddExplosionForce(physicsForce * 50f, position, 12f, 3f, (ForceMode)1); } } public static void SetMeshRenderersEnabled(GameObject gameObject, bool value, bool includeInactive = false) { if ((Object)(object)gameObject == (Object)null) { return; } MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>(includeInactive); foreach (MeshRenderer val in componentsInChildren) { if (!((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger")) { ((Renderer)val).enabled = value; } } SkinnedMeshRenderer[] componentsInChildren2 = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(includeInactive); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { ((Renderer)val2).enabled = value; } } public static int GetForestGiantSpawnCount() { int num = 0; ForestGiantAI[] array = Object.FindObjectsByType<ForestGiantAI>((FindObjectsSortMode)0); foreach (ForestGiantAI val in array) { if (!((EnemyAI)val).isEnemyDead) { num++; } } return num; } public static Vector3 GetMainEntrancePosition() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0043: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0); foreach (EntranceTeleport val in array) { if (val.entranceId == 0) { return ((Component)val).transform.position; } } return Vector3.zero; } public static AudioClip AmplifyClipByDecibels(AudioClip originalClip, float decibelChange) { if ((Object)(object)originalClip == (Object)null) { return null; } float num = Mathf.Pow(10f, decibelChange / 20f); float[] array = new float[originalClip.samples * originalClip.channels]; originalClip.GetData(array, 0); for (int i = 0; i < array.Length; i++) { array[i] *= num; array[i] = Mathf.Clamp(array[i], -1f, 1f); } AudioClip val = AudioClip.Create("AmplifiedClip", originalClip.samples, originalClip.channels, originalClip.frequency, false); val.SetData(array, 0); return val; } public static void LogStackTrace() { StackTrace stackTrace = new StackTrace(); for (int i = 1; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); Type declaringType = method.DeclaringType; string name = method.Name; Plugin.Instance.LogMessageExtended($"Call stack depth {i}: {declaringType}.{name}"); } } public static Coroutine StartCoroutine(IEnumerator routine) { if ((Object)(object)Plugin.Instance != (Object)null) { return ((MonoBehaviour)Plugin.Instance).StartCoroutine(routine); } if ((Object)(object)GameNetworkManager.Instance != (Object)null) { return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(routine); } Plugin.Logger.LogError((object)("Failed to start coroutine. " + routine)); return null; } public static string GetModpackName() { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location); string text = "\\profiles"; int num = directoryName.IndexOf(text, StringComparison.OrdinalIgnoreCase); if (num == -1) { return string.Empty; } int num2 = num + text.Length + 1; if (num2 >= directoryName.Length) { return string.Empty; } string text2 = directoryName.Substring(num2); int num3 = text2.IndexOf('\\'); if (num3 != -1) { return text2.Substring(0, num3); } return string.Empty; } public static bool StringEquals(string input, string[] values, bool matchCase = true) { StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture); foreach (string value in values) { if (input.Equals(value, comparisonType)) { return true; } } return false; } public static bool StringContains(string input, string[] values, bool matchCase = true) { StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture); foreach (string value in values) { if (input.Contains(value, comparisonType)) { return true; } } return false; } public static Vector3 GetLocalPosition(Transform transform, Vector3 position) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_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_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null || (Object)(object)transform.parent == (Object)null) { return position; } return transform.parent.InverseTransformPoint(position); } public static void SetGrabbableObjectPosition(GrabbableObject grabbableObject, Vector3 position) { //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_001c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)grabbableObject == (Object)null)) { grabbableObject.targetFloorPosition = GetLocalPosition(((Component)grabbableObject).transform, position); } } public static void SetGrabbableObjectParent(GrabbableObject grabbableObject, Transform transform) { //IL_0015: 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_0029: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)grabbableObject == (Object)null)) { Vector3 position = ((Component)grabbableObject).transform.position; ((Component)grabbableObject).transform.SetParent(transform); SetGrabbableObjectPosition(grabbableObject, position); } } public static void ExecuteNextFrame(Action action) { StartCoroutine(ExecuteNextFrameCoroutine(action)); } private static IEnumerator ExecuteNextFrameCoroutine(Action action) { yield return null; action?.Invoke(); } public static void ExecuteAfterDelay(Action action, float seconds) { StartCoroutine(ExecuteAfterDelayCoroutine(action, seconds)); } private static IEnumerator ExecuteAfterDelayCoroutine(Action action, float seconds) { yield return (object)new WaitForSeconds(seconds); action?.Invoke(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.TakeyPlush"; public const string PLUGIN_NAME = "TakeyPlush"; public const string PLUGIN_VERSION = "1.13.0"; } } namespace com.github.zehsteam.TakeyPlush.Patches { [HarmonyPatch(typeof(BaboonBirdAI))] internal static class BaboonBirdAIPatch { [HarmonyPatch("GrabItemAndSync")] [HarmonyPrefix] private static bool GrabItemAndSyncPatch(ref BaboonBirdAI __instance, ref NetworkObject item) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)__instance).IsOwner) { return true; } Takey component = ((Component)item).gameObject.GetComponent<Takey>(); if ((Object)(object)component == (Object)null) { return true; } if ((!component.JetpackFly && !component.IsFlying) || !PlayerUtils.IsPlayerNearby(((Component)__instance).gameObject.transform.position, 25f)) { return true; } if (!component.IsFlying) { component.StartFlyingServerRpc(); } return false; } [HarmonyPatch("DropHeldItemAndSync")] [HarmonyPrefix] private static void DropHeldItemAndSyncPatch(ref BaboonBirdAI __instance) { Takey component = ((Component)__instance.heldScrap).gameObject.GetComponent<Takey>(); if (!((Object)(object)component == (Object)null)) { component.RollJetpackFlyServerRpc(); } } } [HarmonyPatch(typeof(BushWolfEnemy))] internal static class BushWolfEnemyPatch { private static List<EnemyAI> _bushWolfsHitByDogs = new List<EnemyAI>(); [HarmonyPatch("HitEnemy")] [HarmonyPrefix] private static void HitEnemyPatch(ref BushWolfEnemy __instance, ref PlayerControllerB playerWhoHit) { if (ExtraFeatureEnabled()) { bool flag = false; if (_bushWolfsHitByDogs.Contains((EnemyAI)(object)__instance)) { _bushWolfsHitByDogs.Remove((EnemyAI)(object)__instance); flag = (Object)(object)playerWhoHit == (Object)null; } AudioClip[] array = (AudioClip[])(object)((!flag) ? new AudioClip[3] { Content.BushWolfHit1SFX, Content.BushWolfHit2SFX, Content.BushWolfHit3SFX } : new AudioClip[2] { Content.BushWolfDogHit1SFX, Content.BushWolfDogHit2SFX }); __instance.hitBushWolfSFX = array[Random.Range(0, array.Length)]; } } [HarmonyPatch("HitTongueLocalClient")] [HarmonyPrefix] private static void HitTongueLocalClientPatch(ref BushWolfEnemy __instance) { if (ExtraFeatureEnabled()) { AudioClip[] array = (AudioClip[])(object)new AudioClip[3] { Content.BushWolfHit1SFX, Content.BushWolfHit2SFX, Content.BushWolfHit3SFX }; __instance.hitBushWolfSFX = array[Random.Range(0, array.Length)]; } } public static void AddBushWolfHitByDog(EnemyAI enemyScript) { if (!_bushWolfsHitByDogs.Contains(enemyScript)) { _bushWolfsHitByDogs.Add(enemyScript); } } private static bool ExtraFeatureEnabled() { if (!Plugin.ConfigManager.ExtraFeatures_Enabled.Value) { return false; } if (!Plugin.ConfigManager.ExtraFeatures_EnableSpecialKidnapperFoxSounds.Value) { return false; } return true; } } [HarmonyPatch(typeof(ButlerEnemyAI))] internal static class ButlerEnemyAIPatch { private static Dictionary<ButlerEnemyAI, TakeyButlerController> _takeyButlerControllerPairs = new Dictionary<ButlerEnemyAI, TakeyButlerController>(); public static void Initialize() { if (NetworkUtils.IsServer) { Events.OnShipLeave = (Action)Delegate.Combine(Events.OnShipLeave, new Action(OnShipLeave)); } } private static void OnShipLeave() { TakeyButlerController[] array = _takeyButlerControllerPairs.Values.ToArray(); TakeyButlerController[] array2 = array; NetworkObject val = default(NetworkObject); foreach (TakeyButlerController takeyButlerController in array2) { if (!((Object)(object)takeyButlerController == (Object)null) && ((Component)takeyButlerController).TryGetComponent<NetworkObject>(ref val) && val.IsSpawned) { val.Despawn(true); } } _takeyButlerControllerPairs.Clear(); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(ref ButlerEnemyAI __instance) { if (!NetworkUtils.IsServer || !Plugin.ConfigManager.ExtraFeatures_Enabled.Value) { return; } bool flag = false; if (PlayerUtils.IsLocalPlayer(PlayerName.Takerst)) { int num = ModpackSaveSystem.ReadValue("TimesForceSetTakeyButler", 0); if (num < 5) { ModpackSaveSystem.WriteValue("TimesForceSetTakeyButler", num + 1); flag = true; } } if (Utils.RandomPercent(Plugin.ConfigManager.ExtraFeatures_ButlerReskinChance.Value) || flag) { SetTakeyButlerOnServer(__instance); } } private static void SetTakeyButlerOnServer(ButlerEnemyAI butlerEnemyAI) { if (NetworkUtils.IsServer) { if (_takeyButlerControllerPairs.ContainsKey(butlerEnemyAI)) { Plugin.Logger.LogError((object)"Failed to set Takey Butler on server. ButlerEnemyAI is already a Takey Butler."); return; } GameObject val = Object.Instantiate<GameObject>(Content.TakeyButlerControllerPrefab); TakeyButlerController component = val.GetComponent<TakeyButlerController>(); NetworkObject component2 = val.GetComponent<NetworkObject>(); component2.Spawn(true); val.transform.SetParent(((Component)butlerEnemyAI).transform); _takeyButlerControllerPairs.Add(butlerEnemyAI, component); } } [HarmonyPatch("StabPlayerServerRpc")] [HarmonyPostfix] private static void StabPlayerServerRpcPatch(ref ButlerEnemyAI __instance, int playerId) { if (NetworkUtils.IsServer && _takeyButlerControllerPairs.TryGetValue(__instance, out var value)) { PlayerControllerB playerScript = StartOfRound.Instance.allPlayerScripts[playerId]; value.OnStabPlayerOnServer(playerScript); } } } [HarmonyPatch(typeof(ForestGiantAI))] internal static class ForestGiantAIPatch { private static Dictionary<ForestGiantAI, bool> _enemiesNearMain = new Dictionary<ForestGiantAI, bool>(); private static Vector3 _mainEntrancePosition; public static void Initialize() { Events.OnShipArrive = (Action)Delegate.Combine(Events.OnShipArrive, new Action(OnShipArrive)); } private static void OnShipArrive() { //IL_000c: 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) _enemiesNearMain.Clear(); _mainEntrancePosition = Utils.GetMainEntrancePosition(); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(ref ForestGiantAI __instance) { Events.OnForestGiantSpawned?.Invoke(__instance); } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePatch(ref ForestGiantAI __instance) { //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 (((EnemyAI)__instance).isEnemyDead) { return; } if (!_enemiesNearMain.ContainsKey(__instance)) { _enemiesNearMain.Add(__instance, value: false); } if (!_enemiesNearMain.TryGetValue(__instance, out var value)) { return; } bool flag = Vector3.Distance(((Component)__instance).transform.position, _mainEntrancePosition) <= 25f; if (value != flag) { _enemiesNearMain[__instance] = flag; if (flag) { Events.OnForestGiantNearMain?.Invoke(__instance); } } } } [HarmonyPatch(typeof(GameNetworkManager))] internal static class GameNetworkManagerPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { AddNetworkPrefabs(); } private static void AddNetworkPrefabs() { AddNetworkPrefab(Content.NetworkHandlerPrefab); AddNetworkPrefab(Content.TakeyButlerControllerPrefab); foreach (TakeyVariantData variant in Content.TakeyVariantDataList.Variants) { AddNetworkPrefab(variant.Prefab); } } private static void AddNetworkPrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { Plugin.Logger.LogError((object)"Failed to register network prefab. GameObject is null."); return; } NetworkManager.Singleton.AddNetworkPrefab(prefab); Plugin.Logger.LogInfo((object)("Registered \"" + ((Object)prefab).name + "\" network prefab.")); } } [HarmonyPatch(typeof(GrabbableObject))] internal static class GrabbableObjectPatch { public static List<string> TakeyALOOEventReceiverItemWhitelist = new List<string>(2) { "Walkie-talkie", "Old phone" }; [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(ref GrabbableObject __instance) { if (TakeyALOOEventReceiverItemWhitelist.Contains(__instance.itemProperties.itemName)) { Object.Instantiate<GameObject>(Content.TakeyALOOEventReceiverPrefab, ((Component)__instance).transform); } } } [HarmonyPatch(typeof(HoarderBugAI))] internal static class HoarderBugAIPatch { [HarmonyPatch("GrabTargetItemIfClose")] [HarmonyPrefix] private static bool GrabTargetItemIfClosePatch(ref HoarderBugAI __instance, ref bool __result) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)__instance).IsOwner) { return true; } if ((Object)(object)__instance.targetItem != (Object)null && __instance.heldItem == null && Vector3.Distance(((Component)__instance).transform.position, ((Component)__instance.targetItem).transform.position) < 0.75f) { Takey component = ((Component)__instance.targetItem).gameObject.GetComponent<Takey>(); if ((Object)(object)component == (Object)null) { return true; } if ((!component.JetpackFly && !component.IsFlying) || !PlayerUtils.IsPlayerNearby(((Component)__instance).gameObject.transform.position, 25f)) { return true; } if (!component.IsFlying) { component.StartFlyingServerRpc(); } __result = true; return false; } return true; } [HarmonyPatch("DropItemAndCallDropRPC")] [HarmonyPostfix] private static void DropItemAndCallDropRPCPatch(ref HoarderBugAI __instance, ref NetworkObject dropItemNetworkObject) { if (((NetworkBehaviour)__instance).IsOwner) { Takey component = ((Component)dropItemNetworkObject).gameObject.GetComponent<Takey>(); if (!((Object)(object)component == (Object)null)) { component.RollJetpackFlyServerRpc(); } } } } [HarmonyPatch(typeof(HUDManager))] internal static class HUDManagerPatch { [HarmonyPatch("DisplayNewScrapFound")] [HarmonyPrefix] private static bool DisplayNewScrapFoundPatch(ref HUDManager __instance) { if (__instance.itemsToBeDisplayed.Count <= 0) { return true; } GrabbableObject val = __instance.itemsToBeDisplayed[0]; if ((Object)(object)val == (Object)null || (Object)(object)val.itemProperties.spawnPrefab == (Object)null) { return true; } Takey takey = val as Takey; if ((Object)(object)takey != (Object)null) { DisplayNewSmolTakeyScrapFound(__instance, takey); return false; } return true; } private static void DisplayNewSmolTakeyScrapFound(HUDManager __instance, Takey takeyBehaviour) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) if (((GrabbableObject)takeyBehaviour).scrapValue < 80) { __instance.UIAudio.PlayOneShot(__instance.displayCollectedScrapSFXSmall); } else { __instance.UIAudio.PlayOneShot(__instance.displayCollectedScrapSFX); } ScrapItemHUDDisplay val = __instance.ScrapItemBoxes[__instance.nextBoxIndex]; GameObject val2 = Object.Instantiate<GameObject>(takeyBehaviour.VariantDataList.GetByIndex(takeyBehaviour.VariantIndex).Prefab, val.itemObjectContainer); Object.Destroy((Object)(object)val2.GetComponent<NetworkObject>()); Object.Destroy((Object)(object)val2.GetComponent<TakeyVariant>()); Animator[] componentsInChildren = val2.GetComponentsInChildren<Animator>(); foreach (Animator val3 in componentsInChildren) { Object.Destroy((Object)(object)val3); } Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(); foreach (Collider val4 in componentsInChildren2) { Object.Destroy((Object)(object)val4); } val2.transform.localPosition = Vector3.zero; val2.transform.localScale = val2.transform.localScale * 4f; val2.transform.rotation = Quaternion.Euler(((GrabbableObject)takeyBehaviour).itemProperties.restingRotation); Renderer[] componentsInChildren3 = val2.GetComponentsInChildren<Renderer>(); foreach (Renderer val5 in componentsInChildren3) { if (((Component)val5).gameObject.layer != 22) { val5.rendererPriority = 70; Material[] sharedMaterials = val5.sharedMaterials; for (int l = 0; l < sharedMaterials.Length; l++) { sharedMaterials[l] = __instance.hologramMaterial; } val5.sharedMaterials = sharedMaterials; ((Component)val5).gameObject.layer = 5; } } val.itemDisplayAnimator.SetTrigger("collect"); ((TMP_Text)val.headerText).text = ((GrabbableObject)takeyBehaviour).itemProperties.itemName + " collected!"; ((TMP_Text)val.valueText).text = $"Value: ${((GrabbableObject)takeyBehaviour).scrapValue}"; if (__instance.boxesDisplaying > 0) { val.UIContainer.anchoredPosition = new Vector2(val.UIContainer.anchoredPosition.x, __instance.ScrapItemBoxes[__instance.bottomBoxIndex].UIContainer.anchoredPosition.y - 124f); } else { val.UIContainer.anchoredPosition = new Vector2(val.UIContainer.anchoredPosition.x, (float)__instance.bottomBoxYPosition); } __instance.bottomBoxIndex = __instance.nextBoxIndex; ((MonoBehaviour)__instance).StartCoroutine(__instance.displayScrapTimer(val2)); __instance.playScrapDisplaySFX(); __instance.boxesDisplaying++; __instance.nextBoxIndex = (__instance.nextBoxIndex + 1) % 3; __instance.itemsToBeDisplayed.RemoveAt(0); } [HarmonyPatch("AddNewScrapFoundToDisplay")] [HarmonyPostfix] private static void AddNewScrapFoundToDisplayPatch(GrabbableObject GObject) { Events.OnNewScrapCollected?.Invoke(GObject); } [HarmonyPatch("DisplayNewDeadline")] [HarmonyPostfix] private static void DisplayNewDeadlinePatch() { Events.OnProfitQuotaFulfilled?.Invoke(); } } [HarmonyPatch(typeof(ItemDropship))] internal static class ItemDropshipPatch { [HarmonyPatch("LandShipOnServer")] [HarmonyPostfix] private static void LandShipOnServerPatch(ref List<int> ___itemsToDeliver) { TryReplaceJetpacksWithTakeypacks(___itemsToDeliver); } private static void TryReplaceJetpacksWithTakeypacks(List<int> itemsToDeliver) { if (!ShopHelper.TryGetBuyItemIndex("Takeypack", out var buyItemIndex)) { return; } for (int i = 0; i < itemsToDeliver.Count; i++) { if (ShopHelper.IsBuyItemIndex(itemsToDeliver[i], "Jetpack") && Utils.RandomPercent(Plugin.ConfigManager.Takeypack_JetpackReplaceChance.Value)) { itemsToDeliver[i] = buyItemIndex; } } } [HarmonyPatch("LandShipOnServer")] [HarmonyPostfix] private static void LandShipOnServerPatch() { TerminalPatch.PreviousOrderedItemsFromTerminal.Clear(); } } [HarmonyPatch(typeof(JetpackItem))] internal static class JetpackItemPatch { private static List<TakeypackItem> _takeypackItemBehaviours = new List<TakeypackItem>(); public static void AddTakeypackItem(TakeypackItem takeypackItemBehaviour) { if (!_takeypackItemBehaviours.Contains(takeypackItemBehaviour)) { _takeypackItemBehaviours.Add(takeypackItemBehaviour); } } public static bool RemoveTakeypackItem(TakeypackItem takeypackItemBehaviour) { return _takeypackItemBehaviours.Remove(takeypackItemBehaviour); } [HarmonyPatch("JetpackEffect")] [HarmonyPostfix] private static void JetpackEffectPatch(ref JetpackItem __instance, bool enable) { if (TryGetTakeypack(__instance, out var takeypackItemBehaviour)) { takeypackItemBehaviour.SetJetpackEffects(enable); } } private static bool TryGetTakeypack(JetpackItem jetpackItem, out TakeypackItem takeypackItemBehaviour) { takeypackItemBehaviour = null; foreach (TakeypackItem takeypackItemBehaviour2 in _takeypackItemBehaviours) { if ((Object)(object)takeypackItemBehaviour2 == (Object)(object)jetpackItem) { takeypackItemBehaviour = takeypackItemBehaviour2; return true; } } return false; } } [HarmonyPatch(typeof(MaskedPlayerEnemy))] internal static class MaskedPlayerEnemyPatch { private static Dictionary<MaskedPlayerEnemy, bool> _enemiesInsideHangarShip = new Dictionary<MaskedPlayerEnemy, bool>(); public static void Initialize() { Events.OnShipArrive = (Action)Delegate.Combine(Events.OnShipArrive, new Action(OnShipArrive)); } private static void OnShipArrive() { _enemiesInsideHangarShip.Clear(); } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePatch(ref MaskedPlayerEnemy __instance) { if (((EnemyAI)__instance).isEnemyDead || !StartOfRound.Instance.shipHasLanded || StartOfRound.Instance.shipIsLeaving) { return; } if (!_enemiesInsideHangarShip.ContainsKey(__instance)) { _enemiesInsideHangarShip.Add(__instance, value: false); } if (_enemiesInsideHangarShip.TryGetValue(__instance, out var value) && value != ((EnemyAI)__instance).isInsidePlayerShip) { _enemiesInsideHangarShip[__instance] = ((EnemyAI)__instance).isInsidePlayerShip; if (((EnemyAI)__instance).isInsidePlayerShip) { Events.OnMaskedEnteredShip?.Invoke(__instance); } } } } [HarmonyPatch(typeof(MouthDogAI))] internal static class MouthDogAIPatch { [HarmonyPatch("OnCollideWithEnemy")] [HarmonyPrefix] private static void OnCollideWithEnemyPatch(EnemyAI collidedEnemy, ref float ___timeSinceHittingOtherEnemy) { if (ExtraFeatureEnabled() && !(collidedEnemy.enemyType.enemyName != "Bush Wolf") && !(___timeSinceHittingOtherEnemy < 1f)) { BushWolfEnemyPatch.AddBushWolfHitByDog(collidedEnemy); } } private static bool ExtraFeatureEnabled() { if (!Plugin.ConfigManager.ExtraFeatures_Enabled.Value) { return false; } if (!Plugin.ConfigManager.ExtraFeatures_EnableSpecialKidnapperFoxSounds.Value) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB))] internal static class PlayerControllerBPatch { private static bool _isPlayerDead; private static bool _ignoreNextFallDamage; private static Coroutine _ignoreNextFallCancelCheck; private static bool _wasSinking; private static bool _wasUnderwater; public static void OnDeadPlayersRevived() { _isPlayerDead = false; } [HarmonyPatch("KillPlayer")] [HarmonyPrefix] private static void KillPlayerPatchPrefix(ref PlayerControllerB __instance) { if (PlayerUtils.IsLocalPlayer(__instance)) { _wasSinking = __instance.isSinking; _wasUnderwater = __instance.isUnderwater; } } [HarmonyPatch("KillPlayer")] [HarmonyPostfix] private static void KillPlayerPatchPostfix(ref PlayerControllerB __instance) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (PlayerUtils.IsLocalPlayer(__instance) && __instance.isPlayerDead && !_isPlayerDead) { _isPlayerDead = true; PlayerDeathReason playerDeathReasonFromStackTrace = GetPlayerDeathReasonFromStackTrace(__instance); Plugin.Instance.LogInfoExtended("Local player died by " + Utils.GetEnumName(playerDeathReasonFromStackTrace)); PluginNetworkBehaviour.Instance.PlayerDiedServerRpc(playerDeathReasonFromStackTrace); } } private static PlayerDeathReason GetPlayerDeathReasonFromStackTrace(PlayerControllerB playerScript) { StackTrace stackTrace = new StackTrace(); for (int i = 1; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); Type declaringType = method.DeclaringType; string name = method.Name; if (!(declaringType == null)) { if (declaringType.Name == "PlayerControllerB" && name.Contains("PlayerHitGroundEffects")) { return PlayerDeathReason.Falling; } if (declaringType.Name == "Landmine" && name.Contains("SpawnExplosion")) { return PlayerDeathReason.Landmine; } } } if (_wasSinking && !_wasUnderwater) { return PlayerDeathReason.Quicksand; } return PlayerDeathReason.Unknown; } [HarmonyPatch("TeleportPlayer")] [HarmonyPostfix] private static void TeleportPlayerPatch(ref PlayerControllerB __instance) { if (!__instance.isPlayerDead) { _isPlayerDead = false; } } [HarmonyPatch("PlayerHitGroundEffects")] [HarmonyPrefix] private static void PlayerHitGroundEffectsPatch(ref PlayerControllerB __instance) { if (PlayerUtils.IsLocalPlayer(__instance) && _ignoreNextFallDamage) { _ignoreNextFallDamage = false; if (__instance.fallValueUncapped < -39f) { __instance.fallValueUncapped = -39f; } if (__instance.fallValue < -38f) { __instance.fallValue = -38f; } Plugin.Instance.LogInfoExtended("Local player ignored fall damage."); } } public static void IgnoreNextFallDamage() { _ignoreNextFallDamage = true; if (_ignoreNextFallCancelCheck != null) { ((MonoBehaviour)StartOfRound.Instance).StopCoroutine(_ignoreNextFallCancelCheck); } _ignoreNextFallCancelCheck = Utils.StartCoroutine(IgnoreNextFallCancelCheck()); } private static IEnumerator IgnoreNextFallCancelCheck() { PlayerControllerB playerScript = PlayerUtils.GetLocalPlayerScript(); if ((Object)(object)playerScript == (Object)null) { _ignoreNextFallDamage = false; yield break; } yield return (object)new WaitForSeconds(1f); if (_ignoreNextFallDamage && playerScript.thisController.isGrounded) { yield return (object)new WaitForSeconds(0.1f); Plugin.Instance.LogInfoExtended("Cancelled local player ignored fall damage."); _ignoreNextFallDamage = false; } } [HarmonyPatch("GrabObjectServerRpc")] [HarmonyPostfix] private static void GrabObjectServerRpcPatch(ref NetworkObjectReference grabbedObject) { NetworkObject val = default(NetworkObject); GrabbableObject obj = default(GrabbableObject); if (NetworkUtils.IsServer && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref obj)) { Events.OnGrabItem?.Invoke(obj); } } [HarmonyPatch("ThrowObjectServerRpc")] [HarmonyPostfix] private static void ThrowObjectServerRpcPatch(ref NetworkObjectReference grabbedObject) { NetworkObject val = default(NetworkObject); GrabbableObject obj = default(GrabbableObject); if (NetworkUtils.IsServer && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref obj)) { Events.OnDiscardItem?.Invoke(obj); } } [HarmonyPatch("PlaceObjectServerRpc")] [HarmonyPostfix] private static void PlaceObjectServerRpcPatch(ref NetworkObjectReference grabbedObject) { NetworkObject val = default(NetworkObject); GrabbableObject obj = default(GrabbableObject); if (NetworkUtils.IsServer && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref obj)) { Events.OnDiscardItem?.Invoke(obj); } } [HarmonyPatch("PlaceGrabbableObject")] [HarmonyPostfix] private static void PlaceGrabbableObjectPatch(Transform parentObject, bool matchRotationOfParent, GrabbableObject placeObject) { if (!((Object)(object)parentObject == (Object)null) && !((Object)(object)placeObject == (Object)null) && !((Object)(object)TakeyMugShelf.Instance == (Object)null) && (Object)(object)parentObject == (Object)(object)((Component)TakeyMugShelf.Instance).transform && matchRotationOfParent) { TakeyMugShelf.Instance.SetGrabbableObjectLocalRotation(placeObject); } } } [HarmonyPatch(typeof(PufferAI))] internal static class PufferAIPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(ref PufferAI __instance) { if (NetworkUtils.IsServer && Plugin.ConfigManager.ExtraFeatures_Enabled.Value && Utils.RandomPercent(Plugin.ConfigManager.ExtraFeatures_SpecialSporeLizardSoundsChance.Value)) { SetPufferNervousAudioClipOnServer(__instance, 0); } } private static void SetPufferNervousAudioClipOnServer(PufferAI pufferAI, int clipIndex) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (NetworkUtils.IsServer) { PluginNetworkBehaviour.Instance.SetPufferNervousAudioClipClientRpc(NetworkObjectReference.op_Implicit(((Component)pufferAI).GetComponent<NetworkObject>()), clipIndex); SetNervousAudioClipOnLocalClient(pufferAI, clipIndex); } } public static void SetNervousAudioClipOnLocalClient(PufferAI pufferAI, int clipIndex) { if (!((Object)(object)pufferAI == (Object)null) && clipIndex == 0) { pufferAI.nervousMumbling = Content.BlubbersYameteKudasaiSFX; } } } [HarmonyPatch(typeof(RoundManager))] internal static class RoundManagerPatch { private static bool ShipArrived; private static bool _increasedSmolTakeyRarityForRound; [HarmonyPatch("FinishGeneratingNewLevelClientRpc")] [HarmonyPostfix] private static void FinishGeneratingNewLevelClientRpcPatch() { if (!ShipArrived) { ShipArrived = true; Events.OnShipArrive?.Invoke(); Utils.StartCoroutine(ResetShipArrivedAfterTime(10f)); } } private static IEnumerator ResetShipArrivedAfterTime(float time) { yield return (object)new WaitForSeconds(time); ShipArrived = false; } [HarmonyPatch("SpawnScrapInLevel")] [HarmonyPrefix] private static void SpawnScrapInLevelPatchPrefix() { if (!NetworkUtils.IsServer || !PlayerUtils.IsLocalPlayer(new PlayerName[3] { PlayerName.Takerst, PlayerName.Lunxara, PlayerName.AGlitchedNpc }) || Utils.StringContains(Utils.GetModpackName(), new string[4] { "TakeyTroup", "HQ", "HighQuota", "High Quota" }, matchCase: false)) { return; } string key = "IncreasedScrapRarityForRounds_10"; float percent = 15f; int num = 15; int num2 = 100; if (!Utils.RandomPercent(percent)) { return; } int num3 = ModpackSaveSystem.ReadValue(key, 0); if (num3 >= num) { return; } ModpackSaveSystem.WriteValue(key, num3 + 1); _increasedSmolTakeyRarityForRound = true; foreach (ItemConfigData instance in ItemConfigData.Instances) { int value = instance.SpawnWeight.Value; if (value > 0) { ItemHelper.UpdateScrapRarity(instance.Item, Mathf.Max(value, num2)); } } } [HarmonyPatch("SpawnScrapInLevel")] [HarmonyPostfix] private static void SpawnScrapInLevelPatchPostfix() { if (!NetworkUtils.IsServer || !_increasedSmolTakeyRarityForRound) { return; } _increasedSmolTakeyRarityForRound = false; foreach (ItemConfigData instance in ItemConfigData.Instances) { ItemHelper.UpdateScrapRarity(instance); } } } [HarmonyPatch(typeof(SandSpiderAI))] internal static class SandSpiderAIPatch { private static Dictionary<SandSpiderAI, GameObject> _cuteSandSpiderPairs = new Dictionary<SandSpiderAI, GameObject>(); public static void Initialize() { Events.OnShipArrive = (Action)Delegate.Combine(Events.OnShipArrive, new Action(OnShipArrive)); } private static void OnShipArrive() { _cuteSandSpiderPairs.Clear(); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(ref SandSpiderAI __instance) { if (!NetworkUtils.IsServer || !Plugin.ConfigManager.ExtraFeatures_Enabled.Value) { return; } bool flag = false; if (PlayerUtils.IsLocalPlayer(PlayerName.Takerst)) { int num = ModpackSaveSystem.ReadValue("TimesForceSetCuteSandSpider", 0); if (num < 5) { ModpackSaveSystem.WriteValue("TimesForceSetCuteSandSpider", num + 1); flag = true; } } if (Utils.RandomPercent(Plugin.ConfigManager.ExtraFeatures_BunkerSpiderReskinChance.Value) || flag) { SetCuteSandSpiderOnServer(__instance); } } private static void SetCuteSandSpiderOnServer(SandSpiderAI sandSpiderAI) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (NetworkUtils.IsServer) { if (_cuteSandSpiderPairs.ContainsKey(sandSpiderAI)) { Plugin.Logger.LogError((object)"Failed to set cute sand spider on server. SandSpiderAI is already a cute sand spider."); return; } PluginNetworkBehaviour.Instance.SetCuteSandSpiderClientRpc(NetworkObjectReference.op_Implicit(((Component)sandSpiderAI).GetComponent<NetworkObject>())); SetCuteSandSpiderOnLocalClient(sandSpiderAI); } } public static void SetCuteSandSpiderOnLocalClient(NetworkObjectReference networkObjectReference) { NetworkObject val = default(NetworkObject); SandSpiderAI cuteSandSpiderOnLocalClient = default(SandSpiderAI); if (!((NetworkObjectReference)(ref networkObjectReference)).TryGet(ref val, (NetworkManager)null)) { Plugin.Logger.LogError((object)"Failed to set cute sand spider on local client. NetworkObject is null."); } else if (((Component)val).TryGetComponent<SandSpiderAI>(ref cuteSandSpiderOnLocalClient)) { SetCuteSandSpiderOnLocalClient(cuteSandSpiderOnLocalClient); } else { Plugin.Logger.LogError((object)"Failed to set cute sand spider on local client. SandSpiderAI is null."); } } private static void SetCuteSandSpiderOnLocalClient(SandSpiderAI sandSpiderAI) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (_cuteSandSpiderPairs.ContainsKey(sandSpiderAI)) { Plugin.Logger.LogError((object)"Failed to set cute sand spider on local client. SandSpiderAI is already a cute sand spider."); return; } try { Transform val = ((Component)sandSpiderAI).transform.Find("MeshContainer").Find("AnimContainer").Find("Armature") .Find("Head"); GameObject val2 = Object.Instantiate<GameObject>(Content.CuteSandSpiderPrefab, val); val2.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); ScanNodeProperties componentInChildren = ((Component)sandSpiderAI).GetComponentInChildren<ScanNodeProperties>(); componentInChildren.headerText = "Linda"; _cuteSandSpiderPairs.Add(sandSpiderAI, val2); Plugin.Instance.LogInfoExtended("Set cute sand spider on local client."); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Failed to set cute sand spider on local client. {arg}"); } } } [HarmonyPatch(typeof(ShipBuildModeManager))] internal static class ShipBuildModeManagerPatch { [HarmonyPatch("StoreObjectServerRpc")] [HarmonyPrefix] private static void StoreObjectServerRpcPatch(NetworkObjectReference objectRef) { NetworkObject val = default(NetworkObject); if (!NetworkUtils.IsServer || !((NetworkObjectReference)(ref objectRef)).TryGet(ref val, (NetworkManager)null) || !val.IsSpawned) { return; } PlaceableShipObject componentInChildren = ((Component)val).GetComponentInChildren<PlaceableShipObject>(); if (!((Object)(object)componentInChildren == (Object)null)) { UnlockableItem unlockableItem = UnlockableItemHelper.GetUnlockableItem(componentInChildren.unlockableID); if (unlockableItem != null && !unlockableItem.inStorage && unlockableItem.canBeStored && unlockableItem.spawnPrefab && unlockableItem == Content.TakeyMugShelf.unlockable) { TakeyMugShelf.Instance?.UnparentGrabbableObjectsOnServer(); } } } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch() { SpawnNetworkHandler(); } private static void SpawnNetworkHandler() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (NetworkUtils.IsServer) { GameObject val = Object.Instantiate<GameObject>(Content.NetworkHandlerPrefab, Vector3.zero, Quaternion.identity); val.GetComponent<NetworkObject>().Spawn(false); } } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { Plugin.ConfigManager.TrySetCustomSettings(); foreach (ItemConfigData instance in ItemConfigData.Instances) { instance.RefreshConfigData(); } foreach (UnlockableItemConfigData instance2 in UnlockableItemConfigData.Instances) { instance2.RefreshConfigData(); } if (NetworkUtils.IsServer && Plugin.ConfigManager.TwitchIntegration_Enabled.Value) { TwitchChat.StartReading(); } } [HarmonyPatch("LoadUnlockables")] [HarmonyPostfix] private static void LoadUnlockablesPatch() { if (!NetworkUtils.IsServer) { return; } foreach (UnlockableItemConfigData instance in UnlockableItemConfigData.Instances) { UnlockableItem unlockableItem = instance.UnlockableItem; if (unlockableItem != null && !unlockableItem.inStorage && instance.UnlockAtStart.Value) { StartOfRound.Instance.UnlockShipObject(instance.UnlockableId); } } } [HarmonyPatch("LoadShipGrabbableItems")] [HarmonyPostfix] private static void LoadShipGrabbableItemsPatch() { TakeyMugShelf.Instance?.ParentGrabbableObjectsNextFrame(); } [HarmonyPatch("OnClientConnect")] [HarmonyPrefix] private static void OnClientConnectPatch(ref ulong clientId) { SendConfigsToNewConnectedPlayer(clientId); } private static void SendConfigsToNewConnectedPlayer(ulong clientId) { if (!NetworkUtils.IsServer) { return; } Plugin.Logger.LogInfo((object)$"Sending item config data to client: {clientId}"); foreach (ItemConfigData instance in ItemConfigData.Instances) { instance.SendConfigDataToClient(clientId); } foreach (UnlockableItemConfigData instance2 in UnlockableItemConfigData.Instances) { instance2.SendConfigDataToClient(clientId); } } [HarmonyPatch("OnPlayerConnectedClientRpc")] [HarmonyPostfix] private static void OnPlayerConnectedClientRp
ProfanityFilter.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using ProfanityFilter.Interfaces; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Stephen Haunts")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Profanity Filter used to detect or censor text in an application. You can use the inbuilt profanity list, or load up your organizations custom list.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ProfanityFilter")] [assembly: AssemblyTitle("ProfanityFilter")] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.0.0")] namespace ProfanityFilter { public class AllowList : IAllowList { private List<string> _allowList; public ReadOnlyCollection<string> ToList => new ReadOnlyCollection<string>(_allowList); public int Count => _allowList.Count; public AllowList() { _allowList = new List<string>(); } public void Add(string wordToAllowlist) { if (string.IsNullOrEmpty(wordToAllowlist)) { throw new ArgumentNullException("wordToAllowlist"); } if (!_allowList.Contains(wordToAllowlist.ToLower(CultureInfo.InvariantCulture))) { _allowList.Add(wordToAllowlist.ToLower(CultureInfo.InvariantCulture)); } } public bool Contains(string wordToCheck) { if (string.IsNullOrEmpty(wordToCheck)) { throw new ArgumentNullException("wordToCheck"); } return _allowList.Contains(wordToCheck.ToLower(CultureInfo.InvariantCulture)); } public void Clear() { _allowList.Clear(); } public bool Remove(string wordToRemove) { if (string.IsNullOrEmpty(wordToRemove)) { throw new ArgumentNullException("wordToRemove"); } return _allowList.Remove(wordToRemove.ToLower(CultureInfo.InvariantCulture)); } } public class ProfanityBase { protected List<string> _profanities; private readonly string[] _wordList = new string[1626] { "8===D", "8==D", "8=D", "2 girls 1 cup", "two girls one cup", "two girls 1 cup", "2 girls one cup", "2g1c", "4r5e", "5h1t", "5hit", "a$$", "a$$hole", "a_s_s", "a2m", "a55", "a55hole", "acrotomophilia", "aeolus", "ahole", "alabama hot pocket", "alaskan pipeline", "anal", "anal impaler", "anal leakage", "analprobe", "anilingus", "angrydragon", "angry dragon", "anus", "apeshit", "ar5e", "arian", "arrse", "arse", "arses", "arsehole", "aryan", "ass", "ass fuck", "ass hole", "assbag", "assbandit", "assbang", "assbanged", "assbanger", "assbangs", "assbite", "assclown", "asscock", "asscracker", "asses", "assface", "assfaces", "assfuck", "assfucker", "ass-fucker", "assfukka", "assgoblin", "assh0le", "asshat", "ass-hat", "asshead", "assho1e", "asshole", "assholes", "asshopper", "ass-jabber", "assjacker", "asslick", "asslicker", "assmaster", "assmonkey", "assmucus", "assmunch", "assmuncher", "assnigger", "asspirate", "ass-pirate", "assshit", "assshole", "asssucker", "asswad", "asswhole", "asswipe", "asswipes", "auto erotic", "autoerotic", "axwound", "axewound", "axe wound", "azazel", "azz", "b!tch", "b00bs", "b17ch", "b1tch", "babeland", "baby batter", "baby juice", "ball gag", "ball gravy", "ball kicking", "ball licking", "ball sack", "ball sucking", "ballbag", "balls", "ballsack", "bampot", "bang (one's) box", "bangbros", "bareback", "barely legal", "barenaked", "barf", "bastard", "bastardo", "bastards", "bastinado", "batty boy", "bawdy", "bbw", "bdsm", "beaner", "beaners", "beardedclam", "beastial", "beastiality", "beatch", "beaver", "beaver cleaver", "beaver lips", "beef curtain", "beef curtains", "beeyotch", "bellend", "bender", "beotch", "bescumber", "bestial", "bestiality", "bi+ch", "biatch", "big black", "big breasts", "big knockers", "big tits", "bigtits", "bimbo", "bimbos", "bint", "birdlock", "bitch", "bitch tit", "bitchass", "bitched", "bitcher", "bitchers", "bitches", "bitchin", "bitching", "bitchtits", "bitchy", "black cock", "blonde action", "blonde on blonde action", "bloodclaat", "bloody", "bloody hell", "blow job", "blow me", "blow mud", "blow your load", "blowjob", "blowjobs", "blue waffle", "blumpkin", "bod", "bodily", "boink", "boiolas", "bollock", "bollocks", "bollok", "bollox", "bondage", "boned", "boner", "boners", "bong", "boob", "boobies", "boobs", "booby", "booger", "bookie", "boong", "booobs", "boooobs", "booooobs", "booooooobs", "bootee", "bootie", "booty", "booty call", "booze", "boozer", "boozy", "bosom", "bosomy", "breasts", "breeder", "brotherfucker", "brown showers", "brunette action", "buceta", "bugger", "bukkake", "bull shit", "bulldyke", "bullet vibe", "bullshit", "bullshits", "bullshitted", "bullturds", "bum", "bum boy", "bumblefuck", "bumclat", "bummer", "buncombe", "bung", "bung hole", "bunghole", "bunny fucker", "bust a load", "busty", "butt", "butt fuck", "butt plug", "buttcheeks", "buttfuck", "buttfucka", "buttfucker", "butthole", "buttmuch", "buttmunch", "butt-pirate", "buttplug", "c.0.c.k", "c.o.c.k.", "c.u.n.t", "c0ck", "c-0-c-k", "c0cksucker", "caca", "cacafuego", "cahone", "camel toe", "cameltoe", "camgirl", "camslut", "camwhore", "carpet muncher", "carpetmuncher", "cawk", "cervix", "chesticle", "chi-chi man", "chick with a dick", "child-fucker", "chinc", "chincs", "chink", "chinky", "choad", "choade", "choc ice", "chocolate rosebuds", "chode", "chodes", "chota bags", "cipa", "circlejerk", "cl1t", "cleveland steamer", "climax", "clit", "clit licker", "clitface", "clitfuck", "clitoris", "clits", "clitty", "clitty litter", "clover clamps", "clunge", "clusterfuck", "cnut", "cocain", "cocaine", "coccydynia", "cock", "c-o-c-k", "cock pocket", "cock snot", "cock sucker", "cockass", "cockbite", "cockblock", "cockburger", "cockeye", "cockface", "cockfucker", "cockhead", "cockholster", "cockjockey", "cockknocker", "cockknoker", "cocklump", "cockmaster", "cockmongler", "cockmongruel", "cockmonkey", "cockmunch", "cockmuncher", "cocknose", "cocknugget", "cocks", "cockshit", "cocksmith", "cocksmoke", "cocksmoker", "cocksniffer", "cocksuck", "cocksucked", "cocksucker", "cock-sucker", "cocksuckers", "cocksucking", "cocksucks", "cocksuka", "cocksukka", "cockwaffle", "coffin dodger", "coital", "cok", "cokmuncher", "coksucka", "commie", "condom", "coochie", "coochy", "coon", "coonnass", "coons", "cooter", "cop some wood", "coprolagnia", "coprophilia", "corksucker", "cornhole", "corp whore", "corp whore", "corpulent", "cox", "crabs", "crack", "cracker", "crackwhore", "crap", "crappy", "creampie", "cretin", "crikey", "cripple", "crotte", "cum", "cum chugger", "cum dumpster", "cum freak", "cum guzzler", "cumbubble", "cumdump", "cumdumpster", "cumguzzler", "cumjockey", "cummer", "cummin", "cumming", "cums", "cumshot", "cumshots", "cumslut", "cumstain", "cumtart", "cunilingus", "cunillingus", "cunnie", "cunnilingus", "cunny", "cunt", "c-u-n-t", "cunt hair", "cuntass", "cuntbag", "cuntface", "cunthole", "cunthunter", "cuntlick", "cuntlicker", "cuntrag", "cunts", "cuntsicle", "cuntslut", "cunt-struck", "cus", "cut rope", "cyalis", "cyberfuc", "cyberfuck", "cyberfucked", "cyberfucker", "cyberfucking", "d0ng", "d0uch3", "d0uche", "d1ck", "d1ld0", "d1ldo", "dago", "dagos", "dammit", "damn", "damned", "damnit", "darkie", "darn", "date rape", "daterape", "dawgie-style", "deep throat", "deepthroat", "deggo", "dendrophilia", "dick", "dick head", "dick hole", "dick shy", "dickbag", "dickbeaters", "dickdipper", "dickface", "dickflipper", "dickfuck", "dickfucker", "dickhead", "dickheads", "dickhole", "dickish", "dick-ish", "dickjuice", "dickmilk", "dickmonger", "dickripper", "dicks", "dicksipper", "dickslap", "dick-sneeze", "dicksucker", "dicksucking", "dicktickler", "dickwad", "dickweasel", "dickweed", "dickwhipper", "dickwod", "dickzipper", "diddle", "dike", "dildo", "dildos", "diligaf", "dillweed", "dimwit", "dingle", "dingleberries", "dingleberry", "dink", "dinks", "dipship", "dirsa", "dirty", "dirty pillows", "dirty sanchez", "div", "dlck", "dog style", "dog-fucker", "doggie style", "doggiestyle", "doggie-style", "doggin", "dogging", "doggy style", "doggystyle", "doggy-style", "dolcett", "domination", "dominatrix", "dommes", "dong", "donkey punch", "donkeypunch", "donkeyribber", "doochbag", "doofus", "dookie", "doosh", "dopey", "double dong", "double penetration", "doublelift", "douch3", "douche", "douchebag", "douchebags", "douche-fag", "douchewaffle", "douchey", "dp action", "drunk", "dry hump", "duche", "dumass", "dumb ass", "dumbass", "dumbasses", "dumbcunt", "dumbfuck", "dumbshit", "dummy", "dumshit", "dvda", "dyke", "dykes", "eat a dick", "eat hair pie", "eat my ass", "ecchi", "ejaculate", "ejaculated", "ejaculates", "ejaculating", "ejaculating", "ejaculatings", "ejaculation", "ejakulate", "erect", "erection", "erotic", "erotism", "escort", "essohbee", "eunuch", "extacy", "extasy", "f u c k", "f u c k e r", "f.u.c.k", "f_u_c_k", "f4nny", "facial", "fack", "fag", "fagbag", "fagfucker", "fagg", "fagged", "fagging", "faggit", "faggitt", "faggot", "faggotcock", "faggots", "faggs", "fagot", "fagots", "fags", "fagtard", "faig", "faigt", "fanny", "fannybandit", "fannyflaps", "fannyfucker", "fanyy", "fart", "fartknocker", "fatass", "fcuk", "fcuker", "fcuking", "fecal", "feck", "fecker", "feist", "felch", "felcher", "felching", "fellate", "fellatio", "feltch", "feltcher", "female squirting", "femdom", "fenian", "fice", "figging", "fingerbang", "fingerfuck", "fingerfucked", "fingerfucker", "fingerfuckers", "fingerfucking", "fingerfucks", "fingering", "fist fuck", "fisted", "fistfuck", "fistfucked", "fistfucker", "fistfuckers", "fistfuckings", "fistfucks", "fisting", "fisty", "flamer", "flange", "flaps", "fleshflute", "flog the log", "floozy", "foad", "foah", "fondle", "foobar", "fook", "fooker", "foot fetish", "footjob", "foreskin", "freex", "frenchify", "frigg", "frigga", "frotting", "fubar", "fuc", "fuck", "f-u-c-k", "fuck buttons", "fuck hole", "fuck off", "fuck puppet", "fuck trophy", "fuck yo mama", "fuck you", "fucka", "fuckass", "fuck-ass", "fuckbag", "fuck bag", "fuck-bitch", "fuckboy", "fuckbrain", "fuckbutt", "fuckbutter", "fucked", "fuckedup", "fucked up", "fucker", "fuckers", "fuckersucker", "fuckface", "fuckhead", "fuckheads", "fuckhole", "fuckin", "fucking", "fuckings", "fuckme", "fuck me", "fuckmeat", "fucknugget", "fucknut", "fucknutt", "fuckoff", "fucks", "fuckstick", "fucktard", "fuck-tard", "fucktards", "fucktart", "fucktoy", "fucktwat", "fuckup", "fuckwad", "fuckwhit", "fuckwit", "fuckwitt", "fudge packer", "fudgepacker", "fudge-packer", "fuk", "fuker", "fukker", "fukkers", "fukkin", "fuks", "fukwhit", "fukwit", "fuq", "futanari", "fux", "fux0r", "fvck", "fxck", "gae", "gai", "gang bang", "gangbang", "gang-bang", "gangbanged", "gangbangs", "ganja", "gash", "gassy ass", "gay sex", "gayass", "gaybob", "gaydo", "gayfuck", "gayfuckist", "gaylord", "gays", "gaysex", "gaytard", "gaywad", "gender bender", "genitals", "gey", "gfy", "ghay", "ghey", "giant cock", "gigolo", "ginger", "gippo", "girl on", "girl on top", "girls gone wild", "glans", "goatcx", "goatse", "god", "god damn", "godamn", "godamnit", "goddam", "god-dam", "goddammit", "goddamn", "goddamned", "god-damned", "goddamnit", "godsdamn", "gokkun", "golden shower", "goldenshower", "golliwog", "gonad", "gonads", "goo girl", "gooch", "goodpoop", "gook", "gooks", "goregasm", "gringo", "grope", "group sex", "gspot", "g-spot", "gtfo", "guido", "guro", "h0m0", "h0mo", "ham flap", "hand job", "handjob", "hard core", "hard on", "hardcore", "hardcoresex", "he11", "hebe", "heeb", "hell", "hemp", "hentai", "heroin", "herp", "herpes", "herpy", "heshe", "he-she", "hircismus", "hitler", "hiv", "hoar", "hoare", "hobag", "hoe", "hoer", "holy shit", "hom0", "homey", "homo", "homodumbshit", "homoerotic", "homoey", "honkey", "honky", "hooch", "hookah", "hooker", "hoor", "hootch", "hooter", "hooters", "hore", "horniest", "horny", "hot carl", "hot chick", "hotsex", "how to kill", "how to murdep", "how to murder", "huge fat", "hump", "humped", "humping", "hun", "hussy", "hymen", "iap", "iberian slap", "inbred", "incest", "injun", "intercourse", "jack off", "jackass", "jackasses", "jackhole", "jackoff", "jack-off", "jaggi", "jagoff", "jail bait", "jailbait", "jap", "japs", "jelly donut", "jerk", "jerk off", "jerk0ff", "jerkass", "jerked", "jerkoff", "jerk-off", "jigaboo", "jiggaboo", "jiggerboo", "jism", "jiz", "jizm", "jizm", "jizz", "jizzed", "jock", "juggs", "jungle bunny", "junglebunny", "junkie", "junky", "kafir", "kawk", "kike", "kikes", "kill", "kinbaku", "kinkster", "kinky", "klan", "knob", "knob end", "knobbing", "knobead", "knobed", "knobend", "knobhead", "knobjocky", "knobjokey", "kock", "kondum", "kondums", "kooch", "kooches", "kootch", "kraut", "kum", "kummer", "kumming", "kums", "kunilingus", "kunja", "kunt", "kwif", "kyke", "l3i+ch", "l3itch", "labia", "lameass", "lardass", "leather restraint", "leather straight jacket", "lech", "lemon party", "LEN", "leper", "lesbian", "lesbians", "lesbo", "lesbos", "lez", "lezza/lesbo", "lezzie", "lmao", "lmfao", "loin", "loins", "lolita", "looney", "lovemaking", "lube", "lust", "lusting", "lusty", "m0f0", "m0fo", "m45terbate", "ma5terb8", "ma5terbate", "mafugly", "mafugly", "make me come", "male squirting", "mams", "masochist", "massa", "masterb8", "masterbat*", "masterbat3", "masterbate", "master-bate", "masterbating", "masterbation", "masterbations", "masturbate", "masturbating", "masturbation", "maxi", "mcfagget", "menage a trois", "menses", "meth", "m-fucking", "mick", "microphallus", "middle finger", "midget", "milf", "minge", "minger", "missionary position", "mof0", "mofo", "mo-fo", "molest", "mong", "moo moo foo foo", "moolie", "moron", "mothafuck", "mothafucka", "mothafuckas", "mothafuckaz", "mothafucked", "mothafucker", "mothafuckers", "mothafuckin", "mothafucking", "mothafucking", "mothafuckings", "mothafucks", "mother fucker", "motherfuck", "motherfucka", "motherfucked", "motherfucker", "motherfuckers", "motherfuckin", "motherfucking", "motherfuckings", "motherfuckka", "motherfucks", "mound of venus", "mr hands", "muff", "muff diver", "muff puff", "muffdiver", "muffdiving", "munging", "munter", "murder", "mutha", "muthafecker", "muthafuckker", "muther", "mutherfucker", "n1gga", "n1gger", "naked", "nambla", "napalm", "nappy", "nawashi", "nazi", "nazism", "need the dick", "negro", "neonazi", "nig nog", "nigaboo", "nigg3r", "nigg4h", "nigga", "niggah", "niggas", "niggaz", "nigger", "niggers", "niggle", "niglet", "nig-nog", "nimphomania", "nimrod", "ninny", "ninnyhammer", "nipple", "nipples", "nob", "nob jokey", "nobhead", "nobjocky", "nobjokey", "nonce", "nsfw images", "nude", "nudity", "numbnuts", "nut butter", "nut butter", "nut sack", "nutsack", "nutter", "nympho", "nymphomania", "octopussy", "old bag", "omg", "omorashi", "one cup two girls", "1 cup 2 girls", "one cup 2 girls", "1 cup two girls", "one guy one jar", "1 guy one jar", "one guy 1 jar", "opiate", "opium", "orally", "organ", "orgasim", "orgasims", "orgasm", "orgasmic", "orgasms", "orgies", "orgy", "ovary", "ovum", "ovums", "p.u.s.s.y.", "p.u.s.s.y", "p0rn", "paedophile", "paki", "panooch", "pansy", "pantie", "panties", "panty", "pawn", "pcp", "pecker", "peckerhead", "pedo", "pedobear", "pedophile", "pedophilia", "pedophiliac", "pee", "peepee", "pegging", "penetrate", "penetration", "penial", "penile", "penis", "penisbanger", "penisfucker", "penispuffer", "perversion", "phallic", "phone sex", "phonesex", "phuck", "phuk", "phuked", "phuking", "phukked", "phukking", "phuks", "phuq", "piece of shit", "pigfucker", "pikey", "pillowbiter", "pimp", "pimpis", "pinko", "piss", "piss off", "piss pig", "pissed", "pissed off", "pisser", "pissers", "pisses", "pissflaps", "piss flaps", "pissin", "pissin", "pissing", "pissoff", "pissoff", "piss-off", "pisspig", "playboy", "pleasure chest", "polack", "pole smoker", "polesmoker", "pollock", "ponyplay", "poof", "poon", "poonani", "poonany", "poontang", "poop", "poop chute", "poopchute", "Poopuncher", "porch monkey", "porchmonkey", "porn", "porno", "pornography", "pornos", "potty", "prick", "pricks", "prickteaser", "prig", "prince albert piercing", "prod", "pron", "prone bone", "pronebone", "prone-bone", "prostitute", "prude", "psycho", "pthc", "pube", "pubes", "pubic", "pubis", "punani", "punanny", "punany", "punkass", "punky", "punta", "puss", "pusse", "pussi", "pussies", "pussy", "pussy fart", "pussy palace", "pussylicking", "pussypounder", "pussys", "pust", "puto", "queaf", "queef", "queer", "queerbait", "queerhole", "queero", "queers", "quicky", "quim", "racy", "raghead", "raging boner", "rape", "raped", "raper", "rapey", "raping", "rapist", "raunch", "rectal", "rectum", "rectus", "reefer", "reetard", "reich", "renob", "retard", "retarded", "reverse cowgirl", "revue", "rimjaw", "rimjob", "rimming", "ritard", "rosy palm", "rosy palm and her 5 sisters", "rtard", "r-tard", "rubbish", "rum", "rump", "rumprammer", "ruski", "rusty trombone", "s&m", "s.h.i.t.", "s.o.b.", "s_h_i_t", "s0b", "sadism", "sadist", "sambo", "sand nigger", "sandbar", "sandbar", "Sandler", "sandnigger", "sanger", "santorum", "sausage queen", "scag", "scantily", "scat", "schizo", "schlong", "scissoring", "screw", "screwed", "screwing", "scroat", "scrog", "scrot", "scrote", "scrotum", "scrud", "scum", "seaman", "seduce", "seks", "semen", "sex", "sexo", "sexual", "sexy", "sh!+", "sh!t", "sh1t", "s-h-1-t", "shag", "shagger", "shaggin", "shagging", "shamedame", "shaved beaver", "shaved pussy", "shemale", "shi+", "shibari", "shirt lifter", "shit", "s-h-i-t", "shit ass", "shit fucker", "shitass", "shitbag", "shitbagger", "shitblimp", "shitbrains", "shitbreath", "shitcanned", "shitcunt", "shitdick", "shite", "shiteater", "shited", "shitey", "shitface", "shitfaced", "shitfuck", "shitfull", "shithead", "shitheads", "shithole", "shithouse", "shiting", "shitings", "shits", "shitspitter", "shitstain", "shitt", "shitted", "shitter", "shitters", "shitters", "shittier", "shittiest", "shitting", "shittings", "shitty", "shiz", "shiznit", "shota", "shrimping", "sissy", "skag", "skank", "skeet", "skullfuck", "slag", "slanteye", "slave", "sleaze", "sleazy", "slope", "slut", "slut bucket", "slutbag", "slutdumper", "slutkiss", "sluts", "smartass", "smartasses", "smeg", "smegma", "smut", "smutty", "snatch", "sniper", "snowballing", "snuff", "s-o-b", "sod off", "sodom", "sodomize", "sodomy", "son of a bitch", "son of a motherless goat", "son of a whore", "son-of-a-bitch", "souse", "soused", "spac", "spade", "sperm", "spic", "spick", "spik", "spiks", "splooge", "splooge moose", "spooge", "spook", "spread legs", "spunk", "stfu", "stiffy", "stoned", "strap on", "strapon", "strappado", "strip", "strip club", "stroke", "stupid", "style doggy", "suck", "suckass", "sucked", "sucking", "sucks", "suicide girls", "sultry women", "sumofabiatch", "swastikav", "swinger", "t1t", "t1tt1e5", "t1tties", "taff", "taig", "tainted love", "taking the piss", "tampon", "tard", "tart", "taste my", "tawdry", "tea bagging", "teabagging", "teat", "teets", "teez", "teste", "testee", "testes", "testical", "testicle", "testis", "threesome", "throating", "thrust", "thug", "thundercunt", "thunder cunt", "tied up", "tight white", "tinkle", "tit", "tit wank", "titfuck", "titi", "tities", "tits", "titt", "tittie5", "tittiefucker", "titties", "titty", "tittyfuck", "tittyfucker", "tittywank", "titwank", "toke", "tongue in a", "toots", "topless", "tosser", "towelhead", "tramp", "tranny", "trashy", "tribadism", "trumped", "tub girl", "tubgirl", "turd", "tush", "tushy", "tw4t", "twat", "twathead", "twatlips", "twats", "twatty", "twatting", "twatwaffle", "twink", "twinkie", "two fingers", "two fingers with tongue", "two girls one cup", "twunt", "twunter", "ugly", "unclefucker", "undies", "undressing", "unwed", "upskirt", "urethra play", "urinal", "urine", "urophilia", "uterus", "uzi", "v14gra", "v1gra", "vag", "vagina", "vajayjay", "va-j-j", "valium", "venus mound", "veqtable", "viagra", "vibrator", "violet wand", "virgin", "vixen", "vjayjay", "vodka", "vomit", "vorarephilia", "voyeur", "vulgar", "vulva", "w00se", "wad", "wang", "wank", "wanker", "wankjob", "wanky", "wazoo", "wedgie", "weed", "weenie", "weewee", "weiner", "weirdo", "wench", "wet dream", "wetback", "wh0re", "wh0reface", "white power", "whiz", "whoar", "whoralicious", "whore", "whorealicious", "whorebag", "whored", "whoreface", "whorehopper", "whorehouse", "whores", "whoring", "wigger", "willies", "willy", "window licker", "wiseass", "wiseasses", "wog", "womb", "wop", "wrapping men", "wrinkled starfish", "xrated", "x-rated", "xx", "xxx", "yaoi", "yeasty", "yellow showers", "yid", "yiffy", "yobbo", "zibbi", "zoophilia", "zubb" }; public int Count => _profanities.Count; public ProfanityBase() { _profanities = new List<string>(_wordList); } protected ProfanityBase(string[] profanityList) { if (profanityList == null) { throw new ArgumentNullException("profanityList"); } _profanities = new List<string>(profanityList); } protected ProfanityBase(List<string> profanityList) { if (profanityList == null) { throw new ArgumentNullException("profanityList"); } _profanities = profanityList; } public void AddProfanity(string profanity) { if (string.IsNullOrEmpty(profanity)) { throw new ArgumentNullException("profanity"); } _profanities.Add(profanity); } public void AddProfanity(string[] profanityList) { if (profanityList == null) { throw new ArgumentNullException("profanityList"); } _profanities.AddRange(profanityList); } public void AddProfanity(List<string> profanityList) { if (profanityList == null) { throw new ArgumentNullException("profanityList"); } _profanities.AddRange(profanityList); } public bool RemoveProfanity(string profanity) { if (string.IsNullOrEmpty(profanity)) { throw new ArgumentNullException("profanity"); } return _profanities.Remove(profanity.ToLower(CultureInfo.InvariantCulture)); } public bool RemoveProfanity(List<string> profanities) { if (profanities == null) { throw new ArgumentNullException("profanities"); } foreach (string profanity in profanities) { if (!RemoveProfanity(profanity)) { return false; } } return true; } public bool RemoveProfanity(string[] profanities) { if (profanities == null) { throw new ArgumentNullException("profanities"); } foreach (string profanity in profanities) { if (!RemoveProfanity(profanity)) { return false; } } return true; } public void Clear() { _profanities.Clear(); } } public class ProfanityFilter : ProfanityBase, IProfanityFilter { public IAllowList AllowList { get; } public ProfanityFilter() { AllowList = new AllowList(); } public ProfanityFilter(string[] profanityList) : base(profanityList) { AllowList = new AllowList(); } public ProfanityFilter(List<string> profanityList) : base(profanityList) { AllowList = new AllowList(); } public bool IsProfanity(string word) { if (string.IsNullOrEmpty(word)) { return false; } if (AllowList.Contains(word.ToLower(CultureInfo.InvariantCulture))) { return false; } return _profanities.Contains(word.ToLower(CultureInfo.InvariantCulture)); } public ReadOnlyCollection<string> DetectAllProfanities(string sentence) { return DetectAllProfanities(sentence, removePartialMatches: false); } public ReadOnlyCollection<string> DetectAllProfanities(string sentence, bool removePartialMatches) { if (string.IsNullOrEmpty(sentence)) { return new ReadOnlyCollection<string>(new List<string>()); } sentence = sentence.ToLower(); sentence = sentence.Replace(".", ""); sentence = sentence.Replace(",", ""); string[] words = sentence.Split(new char[1] { ' ' }); List<string> postAllowList = FilterWordListByAllowList(words); List<string> swearList = new List<string>(); AddMultiWordProfanities(swearList, ConvertWordListToSentence(postAllowList)); if (removePartialMatches) { swearList.RemoveAll((string x) => swearList.Any((string y) => x != y && y.Contains(x))); } return new ReadOnlyCollection<string>(FilterSwearListForCompleteWordsOnly(sentence, swearList).Distinct().ToList()); } public string CensorString(string sentence) { return CensorString(sentence, '*'); } public string CensorString(string sentence, char censorCharacter) { return CensorString(sentence, censorCharacter, ignoreNumbers: false); } public string CensorString(string sentence, char censorCharacter, bool ignoreNumbers) { if (string.IsNullOrEmpty(sentence)) { return string.Empty; } string text = sentence.Trim(); text = text.ToLower(); text = Regex.Replace(text, "[^\\w\\s]", ""); string[] words = text.Split(new char[1] { ' ' }); List<string> postAllowList = FilterWordListByAllowList(words); List<string> swearList = new List<string>(); AddMultiWordProfanities(swearList, ConvertWordListToSentence(postAllowList)); StringBuilder censored = new StringBuilder(sentence); StringBuilder tracker = new StringBuilder(sentence); return CensorStringByProfanityList(censorCharacter, swearList, censored, tracker, ignoreNumbers).ToString(); } public (int, int, string)? GetCompleteWord(string toCheck, string profanity) { if (string.IsNullOrEmpty(toCheck)) { return null; } string value = profanity.ToLower(CultureInfo.InvariantCulture); string text = toCheck.ToLower(CultureInfo.InvariantCulture); if (text.Contains(value)) { int num = text.IndexOf(value, StringComparison.Ordinal); int i = num; while (num > 0 && toCheck[num - 1] != ' ' && !char.IsPunctuation(toCheck[num - 1])) { num--; } for (; i < toCheck.Length && toCheck[i] != ' ' && !char.IsPunctuation(toCheck[i]); i++) { } return (num, i, text.Substring(num, i - num).ToLower(CultureInfo.InvariantCulture)); } return null; } public bool ContainsProfanity(string term) { if (string.IsNullOrWhiteSpace(term)) { return false; } List<string> list = _profanities.Where((string word) => word.Length <= term.Length).ToList(); if (list.Count == 0) { return false; } Regex regex = new Regex(string.Format("(?:{0})", string.Join("|", list).Replace("$", "\\$"), RegexOptions.IgnoreCase)); foreach (Match item in regex.Matches(term)) { if (!AllowList.Contains(item.Value.ToLower(CultureInfo.InvariantCulture))) { return true; } } return false; } private StringBuilder CensorStringByProfanityList(char censorCharacter, List<string> swearList, StringBuilder censored, StringBuilder tracker, bool ignoreNumeric) { foreach (string item in swearList.OrderByDescending((string x) => x.Length)) { (int, int, string)? tuple = (0, 0, ""); string[] array = item.Split(new char[1] { ' ' }); if (array.Length == 1) { do { tuple = GetCompleteWord(tracker.ToString(), item); if (!tuple.HasValue) { continue; } string text = tuple.Value.Item3; if (ignoreNumeric) { text = Regex.Replace(tuple.Value.Item3, "[\\d-]", string.Empty); } if (text == item) { for (int i = tuple.Value.Item1; i < tuple.Value.Item2; i++) { censored[i] = censorCharacter; tracker[i] = censorCharacter; } } else { for (int j = tuple.Value.Item1; j < tuple.Value.Item2; j++) { tracker[j] = censorCharacter; } } } while (tuple.HasValue); } else { censored = censored.Replace(item, CreateCensoredString(item, censorCharacter)); } } return censored; } private List<string> FilterSwearListForCompleteWordsOnly(string sentence, List<string> swearList) { List<string> list = new List<string>(); StringBuilder stringBuilder = new StringBuilder(sentence); foreach (string item in swearList.OrderByDescending((string x) => x.Length)) { (int, int, string)? tuple = (0, 0, ""); string[] array = item.Split(new char[1] { ' ' }); if (array.Length == 1) { do { tuple = GetCompleteWord(stringBuilder.ToString(), item); if (!tuple.HasValue) { continue; } if (tuple.Value.Item3 == item) { list.Add(item); for (int i = tuple.Value.Item1; i < tuple.Value.Item2; i++) { stringBuilder[i] = '*'; } break; } for (int j = tuple.Value.Item1; j < tuple.Value.Item2; j++) { stringBuilder[j] = '*'; } } while (tuple.HasValue); } else { list.Add(item); stringBuilder.Replace(item, " "); } } return list; } private List<string> FilterWordListByAllowList(string[] words) { List<string> list = new List<string>(); foreach (string text in words) { if (!string.IsNullOrEmpty(text) && !AllowList.Contains(text.ToLower(CultureInfo.InvariantCulture))) { list.Add(text); } } return list; } private static string ConvertWordListToSentence(List<string> postAllowList) { string text = string.Empty; foreach (string postAllow in postAllowList) { text = text + postAllow + " "; } return text; } private void AddMultiWordProfanities(List<string> swearList, string postAllowListSentence) { swearList.AddRange(from string profanity in _profanities where postAllowListSentence.ToLower(CultureInfo.InvariantCulture).Contains(profanity) select profanity); } private static string CreateCensoredString(string word, char censorCharacter) { string text = string.Empty; for (int i = 0; i < word.Length; i++) { text = ((word[i] == ' ') ? (text + " ") : (text + censorCharacter)); } return text; } } } namespace ProfanityFilter.Interfaces { public interface IAllowList { int Count { get; } ReadOnlyCollection<string> ToList { get; } void Add(string wordToAllowlist); bool Contains(string wordToCheck); bool Remove(string wordToRemove); void Clear(); } public interface IProfanityFilter { IAllowList AllowList { get; } int Count { get; } bool IsProfanity(string word); ReadOnlyCollection<string> DetectAllProfanities(string sentence); ReadOnlyCollection<string> DetectAllProfanities(string sentence, bool removePartialMatches); bool ContainsProfanity(string term); string CensorString(string sentence); string CensorString(string sentence, char censorCharacter); string CensorString(string sentence, char censorCharacter, bool ignoreNumbers); (int, int, string)? GetCompleteWord(string toCheck, string profanity); void AddProfanity(string profanity); void AddProfanity(string[] profanityList); void AddProfanity(List<string> profanityList); bool RemoveProfanity(string profanity); bool RemoveProfanity(List<string> profanities); bool RemoveProfanity(string[] profanities); void Clear(); } }