Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Clans v1.0.1
plugins/Clans.dll
Decompiled 4 days 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.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Clans.Client; using Clans.Common; using Clans.Compat; using Clans.Core; using Clans.Gameplay; using Clans.Net; using Clans.Server; using Clans.Server.Model; using Clans.Settings; using Clans.UI; using Clans.UI.Pages; using HarmonyLib; using ItemFavoriteFrameworkAPI; using JetBrains.Annotations; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using SimpleJson; using Splatform; using StarLevelSystem; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using ValheimFortress; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Clans")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Clans")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] namespace ValheimFortress { public static class API { private static readonly Type APIReceiver; private static readonly MethodInfo RunChallengeMethod; private static readonly MethodInfo GetSpawnableCreaturesMethod; private static readonly MethodInfo GetRewardItemsMethod; private static readonly MethodInfo GetWaveStylesMethod; private static readonly MethodInfo GetShrineChallengeDefinitionMethod; private static readonly MethodInfo GetShrineTributesMethod; private static readonly MethodInfo StartChallengeMethod; private static readonly MethodInfo GetChallengeStateMethod; private static readonly MethodInfo StopChallengeMethod; private static readonly DataContractJsonSerializerSettings SerializerSettings; public static bool IsAvailable => APIReceiver != null; public static bool SupportsHandles { get { if (StartChallengeMethod != null && GetChallengeStateMethod != null) { return StopChallengeMethod != null; } return false; } } static API() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SerializerSettings = new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true }; APIReceiver = Type.GetType("ValheimFortress.APIReceiver, ValheimFortress"); if (!(APIReceiver == null)) { RunChallengeMethod = APIReceiver.GetMethod("RunChallenge", BindingFlags.Static | BindingFlags.Public); GetSpawnableCreaturesMethod = APIReceiver.GetMethod("GetSpawnableCreatures", BindingFlags.Static | BindingFlags.Public); GetRewardItemsMethod = APIReceiver.GetMethod("GetRewardItems", BindingFlags.Static | BindingFlags.Public); GetWaveStylesMethod = APIReceiver.GetMethod("GetWaveStyles", BindingFlags.Static | BindingFlags.Public); GetShrineChallengeDefinitionMethod = APIReceiver.GetMethod("GetShrineChallengeDefinition", BindingFlags.Static | BindingFlags.Public); GetShrineTributesMethod = APIReceiver.GetMethod("GetShrineTributes", BindingFlags.Static | BindingFlags.Public); StartChallengeMethod = APIReceiver.GetMethod("StartChallenge", BindingFlags.Static | BindingFlags.Public); GetChallengeStateMethod = APIReceiver.GetMethod("GetChallengeState", BindingFlags.Static | BindingFlags.Public); StopChallengeMethod = APIReceiver.GetMethod("StopChallenge", BindingFlags.Static | BindingFlags.Public); } } public static bool RunChallenge(VFChallengeDefinition definition, Vector3[] spawnPoints, Vector3 rewardLocation) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (RunChallengeMethod == null || definition == null) { return false; } string text = Serialize(definition); if (text == null) { return false; } object obj = RunChallengeMethod.Invoke(null, new object[3] { text, spawnPoints, rewardLocation }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } public static bool RunChallenge(VFChallengeDefinition definition, List<Vector3> spawnPoints, Vector3 rewardLocation) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) return RunChallenge(definition, spawnPoints?.ToArray(), rewardLocation); } public static string StartChallenge(VFChallengeDefinition definition, Vector3[] spawnPoints, Vector3 rewardLocation) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (StartChallengeMethod == null || definition == null) { return null; } string text = Serialize(definition); if (text == null) { return null; } return StartChallengeMethod.Invoke(null, new object[3] { text, spawnPoints, rewardLocation }) as string; } public static VFChallengeState GetChallengeState(string handle) { if (GetChallengeStateMethod == null || string.IsNullOrEmpty(handle)) { return null; } if (!(GetChallengeStateMethod.Invoke(null, new object[1] { handle }) is Dictionary<string, int> values)) { return null; } return VFChallengeState.From(values); } public static bool StopChallenge(string handle) { if (StopChallengeMethod == null || string.IsNullOrEmpty(handle)) { return false; } object obj = StopChallengeMethod.Invoke(null, new object[1] { handle }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } public static List<string> GetSpawnableCreatures() { if (GetSpawnableCreaturesMethod == null) { return new List<string>(); } return (List<string>)GetSpawnableCreaturesMethod.Invoke(null, null); } public static List<string> GetRewardItems() { if (GetRewardItemsMethod == null) { return new List<string>(); } return (List<string>)GetRewardItemsMethod.Invoke(null, null); } public static List<string> GetWaveStyles() { if (GetWaveStylesMethod == null) { return new List<string>(); } return (List<string>)GetWaveStylesMethod.Invoke(null, null); } public static VFChallengeDefinition GetShrineChallengeDefinition(string shrineName, string tributePrefab) { if (GetShrineChallengeDefinitionMethod == null || string.IsNullOrEmpty(shrineName) || string.IsNullOrEmpty(tributePrefab)) { return null; } return Deserialize(GetShrineChallengeDefinitionMethod.Invoke(null, new object[2] { shrineName, tributePrefab }) as string); } public static Dictionary<string, List<string>> GetShrineTributes() { if (GetShrineTributesMethod == null) { return new Dictionary<string, List<string>>(); } return (Dictionary<string, List<string>>)GetShrineTributesMethod.Invoke(null, null); } private static string Serialize(VFChallengeDefinition definition) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { using MemoryStream memoryStream = new MemoryStream(); ((XmlObjectSerializer)new DataContractJsonSerializer(typeof(VFChallengeDefinition), SerializerSettings)).WriteObject((Stream)memoryStream, (object)definition); return Encoding.UTF8.GetString(memoryStream.ToArray()); } catch { return null; } } private static VFChallengeDefinition Deserialize(string json) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(json)) { return null; } try { using MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(json)); return ((XmlObjectSerializer)new DataContractJsonSerializer(typeof(VFChallengeDefinition), SerializerSettings)).ReadObject((Stream)memoryStream) as VFChallengeDefinition; } catch { return null; } } } [DataContract] public class VFChallengeDefinition { public const int CurrentSchemaVersion = 4; [DataMember] public int SchemaVersion { get; set; } = 4; [DataMember(EmitDefaultValue = false, IsRequired = false)] public Biome Biome { get; set; } = (Biome)1; [DataMember(EmitDefaultValue = false, IsRequired = false)] public short Difficulty { get; set; } = 1; [DataMember(EmitDefaultValue = false, IsRequired = false)] public string WaveStyle { get; set; } = "Normal"; [DataMember(EmitDefaultValue = false, IsRequired = false)] public short NumPhases { get; set; } = 4; [DataMember(EmitDefaultValue = false, IsRequired = false)] public short MaxCreaturesPerPhase { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> OnlySelectMonsters { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> ExcludeSelectMonsters { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public VFSpawnModifiers CommonSpawnModifiers { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public VFSpawnModifiers RareSpawnModifiers { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public VFSpawnModifiers EliteSpawnModifiers { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool HardMode { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool BossMode { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool SiegeMode { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool EnableCreatureDrops { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public Dictionary<string, bool> CreatureDropOverrides { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<VFCreatureRule> CreatureRules { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<List<VFHoardEntry>> ExplicitPhases { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<VFHoardEntry> FinalPhase { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public Dictionary<string, short> ScaledRewards { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public Dictionary<string, short> FixedRewards { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public string WaveStartMessage { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public string WaveEndMessage { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> BetweenWavePhrases { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool OrderedPhrases { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool DrawMapOverlay { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool SpawnPortalVisuals { get; set; } } public class VFChallengeState { public bool Exists { get; set; } public bool Starting { get; set; } public bool Active { get; set; } public int Phase { get; set; } public int Phases { get; set; } public int Alive { get; set; } public bool Completed { get; set; } public bool Stopped { get; set; } internal static VFChallengeState From(Dictionary<string, int> values) { return new VFChallengeState { Exists = (Value("exists") != 0), Starting = (Value("starting") != 0), Active = (Value("active") != 0), Phase = Value("phase"), Phases = Value("phases"), Alive = Value("alive"), Completed = (Value("completed") != 0), Stopped = (Value("stopped") != 0) }; int Value(string key) { if (!values.TryGetValue(key, out var value)) { return 0; } return value; } } } [DataContract] public class VFHoardEntry { [DataMember(EmitDefaultValue = false, IsRequired = false)] public string Creature { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public short Amount { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public short Stars { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public VFModifierSet Modifiers { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public float? HealthMultiplier { get; set; } } [DataContract] public class VFCreatureRule { [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<int> Waves { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> Creatures { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> SpawnTypes { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public int? MinStars { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public int? MaxStars { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public VFModifierSet Modifiers { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public float? HealthMultiplier { get; set; } } [DataContract] public class VFModifierSet { [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> Major { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> Minor { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public List<string> Boss { get; set; } public VFModifierSet Overlay(VFModifierSet other) { return new VFModifierSet { Major = Copy(other?.Major ?? Major), Minor = Copy(other?.Minor ?? Minor), Boss = Copy(other?.Boss ?? Boss) }; } public bool IsEmpty() { if ((Major == null || Major.Count == 0) && (Minor == null || Minor.Count == 0)) { if (Boss != null) { return Boss.Count == 0; } return true; } return false; } private static List<string> Copy(List<string> names) { if (names != null) { return new List<string>(names); } return null; } } [DataContract] public class VFSpawnModifiers { [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool LinearDecreaseRandomWaveAdjustment { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool LinearIncreaseRandomWaveAdjustment { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool PartialRandomWaveAdjustment { get; set; } [DataMember(EmitDefaultValue = false, IsRequired = false)] public bool OnlyGenerateInSecondHalf { get; set; } } } namespace StarLevelSystem { [PublicAPI] public static class API { private static readonly Type APIReciever; private static readonly MethodInfo UpdateCreatureLevel; private static readonly MethodInfo UpdateCreatureColorization; private static readonly MethodInfo GetBaseAttributeValue; private static readonly MethodInfo UpdateCreatureBaseAttributes; private static readonly MethodInfo GetAllBaseAttributeValues; private static readonly MethodInfo SetAllBaseAttributeValues; private static readonly MethodInfo GetPerLevelAttributeValue; private static readonly MethodInfo UpdateCreaturePerLevelAttributes; private static readonly MethodInfo GetAllPerLevelAttributeValues; private static readonly MethodInfo SetAllPerLevelAttributeValues; private static readonly MethodInfo GetCreatureDamageRecievedModifier; private static readonly MethodInfo UpdateCreatureDamageRecievedModifier; private static readonly MethodInfo GetAllDamageRecievedModifiers; private static readonly MethodInfo SetAllDamageRecievedModifiers; private static readonly MethodInfo GetCreatureDamageBonus; private static readonly MethodInfo UpdateCreatureDamageBonus; private static readonly MethodInfo GetAllDamageBonus; private static readonly MethodInfo SetAllDamageBonus; private static readonly MethodInfo ApplyUpdatesToCreature; private static readonly MethodInfo SetCreatureSpawnManagedMethod; private static readonly MethodInfo GetPossibleModifiersForType; private static readonly MethodInfo GetAllModifiersForCreature; private static readonly MethodInfo AddModifierToCreature; private static readonly MethodInfo AddNewModifierToSLS; private static readonly MethodInfo RegisterLocationResetTargetMethod; private static readonly MethodInfo UnregisterLocationResetTargetMethod; private static readonly MethodInfo GetRegisteredLocationResetTargetsMethod; private static readonly MethodInfo GetLocationResetTargetInfoMethod; private static readonly MethodInfo IsLocationResetReadyMethod; private static readonly MethodInfo GetLocationResetStatusMethod; private static readonly MethodInfo IsKnownResetTargetNameMethod; private static readonly MethodInfo GetLocationLastResetMethod; private static readonly MethodInfo GetSecondsUntilLocationResetMethod; private static readonly MethodInfo GetLocationResetInfoMethod; private static readonly MethodInfo GetChunkResetInfoMethod; private static readonly MethodInfo ResetNamedLocationMethod; private static readonly MethodInfo ResetLocationsInRadiusMethod; public static bool IsAvailable => APIReciever != null; public static bool SupportsLocationReset => ResetNamedLocationMethod != null; public static bool SupportsSpawnManaged => SetCreatureSpawnManagedMethod != null; static API() { APIReciever = Type.GetType("StarLevelSystem.modules.APIReciever, StarLevelSystem"); if (!(APIReciever == null)) { UpdateCreatureLevel = APIReciever.GetMethod("UpdateCreatureLevel", BindingFlags.Static | BindingFlags.Public); UpdateCreatureColorization = APIReciever.GetMethod("UpdateCreatureColorization", BindingFlags.Static | BindingFlags.Public); GetBaseAttributeValue = APIReciever.GetMethod("GetBaseAttributeValue", BindingFlags.Static | BindingFlags.Public); UpdateCreatureBaseAttributes = APIReciever.GetMethod("UpdateCreatureBaseAttributes", BindingFlags.Static | BindingFlags.Public); GetAllBaseAttributeValues = APIReciever.GetMethod("GetAllBaseAttributes", BindingFlags.Static | BindingFlags.Public); SetAllBaseAttributeValues = APIReciever.GetMethod("SetAllBaseAttributes", BindingFlags.Static | BindingFlags.Public); GetPerLevelAttributeValue = APIReciever.GetMethod("GetPerLevelAttributeValue", BindingFlags.Static | BindingFlags.Public); UpdateCreaturePerLevelAttributes = APIReciever.GetMethod("UpdateCreaturePerLevelAttributes", BindingFlags.Static | BindingFlags.Public); GetAllPerLevelAttributeValues = APIReciever.GetMethod("GetAllPerLevelAttributes", BindingFlags.Static | BindingFlags.Public); SetAllPerLevelAttributeValues = APIReciever.GetMethod("SetAllPerLevelAttributes", BindingFlags.Static | BindingFlags.Public); GetCreatureDamageRecievedModifier = APIReciever.GetMethod("GetCreatureDamageRecievedModifier", BindingFlags.Static | BindingFlags.Public); UpdateCreatureDamageRecievedModifier = APIReciever.GetMethod("UpdateCreatureDamageRecievedModifier", BindingFlags.Static | BindingFlags.Public); GetAllDamageRecievedModifiers = APIReciever.GetMethod("GetAllDamageRecievedModifiers", BindingFlags.Static | BindingFlags.Public); SetAllDamageRecievedModifiers = APIReciever.GetMethod("SetAllDamageRecievedModifiers", BindingFlags.Static | BindingFlags.Public); GetCreatureDamageBonus = APIReciever.GetMethod("GetCreatureDamageBonus", BindingFlags.Static | BindingFlags.Public); UpdateCreatureDamageBonus = APIReciever.GetMethod("UpdateCreatureDamageBonus", BindingFlags.Static | BindingFlags.Public); GetAllDamageBonus = APIReciever.GetMethod("GetAllDamageBonus", BindingFlags.Static | BindingFlags.Public); SetAllDamageBonus = APIReciever.GetMethod("SetAllDamageBonus", BindingFlags.Static | BindingFlags.Public); ApplyUpdatesToCreature = APIReciever.GetMethod("ApplyUpdatesToCreature", BindingFlags.Static | BindingFlags.Public); SetCreatureSpawnManagedMethod = APIReciever.GetMethod("SetCreatureSpawnManaged", BindingFlags.Static | BindingFlags.Public); GetPossibleModifiersForType = APIReciever.GetMethod("GetPossibleModifiersForType", BindingFlags.Static | BindingFlags.Public); GetAllModifiersForCreature = APIReciever.GetMethod("GetAllModifiersForCreature", BindingFlags.Static | BindingFlags.Public); AddModifierToCreature = APIReciever.GetMethod("AddModifierToCreature", BindingFlags.Static | BindingFlags.Public); AddNewModifierToSLS = APIReciever.GetMethod("AddNewModifierToSLS", BindingFlags.Static | BindingFlags.Public); RegisterLocationResetTargetMethod = APIReciever.GetMethod("RegisterLocationResetTarget", BindingFlags.Static | BindingFlags.Public); UnregisterLocationResetTargetMethod = APIReciever.GetMethod("UnregisterLocationResetTarget", BindingFlags.Static | BindingFlags.Public); GetRegisteredLocationResetTargetsMethod = APIReciever.GetMethod("GetRegisteredLocationResetTargets", BindingFlags.Static | BindingFlags.Public); GetLocationResetTargetInfoMethod = APIReciever.GetMethod("GetLocationResetTargetInfo", BindingFlags.Static | BindingFlags.Public); IsLocationResetReadyMethod = APIReciever.GetMethod("IsLocationResetReady", BindingFlags.Static | BindingFlags.Public); GetLocationResetStatusMethod = APIReciever.GetMethod("GetLocationResetStatus", BindingFlags.Static | BindingFlags.Public); IsKnownResetTargetNameMethod = APIReciever.GetMethod("IsKnownResetTargetName", BindingFlags.Static | BindingFlags.Public); GetLocationLastResetMethod = APIReciever.GetMethod("GetLocationLastReset", BindingFlags.Static | BindingFlags.Public); GetSecondsUntilLocationResetMethod = APIReciever.GetMethod("GetSecondsUntilLocationReset", BindingFlags.Static | BindingFlags.Public); GetLocationResetInfoMethod = APIReciever.GetMethod("GetLocationResetInfo", BindingFlags.Static | BindingFlags.Public); GetChunkResetInfoMethod = APIReciever.GetMethod("GetChunkResetInfo", BindingFlags.Static | BindingFlags.Public); ResetNamedLocationMethod = APIReciever.GetMethod("ResetNamedLocation", BindingFlags.Static | BindingFlags.Public); ResetLocationsInRadiusMethod = APIReciever.GetMethod("ResetLocationsInRadius", BindingFlags.Static | BindingFlags.Public); } } private static object Call(MethodInfo method, object fallback, params object[] args) { if (method == null) { return fallback; } return method.Invoke(null, args); } public static bool SetCreatureLevel(Character creatureId, int newLevel) { return (bool)UpdateCreatureLevel.Invoke(null, new object[2] { creatureId, newLevel }); } public static bool SetCreatureColorization(Character creatureId, float value, float hue, float sat, bool emission = false) { return (bool)UpdateCreatureColorization.Invoke(null, new object[5] { creatureId, value, hue, sat, emission }); } public static float GetCreatureBaseAttribute(Character creatureId, int attribute) { return (float)GetBaseAttributeValue.Invoke(null, new object[2] { creatureId, attribute }); } public static bool SetCreatureBaseAttribute(Character creatureId, int attribute, float value) { return (bool)UpdateCreatureBaseAttributes.Invoke(null, new object[3] { creatureId, attribute, value }); } public static Dictionary<int, float> GetAllCreatureBaseAttributes(Character creatureId) { return (Dictionary<int, float>)GetAllBaseAttributeValues.Invoke(null, new object[1] { creatureId }); } public static bool SetAllCreatureBaseAttributes(Character creatureId, Dictionary<int, float> attributes) { return (bool)SetAllBaseAttributeValues.Invoke(null, new object[2] { creatureId, attributes }); } public static float GetCreaturePerLevelAttribute(Character creatureId, int attribute) { return (float)GetPerLevelAttributeValue.Invoke(null, new object[2] { creatureId, attribute }); } public static bool SetCreaturePerLevelAttribute(Character creatureId, int attribute, float value) { return (bool)UpdateCreaturePerLevelAttributes.Invoke(null, new object[3] { creatureId, attribute, value }); } public static Dictionary<int, float> GetAllCreaturePerLevelAttributes(Character creatureId) { return (Dictionary<int, float>)GetAllPerLevelAttributeValues.Invoke(null, new object[1] { creatureId }); } public static bool SetAllCreaturePerLevelAttributes(Character creatureId, Dictionary<int, float> attributes) { return (bool)SetAllPerLevelAttributeValues.Invoke(null, new object[2] { creatureId, attributes }); } public static float GetCreatureDamageReceivedModifier(Character creatureId, int damageType) { return (float)GetCreatureDamageRecievedModifier.Invoke(null, new object[2] { creatureId, damageType }); } public static bool SetCreatureDamageReceivedModifier(Character creatureId, int damageType, float value) { return (bool)UpdateCreatureDamageRecievedModifier.Invoke(null, new object[3] { creatureId, damageType, value }); } public static Dictionary<int, float> GetAllCreatureDamageReceivedModifiers(Character creatureId) { return (Dictionary<int, float>)GetAllDamageRecievedModifiers.Invoke(null, new object[1] { creatureId }); } public static bool SetAllCreatureDamageReceivedModifiers(Character creatureId, Dictionary<int, float> attributes) { return (bool)SetAllDamageRecievedModifiers.Invoke(null, new object[2] { creatureId, attributes }); } public static float GetCreatureFlatDamageBonus(Character creatureId, int damageType) { return (float)GetCreatureDamageBonus.Invoke(null, new object[2] { creatureId, damageType }); } public static bool SetCreatureFlatDamageBonus(Character creatureId, int damageType, float value) { return (bool)UpdateCreatureDamageBonus.Invoke(null, new object[3] { creatureId, damageType, value }); } public static Dictionary<int, float> GetAllCreatureFlatDamageBonuses(Character creatureId) { return (Dictionary<int, float>)GetAllDamageBonus.Invoke(null, new object[1] { creatureId }); } public static bool SetAllCreatureFlatDamageBonuses(Character creatureId, Dictionary<int, float> attributes) { return (bool)SetAllDamageBonus.Invoke(null, new object[2] { creatureId, attributes }); } public static bool ApplyCreatureUpdates(Character creatureId) { return (bool)ApplyUpdatesToCreature.Invoke(null, new object[1] { creatureId }); } public static bool SetCreatureSpawnManaged(Character creatureId, bool managed = true) { return (bool)Call(SetCreatureSpawnManagedMethod, false, creatureId, managed); } public static List<string> GetPossibleModifiers(int modType = 0) { return (List<string>)GetPossibleModifiersForType.Invoke(null, new object[1] { modType }); } public static Dictionary<string, int> GetCreaturesModifiers(Character creatureId) { return (Dictionary<string, int>)GetAllModifiersForCreature.Invoke(null, new object[1] { creatureId }); } public static bool AddModifierToTargetCreature(Character creatureId, string modifierName, int modifierType, bool update = true) { return (bool)AddModifierToCreature.Invoke(null, new object[4] { creatureId, modifierName, modifierType, update }); } public static bool AddNewModifier(int modifierID, string modifier_name, Delegate setupMethod = null, float selectionWeight = 10f, float basepower = 0f, float perlevelpower = 0f, Dictionary<Biome, List<string>> biomeConfig = null, int namingStyle = 2, string name_suffixes = null, string name_prefixes = null, int visualStyle = 0, Sprite starIcon = null, GameObject visualEffect = null, List<string> allowed_creatures = null, List<string> unallowed_creatures = null, List<Biome> allowed_biomes = null) { return (bool)AddNewModifierToSLS.Invoke(null, new object[16] { modifierID, modifier_name, setupMethod, selectionWeight, basepower, perlevelpower, biomeConfig, namingStyle, name_suffixes, name_prefixes, visualStyle, starIcon, visualEffect, allowed_creatures, unallowed_creatures, allowed_biomes }); } public static bool RegisterLocationReset(string prefabName, string sourceId, float resetHours = 0f, string resetSchedule = null, bool enabled = true, int mode = 0, bool resetTerrain = false, float terrainRadius = 0f, float extraTerrainRadius = 0f, bool resetInterior = true, float minDistance = 0f, float maxDistance = 0f, Action<bool> onResult = null) { return (bool)Call(RegisterLocationResetTargetMethod, false, prefabName, sourceId, resetHours, resetSchedule, mode, resetTerrain, terrainRadius, extraTerrainRadius, resetInterior, minDistance, maxDistance, enabled, onResult); } public static bool UnregisterLocationReset(string prefabName, string sourceId, Action<bool> onResult = null) { return (bool)Call(UnregisterLocationResetTargetMethod, false, prefabName, sourceId, onResult); } public static bool GetRegisteredLocationResets(string sourceId, Action<List<string>> onResult) { return (bool)Call(GetRegisteredLocationResetTargetsMethod, false, sourceId, onResult); } public static bool GetLocationResetTargetInfo(string prefabName, Action<Dictionary<string, object>> onResult) { return (bool)Call(GetLocationResetTargetInfoMethod, false, prefabName, onResult); } public static bool IsLocationResetReady(Action<bool> onResult) { return (bool)Call(IsLocationResetReadyMethod, false, onResult); } public static bool GetLocationResetStatus(Action<Dictionary<string, object>> onResult) { return (bool)Call(GetLocationResetStatusMethod, false, onResult); } public static bool IsKnownLocationResetTarget(string prefabName, Action<bool> onResult) { return (bool)Call(IsKnownResetTargetNameMethod, false, prefabName, onResult); } public static bool GetLocationLastReset(string locationName, Vector3 center, float radius, Action<long> onResult) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) return (bool)Call(GetLocationLastResetMethod, false, locationName, center, radius, onResult); } public static bool GetSecondsUntilLocationReset(string locationName, Vector3 center, float radius, Action<double> onResult) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) return (bool)Call(GetSecondsUntilLocationResetMethod, false, locationName, center, radius, onResult); } public static bool GetLocationResetInfo(string locationName, Vector3 center, float radius, Action<Dictionary<string, object>> onResult) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) return (bool)Call(GetLocationResetInfoMethod, false, locationName, center, radius, onResult); } public static bool GetChunkResetInfo(Vector3 position, bool includePrefabs, Action<Dictionary<string, object>> onResult) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) return (bool)Call(GetChunkResetInfoMethod, false, position, includePrefabs, onResult); } public static bool ResetNamedLocation(string locationName, Vector3 center, float radius = 128f, int safety = 0, bool resetAllMatches = false, float safeWaitSeconds = 0f, bool includeDetail = false, Action<Dictionary<string, object>> onComplete = null) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) return (bool)Call(ResetNamedLocationMethod, false, locationName, center, radius, safety, resetAllMatches, safeWaitSeconds, includeDetail, onComplete); } public static bool ResetLocationsInRadius(Vector3 center, float radius = 128f, int safety = 0, float safeWaitSeconds = 0f, bool includeDetail = false, Action<Dictionary<string, object>> onComplete = null) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) return (bool)Call(ResetLocationsInRadiusMethod, false, center, radius, safety, safeWaitSeconds, includeDetail, onComplete); } } } namespace ItemFavoriteFrameworkAPI { public static class ItemFavorites { private delegate bool StartRollFn(ItemDrop drop, string playerIdsJson, string optionsJson, ref string rollId, ref string error); private delegate bool StartRollForItemFn(ItemData item, Vector3 position, string playerIdsJson, string optionsJson, ref string rollId, ref string error); public const string PluginGuid = "MidnightsFX.ItemFavoriteFramework"; public const int MarkItemFavorite = 1; public const int MarkSlotFavorite = 2; public const int MarkTrash = 4; public const string MarkIdFavorite = "favorite"; public const string MarkIdTrash = "trash"; public const int ButtonLeft = 0; public const int ButtonRight = 1; public const int RollPass = 1; public const int RollGreed = 2; public const int RollNeed = 3; private const string ApiTypeName = "ItemFavoriteFramework.API, ItemFavoriteFramework"; private static bool bound; private static Type apiType; private static Func<int> getApiVersion; private static Func<string> getPluginVersion; private static Func<string, bool> hasEndpoint; private static Func<bool> isReady; private static Func<ItemData, bool> isItemFavorited; private static Func<ItemData, bool> isItemTrashFlagged; private static Func<int, int, bool> isSlotFavorited; private static Func<ItemData, bool> isItemInFavoritedSlot; private static Func<ItemData, bool> isProtected; private static Func<ItemData, int> getMarks; private static Func<Inventory, List<ItemData>> getFavoritedItems; private static Func<Inventory, List<ItemData>> getTrashFlaggedItems; private static Func<Inventory, List<ItemData>> getProtectedItems; private static Func<List<Vector2i>> getFavoritedSlots; private static Func<ItemData, bool, bool> setItemFavorited; private static Func<ItemData, bool, bool> setItemTrashFlagged; private static Func<int, int, bool, bool> setSlotFavorited; private static Action<Action> addChangedListener; private static Action<Action> removeChangedListener; private static Func<Sprite> getFavoriteIcon; private static Func<Sprite> getTrashIcon; private static Func<Color> getFavoriteColor; private static Func<Color> getFavoritedSlotColor; private static Func<Color> getTrashColor; private static Func<string, string, Color, Sprite, string, bool> registerMarkType; private static Func<string, bool> isMarkTypeRegistered; private static Func<ItemData, string, bool> hasCustomMark; private static Func<ItemData, List<string>> getCustomMarks; private static Func<ItemData, string, bool, bool> setCustomMark; private static Action<Action<ItemData, string, bool>> addMarkListener; private static Action<Action<ItemData, string, bool>> removeMarkListener; private static Action<Func<Inventory, ItemData, int, bool>> addItemClickHandler; private static Action<Func<Inventory, ItemData, int, bool>> removeItemClickHandler; private static Func<ItemData, bool> isItemWishlisted; private static Func<string> getWishlistJson; private static Func<string, string, bool> addWishlistEntry; private static Func<ItemData, bool> addWishlistEntryFromItem; private static Func<string, int> removeWishlistEntries; private static Action<Action> addWishlistChangedListener; private static Action<Action> removeWishlistChangedListener; private static Action openWishlistEditor; private static Func<string, Func<string, string>, Func<ItemData, string, bool>, Func<string, string>, Func<ItemData, string>, bool> registerWishlistProvider; private static Func<string, bool> unregisterWishlistProvider; private static Func<Sprite> getWishlistIcon; private static Func<Color> getWishlistColor; private static Action<Func<ItemData, string>> addItemNameProvider; private static Action<Func<ItemData, string>> removeItemNameProvider; private static Func<string> getServerFeaturesJson; private static Func<string> getConnectedPlayersJson; private static Func<long, string> getPlayerWishlistJson; private static Func<ItemData, string> getWantedByJson; private static Func<bool> isRollingAvailable; private static StartRollFn startRoll; private static StartRollForItemFn startRollForItem; private static Func<ItemDrop, string> getRollStateJson; private static Func<ItemDrop, bool> isDropLocked; private static Func<ItemDrop, long, bool> canPlayerPickUp; private static Func<string, int, bool> submitRollVote; private static Action<Action<string>> addRollListener; private static Action<Action<string>> removeRollListener; private static Func<Vector3, float, string> getPlayerIdsNearJson; private static Func<Character, string> getDamagerPlayerIdsJson; public static bool IsLoaded() { Bind(); return apiType != null; } public static int GetApiVersion() { Bind(); if (getApiVersion == null) { return 0; } return getApiVersion(); } public static string GetPluginVersion() { Bind(); if (getPluginVersion == null) { return ""; } return getPluginVersion(); } public static bool HasEndpoint(string name) { Bind(); if (hasEndpoint != null) { return hasEndpoint(name); } return false; } public static bool IsReady() { Bind(); if (isReady != null) { return isReady(); } return false; } public static bool IsItemFavorited(ItemData item) { Bind(); if (isItemFavorited != null) { return isItemFavorited(item); } return false; } public static bool IsItemTrashFlagged(ItemData item) { Bind(); if (isItemTrashFlagged != null) { return isItemTrashFlagged(item); } return false; } public static bool IsSlotFavorited(int x, int y) { Bind(); if (isSlotFavorited != null) { return isSlotFavorited(x, y); } return false; } public static bool IsItemInFavoritedSlot(ItemData item) { Bind(); if (isItemInFavoritedSlot != null) { return isItemInFavoritedSlot(item); } return false; } public static bool IsProtected(ItemData item) { Bind(); if (isProtected != null) { return isProtected(item); } return false; } public static int GetMarks(ItemData item) { Bind(); if (getMarks == null) { return 0; } return getMarks(item); } public static List<ItemData> GetFavoritedItems(Inventory inventory) { Bind(); if (getFavoritedItems == null) { return new List<ItemData>(); } return getFavoritedItems(inventory); } public static List<ItemData> GetTrashFlaggedItems(Inventory inventory) { Bind(); if (getTrashFlaggedItems == null) { return new List<ItemData>(); } return getTrashFlaggedItems(inventory); } public static List<ItemData> GetProtectedItems(Inventory inventory) { Bind(); if (getProtectedItems == null) { return new List<ItemData>(); } return getProtectedItems(inventory); } public static List<Vector2i> GetFavoritedSlots() { Bind(); if (getFavoritedSlots == null) { return new List<Vector2i>(); } return getFavoritedSlots(); } public static bool SetItemFavorited(ItemData item, bool favorited) { Bind(); if (setItemFavorited != null) { return setItemFavorited(item, favorited); } return false; } public static bool SetItemTrashFlagged(ItemData item, bool trashFlagged) { Bind(); if (setItemTrashFlagged != null) { return setItemTrashFlagged(item, trashFlagged); } return false; } public static bool SetSlotFavorited(int x, int y, bool favorited) { Bind(); if (setSlotFavorited != null) { return setSlotFavorited(x, y, favorited); } return false; } public static void AddChangedListener(Action listener) { Bind(); addChangedListener?.Invoke(listener); } public static void RemoveChangedListener(Action listener) { Bind(); removeChangedListener?.Invoke(listener); } public static Sprite GetFavoriteIcon() { Bind(); if (getFavoriteIcon == null) { return null; } return getFavoriteIcon(); } public static Sprite GetTrashIcon() { Bind(); if (getTrashIcon == null) { return null; } return getTrashIcon(); } public static Color GetFavoriteColor() { //IL_0026: 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) Bind(); if (getFavoriteColor == null) { return new Color(1f, 0.85f, 0f); } return getFavoriteColor(); } public static Color GetFavoritedSlotColor() { //IL_0026: 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) Bind(); if (getFavoritedSlotColor == null) { return new Color(0f, 0.5f, 1f); } return getFavoritedSlotColor(); } public static Color GetTrashColor() { //IL_0026: 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) Bind(); if (getTrashColor == null) { return new Color(0.5f, 0f, 0f); } return getTrashColor(); } public static bool RegisterMarkType(string id, string group, Color color, Sprite icon, string tooltipToken) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Bind(); if (registerMarkType != null) { return registerMarkType(id, group, color, icon, tooltipToken); } return false; } public static bool IsMarkTypeRegistered(string id) { Bind(); if (isMarkTypeRegistered != null) { return isMarkTypeRegistered(id); } return false; } public static bool HasCustomMark(ItemData item, string id) { Bind(); if (hasCustomMark != null) { return hasCustomMark(item, id); } return false; } public static List<string> GetCustomMarks(ItemData item) { Bind(); if (getCustomMarks == null) { return new List<string>(); } return getCustomMarks(item); } public static bool SetCustomMark(ItemData item, string id, bool marked) { Bind(); if (setCustomMark != null) { return setCustomMark(item, id, marked); } return false; } public static void AddMarkListener(Action<ItemData, string, bool> listener) { Bind(); addMarkListener?.Invoke(listener); } public static void RemoveMarkListener(Action<ItemData, string, bool> listener) { Bind(); removeMarkListener?.Invoke(listener); } public static void AddItemClickHandler(Func<Inventory, ItemData, int, bool> handler) { Bind(); addItemClickHandler?.Invoke(handler); } public static void RemoveItemClickHandler(Func<Inventory, ItemData, int, bool> handler) { Bind(); removeItemClickHandler?.Invoke(handler); } public static bool IsItemWishlisted(ItemData item) { Bind(); if (isItemWishlisted != null) { return isItemWishlisted(item); } return false; } public static string GetWishlistJson() { Bind(); if (getWishlistJson == null) { return "[]"; } return getWishlistJson(); } public static bool AddWishlistEntry(string prefabName, string criteriaJson) { Bind(); if (addWishlistEntry != null) { return addWishlistEntry(prefabName, criteriaJson); } return false; } public static bool AddWishlistEntryFromItem(ItemData item) { Bind(); if (addWishlistEntryFromItem != null) { return addWishlistEntryFromItem(item); } return false; } public static int RemoveWishlistEntries(string prefabName) { Bind(); if (removeWishlistEntries == null) { return 0; } return removeWishlistEntries(prefabName); } public static void AddWishlistChangedListener(Action listener) { Bind(); addWishlistChangedListener?.Invoke(listener); } public static void RemoveWishlistChangedListener(Action listener) { Bind(); removeWishlistChangedListener?.Invoke(listener); } public static void OpenWishlistEditor() { Bind(); openWishlistEditor?.Invoke(); } public static bool RegisterWishlistProvider(string providerId, Func<string, string> getSchemaJson, Func<ItemData, string, bool> matches, Func<string, string> describe, Func<ItemData, string> suggest) { Bind(); if (registerWishlistProvider != null) { return registerWishlistProvider(providerId, getSchemaJson, matches, describe, suggest); } return false; } public static bool UnregisterWishlistProvider(string providerId) { Bind(); if (unregisterWishlistProvider != null) { return unregisterWishlistProvider(providerId); } return false; } public static Sprite GetWishlistIcon() { Bind(); if (getWishlistIcon == null) { return null; } return getWishlistIcon(); } public static Color GetWishlistColor() { //IL_0026: 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) Bind(); if (getWishlistColor == null) { return new Color(0.95f, 0.36f, 0.55f); } return getWishlistColor(); } public static void AddItemNameProvider(Func<ItemData, string> provider) { Bind(); addItemNameProvider?.Invoke(provider); } public static void RemoveItemNameProvider(Func<ItemData, string> provider) { Bind(); removeItemNameProvider?.Invoke(provider); } public static string GetServerFeaturesJson() { Bind(); if (getServerFeaturesJson == null) { return "{\"iff\":false}"; } return getServerFeaturesJson(); } public static string GetConnectedPlayersJson() { Bind(); if (getConnectedPlayersJson == null) { return "[]"; } return getConnectedPlayersJson(); } public static string GetPlayerWishlistJson(long playerId) { Bind(); if (getPlayerWishlistJson == null) { return "[]"; } return getPlayerWishlistJson(playerId); } public static string GetWantedByJson(ItemData item) { Bind(); if (getWantedByJson == null) { return "[]"; } return getWantedByJson(item); } public static bool IsRollingAvailable() { Bind(); if (isRollingAvailable != null) { return isRollingAvailable(); } return false; } public static bool StartRoll(ItemDrop drop, string playerIdsJson, string optionsJson, out string rollId, out string error) { Bind(); rollId = ""; error = "notInstalled"; if (startRoll == null) { return false; } string rollId2 = ""; string error2 = ""; bool result = startRoll(drop, playerIdsJson, optionsJson, ref rollId2, ref error2); rollId = rollId2; error = error2; return result; } public static bool StartRollForItem(ItemData item, Vector3 position, string playerIdsJson, string optionsJson, out string rollId, out string error) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) Bind(); rollId = ""; error = "notInstalled"; if (startRollForItem == null) { return false; } string rollId2 = ""; string error2 = ""; bool result = startRollForItem(item, position, playerIdsJson, optionsJson, ref rollId2, ref error2); rollId = rollId2; error = error2; return result; } public static string GetRollStateJson(ItemDrop drop) { Bind(); if (getRollStateJson == null) { return "{\"phase\":\"free\"}"; } return getRollStateJson(drop); } public static bool IsDropLocked(ItemDrop drop) { Bind(); if (isDropLocked != null) { return isDropLocked(drop); } return false; } public static bool CanPlayerPickUp(ItemDrop drop, long playerId) { Bind(); if (canPlayerPickUp != null) { return canPlayerPickUp(drop, playerId); } return true; } public static bool SubmitRollVote(string rollId, int choice) { Bind(); if (submitRollVote != null) { return submitRollVote(rollId, choice); } return false; } public static void AddRollListener(Action<string> listener) { Bind(); addRollListener?.Invoke(listener); } public static void RemoveRollListener(Action<string> listener) { Bind(); removeRollListener?.Invoke(listener); } public static string GetPlayerIdsNearJson(Vector3 point, float radius) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) Bind(); if (getPlayerIdsNearJson == null) { return "[]"; } return getPlayerIdsNearJson(point, radius); } public static string GetDamagerPlayerIdsJson(Character character) { Bind(); if (getDamagerPlayerIdsJson == null) { return "[]"; } return getDamagerPlayerIdsJson(character); } public static string PlayerIdsToJson(IEnumerable<long> playerIds) { return "[" + string.Join(",", playerIds.Select((long id) => "\"" + id.ToString(CultureInfo.InvariantCulture) + "\"").ToArray()) + "]"; } private static void Bind() { if (!bound) { bound = true; apiType = Type.GetType("ItemFavoriteFramework.API, ItemFavoriteFramework", throwOnError: false); if (!(apiType == null)) { getApiVersion = Get<Func<int>>("GetApiVersion"); getPluginVersion = Get<Func<string>>("GetPluginVersion"); hasEndpoint = Get<Func<string, bool>>("HasEndpoint"); isReady = Get<Func<bool>>("IsReady"); isItemFavorited = Get<Func<ItemData, bool>>("IsItemFavorited"); isItemTrashFlagged = Get<Func<ItemData, bool>>("IsItemTrashFlagged"); isSlotFavorited = Get<Func<int, int, bool>>("IsSlotFavorited"); isItemInFavoritedSlot = Get<Func<ItemData, bool>>("IsItemInFavoritedSlot"); isProtected = Get<Func<ItemData, bool>>("IsProtected"); getMarks = Get<Func<ItemData, int>>("GetMarks"); getFavoritedItems = Get<Func<Inventory, List<ItemData>>>("GetFavoritedItems"); getTrashFlaggedItems = Get<Func<Inventory, List<ItemData>>>("GetTrashFlaggedItems"); getProtectedItems = Get<Func<Inventory, List<ItemData>>>("GetProtectedItems"); getFavoritedSlots = Get<Func<List<Vector2i>>>("GetFavoritedSlots"); setItemFavorited = Get<Func<ItemData, bool, bool>>("SetItemFavorited"); setItemTrashFlagged = Get<Func<ItemData, bool, bool>>("SetItemTrashFlagged"); setSlotFavorited = Get<Func<int, int, bool, bool>>("SetSlotFavorited"); addChangedListener = Get<Action<Action>>("AddChangedListener"); removeChangedListener = Get<Action<Action>>("RemoveChangedListener"); getFavoriteIcon = Get<Func<Sprite>>("GetFavoriteIcon"); getTrashIcon = Get<Func<Sprite>>("GetTrashIcon"); getFavoriteColor = Get<Func<Color>>("GetFavoriteColor"); getFavoritedSlotColor = Get<Func<Color>>("GetFavoritedSlotColor"); getTrashColor = Get<Func<Color>>("GetTrashColor"); registerMarkType = Get<Func<string, string, Color, Sprite, string, bool>>("RegisterMarkType"); isMarkTypeRegistered = Get<Func<string, bool>>("IsMarkTypeRegistered"); hasCustomMark = Get<Func<ItemData, string, bool>>("HasCustomMark"); getCustomMarks = Get<Func<ItemData, List<string>>>("GetCustomMarks"); setCustomMark = Get<Func<ItemData, string, bool, bool>>("SetCustomMark"); addMarkListener = Get<Action<Action<ItemData, string, bool>>>("AddMarkListener"); removeMarkListener = Get<Action<Action<ItemData, string, bool>>>("RemoveMarkListener"); addItemClickHandler = Get<Action<Func<Inventory, ItemData, int, bool>>>("AddItemClickHandler"); removeItemClickHandler = Get<Action<Func<Inventory, ItemData, int, bool>>>("RemoveItemClickHandler"); isItemWishlisted = Get<Func<ItemData, bool>>("IsItemWishlisted"); getWishlistJson = Get<Func<string>>("GetWishlistJson"); addWishlistEntry = Get<Func<string, string, bool>>("AddWishlistEntry"); addWishlistEntryFromItem = Get<Func<ItemData, bool>>("AddWishlistEntryFromItem"); removeWishlistEntries = Get<Func<string, int>>("RemoveWishlistEntries"); addWishlistChangedListener = Get<Action<Action>>("AddWishlistChangedListener"); removeWishlistChangedListener = Get<Action<Action>>("RemoveWishlistChangedListener"); openWishlistEditor = Get<Action>("OpenWishlistEditor"); registerWishlistProvider = Get<Func<string, Func<string, string>, Func<ItemData, string, bool>, Func<string, string>, Func<ItemData, string>, bool>>("RegisterWishlistProvider"); unregisterWishlistProvider = Get<Func<string, bool>>("UnregisterWishlistProvider"); getWishlistIcon = Get<Func<Sprite>>("GetWishlistIcon"); getWishlistColor = Get<Func<Color>>("GetWishlistColor"); addItemNameProvider = Get<Action<Func<ItemData, string>>>("AddItemNameProvider"); removeItemNameProvider = Get<Action<Func<ItemData, string>>>("RemoveItemNameProvider"); getServerFeaturesJson = Get<Func<string>>("GetServerFeaturesJson"); getConnectedPlayersJson = Get<Func<string>>("GetConnectedPlayersJson"); getPlayerWishlistJson = Get<Func<long, string>>("GetPlayerWishlistJson"); getWantedByJson = Get<Func<ItemData, string>>("GetWantedByJson"); isRollingAvailable = Get<Func<bool>>("IsRollingAvailable"); startRoll = Get<StartRollFn>("StartRoll"); startRollForItem = Get<StartRollForItemFn>("StartRollForItem"); getRollStateJson = Get<Func<ItemDrop, string>>("GetRollStateJson"); isDropLocked = Get<Func<ItemDrop, bool>>("IsDropLocked"); canPlayerPickUp = Get<Func<ItemDrop, long, bool>>("CanPlayerPickUp"); submitRollVote = Get<Func<string, int, bool>>("SubmitRollVote"); addRollListener = Get<Action<Action<string>>>("AddRollListener"); removeRollListener = Get<Action<Action<string>>>("RemoveRollListener"); getPlayerIdsNearJson = Get<Func<Vector3, float, string>>("GetPlayerIdsNearJson"); getDamagerPlayerIdsJson = Get<Func<Character, string>>("GetDamagerPlayerIdsJson"); } } } private static TDelegate Get<TDelegate>(string name) where TDelegate : class { MethodInfo method = typeof(TDelegate).GetMethod("Invoke"); Type[] types = (from p in method.GetParameters() select p.ParameterType).ToArray(); MethodInfo method2 = apiType.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, types, null); if (method2 == null || method2.ReturnType != method.ReturnType) { return null; } return Delegate.CreateDelegate(typeof(TDelegate), method2, throwOnBindFailure: false) as TDelegate; } } } namespace Clans { public static class API { public const int ApiVersion = 1; private static IApiReceiver Receiver => ApiReceiver.Current; public static int GetApiVersion() { return 1; } public static string GetPluginVersion() { return "1.0.1"; } public static string GetPluginId() { return "MidnightsFX.Clans"; } public static bool HasEndpoint(string name) { return GetEndpointNames().Contains(name); } public static List<string> GetEndpointNames() { return (from m in typeof(API).GetMethods(BindingFlags.Static | BindingFlags.Public) select m.Name).Distinct().OrderBy<string, string>((string n) => n, StringComparer.Ordinal).ToList(); } public static bool IsReady() { return Receiver.IsReady(); } public static bool HasFullData() { return Receiver.HasFullData(); } public static string GetLocalAccountId() { return Receiver.GetLocalAccountId(); } public static string GetAccountId(Player player) { return Receiver.GetAccountId(player); } public static string GetAccountIdOfPeer(long peerId) { return Receiver.GetAccountIdOfPeer(peerId); } public static string GetAccountIdOfPlayerId(long playerId) { return Receiver.GetAccountIdOfPlayerId(playerId); } public static string GetPlayerName(string accountId) { return Receiver.GetPlayerName(accountId); } public static bool IsOnline(string accountId) { return Receiver.IsOnline(accountId); } public static List<long> GetClanIds() { return Receiver.GetClanIds(); } public static bool ClanExists(long clanId) { return Receiver.ClanExists(clanId); } public static string GetClanName(long clanId) { return Receiver.GetClanName(clanId); } public static long FindClanByName(string name) { return Receiver.FindClanByName(name); } public static int GetClanLevel(long clanId) { return Receiver.GetClanLevel(clanId); } public static int GetMaxClanLevel() { return Receiver.GetMaxClanLevel(); } public static int GetMemberCount(long clanId) { return Receiver.GetMemberCount(clanId); } public static string GetLeaderId(long clanId) { return Receiver.GetLeaderId(clanId); } public static bool AreAtWar(long clanA, long clanB) { return Receiver.AreAtWar(clanA, clanB); } public static string GetClanJson(long clanId) { return Receiver.GetClanJson(clanId); } public static string GetClansJson() { return Receiver.GetClansJson(); } public static long GetClanIdOf(string accountId) { return Receiver.GetClanIdOf(accountId); } public static long GetClanIdOfPlayer(Player player) { return Receiver.GetClanIdOfPlayer(player); } public static bool IsInClan(string accountId) { return Receiver.IsInClan(accountId); } public static bool AreClanmates(string accountA, string accountB) { return Receiver.AreClanmates(accountA, accountB); } public static List<string> GetMemberIds(long clanId) { return Receiver.GetMemberIds(clanId); } public static List<string> GetOnlineMemberIds(long clanId) { return Receiver.GetOnlineMemberIds(clanId); } public static string GetMembersJson(long clanId) { return Receiver.GetMembersJson(clanId); } public static int GetRankIndex(string accountId) { return Receiver.GetRankIndex(accountId); } public static int GetRankId(string accountId) { return Receiver.GetRankId(accountId); } public static string GetRankName(string accountId) { return Receiver.GetRankName(accountId); } public static bool IsLeader(string accountId) { return Receiver.IsLeader(accountId); } public static bool HasPermission(string accountId, string permission) { return Receiver.HasPermission(accountId, permission); } public static List<string> GetPermissionNames() { return Receiver.GetPermissionNames(); } public static string GetRanksJson(long clanId) { return Receiver.GetRanksJson(clanId); } public static long GetPartyId(string accountId) { return Receiver.GetPartyId(accountId); } public static bool ArePartymates(string accountA, string accountB) { return Receiver.ArePartymates(accountA, accountB); } public static string GetPartyLeaderId(long partyId) { return Receiver.GetPartyLeaderId(partyId); } public static List<string> GetPartyMemberIds(long partyId) { return Receiver.GetPartyMemberIds(partyId); } public static string GetPartyJson(long partyId) { return Receiver.GetPartyJson(partyId); } public static long GetRaidId(string accountId) { return Receiver.GetRaidId(accountId); } public static int GetSquad(string accountId) { return Receiver.GetSquad(accountId); } public static bool AreRaidmates(string accountA, string accountB) { return Receiver.AreRaidmates(accountA, accountB); } public static string GetRaidLeaderId(long raidId) { return Receiver.GetRaidLeaderId(raidId); } public static List<string> GetRaidMemberIds(long raidId) { return Receiver.GetRaidMemberIds(raidId); } public static string GetRaidJson(long raidId) { return Receiver.GetRaidJson(raidId); } public static long GetTreasury(long clanId) { return Receiver.GetTreasury(clanId); } public static bool AddTreasury(long clanId, long coins, string reason) { return Receiver.AddTreasury(clanId, coins, reason); } public static bool TakeTreasury(long clanId, long coins, string reason) { return Receiver.TakeTreasury(clanId, coins, reason); } public static int GetSharedTabCount(long clanId) { return Receiver.GetSharedTabCount(clanId); } public static string GetStorageJson(long clanId) { return Receiver.GetStorageJson(clanId); } public static int CountStorageItem(long clanId, string prefab) { return Receiver.CountStorageItem(clanId, prefab); } public static void RequestStorageJson(Action<bool, string> callback) { Receiver.RequestStorageJson(callback); } public static bool TakeStorageItems(long clanId, string itemsJson, string reason, out string error) { return Receiver.TakeStorageItems(clanId, itemsJson, reason, out error); } public static bool AddStorageItems(long clanId, string itemsJson, string reason, out string error) { return Receiver.AddStorageItems(clanId, itemsJson, reason, out error); } public static bool AddStorageItem(long clanId, ItemData item, string reason, out string error) { return Receiver.AddStorageItem(clanId, item, reason, out error); } public static void AddChangedListener(Action listener) { Receiver.AddChangedListener(listener); } public static void RemoveChangedListener(Action listener) { Receiver.RemoveChangedListener(listener); } public static void AddServerEventListener(Action<string> listener) { Receiver.AddServerEventListener(listener); } public static void RemoveServerEventListener(Action<string> listener) { Receiver.RemoveServerEventListener(listener); } } internal static class ApiEvents { private static readonly List<Action> changed = new List<Action>(); private static readonly List<Action<string>> serverEvents = new List<Action<string>>(); internal static void Init() { ClanClient.DirectoryChanged += RaiseChanged; ClanClient.RosterChanged += RaiseChanged; ClanClient.AccountChanged += RaiseChanged; ClanClient.DetailChanged += RaiseChanged; PartyClient.Changed += RaiseChanged; } internal static void AddChanged(Action listener) { if (listener != null && !changed.Contains(listener)) { changed.Add(listener); } } internal static void RemoveChanged(Action listener) { changed.Remove(listener); } internal static void AddServer(Action<string> listener) { if (listener != null && !serverEvents.Contains(listener)) { serverEvents.Add(listener); } } internal static void RemoveServer(Action<string> listener) { serverEvents.Remove(listener); } internal static void RaiseChanged() { if (changed.Count == 0) { return; } Action[] array = changed.ToArray(); foreach (Action action in array) { try { action(); } catch (Exception arg) { Logger.LogError($"A Clans API changed listener failed: {arg}"); } } } internal static void ClanFounded(ClanRecord clan, string account, string name) { if (serverEvents.Count != 0) { Send(Start("clanFounded", clan).Field("name", clan.Name).Field("account", account).Field("playerName", name)); } } internal static void ClanDisbanded(ClanRecord clan) { if (serverEvents.Count != 0) { Send(Start("clanDisbanded", clan).Field("name", clan.Name)); } } internal static void MemberJoined(ClanRecord clan, string account) { if (serverEvents.Count != 0) { Send(Rank(Start("memberJoined", clan), clan, account)); } } internal static void MemberLeft(ClanRecord clan, string account, string name, string reason) { if (serverEvents.Count != 0) { Send(Start("memberLeft", clan).Field("account", account).Field("playerName", name ?? "").Field("reason", reason)); } } internal static void RankChanged(ClanRecord clan, string account) { if (serverEvents.Count != 0) { Send(Rank(Start("rankChanged", clan), clan, account)); } } internal static void RanksChanged(ClanRecord clan) { if (serverEvents.Count != 0) { Send(Start("ranksChanged", clan)); } } internal static void LevelChanged(ClanRecord clan, int previous) { if (serverEvents.Count != 0) { Send(Start("levelChanged", clan).Field("level", ClanRules.Level(clan)).Field("previous", previous)); } } internal static void TreasuryChanged(ClanRecord clan, long change) { if (serverEvents.Count != 0) { Send(Start("treasuryChanged", clan).Field("treasury", clan.Treasury).Field("change", change)); } } internal static void StorageChanged(ClanRecord clan, int tab) { if (serverEvents.Count != 0) { Send(Start("storageChanged", clan).Field("tab", tab)); } } internal static void PartyJoined(long partyId, string account) { if (serverEvents.Count != 0) { Send(Party("partyJoined", partyId).Field("account", account).Field("playerName", NameOf(account))); } } internal static void PartyLeft(long partyId, string account, string reason) { if (serverEvents.Count != 0) { Send(Party("partyLeft", partyId).Field("account", account).Field("playerName", NameOf(account)).Field("reason", reason)); } } internal static void PartyLeaderChanged(long partyId, string account) { if (serverEvents.Count != 0) { Send(Party("partyLeaderChanged", partyId).Field("account", account).Field("playerName", NameOf(account))); } } internal static void PartyDisbanded(long partyId) { if (serverEvents.Count != 0) { Send(Party("partyDisbanded", partyId)); } } internal static void RaidJoined(long raidId, long partyId, int squad) { if (serverEvents.Count != 0) { Send(Raid("raidJoined", raidId).Field("party", partyId).Field("squad", squad)); } } internal static void RaidLeft(long raidId, long partyId) { if (serverEvents.Count != 0) { Send(Raid("raidLeft", raidId).Field("party", partyId)); } } internal static void RaidLeaderChanged(long raidId, string account) { if (serverEvents.Count != 0) { Send(Raid("raidLeaderChanged", raidId).Field("account", account).Field("playerName", NameOf(account))); } } internal static void RaidDisbanded(long raidId) { if (serverEvents.Count != 0) { Send(Raid("raidDisbanded", raidId)); } } private static JsonOut Start(string name, ClanRecord clan) { return new JsonOut().Object().Field("event", name).Field("clan", clan.Id); } private static JsonOut Party(string name, long partyId) { return new JsonOut().Object().Field("event", name).Field("party", partyId); } private static JsonOut Raid(string name, long raidId) { return new JsonOut().Object().Field("event", name).Field("raid", raidId); } private static string NameOf(string account) { ClanSender clanSender = Sessions.Get(account); object obj; if (clanSender == null) { obj = ClanRules.Account(account)?.LastCharacterName; if (obj == null) { return ""; } } else { obj = clanSender.CharacterName; } return (string)obj; } private static JsonOut Rank(JsonOut json, ClanRecord clan, string account) { MemberRecord memberRecord = ClanRules.Member(clan, account); int num = ((memberRecord == null) ? (-1) : ClanRules.RankIndex(clan, memberRecord.RankId)); return json.Field("account", account).Field("playerName", memberRecord?.LastCharacterName ?? "").Field("rankId", memberRecord?.RankId ?? 0) .Field("rankIndex", num) .Field("rank", (num >= 0) ? ApiReceiver.Localize(clan.Ranks[num].Name) : ""); } private static void Send(JsonOut json) { string obj = json.End().ToString(); Action<string>[] array = serverEvents.ToArray(); foreach (Action<string> action in array) { try { action(obj); } catch (Exception arg) { Logger.LogError($"A Clans API event listener failed: {arg}"); } } } } internal abstract class ApiReceiver : IApiReceiver { private static readonly ServerReceiver server = new ServerReceiver(); private static readonly ClientReceiver client = new ClientReceiver(); private static Dictionary<string, ClanPermission> permissionsByName; internal static IApiReceiver Current { get { if (!ServerReceiver.Active) { return client; } return server; } } public abstract bool IsReady(); public abstract bool HasFullData(); public abstract string GetAccountId(Player player); public abstract string GetAccountIdOfPeer(long peerId); public abstract string GetAccountIdOfPlayerId(long playerId); public abstract string GetPlayerName(string accountId); public abstract bool IsOnline(string accountId); public abstract List<long> GetClanIds(); public abstract bool ClanExists(long clanId); public abstract string GetClanName(long clanId); public abstract long FindClanByName(string name); public abstract int GetClanLevel(long clanId); public abstract bool AreAtWar(long clanA, long clanB); public abstract long GetClanIdOf(string accountId); public abstract List<string> GetOnlineMemberIds(long clanId); public abstract long GetTreasury(long clanId); public abstract int GetSharedTabCount(long clanId); public abstract bool AddTreasury(long clanId, long coins, string reason); public abstract bool TakeTreasury(long clanId, long coins, string reason); public abstract bool TakeStorageItems(long clanId, string itemsJson, string reason, out string error); public abstract bool AddStorageItems(long clanId, string itemsJson, string reason, out string error); public abstract bool AddStorageItem(long clanId, ItemData item, string reason, out string error); protected abstract ClanView Clan(long clanId); protected abstract List<long> Enemies(long clanId); protected abstract bool TryRank(string accountId, out RankInfo rank); protected abstract List<MemberView> Members(long clanId); protected abstract List<RankDef> Ranks(long clanId); protected abstract ClanPermission Permissions(string accountId); protected abstract bool TryParty(string accountId, out PartyInfo party); protected abstract PartyView Party(long partyId); protected abstract RaidView Raid(long raidId); protected abstract StorageContents Storage(long clanId); public string GetLocalAccountId() { return ClanClient.MyAccount ?? ""; } public int GetMaxClanLevel() { return ClansSettings.Levels.MaxLevel; } public int GetMemberCount(long clanId) { return Clan(clanId)?.MemberCount ?? 0; } public string GetLeaderId(long clanId) { return Clan(clanId)?.LeaderAccount ?? ""; } public string GetClanJson(long clanId) { ClanView clanView = Clan(clanId); if (clanView != null) { return ClanJson(new JsonOut(), clanView).ToString(); } return ""; } public string GetClansJson() { JsonOut jsonOut = new JsonOut().Array(); foreach (long clanId in GetClanIds()) { ClanView clanView = Clan(clanId); if (clanView != null) { ClanJson(jsonOut, clanView); } } return jsonOut.End().ToString(); } public long GetClanIdOfPlayer(Player player) { return GetClanIdOf(GetAccountId(player)); } public bool IsInClan(string accountId) { return GetClanIdOf(accountId) != 0; } public bool AreClanmates(string accountA, string accountB) { long clanIdOf = GetClanIdOf(accountA); if (clanIdOf != 0L) { return clanIdOf == GetClanIdOf(accountB); } return false; } public List<string> GetMemberIds(long clanId) { return (from m in Members(clanId) select m.Account).ToList(); } public string GetMembersJson(long clanId) { JsonOut jsonOut = new JsonOut().Array(); foreach (MemberView item in Members(clanId)) { jsonOut.Object().Field("id", item.Account).Field("name", item.Name) .Field("rankId", item.RankId) .Field("rankIndex", item.RankIndex) .Field("rank", Localize(item.RankName)) .Field("leader", item.RankIndex == 0) .Field("online", item.Online) .Field("joinedUtc", item.JoinedUtc) .Field("lastSeenUtc", item.LastSeenUtc) .End(); } return jsonOut.End().ToString(); } private JsonOut ClanJson(JsonOut json, ClanView clan) { LevelsSettings levels = ClansSettings.Levels; json.Object().Field("id", clan.Id).Field("name", clan.Name) .Field("description", clan.Description) .Field("level", clan.Level) .Field("maxLevel", levels.MaxLevel) .Field("maxMembers", levels.Get(clan.Level).MaxMembers) .Field("memberCount", clan.MemberCount) .Field("recruiting", clan.Recruiting) .Field("leaderId", clan.LeaderAccount) .Field("leaderName", clan.LeaderName) .Array("enemies"); foreach (long item in Enemies(clan.Id)) { json.Value(item); } return json.End().Field("detail", clan.Detail).Field("xp", clan.Xp) .Field("treasury", clan.Treasury) .Field("sharedTabs", clan.SharedTabs) .End(); } public int GetRankIndex(string accountId) { if (!TryRank(accountId, out var rank)) { return -1; } return rank.Index; } public int GetRankId(string accountId) { if (!TryRank(accountId, out var rank)) { return 0; } return rank.Id; } public string GetRankName(string accountId) { if (!TryRank(accountId, out var rank)) { return ""; } return Localize(rank.StoredName); } public bool IsLeader(string accountId) { return GetRankIndex(accountId) == 0; } public bool HasPermission(string accountId, string permission) { if (TryPermission(permission, out var flag)) { return Permissions(accountId).Has(flag); } return false; } public List<string> GetPermissionNames() { return (from p in ClanPermissions.Split(ClanPermissions.All) select p.ToString()).ToList(); } public string GetRanksJson(long clanId) { JsonOut jsonOut = new JsonOut().Array(); List<RankDef> list = Ranks(clanId); if (list != null) { for (int i = 0; i < list.Count; i++) { RankDef rankDef = list[i]; jsonOut.Object().Field("id", rankDef.Id).Field("index", i) .Field("name", Localize(rankDef.Name)) .Field("storedName", rankDef.Name ?? "") .Field("leader", i == 0) .Field("entry", i == list.Count - 1) .Array("permissions"); foreach (ClanPermission item in ClanPermissions.Split(ClanPermissions.Effective(i, rankDef.Permissions))) { jsonOut.Value(item.ToString()); } jsonOut.End().End(); } } return jsonOut.End().ToString(); } private static bool TryPermission(string name, out ClanPermission flag) { if (permissionsByName == null) { permissionsByName = new Dictionary<string, ClanPermission>(StringComparer.OrdinalIgnoreCase); foreach (ClanPermission item in ClanPermissions.Split(ClanPermissions.All)) { permissionsByName[item.ToString()] = item; } } return permissionsByName.TryGetValue(name ?? "", out flag); } public long GetPartyId(string accountId) { if (!TryParty(accountId, out var party)) { return 0L; } return party.PartyId; } public bool ArePartymates(string accountA, string accountB) { long partyId = GetPartyId(accountA); if (partyId != 0L) { return partyId == GetPartyId(accountB); } return false; } public string GetPartyLeaderId(long partyId) { return Party(partyId)?.Leader ?? ""; } public List<string> GetPartyMemberIds(long partyId) { return Party(partyId)?.Members.Select((PartyMemberView m) => m.Account).ToList() ?? new List<string>(); } public string GetPartyJson(long partyId) { PartyView partyView = Party(partyId); if (partyView != null) { return PartyJson(new JsonOut(), partyView).ToString(); } return ""; } public long GetRaidId(string accountId) { if (!TryParty(accountId, out var party)) { return 0L; } return party.RaidId; } public int GetSquad(string accountId) { if (!TryParty(accountId, out var party)) { return 0; } return party.Squad; } public bool AreRaidmates(string accountA, string accountB) { long raidId = GetRaidId(accountA); if (raidId != 0L) { return raidId == GetRaidId(accountB); } return false; } public string GetRaidLeaderId(long raidId) { return Raid(raidId)?.Leader ?? ""; } public List<string> GetRaidMemberIds(long raidId) { return (from m in Raid(raidId)?.Squads.SelectMany((PartyView s) => s.Members) select m.Account).ToList() ?? new List<string>(); } public string GetRaidJson(long raidId) { RaidView raidView = Raid(raidId); if (raidView == null) { return ""; } JsonOut jsonOut = new JsonOut().Object().Field("id", raidView.Id).Field("leaderId", raidView.Leader) .Array("squads"); foreach (PartyView squad in raidView.Squads) { PartyJson(jsonOut, squad); } return jsonOut.End().End().ToString(); } private static JsonOut PartyJson(JsonOut json, PartyView party) { json.Object().Field("id", party.Id).Field("leaderId", party.Leader) .Field("raidId", party.RaidId) .Field("squad", party.Squad) .Array("members"); foreach (PartyMemberView member in party.Members) { json.Object().Field("id", member.Account).Field("name", member.Name) .Field("leader", member.Account == party.Leader) .Field("online", member.Online) .Field("clanId", member.ClanId) .End(); } return json.End().End(); } public string GetStorageJson(long clanId) { StorageContents storageContents = Storage(clanId); if (storageContents != null) { return StorageJson(storageContents); } return ""; } public int CountStorageItem(long clanId, string prefab) { StorageContents storageContents = Storage(clanId); if (storageContents == null) { return -1; } long num = 0L; foreach (StorageContents.Item item in storageContents.Items) { if (item.Prefab == prefab) { num += item.Stack; } } return (int)Math.Min(2147483647L, num); } public void RequestStorageJson(Action<bool, string> callback) { if (callback == null) { return; } if (!ClanClient.Welcomed) { callback(arg1: false, "notReady"); return; } ClanRequests.Send(Op.ReadStorage, delegate { }, delegate(NetResult result) { if (result.Ok) { callback(arg1: true, StorageJson(StorageContents.Read(result.Extra))); } else { callback(arg1: false, RequestError(result)); } }); } private static string RequestError(NetResult result) { if (result.TimedOut) { return "timeout"; } return result.Token switch { "$clans_err_not_in_clan" => "notInClan", "$clans_err_no_permission" => "noPermission", "$clans_err_storage_off" => "storageOff", "$clans_err_no_server" => "noServer", _ => result.Token.TrimStart(new char[1] { '$' }), }; } private static string StorageJson(StorageContents contents) { JsonOut jsonOut = new JsonOut().Object().Field("clan", contents.ClanId).Array("tabs"); for (int i = 0; i < contents.OpenBy.Count; i++) { jsonOut.Object().Field("index", i).Field("openBy", contents.OpenBy[i]) .Array("items"); foreach (StorageContents.Item item in contents.Items) { if (item.Tab == i) { jsonOut.Object().Field("prefab", item.Prefab).Field("stack", item.Stack) .Field("quality", item.Quality) .Field("x", item.X) .Field("y", item.Y) .Field("custom", item.Custom) .End(); } } jsonOut.End().End(); } return jsonOut.End().End().ToString(); } public void AddChangedListener(Action listener) { ApiEvents.AddChanged(listener); } public void RemoveChangedListener(Action listener) { ApiEvents.RemoveChanged(listener); } public void AddServerEventListener(Action<string> listener) { ApiEvents.AddServer(listener); } public void RemoveServerEventListener(Action<string> listener) { ApiEvents.RemoveServer(listener); } internal static string Localize(string text) { if (string.IsNullOrEmpty(text)) { return ""; } if (Localization.instance == null) { return text; } return Localization.instance.Localize(text); } protected static int IndexOf(List<RankDef> ranks, int rankId) { for (int i = 0; i < ranks.Count; i++) { if (ranks[i].Id == rankId) { return i; } } return ranks.Count - 1; } protected static bool Rank(long clanId, int rankId, List<RankDef> ranks, out RankInfo rank) { int num = IndexOf(ranks, rankId); rank = new RankInfo { ClanId = clanId, Id = rankId, Index = num, StoredName = ((num >= 0) ? (ranks[num].Name ?? "") : "") }; return num >= 0; } } internal sealed class ClanView { internal long Id; internal string Name = ""; internal string Description = ""; internal int Level; internal int MemberCount; internal bool Recruiting; internal string LeaderAccount = ""; internal string LeaderName = ""; internal bool Detail; internal long Xp = -1L; internal long Treasury = -1L; internal int SharedTabs = -1; } internal sealed class MemberView { internal string Account = ""; internal string Name = ""; internal int RankId; internal int RankIndex = -1; internal string RankName = ""; internal bool Online; internal long JoinedUtc; internal long LastSeenUtc; } internal struct RankInfo { internal long ClanId; internal int Id; internal int Index; internal string StoredName; } internal struct PartyInfo { internal long PartyId; internal long RaidId; internal int Squad; } internal sealed class PartyMemberView { internal string Account = ""; internal string Name = ""; internal bool Online; internal long ClanId; } internal sealed class PartyView { internal long Id; internal string Leader = ""; internal long RaidId; internal int Squad; internal List<PartyMemberView> Members = new List<PartyMemberView>(); } internal sealed class RaidView { internal long Id; internal string Leader = ""; internal List<PartyView> Squads = new List<PartyView>(); } internal sealed class ClientReceiver : ApiReceiver { private const string NotServer = "notServer"; public override bool IsReady() { return ClanClient.Welcomed; } public override bool HasFullData() { return false; } public override string GetAccountId(Player player) { if ((Object)(object)player == (Object)null) { return ""; } if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { return GetLocalAccountId(); } return PlayerMap.AccountOf(player) ?? ""; } public override string GetAccountIdOfPeer(long peerId) { return PlayerMap.AccountOfPeer(peerId) ?? ""; } public override string GetAccountIdOfPlayerId(long playerId) { //IL_0084: 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_008b: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if (playerId == 0L) { return ""; } foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null && allPlayer.GetPlayerID() == playerId) { return GetAccountId(allPlayer); } } if ((Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null) { return ""; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { ZDOID characterID = player.m_characterID; if (!((ZDOID)(ref characterID)).IsNone()) { ZDO zDO = ZDOMan.instance.GetZDO(player.m_characterID); if (zDO != null && zDO.GetLong(ZDOVars.s_playerID, 0L) == playerId) { return AccountId.ForPlayerInfo(player); } } } return ""; } public override string GetPlayerName(string accountId) { if (string.IsNullOrEmpty(accountId)) { return ""; } RosterEntry rosterEntry = ClanClient.RosterOf(accountId); if (rosterEntry != null) { return rosterEntry.Name; } global::Clans.Net.MemberInfo memberInfo = OwnClanMember(accountId); if (memberInfo != null) { return memberInfo.Name; } int squadIndex; return OwnPartyMember(accountId, out squadIndex)?.Name ?? ""; } public override bool IsOnline(string accountId) { if (!string.IsNullOrEmpty(accountId)) { return ClanClient.RosterOf(accountId) != null; } return false; } public override List<long> GetClanIds() { return new List<long>(ClanClient.Clans.Keys); } public override bool ClanExists(long clanId) { return ClanClient.Clan(clanId) != null; } public override string GetClanName(long clanId) { return ClanClient.Clan(clanId)?.Name ?? ""; } public override long FindClanByName(string name) { if (string.IsNullOrEmpty(name)) { return 0L; } string text = ClanRules.NameKey(name); foreach (ClanSummary value in ClanClient.Clans.Values) { if (ClanRules.NameKey(value.Name) == text) { return value.Id; } } return 0L; } public override int GetClanLevel(long clanId) { return ClanClient.Clan(clanId)?.Level ?? 0; } public override bool AreAtWar(long clanA, long clanB) { return ClanClient.ActiveWar(clanA, clanB) != null; } protected override List<long> Enemies(long clanId) { List<long> list = new List<long>(); foreach (WarSummary war in ClanClient.Wars) { if (war.State == WarState.Active && war.Involves(clanId)) { list.Add(war.Other(clanId)); } } return list; } protected override ClanView Clan(long clanId) { ClanSummary clanSummary = ClanClient.Clan(clanId); if (clanSummary == null) { return null; } ClanView clanView = new ClanView { Id = clanSummary.Id, Name = (clanSummary.Name ?? ""), Description = (clanSummary.Description ?? ""), Level = clanSummary.Level, MemberCount = clanSummary.MemberCount, Recruiting = clanSummary.Recruiting, LeaderAccount = (clanSummary.LeaderAccount ?? ""), LeaderName = (clanSummary.LeaderName ?? "") }; ClanDetailInfo clanDetailInfo = OwnClan(clanId); if (clanDetailInfo != null) { clanView.Detail = true; clanView.Xp = clanDetailInfo.Xp; clanView.Treasury = clanDetailInfo.Treasury; clanView.SharedTabs = clanDetailInfo.SharedTabs; } return clanView; } public override long GetClanIdOf(string accountId) { if (string.IsNullOrEmpty(accountId)) { return 0L; } if (accountId == ClanClient.MyAccount) { return ClanClient.Me.ClanId; } RosterEntry rosterEntry = ClanClient.RosterOf(accountId); if (rosterEntry != null) { return rosterEntry.ClanId; } if (OwnClanMember(accountId) == null) { return 0L; } return ClanClient.MyClan.Id; } protected override bool TryRank(string accountId, out RankInfo rank) { global::Clans.Net.MemberInfo memberInfo = OwnClanMember(accountId); if (memberInfo != null) { return ApiReceiver.Rank(ClanClient.MyClan.Id, memberInfo.RankId, ClanClient.MyClan.Ranks, out rank); } RosterEntry rosterEntry = ClanClient.RosterOf(accountId); if (rosterEntry == null || rosterEntry.ClanId == 0L || rosterEntry.RankIndex < 0) { rank = default(RankInfo); return false; } rank = new RankInfo { ClanId = rosterEntry.ClanId, Id = rosterEntry.RankId, Index = rosterEntry.RankIndex, StoredName = (rosterEntry.RankName ?? "") }; return true; } protected override List<MemberView> Members(long clanId) { List<MemberView> list = new List<MemberView>(); if (clanId == 0L) { return list; } ClanDetailInfo clanDetailInfo = OwnClan(clanId); if (clanDetailInfo != null) { foreach (global::Clans.Net.MemberInfo member in clanDetailInfo.Members) { ApiReceiver.Rank(clanDetailInfo.Id, member.RankId, clanDetailInfo.Ranks, out var rank); list.Add(new MemberView { Account = member.Account, Name = (member.Name ?? ""), RankId = rank.Id, RankIndex = rank.Index, RankName = rank.StoredName, Online = (ClanClient.RosterOf(member.Account) != null), JoinedUtc = member.JoinedUtc, LastSeenUtc = member.LastSeenUtc }); } return list; } foreach (RosterEntry value in ClanClient.Roster.Values) { if (value.ClanId == clanId) { list.Add(new MemberView { Account = value.Account, Name = (value.Name ?? ""), RankId = value.RankId, RankIndex = value.RankIndex, RankName = (value.RankName ?? ""), Online = true }); } } return list; } public override List<string> GetOnlineMemberIds(long clanId) { List<string> list = new List<string>(); if (clanId == 0L) { return list; } foreach (RosterEntry value in ClanClient.Roster.Values) { if (value.ClanId == clanId) { list.Add(value.Account); } } return list; } protected override List<RankDef> Ranks(long clanId) { return OwnClan(clanId)?.Ranks; } protected override ClanPermission Permissions(string accountId) { if (string.IsNullOrEmpty(accountId)) { return ClanPermission.None; } if (accountId == ClanClient.MyAccount) { return ClanClient.Me.Permissions; } global::Clans.Net.MemberInfo memberInfo = OwnClanMember(accountId); if (memberInfo == null) { return ClanPermission.None; } List<RankDef> ranks = ClanClient.MyClan.Ranks; int num = ApiReceiver.IndexOf(ranks, memberInfo.RankId); return ClanPermissions.Effective(num, (num >= 0) ? ranks[num].Permissions : ClanPermission.None); } protected override bool TryParty(string accountId, out PartyInfo party) { party = default(PartyInfo); if (string.IsNullOrEmpty(accountId)) { return false; } if (OwnPartyMember(accountId, out var squadIndex) != null) { PartyClient.Squad squad = PartyClient.Squads[squadIndex]; party = new PartyInfo { PartyId = squad.PartyId, RaidId = PartyClient.RaidId, Squad = (PartyClient.InRaid ? (squadIndex + 1) : 0) }; return true; } RosterEntry rosterEntry = ClanClient.RosterOf(accountId); if (rosterEntry == null || rosterEntry.PartyId == 0L) { return false; } party = new PartyInfo { PartyId = rosterEntry.PartyId, RaidId = rosterEntry.RaidId, Squad = rosterEntry.Squad }; return true; } protected override PartyView Party(long partyId) { if (partyId == 0L) { return null; } int num = PartyClient.Squads.FindIndex((PartyClient.Squad s) => s.PartyId == partyId); if (num >= 0) { return OwnSquadView(num); } PartyView partyView = null; foreach (RosterEntry value in ClanClient.Roster.Values) { if (value.PartyId == partyId) { if (partyView == null) { partyView = new PartyView { Id = partyId, RaidId = value.RaidId, Squad = value.Squad }; } if (value.PartyLeader) { partyView.Leader = value.Account; } partyView.Members.Add(RosterMember(value)); } } return partyView; } protected override RaidView Raid(long raidId) { if (raidId == 0L) { return null; } if (PartyClient.RaidId == raidId) { RaidView raidView = new RaidView { Id = raidId, Leader = (PartyClient.RaidLeader ?? "") }; for (int i = 0; i < PartyClient.Squads.Count; i++) { raidView.Squads.Add(OwnSquadView(i)); } return raidView; } RaidView raidView2 = null; SortedDictionary<int, PartyView> sortedDictionary = new SortedDictionary<int, PartyView>(); foreach (RosterEntry value2 in ClanClient.Roster.Values) { if (value2.RaidId == raidId) { if (raidView2 == null) { raidView2 = new RaidView { Id = raidId }; } if (value2.RaidLeader) { raidView2.Leader = value2.Account; } if (!sortedDictionary.TryGetValue(value2.Squad, out var value)) { value = new PartyView { Id = value2.PartyId, RaidId = raidId, Squad = value2.Squad }; sortedDictionary[value2.Squad] = value; } if (value2.PartyLeader) { value.Leader = value2.Account; } value.Members.Add(RosterMember(value2)); } } raidView2?.Squads.AddRange(sortedDictionary.Values); return raidView2; } private static PartyView OwnSquadView(int index) { PartyClient.Squad squad = PartyClient.Squads[index]; PartyView partyView = new PartyView { Id = squad.PartyId, Leader = (squad.Leader ?? ""), RaidId = PartyClient.RaidId, Squad = (PartyClient.InRaid ? (index + 1) : 0) }; foreach (PartyClient.Member member in squad.Members) { partyView.Members.Add(new PartyMemberView { Account = member.Account, Name = (member.Name ?? ""), Online = member.Online, ClanId = member.ClanId }); } return partyView; } private static PartyMemberView RosterMember(RosterEntry entry) { return new PartyMemberView { Account = entry.Account, Name = (entry.Name ?? ""), Online = true, ClanId = entry.ClanId }; } public override long GetTreasury(long clanId) { return OwnClan(clanId)?.Treasury ?? (-1); } public override int GetSharedTabCount(long clanId) { return OwnClan(clanId)?.SharedTabs ?? (-1); } protected override StorageContents Storage(long clanId) { return null; } public override bool AddTreasury(long clanId, long coins, string reason) { return false; } public override bool TakeTreasury(long clanId, long coins, string reason) { return false; } public override bool TakeStorageItems(long clanId, string itemsJson, string reason, out string error) { error = "notServer"; return false; } public override bool AddStorageItems(long clanId, string itemsJson, string reason, out string error) { error = "notServer"; return false; } public override bool AddStorageItem(long clanId, ItemData item, string reason, out string error) { error = "notServer"; return false; } private static ClanDetailInfo OwnClan(long clanId) { ClanDetailInfo myClan = ClanClient.MyClan; if (myClan == null || myClan.Id != clanId || clanId == 0L) { return null; } return myClan; } private static global::Clans.Net.MemberInfo OwnClanMember(string accountId) { ClanDetailInfo myClan = ClanClient.MyClan; if (myClan == null) { return null; } foreach (global::Clans.Net.MemberInfo member in myClan.Members) { if (member.Account == accountId) { return member; } } return null; } private static PartyClient.Member OwnPartyMember(string accountId, out int squadIndex) { for (squadIndex = 0; squadIndex < PartyClient.Squads.Count; squadIndex++) { foreach (PartyClient.Member member in PartyClient.Squads[squadIndex].Members) { if (member.Account == accountId) { return member; } } } squadIndex = -1; return null; } } internal interface IApiReceiver { bool IsReady(); bool HasFullData(); string GetLocalAccountId(); string GetAccountId(Player player); string GetAccountIdOfPeer(long peerId); string GetAccountIdOfPlayerId(long playerId); string GetPlayerName(string accountId); bool IsOnline(string accountId); List<long> GetClanIds(); bool ClanExists(long clanId); string GetClanName(long clanId); long FindClanByName(string name); int GetClanLevel(long clanId); int GetMaxClanLevel(); int GetMemberCount(long clanId); string GetLeaderId(long clanId); bool AreAtWar(long clanA, long clanB); string GetClanJson(long clanId); string GetClansJson(); long GetClanIdOf(string accountId); long GetClanIdOfPlayer(Player player); bool IsInClan(string accountId); bool AreClanmates(string accountA, string accountB); List<string> GetMemberIds(long clanId); List<string> GetOnlineMemberIds(long clanId); string GetMembersJson(long clanId); int GetRankIndex(string accountId); int GetRankId(string accountId); string GetRankName(string accountId); bool IsLeader(string accountId); bool HasPermission(string accountId, string permission); List<string> GetPermissionNames(); string GetRanksJson(long clanId); long GetPartyId(string accountId); bool ArePartymates(string accountA, string accountB); string GetPartyLeaderId(long partyId); List<string> GetPartyMemberIds(long partyId); string GetPartyJson(long partyId); long GetRaidId(string accountId); int GetSquad(string accountId); bool AreRaidmates(string accountA, string accountB); string GetRaidLeaderId(long raidId); List<string> GetRaidMemberIds(long raidId); string GetRaidJson(long raidId); long GetTreasury(long clanId); bool AddTreasury(long clanId, long coins, string reason); bool TakeTreasury(long clanId, long coins, string reason); int GetSharedTabCount(long clanId); string GetStorageJson(long clanId); int CountStorageItem(long clanId, string prefab); void RequestStorageJson(Action<bool, string> callback); bool TakeStorageItems(long clanId, string itemsJson, string reason, out string error); bool AddStorageItems(long clanId, string itemsJson, string reason, out string error); bool AddStorageItem(long clanId, ItemData item, string reason, out string error); void AddChangedListener(Action listener); void RemoveChangedListener(Action listener); void AddServerEventListener(Action<string> listener); void RemoveServerEventListener(Action<string> listener); } internal sealed class JsonOut { private readonly StringBuilder text = new StringBuilder(); private readonly Stack<char> closers = new Stack<char>(); private bool first = true; internal JsonOut Object() { Next(); return Open('{', '}'); } internal JsonOut Object(string key) { Name(key); return Open('{', '}'); } internal JsonOut Array() { Next(); return Open('[', ']'); } internal JsonOut Array(string key) { Name(key); return Open('[', ']'); } internal JsonOut End() { text.Append(closers.Pop()); first = false; return this; } internal JsonOut Field(string key, string value) { Name(key); Quote(value); return this; } internal JsonOut Field(string key, long value) { Name(key); text.Append(value.ToString(CultureInfo.InvariantCulture)); return this; } internal JsonOut Field(string key, bool value) { Name(key); text.Append(value ? "true" : "false"); return this; } internal JsonOut Value(string value) { Next(); Quote(value); return this; } internal JsonOut Value(long value) { Next(); text.Append(value.ToString(CultureInfo.InvariantCulture)); return this; } public override string ToString() { return text.ToString(); } private JsonOut Open(char opener, char closer) { text.Append(opener); closers.Push(closer); first = true; return this; } private void Next() { if (!first) { text.Append(','); } first = false; } private void Name(string key) { Next(); Quote(key); text.Append(':'); } private void Quote(string value) { this.text.Append('"'); string text = value ?? ""; foreach (char c in text) { switch (c) { case '"': this.text.Append("\\\""); continue; case '\\': this.text.Append("\\\\"); continue; case '\n': this.text.Append("\\n"); continue; case '\r': this.text.Append("\\r"); continue; case '\t': this.text.Append("\\t"); continue; case '\b': this.text.Append("\\b"); continue; case '\f': this.text.Append("\\f"); continue; } if (c < ' ') { StringBuilder stringBuilder = this.text.Append("\\u"); int num = c; stringBuilder.Append(num.ToString("x4", CultureInfo.InvariantCulture)); } else { this.text.Append