Decompiled source of Skyla v0.7.2
plugins/Skyla.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.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.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using Tyrenheim_Skyla.GUI; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Tyrenheim-Ward")] [assembly: AssemblyDescription("")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyProduct("Tyrenheim-Ward")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6941129c-0802-45bb-b0e2-2a2c7a44bc81")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyCompany("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Tyrenheim_Skyla { public class Assets { [HarmonyPatch(typeof(ObjectDB), "Awake")] public class ObjectDB_Awake_Patch { public static void Postfix(ObjectDB __instance) { LoadAssets(); GameObject[] s_prefabs = Assets.s_prefabs; foreach (GameObject val in s_prefabs) { ItemDrop component = val.GetComponent<ItemDrop>(); if (!((Object)(object)component != (Object)null)) { continue; } __instance.m_items.Add(val); __instance.m_itemByHash.Add(StringExtensionMethods.GetStableHashCode(((Object)val).name), val); if (PerkConfig.s_chimeMap.ContainsKey(component.m_itemData.m_shared.m_name)) { Chime.AddChime(val); Skyla.ChimeType key = PerkConfig.s_chimeMap[component.m_itemData.m_shared.m_name]; if (!PerkConfig.s_chimePrefabMap.ContainsKey(key)) { PerkConfig.s_chimePrefabMap.Add(key, val); } } } Recipe[] s_recipes = Assets.s_recipes; foreach (Recipe item in s_recipes) { __instance.m_recipes.Add(item); } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public class ZNetScene_Awake_Patch { public static bool Prefix(ZNetScene __instance) { LoadAssets(); GameObject[] s_prefabs = Assets.s_prefabs; foreach (GameObject val in s_prefabs) { if ((Object)(object)val.GetComponent<ZNetView>() != (Object)null) { __instance.m_prefabs.Add(val); } } return true; } public static void Postfix(ZNetScene __instance) { s_applyBlessingFXPrefab = __instance.GetPrefab(s_applyBlessingFX); s_activateFXPrefab = __instance.GetPrefab(s_activateFX); s_deactivateFXPrefab = __instance.GetPrefab(s_deactivateFX); } } private static bool assetsLoaded = false; public static string s_resourceName = "skyla"; public static GameObject[] s_prefabs = null; public static Recipe[] s_recipes = null; private static string s_applyBlessingFX = "vfx_skyla_applyblessing"; public static GameObject s_applyBlessingFXPrefab; private static string s_activateFX = "sfx_skyla_activate"; public static GameObject s_activateFXPrefab; private static string s_deactivateFX = "sfx_skyla_deactivate"; public static GameObject s_deactivateFXPrefab; private static AssetBundle GetAssetBundleFromResources(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); return AssetBundle.LoadFromStream(executingAssembly.GetManifestResourceStream(name)); } public static void LoadAssets() { if (!assetsLoaded) { AssetBundle assetBundleFromResources = GetAssetBundleFromResources(s_resourceName); if ((Object)(object)assetBundleFromResources == (Object)null) { Debug.Log((object)("Failed to load AssetBundle " + s_resourceName)); return; } s_prefabs = assetBundleFromResources.LoadAllAssets<GameObject>(); s_recipes = assetBundleFromResources.LoadAllAssets<Recipe>(); Debug.Log((object)$"Loaded {s_prefabs.Count()} prefabs and {s_recipes.Count()} recipes from assetBundle {s_resourceName}"); assetBundleFromResources.Unload(false); SkylaGUI.Init(); assetsLoaded = true; } } } public class Chime : MonoBehaviour { private static AudioSource s_master; private static HashSet<AudioSource> s_sources = new HashSet<AudioSource>(); private AudioSource m_source; public static void AddChime(GameObject prefab) { if ((Object)(object)prefab.GetComponentInChildren<Chime>() == (Object)null) { GameObject val = prefab; Transform val2 = prefab.transform.Find("attach"); if ((Object)(object)val2 != (Object)null) { val = ((Component)val2).gameObject; } val.AddComponent<Chime>(); } } private void Awake() { m_source = ((Component)this).GetComponentInChildren<AudioSource>(); s_sources.Add(m_source); ((Component)this).GetComponentInChildren<ZSFX>().Play(); if ((Object)(object)s_master == (Object)null) { s_master = m_source; } else { m_source.timeSamples = s_master.timeSamples; } } private void OnDestroy() { s_sources.Remove(m_source); s_master = null; using HashSet<AudioSource>.Enumerator enumerator = s_sources.GetEnumerator(); if (enumerator.MoveNext()) { s_master = enumerator.Current; } } } public class WNTFix { [HarmonyPatch(typeof(WearNTear), "Start")] public class WNT_Patch { public static bool Prefix(WearNTear __instance) { CheckHeightMap(__instance); return false; } } public static void CheckHeightMap(WearNTear wnt) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) wnt.m_connectedHeightMap = Heightmap.FindHeightmap(((Component)wnt).transform.position); if ((Object)(object)wnt.m_connectedHeightMap != (Object)null) { wnt.m_connectedHeightMap.m_clearConnectedWearNTearCache += wnt.ClearCachedSupport; } } [HarmonyPatch(typeof(WearNTear), "UpdateSupport")] public static void Prefix(WearNTear __instance) { CheckHeightMap(__instance); } } internal class ParticleMist_Patch { } internal class SE_Rested_Patch { [HarmonyPatch(typeof(SE_Rested), "CalculateComfortLevel", new Type[] { typeof(bool), typeof(Vector3) })] public static class FE_Resteed_CalculateComfortLevel_Patch { public static void Postfix(bool inShelter, Vector3 position, ref int __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(position, Skyla.ChimeType.CHIME_COMFORT)) { __result += 3; } } } } internal class EnvManPatch { [HarmonyPatch(typeof(EnvMan), "GetEnvironmentOverride")] public static class EnvMan_GetEnvironmentOverride_Patch { public static void Postfix(EnvMan __instance, ref string __result) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (__result == null && (Object)(object)Player.m_localPlayer != (Object)null) { switch (Skyla.FindWeatherMode(((Component)Player.m_localPlayer).transform.position)) { case PerkConfig.WeatherMode.WEATHER_SNOW: __result = (EnvMan.IsDay() ? "Snow" : "Twilight_Snow"); break; case PerkConfig.WeatherMode.WEATHER_STORM: __result = "ThunderStorm"; break; case PerkConfig.WeatherMode.WEATHER_SNOWSTORM: __result = (EnvMan.IsDay() ? "SnowStorm" : "Twilight_SnowStorm"); break; case PerkConfig.WeatherMode.WEATHER_MISTLANDS_STORM: __result = "Mistlands_thunder"; break; case PerkConfig.WeatherMode.WEATHER_ASHRAIN: __result = "Ashrain"; break; case PerkConfig.WeatherMode.WEATHER_CLEAR: __result = "Clear"; break; } } } } } internal class PiecePatch { [HarmonyPatch(typeof(Piece), "DropResources")] public static class Piece_DropResources_Patch { public static void Postfix(Piece __instance) { Skyla component = ((Component)__instance).GetComponent<Skyla>(); if ((Object)(object)component != (Object)null) { component.DropResources(); } } } [HarmonyPatch(typeof(Piece), "SetCreator")] public static class Piece_SetCreator_Patch { public static void Postfix(Piece __instance, long uid) { if (Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsValid()) { Skyla component = ((Component)__instance).gameObject.GetComponent<Skyla>(); if ((Object)(object)component != (Object)null) { component.OnPlaced(uid); } } } } } public class PerkConfig { public enum WeatherMode { WEATHER_NONE, WEATHER_SNOW, WEATHER_STORM, WEATHER_SNOWSTORM, WEATHER_MISTLANDS_STORM, WEATHER_ASHRAIN, WEATHER_CLEAR, WEATHER_MAX } public class Farming { public const float c_harvestIncreaseProbability = 0.5f; public const int c_harvestIncrease = 1; public const float c_growTimeFactor = 0.85f; } public class Cooking { public const float c_fuelBurnRateFactor = 0.5f; public const float c_cookingTimeFactor = 0.8f; } public class Comfort { public const int c_comfortBoost = 3; } public class Industry { public const float c_fuelBurnRateFactor = 0.5f; public const float c_bakeRateFactor = 1.2f; } public static Dictionary<string, Skyla.ChimeType> s_chimeMap = new Dictionary<string, Skyla.ChimeType> { { "Chime of Fertility", Skyla.ChimeType.CHIME_FARMING }, { "Chime of the Hearth", Skyla.ChimeType.CHIME_COOKING }, { "Chime of Comfort", Skyla.ChimeType.CHIME_COMFORT }, { "Chime of Industry", Skyla.ChimeType.CHIME_INDUSTRY }, { "Snow Chime", Skyla.ChimeType.CHIME_SNOW }, { "Blizzard Chime", Skyla.ChimeType.CHIME_SNOWSTORM }, { "Chime of Ashes", Skyla.ChimeType.CHIME_ASHRAIN }, { "Storm Chime", Skyla.ChimeType.CHIME_STORM }, { "Tempest Chime", Skyla.ChimeType.CHIME_MISTLANDS_STORM }, { "Balmy Chime", Skyla.ChimeType.CHIME_CLEAR } }; public static Dictionary<Skyla.ChimeType, GameObject> s_chimePrefabMap = new Dictionary<Skyla.ChimeType, GameObject>(); public static Dictionary<Skyla.ChimeType, string> s_powerNameMap = new Dictionary<Skyla.ChimeType, string> { { Skyla.ChimeType.CHIME_FARMING, "Fertility" }, { Skyla.ChimeType.CHIME_COOKING, "Hearth" }, { Skyla.ChimeType.CHIME_COMFORT, "Comfort" }, { Skyla.ChimeType.CHIME_INDUSTRY, "Industry" } }; public static Dictionary<WeatherMode, string> s_weatherNameMap = new Dictionary<WeatherMode, string> { { WeatherMode.WEATHER_NONE, "<none>" }, { WeatherMode.WEATHER_CLEAR, "Clear" }, { WeatherMode.WEATHER_SNOW, "Snow" }, { WeatherMode.WEATHER_STORM, "Storm" }, { WeatherMode.WEATHER_SNOWSTORM, "Blizzard" }, { WeatherMode.WEATHER_MISTLANDS_STORM, "Tempest" }, { WeatherMode.WEATHER_ASHRAIN, "Ashrain" } }; } internal class ArmorStandPatch { [HarmonyPatch(typeof(ArmorStand), "UseItem")] public static class ArmorStand_UseItem_Patch { public static bool Prefix(ItemStand __instance, Switch caller, Humanoid user, ItemData item) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)user, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_ITEMSTAND); } } } internal class CookingStationPatch { [HarmonyPatch(typeof(CookingStation), "UpdateFuel")] public static class CookngStation_UpdateFuel_Patch { public static bool Prefix(CookingStation __instance, ref float dt) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(((Component)__instance).gameObject.transform.position, Skyla.ChimeType.CHIME_COOKING)) { dt *= 0.5f; } return true; } } [HarmonyPatch(typeof(CookingStation), "UpdateCooking")] public static class CookingStation_UpdateCooking_Patch { public static bool Prefix(CookingStation __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!ZNetScene.instance.IsAreaReady(((Component)__instance).transform.position)) { return false; } return true; } } [HarmonyPatch(typeof(CookingStation), "GetSlot")] public static class CookingStation_GetSlot_Patch { public static void Postfix(CookingStation __instance, ref string itemName, ref float cookedTime, ref Status status) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(((Component)__instance).gameObject.transform.position, Skyla.ChimeType.CHIME_COOKING)) { ItemConversion itemConversion = __instance.GetItemConversion(itemName); if (itemConversion != null) { cookedTime = Math.Min(cookedTime, itemConversion.m_cookTime * 1.1f); } } } } [HarmonyPatch(typeof(CookingStation), "SetSlot")] public static class CookingStation_SetSlot_Patch { public static bool Prefix(CookingStation __instance, int slot, ref string itemName, ref float cookedTime, ref Status status) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(((Component)__instance).gameObject.transform.position, Skyla.ChimeType.CHIME_COOKING)) { float @float = __instance.m_nview.GetZDO().GetFloat("slot" + slot, 0f); if (__instance.m_nview.GetZDO().GetInt("slotstatus" + slot, 0) != (int)status && (int)status == 2) { itemName = __instance.m_nview.GetZDO().GetString("slot" + slot, ""); status = (Status)1; } float num = cookedTime - @float; cookedTime = @float + num * 1.25f; } return true; } } } internal class MineRockPatch { [HarmonyPatch(typeof(MineRock), "RPC_Hit")] public static class MineRock_Hit_Patch { public static bool Prefix(MineRock __instance, long sender, ref HitData hit) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || hit == null) { return false; } if ((Object)(object)hit.GetAttacker() == (Object)null || !hit.GetAttacker().IsPlayer()) { float num = 1f - Skyla.FindMaxSkylaPower(((Component)__instance).transform.position); if (num > 0f) { hit.ApplyModifier(num); return true; } return false; } return Skyla.CheckAccess(hit.GetAttacker(), ((Component)__instance).transform.position, Skyla.ActionType.ACTION_DAMAGE); } } [HarmonyPatch(typeof(MineRock5), "RPC_Damage")] public static class MineRock5_Damage_Patch { public static bool Prefix(MineRock5 __instance, long sender, ref HitData hit) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || hit == null) { return false; } if ((Object)(object)hit.GetAttacker() == (Object)null || !hit.GetAttacker().IsPlayer()) { float num = 1f - Skyla.FindMaxSkylaPower(((Component)__instance).transform.position); if (num > 0f) { hit.ApplyModifier(num); return true; } return false; } return Skyla.CheckAccess(hit.GetAttacker(), ((Component)__instance).transform.position, Skyla.ActionType.ACTION_DAMAGE); } } } internal class SpawnerPatches { [HarmonyPatch(typeof(CreatureSpawner), "Spawn")] public static class CreatureSpawner_Spawn_Patch { public static bool Prefix(CreatureSpawner __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.FindMaxSkylaPower(((Component)__instance).transform.position) < 0.99f; } } [HarmonyPatch(typeof(SpawnArea), "SpawnOne")] public static class SpawnArea_SpawnOne_Patch { public static bool Prefix(SpawnArea __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.FindMaxSkylaPower(((Component)__instance).transform.position) < 0.99f; } } [HarmonyPatch(typeof(SpawnSystem), "UpdateSpawning")] public static class SpawnSystem_UpdateSpawning_Patch { public static bool Prefix(SpawnSystem __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.FindMaxSkylaPower(((Component)__instance).transform.position) < 0.99f; } } } internal class PlantPatch { [HarmonyPatch(typeof(Plant), "Grow")] public static class Plant_Grow_Patch { public static void Postfix(Plant __instance, ref GameObject __result) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__result == (Object)null) { return; } ZNetView component = __result.GetComponent<ZNetView>(); if ((Object)(object)__result.GetComponent<Pickable>() != (Object)null && (Object)(object)component != (Object)null) { component.GetZDO().Set("ProtectedPickable", true); if (Skyla.ChimeApplies(((Component)__instance).gameObject.transform.position, Skyla.ChimeType.CHIME_FARMING) && Random.value < 0.5f) { component.GetZDO().Set("HarvestAmountOverride", 1); } } } } [HarmonyPatch(typeof(Plant), "GetGrowTime")] public static class Plant_GetGrowTime_Patch { public static void Postfix(Plant __instance, ref float __result) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(((Component)__instance).gameObject.transform.position, Skyla.ChimeType.CHIME_FARMING)) { __result *= 0.85f; } } } } internal class TreeBasePatch { [HarmonyPatch(typeof(TreeBase), "RPC_Damage")] public static class TreeBase_Damage_Patch { public static bool Prefix(TreeBase __instance, long sender, ref HitData hit) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || hit == null) { return false; } if ((Object)(object)hit.GetAttacker() == (Object)null || !hit.GetAttacker().IsPlayer()) { float num = 1f - Skyla.FindMaxSkylaPower(((Component)__instance).transform.position); if (num > 0f) { hit.ApplyModifier(num); return true; } return false; } return Skyla.CheckAccess(hit.GetAttacker(), ((Component)__instance).transform.position, Skyla.ActionType.ACTION_DAMAGE); } } } internal class TeleporWorld { [HarmonyPatch(typeof(TeleportWorld), "Interact")] public static class TeleportWorld_Interact_Patch { public static bool Prefix(TeleportWorld __instance, Humanoid human, bool hold, bool alt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)human, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_PORTAL); } } } internal class SmelterPatch { [HarmonyPatch(typeof(Smelter), "Spawn")] public static class Smelter_Spawn_Patch { public static bool Prefix(Smelter __instance, string ore, int stack) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } ItemConversion itemConversion = __instance.GetItemConversion(ore); if (itemConversion != null) { __instance.m_produceEffects.Create(((Component)__instance).gameObject.transform.position, ((Component)__instance).gameObject.transform.rotation, (Transform)null, 1f, -1); GameObject obj = Object.Instantiate<GameObject>(((Component)itemConversion.m_to).gameObject, __instance.m_outputPoint.position, __instance.m_outputPoint.rotation); obj.GetComponent<ItemDrop>().m_itemData.m_stack = stack; obj.GetComponent<ZNetView>().GetZDO().Set("ProtectedItem", true); } return false; } } [HarmonyPatch(typeof(Smelter), "SetFuel")] public static class Smelter_SetFuel_Patch { public static bool Prefix(Smelter __instance, ref float __state) { __state = __instance.GetFuel(); return true; } public static void Postfix(Smelter __instance, float __state) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(((Component)__instance).transform.position, Skyla.ChimeType.CHIME_INDUSTRY)) { float fuel = __instance.GetFuel(); float num = fuel - __state; if (num < 0f) { float fuel2 = fuel - num * 0.5f; __instance.SetFuel(fuel2); } } } } [HarmonyPatch(typeof(Smelter), "SetBakeTimer")] public static class Smelter_SetBakeTimer_Patch { public static bool Prefix(Smelter __instance, ref float __state) { __state = __instance.GetBakeTimer(); return true; } public static void Postfix(Smelter __instance, float __state) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (Skyla.ChimeApplies(((Component)__instance).transform.position, Skyla.ChimeType.CHIME_INDUSTRY)) { float num = __instance.GetBakeTimer() - __state; if (num > 0f) { float bakeTimer = __state + num * 1.2f; __instance.SetBakeTimer(bakeTimer); } } } } } internal class SignPatch { [HarmonyPatch(typeof(Sign), "Interact")] public static class Sign_Interact_Patch { public static bool Prefix(Sign __instance, Humanoid character, bool hold, bool alt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)character, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_SIGN); } } } internal class ItemStandPatch { [HarmonyPatch(typeof(ItemStand), "Interact")] public static class ItemStand_Interact_Patch { public static bool Prefix(ItemStand __instance, Humanoid user, bool hold, bool alt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)user, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_ITEMSTAND); } } [HarmonyPatch(typeof(ItemStand), "UseItem")] public static class ItemStand_UseItem_Patch { public static bool Prefix(ItemStand __instance, Humanoid user, ItemData item) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)user, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_ITEMSTAND); } } } public class SkylaConfig { public static ConfigEntry<float> s_totalSkylaAreaLimit; public static ConfigEntry<float> s_maxSingleSkylaRadius; public static ConfigEntry<int> s_skylaPowerUpTime; public static void SetupConfig(Mod instance) { s_totalSkylaAreaLimit = instance.SyncedConfig("Config", "TotalPlayerAreaLimit", 9600f, "The total area (in m²) that any individual player may have covered by their Skýla (active or otherwise)."); s_maxSingleSkylaRadius = instance.SyncedConfig("Config", "WardMaxRadius", 32f, "The maximum radius (in m) that any single Skýla may have."); s_skylaPowerUpTime = instance.SyncedConfig("Config", "PowerUpTime", 3600, "The time (in seconds) taken for a Skýla to reach full power. Valheim's normal day/night cycle lasts 1800 seconds (30 minutes)"); } public static float TotalAreaLimit() { return s_totalSkylaAreaLimit.Value; } public static float MaxSkylaRadius() { return s_maxSingleSkylaRadius.Value; } public static int PowerUpTimeSecs() { return s_skylaPowerUpTime.Value; } } public class LocalManager { private static ISet<ZDOID> s_localPlayerSkylaSet = new HashSet<ZDOID>(); private static float s_localPlayerSkylaAreaLimit = 0f; private static bool s_hasReceivedInfo = false; public static void RegisterRPC() { ZRoutedRpc.instance.Register<float, ZPackage>("ReceiveServerSkylaData", (Action<long, float, ZPackage>)RPC_ReceiveServerSkylaData); } private static void OutputLocalState() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"=================================="); Debug.Log((object)"Dumping out local Skyla info:"); float num = 0f; foreach (ZDOID item in s_localPlayerSkylaSet) { float @float = ZDOMan.instance.GetZDO(item).GetFloat("SkylaRadius", 0f); Debug.Log((object)$"ZDOID {item}, Radius: {@float}"); num += (float)Math.PI * @float * @float; } Debug.Log((object)$"Total area used: {num}"); Debug.Log((object)"=================================="); } private static ISet<ZDOID> Decode(ZPackage zp) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) ISet<ZDOID> set = new HashSet<ZDOID>(); int num = zp.ReadInt(); for (int i = 0; i < num; i++) { ZDOID item = zp.ReadZDOID(); set.Add(item); } return set; } private static float GetLocalPlayerAreaLimit() { return s_localPlayerSkylaAreaLimit; } private static void RPC_ReceiveServerSkylaData(long sender, float maxWardedArea, ZPackage zp) { if (!float.IsNaN(maxWardedArea)) { s_localPlayerSkylaAreaLimit = maxWardedArea; } s_localPlayerSkylaSet = Decode(zp); s_hasReceivedInfo = true; } private static float GetUsedArea() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) float num = 0f; foreach (ZDOID item in s_localPlayerSkylaSet) { ZDO zDO = ZDOMan.instance.GetZDO(item); float num2 = ((zDO != null) ? zDO.GetFloat("SkylaRadius", 0f) : 0f); num += (float)Math.PI * num2 * num2; } return num; } public static float GetRemainingArea() { return Math.Max(GetLocalPlayerAreaLimit() - GetUsedArea(), 0f); } private static float DistanceToNearestBlockingSkyla(Skyla skyla) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) float val = 9999f; foreach (Skyla s_localSkyla in Skyla.s_localSkylaList) { if (s_localSkyla.GetOwner() != skyla.GetOwner()) { float val2 = Vector3.Distance(((Component)s_localSkyla).transform.position, ((Component)skyla).transform.position) - s_localSkyla.GetRadius(); val = Math.Min(val, val2); } } return Math.Max(val, 0f); } private static float DistanceToNearestNoBuildZone(Skyla skyla) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) float val = 9999f; foreach (Location s_allLocation in Location.s_allLocations) { if (s_allLocation.m_noBuild && s_allLocation.m_exteriorRadius > 0f) { float val2 = Vector3.Distance(((Component)s_allLocation).transform.position, ((Component)skyla).transform.position) - s_allLocation.m_exteriorRadius; val = Math.Min(val, val2); } } return Math.Max(val, 0f); } public static float GetMaxRadiusForSkyla(Skyla skyla) { float remainingArea = GetRemainingArea(); float radius = skyla.GetRadius(); remainingArea += (float)Math.PI * radius * radius; return Math.Min(DistanceToNearestBlockingSkyla(skyla), Math.Min(SkylaConfig.MaxSkylaRadius(), Math.Min(DistanceToNearestNoBuildZone(skyla), (float)Math.Sqrt(remainingArea / (float)Math.PI)))); } private static void Local_RegisterSkyla(ZDO skylaZDO) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer != (Object)null && skylaZDO.GetLong("creator", 0L) == Player.m_localPlayer.GetPlayerID()) { s_localPlayerSkylaSet.Add(skylaZDO.m_uid); } } private static void Local_UnregisterSkyla(ZDO skylaZDO) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (skylaZDO.GetLong("creator", 0L) == Player.m_localPlayer.GetPlayerID()) { s_localPlayerSkylaSet.Remove(skylaZDO.m_uid); } } public static void RemoveSkyla(ZDO skylaZDO) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) Local_UnregisterSkyla(skylaZDO); ZRoutedRpc.instance.InvokeRoutedRPC("UnregisterSkyla", new object[1] { skylaZDO.m_uid }); } public static void AddSkyla(ZDO skylaZDO) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) Local_RegisterSkyla(skylaZDO); ZRoutedRpc.instance.InvokeRoutedRPC("RegisterSkyla", new object[1] { skylaZDO.m_uid }); } public static void RequestInfo(long playerID) { ZRoutedRpc.instance.InvokeRoutedRPC("RequestInfo", new object[1] { playerID }); } } public class ServerManager { private static bool s_initialized = false; private static Dictionary<long, HashSet<ZDO>> s_playerSkylaMap = new Dictionary<long, HashSet<ZDO>>(); private static Dictionary<string, float> s_playerMaxTotalArea = new Dictionary<string, float>(); private static string s_vipPlayerFileName = "skyla_area_overrides.txt"; public static void Initialize() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) List<ZDO> list = new List<ZDO>(); if (!ZNet.instance.IsServer() || s_initialized) { return; } int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(Skyla.s_prefabName, list, ref num)) { } foreach (ZDO item in list) { long @long = item.GetLong("creator", 0L); if (float.IsNaN(item.GetFloat("SkylaRadius", 0f))) { Debug.Log((object)$"Skyla ServerManager :: Fixing NaN Skyla at {item.GetPosition()}"); item.Set("SkylaRadius", 0f); } RegisterSkyla(@long, item); } Debug.Log((object)string.Format("SkylaManager::Initialize - found {0} {1} ZDOs", list.Count, "Skýla")); LoadSpecialPlayerList(); s_initialized = true; } public static void LoadSpecialPlayerList() { Debug.Log((object)"SkylaManager :: Loading Player Override List"); string path = Path.Combine(Paths.ConfigPath, s_vipPlayerFileName); Dictionary<string, float> dictionary = new Dictionary<string, float>(); if (!File.Exists(path)) { return; } try { string[] array = File.ReadAllLines(path); foreach (string text in array) { if (text.StartsWith("//")) { continue; } string[] array2 = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { try { string key = array2[0]; float val = float.Parse(array2[1]); dictionary.Add(key, Math.Max(0f, val)); } catch { } } } } catch { return; } s_playerMaxTotalArea = dictionary; } public static void RegisterRPC() { ZRoutedRpc.instance.Register<ZDOID>("RegisterSkyla", (Action<long, ZDOID>)RPC_RegisterSkyla); ZRoutedRpc.instance.Register<ZDOID>("UnregisterSkyla", (Action<long, ZDOID>)RPC_UnregisterSkyla); ZRoutedRpc.instance.Register<long>("RequestInfo", (Action<long, long>)RPC_RequestInfo); } private static float GetMaxAreaForPlayer(string steamID) { if (s_playerMaxTotalArea.ContainsKey(steamID)) { return s_playerMaxTotalArea[steamID]; } return SkylaConfig.TotalAreaLimit(); } private static string GetSteamIDForPeer(long sender) { ZNetPeer peer = ZNet.instance.GetPeer(sender); string text = "<unknown>"; if (peer != null) { text = peer.m_socket.GetHostName(); Debug.Log((object)("SkylaManager :: Finding SteamID for player " + peer.m_playerName + " :: got " + text)); } if (!text.StartsWith("Steam_")) { return text; } return text.Substring(6); } private static void RPC_RequestInfo(long sender, long playerID) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (s_playerSkylaMap.ContainsKey(playerID)) { _ = s_playerSkylaMap[playerID].Count; } Initialize(); LoadSpecialPlayerList(); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "ReceiveServerSkylaData", new object[2] { GetMaxAreaForPlayer(GetSteamIDForPeer(sender)), EncodeWards(playerID) }); if (!s_playerSkylaMap.ContainsKey(playerID)) { return; } foreach (ZDO item in s_playerSkylaMap[playerID]) { ZDOMan.instance.ForceSendZDO(sender, item.m_uid); } } private static ZPackage EncodeWards(long playerID) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); if (s_playerSkylaMap.ContainsKey(playerID)) { Debug.Log((object)string.Format("SkylaManager :: Encoding data of {0} {1} for playerID {2}", s_playerSkylaMap[playerID].Count, "Skýla", playerID)); val.Write(s_playerSkylaMap[playerID].Count); foreach (ZDO item in s_playerSkylaMap[playerID]) { val.Write(item.m_uid); } } else { val.Write(0); } return val; } private static float GetUsedArea(long playerID) { float num = 0f; if (s_playerSkylaMap.ContainsKey(playerID)) { foreach (ZDO item in s_playerSkylaMap[playerID]) { float @float = item.GetFloat("SkylaRadius", 0f); num += (float)Math.PI * @float * @float; } } return num; } private static float GetRemainingAreaBudget(long playerID) { return SkylaConfig.TotalAreaLimit() - GetUsedArea(playerID); } private static void RegisterSkyla(long playerID, ZDO ward) { if (!s_playerSkylaMap.ContainsKey(playerID)) { s_playerSkylaMap.Add(playerID, new HashSet<ZDO>()); } s_playerSkylaMap[playerID].Add(ward); } private static void RPC_RegisterSkyla(long sender, ZDOID ward) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(ward); if (zDO != null) { RegisterSkyla(zDO.GetLong("creator", 0L), zDO); } } private static void UnregisterSkyla(long playerID, ZDO ward) { if (s_playerSkylaMap.ContainsKey(playerID)) { s_playerSkylaMap[playerID].Remove(ward); } } private static void RPC_UnregisterSkyla(long sender, ZDOID ward) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(ward); if (zDO != null) { UnregisterSkyla(zDO.GetLong("creator", 0L), zDO); } } } internal class BeehivePatch { [HarmonyPatch(typeof(Beehive), "Interact")] public static class Beehive_Interact_Patch { public static bool Prefix(Beehive __instance, Humanoid character, bool repeat, bool alt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)character, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_BEEHIVE); } } } public class PlayerPatch { [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Player_OnSpawned_Patch { public static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { LocalManager.RequestInfo(Player.m_localPlayer.GetPlayerID()); } } } [HarmonyPatch(typeof(Player), "OnRespawn")] public static class Player_OnRespawn_Patch { public static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { LocalManager.RequestInfo(Player.m_localPlayer.GetPlayerID()); } } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] public static class Player_CheckCanRemovePiece_Patch { public static bool Prefix(Player __instance, Piece piece) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)((Component)piece).gameObject.GetComponent<Vagon>() != (Object)null) { return Skyla.CanUseWagon(((Component)piece).gameObject.GetComponent<Vagon>(), (Character)(object)__instance); } if ((Object)(object)((Component)piece).gameObject.GetComponent<Ship>() != (Object)null) { return Skyla.CanUseShip(((Component)piece).gameObject.GetComponent<Ship>(), (Character)(object)__instance); } if ((Object)(object)((Component)piece).gameObject.GetComponent<Skyla>() != (Object)null) { return ((Component)piece).gameObject.GetComponent<Skyla>().IsPermitted((Character)(object)__instance, Skyla.ActionType.ACTION_REMOVE_SKYLA); } return Skyla.CheckAccess((Character)(object)__instance, ((Component)piece).transform.position, Skyla.ActionType.ACTION_BUILD); } } [HarmonyPatch(typeof(Player), "AutoPickup")] public static class Player_AutoPickup_Patch { public static bool Prefix(Player __instance, float dt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)__instance, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_AUTO_PICKUP); } } } internal class TerrainHandling { [HarmonyPatch(typeof(Attack), "SpawnOnHitTerrain")] public static class Attack_SpawnOnHitTerrain_Patch { public static bool Prefix(Vector3 hitPoint, Character character) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Skyla.CheckAccess(character, hitPoint, Skyla.ActionType.ACTION_TERRAIN_MODIFICATION); } } } internal class ShipControlsPatch { [HarmonyPatch(typeof(ShipControlls), "Interact")] public static class ShipControlls_Interact_Patch { public static bool Prefix(ShipControlls __instance, Humanoid character, bool repeat, bool alt) { if ((Object)(object)__instance == (Object)null) { return false; } if (!IsCreator(__instance.m_ship, (Player)(object)((character is Player) ? character : null))) { return Skyla.CanUseShip(__instance.m_ship, (Character)(object)character); } return true; } } private static bool IsCreator(Ship v, Player p) { return ((Component)v).gameObject.GetComponent<Piece>().GetCreator() == p.GetPlayerID(); } } internal class VagonPatch { [HarmonyPatch(typeof(Vagon), "Interact")] public static class Vagon_Interact_Patch { public static bool Prefix(Vagon __instance, Humanoid character, bool hold, bool alt) { if ((Object)(object)__instance == (Object)null) { return false; } if (!IsCreator(__instance, (Player)(object)((character is Player) ? character : null))) { return Skyla.CanUseWagon(__instance, (Character)(object)character); } return true; } } private static bool IsCreator(Vagon v, Player p) { return ((Component)v).gameObject.GetComponent<Piece>().GetCreator() == p.GetPlayerID(); } } internal class FireplacePatch { [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] public static class Fireplace_UpdateFireplace_Patch { public static bool Prefix(Fireplace __instance, ref float __state) { if (__instance.m_nview.IsOwner()) { __state = __instance.m_nview.GetZDO().GetFloat("fuel", 0f); } return true; } public static void Postfix(Fireplace __instance, float __state) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_nview.IsOwner()) { float @float = __instance.m_nview.GetZDO().GetFloat("fuel", 0f); float num = Skyla.FindMaxSkylaPower(((Component)__instance).transform.position); float num2 = __state - @float; float num3 = ((num > 0.99f) ? __instance.m_maxFuel : Math.Min(__instance.m_maxFuel, @float + num2 * num)); __instance.m_nview.GetZDO().Set("fuel", num3); } } } } internal class FermenterPatch { [HarmonyPatch(typeof(Fermenter), "Interact")] public static class Fermenter_Interact_Patch { public static bool Prefix(Fermenter __instance, Humanoid user, bool hold, bool alt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)user, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_FERMENTER); } } } internal class DoorPatch { [HarmonyPatch(typeof(Door), "Interact")] public static class Door_Interact_Patch { public static bool Prefix(Door __instance, Humanoid character, bool hold, bool alt) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } return Skyla.CheckAccess((Character)(object)character, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_DOOR); } } } internal class ContainerPatch { [HarmonyPatch(typeof(Container), "Interact")] public static class Container_Interact_Patch { public static bool Prefix(Container __instance, Humanoid character, bool hold, bool alt) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } if (!((Character)character).IsPlayer()) { return false; } Player component = ((Component)character).GetComponent<Player>(); Vagon componentInParent = ((Component)__instance).gameObject.GetComponentInParent<Vagon>(); if ((Object)(object)componentInParent != (Object)null) { return Skyla.CanUseWagon(componentInParent, (Character)(object)character); } Ship componentInParent2 = ((Component)__instance).gameObject.GetComponentInParent<Ship>(); if ((Object)(object)componentInParent2 != (Object)null) { return Skyla.CanUseShip(componentInParent2, (Character)(object)character); } if ((Object)(object)((Component)__instance).gameObject.GetComponent<TombStone>() != (Object)null) { return true; } return Skyla.CheckAccess((Character)(object)component, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_USE_CONTAINER); } } } internal class DestructiblePatch { [HarmonyPatch(typeof(Destructible), "RPC_Damage")] public static class Destructible_Damage_Patch { public static bool Prefix(Destructible __instance, long sender, ref HitData hit) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || hit == null) { return false; } if ((Object)(object)((Component)__instance).GetComponent<RandomFlyingBird>() != (Object)null) { return true; } if ((Object)(object)hit.GetAttacker() == (Object)null || !hit.GetAttacker().IsPlayer()) { float num = 1f - Skyla.FindMaxSkylaPower(((Component)__instance).transform.position); if (num > 0f) { hit.ApplyModifier(num); return true; } return false; } return Skyla.CheckAccess(hit.GetAttacker(), ((Component)__instance).transform.position, Skyla.ActionType.ACTION_DAMAGE); } } } internal class PickablePatch { [HarmonyPatch(typeof(Pickable), "Interact")] public static class Pickable_Interact_Patch { public static bool Prefix(Pickable __instance, Humanoid character, bool repeat, bool alt) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } __instance.m_amount += __instance.m_nview.GetZDO().GetInt("HarvestAmountOverride", __instance.m_amount); if (__instance.m_nview.GetZDO().GetBool("ProtectedPickable", false)) { return Skyla.CheckAccess((Character)(object)character, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_PICKABLE); } return true; } } } [HarmonyPatch(typeof(PickableItem), "Interact")] public static class PickableItem_Interact_Patch { public static bool Prefix(PickableItem __instance, Humanoid character, bool repeat, bool alt) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } if (__instance.m_nview.GetZDO().GetBool("ProtectedPickable", false)) { return Skyla.CheckAccess((Character)(object)character, ((Component)__instance).transform.position, Skyla.ActionType.ACTION_PICKABLE); } return true; } } public class WNTPatch { [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] public static class WNT_Damage_Patch { public static bool Prefix(WearNTear __instance, long sender, ref HitData hit) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || hit == null) { return false; } if (!Object.op_Implicit((Object)(object)hit.GetAttacker()) || !hit.GetAttacker().IsPlayer()) { float num = 0f; Skyla component = ((Component)__instance).gameObject.GetComponent<Skyla>(); num = ((!((Object)(object)component != (Object)null)) ? Skyla.FindMaxSkylaPower(((Component)__instance).transform.position) : component.GetSkylaPower()); float num2 = 1f - num; if (num2 > 0.001f) { hit.ApplyModifier(num2); return true; } return false; } if ((Object)(object)((Component)__instance).gameObject.GetComponent<Vagon>() != (Object)null) { return Skyla.CanUseWagon(((Component)__instance).gameObject.GetComponent<Vagon>(), hit.GetAttacker()); } if ((Object)(object)((Component)__instance).gameObject.GetComponent<Ship>() != (Object)null) { return Skyla.CanUseShip(((Component)__instance).gameObject.GetComponent<Ship>(), hit.GetAttacker()); } return Skyla.CheckAccess(hit.GetAttacker(), ((Component)__instance).transform.position, Skyla.ActionType.ACTION_DAMAGE); } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] public static class WNT_UpdateWear_Patch { public static bool Prefix(WearNTear __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (Skyla.CheckWeatherProtection(((Component)__instance).transform.position)) { __instance.m_rainTimer = Time.time; } return true; } } } public class Skyla : MonoBehaviour, Hoverable, Interactable { public enum ActionType { ACTION_NONE, ACTION_CONTROL_SKYLA, ACTION_REMOVE_SKYLA, ACTION_DAMAGE, ACTION_BUILD, ACTION_TERRAIN_MODIFICATION, ACTION_USE_PORTAL, ACTION_USE_CONTAINER, ACTION_USE_DOOR, ACTION_USE_SIGN, ACTION_USE_ITEMSTAND, ACTION_USE_FERMENTER, ACTION_USE_BEEHIVE, ACTION_PICKUP_FACTORY_OUTPUT, ACTION_AUTO_PICKUP, ACTION_PICKABLE, ACTION_USE_SHIP, ACTION_USE_WAGON, PROTECTION_WEATHER, PROTECTION_MIST } public enum ChimeType { CHIME_FARMING = 0, CHIME_COOKING = 1, CHIME_STABILITY = 2, CHIME_COMFORT = 4, CHIME_INDUSTRY = 5, CHIME_STORM = 10, CHIME_SNOW = 11, CHIME_SNOWSTORM = 12, CHIME_MISTLANDS_STORM = 13, CHIME_ASHRAIN = 14, CHIME_CLEAR = 15 } [HarmonyPatch(typeof(ZDOMan), "Load")] public class ZDOMan_Load_Patch { public static void Postfix(ZDOMan __instance) { ServerManager.Initialize(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public class ZNetScene_Awake_Patch { public static void Postfix(ZNetScene __instance) { GameObject prefab = __instance.GetPrefab(s_prefabName); if ((Object)(object)prefab != (Object)null) { s_skylaPrefab = prefab; if ((Object)(object)prefab.GetComponent<Skyla>() == (Object)null) { prefab.AddComponent<Skyla>(); } } AddToHammer(s_skylaPrefab); } } [HarmonyPatch(typeof(ZNet), "Awake")] public static class ZNetAwakePatch { public static void Postfix(ZNet __instance) { ServerManager.RegisterRPC(); LocalManager.RegisterRPC(); } } [HarmonyPatch(typeof(ZNetScene), "Destroy")] private static class ZNetScene_Destroy_Patch { private static bool Prefix(ZNetScene __instance, GameObject go) { Skyla component = go.GetComponent<Skyla>(); if ((Object)(object)component != (Object)null) { LocalManager.RemoveSkyla(component.m_nview.GetZDO()); } return true; } } private static GameObject s_skylaPrefab; private static float s_defaultSkylaRadius = 15f; private const float c_fullLightIntensity = 3f; private const float c_fullRuneIntensity = 4.8f; private const float c_halfHeight = 50f; private const int c_pulseTimeSecs = 4; public static ISet<Skyla> s_localSkylaList = new HashSet<Skyla>(); public static string s_prefabName = "RunicSkyla"; public const string c_skylaName = "Runic Skýla"; public const string c_skylaShortName = "Skýla"; public const string c_permittedName = "Vinir"; private const string c_zdoSkylaPower = "SkylaPower"; private const string c_zdoIsActive = "IsActive"; public const string c_zdoSkylaRadius = "SkylaRadius"; public const string c_zdoPieceCreator = "creator"; public const string c_zdoProtectedItemDrop = "ProtectedItem"; public const string c_zdoProtectedPickable = "ProtectedPickable"; public const string c_zdoHarvestBonus = "HarvestAmountOverride"; public const string c_zdoChimeBitvector = "ChimesData"; public const string c_zdoWeatherMode = "WeatherMode"; private static Dictionary<ActionType, string> s_zdoAccessMap = new Dictionary<ActionType, string> { { ActionType.ACTION_USE_CONTAINER, "public_use_container" }, { ActionType.ACTION_USE_DOOR, "public_use_door" }, { ActionType.ACTION_USE_SIGN, "public_use_sign" }, { ActionType.ACTION_USE_ITEMSTAND, "public_use_itemstand" }, { ActionType.ACTION_USE_BEEHIVE, "public_use_beehive" }, { ActionType.ACTION_USE_FERMENTER, "public_use_fermenter" }, { ActionType.ACTION_PICKUP_FACTORY_OUTPUT, "public_pickup_factory" }, { ActionType.ACTION_PICKABLE, "public_pickable" }, { ActionType.ACTION_USE_SHIP, "public_use_ship" }, { ActionType.ACTION_USE_WAGON, "public_use_wagon" }, { ActionType.PROTECTION_WEATHER, "weather_protection" }, { ActionType.PROTECTION_MIST, "mist_protection" } }; public static Dictionary<ChimeType, PerkConfig.WeatherMode> s_weatherChimeMap = new Dictionary<ChimeType, PerkConfig.WeatherMode> { { ChimeType.CHIME_STORM, PerkConfig.WeatherMode.WEATHER_STORM }, { ChimeType.CHIME_SNOW, PerkConfig.WeatherMode.WEATHER_SNOW }, { ChimeType.CHIME_SNOWSTORM, PerkConfig.WeatherMode.WEATHER_SNOWSTORM }, { ChimeType.CHIME_MISTLANDS_STORM, PerkConfig.WeatherMode.WEATHER_MISTLANDS_STORM }, { ChimeType.CHIME_ASHRAIN, PerkConfig.WeatherMode.WEATHER_ASHRAIN }, { ChimeType.CHIME_CLEAR, PerkConfig.WeatherMode.WEATHER_CLEAR } }; private MeshRenderer m_model; private ZNetView m_nview; private Light m_lightSource; private Piece m_piece; private CircleProjector m_circleProjector; private DateTime m_awakeTime; public float GetSkylaPower() { if (!m_nview.IsValid()) { return 0f; } if (!IsActive()) { return 0f; } return m_nview.GetZDO().GetFloat("SkylaPower", 0f); } public float GetRadius() { if (m_nview.IsValid()) { return m_nview.GetZDO().GetFloat("SkylaRadius", 0f); } return 0f; } public void SetRadius(float radius) { radius = Math.Min(radius, LocalManager.GetMaxRadiusForSkyla(this)); m_nview.GetZDO().Set("SkylaRadius", radius); } private double GetDeltaTime() { DateTime time = ZNet.instance.GetTime(); DateTime dateTime = new DateTime(m_nview.GetZDO().GetLong("SkylaTime", time.Ticks)); double totalSeconds = (time - dateTime).TotalSeconds; m_nview.GetZDO().Set("SkylaTime", time.Ticks); return totalSeconds; } public void Start() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_nview.IsValid(); } private void Awake() { m_awakeTime = DateTime.Now; m_piece = ((Component)this).GetComponent<Piece>(); m_lightSource = ((Component)this).GetComponent<Light>(); m_circleProjector = ((Component)this).GetComponentInChildren<CircleProjector>(); if ((Object)(object)m_circleProjector != (Object)null) { ((Component)m_circleProjector).gameObject.SetActive(false); } m_nview = ((Component)this).GetComponent<ZNetView>(); if (!m_nview.IsValid() || m_nview.GetZDO() == null) { return; } s_localSkylaList.Add(this); ((MonoBehaviour)this).InvokeRepeating("UpdateState", 0f, 1f); if (m_nview.GetZDO().GetString("CreatorName", "").Length == 0) { Player player = Player.GetPlayer(m_piece.GetCreator()); if ((Object)(object)player != (Object)null) { m_nview.GetZDO().Set("CreatorName", player.GetPlayerName()); } } m_nview.Register<long>("ToggleEnabled", (Action<long, long>)RPC_ToggleEnabled); m_nview.Register<long>("TogglePermitted", (Action<long, long>)RPC_TogglePermitted); m_nview.Register<int>("AddChime", (Action<long, int>)RPC_AddChime); m_nview.Register<long>("RequestSetup", (Action<long, long>)RPC_RequestSetup); m_nview.Register<bool>("RequestSetupResponse", (Action<long, bool>)RPC_RequestSetupResponse); LocalManager.AddSkyla(m_nview.GetZDO()); } private void OnDestroy() { s_localSkylaList.Remove(this); } public void DropResources() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) foreach (ChimeType value in Enum.GetValues(typeof(ChimeType))) { if (HasChime(value)) { GameObject val = PerkConfig.s_chimePrefabMap[value]; if ((Object)(object)val != (Object)null) { Object.Instantiate<GameObject>(val, ((Component)this).transform.position + Vector3.up, Quaternion.identity); } } } } private void UpdateState() { if (!m_nview.IsValid() || !m_nview.IsOwner()) { return; } float num = Math.Max(0f, Math.Min(5f, (float)GetDeltaTime())); if (IsActive()) { float num2 = Math.Min(1f, GetSkylaPower() + num / (float)SkylaConfig.PowerUpTimeSecs()); if ((Object)(object)Player.m_localPlayer != (Object)null && IsOwner(Player.m_localPlayer.GetPlayerID()) && ((Character)Player.m_localPlayer).InGodMode()) { num2 = 1f; } m_nview.GetZDO().Set("SkylaPower", num2); } } public void Update() { UpdateVFX(); UpdateMarker(); } private void UpdateVFX() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_model == (Object)null) { m_model = ((Component)this).GetComponentInChildren<MeshRenderer>(); if ((Object)(object)m_model == (Object)null) { return; } } Color val = Color.white * 4.8f; val.a = 1f; float num = (float)DateTime.Now.Subtract(m_awakeTime).TotalSeconds; float skylaPower = GetSkylaPower(); float num2 = ((!IsActive()) ? 0f : ((skylaPower < 1f) ? (((float)Math.Cos((double)(num / 4f) * Math.PI * 2.0) * 0.5f + 0.5f) * skylaPower) : 1f)); ((Renderer)m_model).material.SetColor("_EmissionColor", Color.Lerp(Color.black, val, num2)); if ((Object)(object)m_lightSource != (Object)null) { m_lightSource.intensity = 3f * num2; } } public bool ProtectsFromWeather() { if (IsActive()) { return CheckPublicAccess(ActionType.PROTECTION_WEATHER); } return false; } public bool ProtectsFromMist() { if (IsActive()) { return CheckPublicAccess(ActionType.PROTECTION_MIST); } return false; } public void Broadcast() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) ZDOMan.instance.ForceSendZDO(m_nview.GetZDO().m_uid); } public void OnPlaced(long playerID) { Player player = Player.GetPlayer(playerID); if ((Object)(object)player != (Object)null) { m_nview.GetZDO().Set("CreatorName", player.GetPlayerName()); } SetRadius(Math.Min(LocalManager.GetMaxRadiusForSkyla(this), s_defaultSkylaRadius)); LocalManager.AddSkyla(m_nview.GetZDO()); Broadcast(); } private void UpdateMarker() { if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)m_circleProjector != (Object)null) { float radius = GetRadius(); bool active = ((Character)Player.m_localPlayer).InPlaceMode() && m_nview.IsValid() && radius > 0f; m_circleProjector.m_radius = radius; ((Component)m_circleProjector).gameObject.SetActive(active); } } public bool IsActive() { if (m_nview.IsValid()) { return m_nview.GetZDO().GetBool("IsActive", false); } return false; } public void SetActive(bool active) { if (m_nview.IsValid()) { m_nview.GetZDO().Set("IsActive", active); } } public long GetOwner() { return m_piece.GetCreator(); } public bool IsOwner(long playerID) { return m_piece.GetCreator() == playerID; } public string GetOwnerName() { if (m_nview.IsValid()) { return m_nview.GetZDO().GetString("CreatorName", ""); } return ""; } public bool Interact(Humanoid h, bool hold, bool alt) { if (hold) { return false; } if (!((Character)h).IsPlayer()) { return false; } Player val = (Player)(object)((h is Player) ? h : null); if (IsOwner(val.GetPlayerID())) { if (Input.GetKey((KeyCode)304)) { m_nview.InvokeRPC("RequestSetup", new object[1] { ((Player)((h is Player) ? h : null)).GetPlayerID() }); } else { m_nview.InvokeRPC("ToggleEnabled", new object[1] { ((Player)((h is Player) ? h : null)).GetPlayerID() }); } return true; } if (val.m_godMode) { m_nview.InvokeRPC("ToggleEnabled", new object[1] { ((Player)((h is Player) ? h : null)).GetPlayerID() }); return true; } if (!IsActive()) { m_nview.InvokeRPC("TogglePermitted", new object[1] { ((Player)((h is Player) ? h : null)).GetPlayerID() }); return true; } return false; } public bool UseItem(Humanoid user, ItemData item) { if (PerkConfig.s_chimeMap.ContainsKey(item.m_shared.m_name)) { if (!IsOwner(((Player)((user is Player) ? user : null)).GetPlayerID())) { ((Character)user).Message((MessageType)2, "Only the owner may apply chimes", 0, (Sprite)null); return true; } if (IsActive()) { ((Character)user).Message((MessageType)2, "A Skýla must be deactivated to receive a chime", 0, (Sprite)null); return true; } ChimeType chimeType = PerkConfig.s_chimeMap[item.m_shared.m_name]; if (HasChime(chimeType)) { ((Character)user).Message((MessageType)2, "This Skýla already has this chime", 0, (Sprite)null); return true; } m_nview.InvokeRPC("AddChime", new object[1] { (int)chimeType }); ((Character)user).ShowRemovedMessage(item, 1); user.GetInventory().RemoveItem(item.m_shared.m_name, 1, -1, true); return true; } return false; } public static float FindMaxSkylaPower(Vector3 point) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) float num = 0f; foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsActive() && s_localSkyla.IsInside(point, 0f)) { num = Math.Max(num, s_localSkyla.GetSkylaPower()); } } return num; } public static bool CanUseWagon(Vagon v, Character user) { return CanUseVehicle(((Component)v).gameObject.GetComponent<Piece>(), (Player)(object)((user is Player) ? user : null), ActionType.ACTION_USE_WAGON); } public static bool CanUseShip(Ship s, Character user) { return CanUseVehicle(((Component)s).gameObject.GetComponent<Piece>(), (Player)(object)((user is Player) ? user : null), ActionType.ACTION_USE_SHIP); } private static bool CanUseVehicle(Piece vehiclePiece, Player user, ActionType action) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) long creator = vehiclePiece.GetCreator(); if (user.m_godMode) { return true; } foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsInside(((Component)vehiclePiece).transform.position, 0f) && !s_localSkyla.CheckPublicAccess(action) && s_localSkyla.IsPermitted(creator) && !s_localSkyla.IsPermitted(user.GetPlayerID())) { ((Character)user).Message((MessageType)2, "You are prevented by a Skýla", 0, (Sprite)null); return false; } } return true; } public static bool ChimeApplies(Vector3 point, ChimeType perk) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsInside(point, 0f) && s_localSkyla.IsActive() && s_localSkyla.HasChime(perk)) { return true; } } return false; } public static PerkConfig.WeatherMode FindWeatherMode(Vector3 point) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsInside(point, 0f, 2f) && s_localSkyla.IsActive()) { PerkConfig.WeatherMode stormChimeWeatherMode = s_localSkyla.GetStormChimeWeatherMode(); if (stormChimeWeatherMode != 0) { return stormChimeWeatherMode; } } } return PerkConfig.WeatherMode.WEATHER_NONE; } public PerkConfig.WeatherMode GetStormChimeWeatherMode() { if (!m_nview.IsValid()) { return PerkConfig.WeatherMode.WEATHER_NONE; } return (PerkConfig.WeatherMode)m_nview.GetZDO().GetInt("WeatherMode", 0); } public void SetStormChimeWeatherMode(PerkConfig.WeatherMode weather) { m_nview.GetZDO().Set("WeatherMode", (int)weather); } public static bool CheckWeatherProtection(Vector3 point) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsInside(point, 0f) && s_localSkyla.ProtectsFromWeather()) { return true; } } return false; } public static bool CheckMistProtection(Vector3 point) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsInside(point, 0f, s_localSkyla.GetSkylaPower()) && s_localSkyla.ProtectsFromMist()) { return true; } } return false; } public static bool CheckAccess(Character c, Vector3 point, ActionType action) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) float num = 0f; num = action switch { ActionType.ACTION_AUTO_PICKUP => Player.m_localPlayer.m_autoPickupRange * 1.5f, ActionType.ACTION_TERRAIN_MODIFICATION => 3f, _ => 0f, }; foreach (Skyla s_localSkyla in s_localSkylaList) { if (s_localSkyla.IsInside(point, num) && !s_localSkyla.IsPermitted(c, action)) { return false; } } return true; } public void SetPublicAccess(ActionType action, bool allow) { if (s_zdoAccessMap.TryGetValue(action, out var value)) { m_nview.GetZDO().Set(value, allow); } } public bool CheckPublicAccess(ActionType action) { if (s_zdoAccessMap.TryGetValue(action, out var value)) { return m_nview.GetZDO().GetBool(value, action == ActionType.PROTECTION_WEATHER || action == ActionType.PROTECTION_MIST); } return false; } public void AddChime(ChimeType chime) { int @int = m_nview.GetZDO().GetInt("ChimesData", 0); m_nview.GetZDO().Set("ChimesData", @int | (1 << (int)chime)); } public bool HasChime(ChimeType chime) { return (m_nview.GetZDO().GetInt("ChimesData", 0) & (1 << (int)chime)) != 0; } public int NumWeatherChimes() { int @int = m_nview.GetZDO().GetInt("ChimesData", 0); int num = 0; foreach (ChimeType key in s_weatherChimeMap.Keys) { if ((@int & (1 << (int)key)) != 0) { num++; } } return num; } public List<ChimeType> GetWeatherChimes() { List<ChimeType> list = new List<ChimeType>(); int @int = m_nview.GetZDO().GetInt("ChimesData", 0); foreach (ChimeType key in s_weatherChimeMap.Keys) { if ((@int & (1 << (int)key)) != 0) { list.Add(key); } } return list; } public bool IsPermitted(Character c, ActionType action) { if (!IsActive() && action != ActionType.ACTION_REMOVE_SKYLA) { return true; } if ((Object)(object)c == (Object)null || !c.IsPlayer()) { return false; } Player val = (Player)(object)((c is Player) ? c : null); if ((Object)(object)val != (Object)null) { if (val.m_godMode || IsOwner(val.GetPlayerID()) || (OnPermittedList(val) && action != ActionType.ACTION_REMOVE_SKYLA)) { return true; } if (CheckPublicAccess(action)) { return true; } if (action != ActionType.ACTION_AUTO_PICKUP) { ((Character)val).Message((MessageType)2, "You are prevented by a Skýla", 0, (Sprite)null); } } return false; } private bool OnPermittedList(Player p) { return IsPermitted(p.GetPlayerID()); } private bool IsInside(Vector3 point, float grace, float radiusScale = 1f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (Utils.DistanceXZ(((Component)this).transform.position, point) < GetRadius() * radiusScale + grace) { return Math.Abs(((Component)this).transform.position.y - point.y) < 50f; } return false; } public string GetHoverName() { return "Runic Skýla"; } public string GetHoverText() { StringBuilder stringBuilder = new StringBuilder(256); if (!m_nview.IsValid()) { return ""; } if (IsActive()) { stringBuilder.Append(string.Format("{0} is {1}% charged", "Skýla", (int)(GetSkylaPower() * 100f))); } bool flag = m_piece.GetCreator() == Player.m_localPlayer.GetPlayerID(); if (Player.m_localPlayer.m_godMode || flag) { if (IsActive()) { stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] : Deactivate"); } else { stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] : Activate"); } if (flag) { stringBuilder.Append("\n[<color=yellow><b>Shift + $KEY_Use</b></color>] : Setup"); if (!IsActive()) { stringBuilder.Append("\n[<color=yellow><b>1-8</b></color>] Add Chime"); } } } else if (!IsActive()) { if (OnPermittedList(Player.m_localPlayer)) { stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] : Unpermit"); } else { stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] : Permit"); } } stringBuilder.Append("\nOwner: " + GetOwnerName()); AddUserList(stringBuilder); AddChimeList(stringBuilder); return Localization.instance.Localize(stringBuilder.ToString()); } private void RPC_RequestSetup(long uid, long playerID) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (IsOwner(playerID)) { ZDOMan.instance.ForceSendZDO(uid, m_nview.GetZDO().m_uid); m_nview.GetZDO().SetOwner(uid); m_nview.InvokeRPC(uid, "RequestSetupResponse", new object[1] { true }); } } private void RPC_RequestSetupResponse(long uid, bool allowed) { if (allowed) { SkylaGUI.ToggleGUI(this); } } private void RPC_ToggleEnabled(long uid, long playerID) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsOwner()) { SetActive(!IsActive()); Broadcast(); Object.Instantiate<GameObject>(IsActive() ? Assets.s_activateFXPrefab : Assets.s_deactivateFXPrefab, ((Component)this).transform.position + Vector3.up * 1.6f, ((Component)this).transform.rotation); } } private void RPC_TogglePermitted(long uid, long playerID) { if (m_nview.IsOwner() && !IsActive()) { if (IsPermitted(playerID)) { RemovePermitted(playerID); } else { AddPermitted(playerID, Player.GetPlayer(playerID).GetPlayerName()); } Broadcast(); } } private void RPC_AddChime(long uid, int chime) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsOwner()) { AddChime((ChimeType)chime); Broadcast(); if (((Behaviour)this).enabled) { Object.Instantiate<GameObject>(Assets.s_applyBlessingFXPrefab, ((Component)this).transform.position + Vector3.up * 1.6f, ((Component)this).transform.rotation); } } } private List<KeyValuePair<long, string>> GetPermittedPlayers() { List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>(); if (m_nview.IsValid()) { int @int = m_nview.GetZDO().GetInt("permitted", 0); for (int i = 0; i < @int; i++) { long @long = m_nview.GetZDO().GetLong("pu_id" + i, 0L); string @string = m_nview.GetZDO().GetString("pu_name" + i, ""); if (@long != 0L) { list.Add(new KeyValuePair<long, string>(@long, @string)); } } } return list; } private void SetPermittedPlayers(List<KeyValuePair<long, string>> users) { if (m_nview.IsValid()) { m_nview.GetZDO().Set("permitted", users.Count); for (int i = 0; i < users.Count; i++) { KeyValuePair<long, string> keyValuePair = users[i]; m_nview.GetZDO().Set("pu_id" + i, keyValuePair.Key); m_nview.GetZDO().Set("pu_name" + i, keyValuePair.Value); } } } private bool IsPermitted(long playerID) { if (m_piece.GetCreator() == playerID) { return true; } foreach (KeyValuePair<long, string> permittedPlayer in GetPermittedPlayers()) { if (permittedPlayer.Key == playerID) { return true; } } return false; } private void AddPermitted(long playerID, string playerName) { List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(); foreach (KeyValuePair<long, string> item in permittedPlayers) { if (item.Key == playerID) { return; } } permittedPlayers.Add(new KeyValuePair<long, string>(playerID, playerName)); SetPermittedPlayers(permittedPlayers); } private void RemovePermitted(long playerID) { List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(); if (permittedPlayers.RemoveAll((KeyValuePair<long, string> x) => x.Key == playerID) > 0) { SetPermittedPlayers(permittedPlayers); } } private void AddUserList(StringBuilder text) { List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(); if (permittedPlayers.Count == 0) { return; } text.Append("\nVinir: "); for (int i = 0; i < permittedPlayers.Count; i++) { text.Append(permittedPlayers[i].Value); if (i != permittedPlayers.Count - 1) { text.Append(", "); } } } private void AddChimeList(StringBuilder text) { List<string> list = new List<string>(); foreach (ChimeType key in PerkConfig.s_powerNameMap.Keys) { if (HasChime(key)) { list.Add(PerkConfig.s_powerNameMap[key]); } } if (list.Count > 0) { text.Append("\nChimes: " + string.Join(", ", list)); } int num = NumWeatherChimes(); if (num > 0) { text.Append($"\nWeather Chimes: {num}"); } } public static void AddToHammer(GameObject prefab) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { return; } PieceTable val = null; Object[] array = Resources.FindObjectsOfTypeAll(typeof(PieceTable)); for (int i = 0; i < array.Length; i++) { PieceTable val2 = (PieceTable)array[i]; if (((Object)((Component)val2).gameObject).name.Contains("_HammerPieceTable")) { val = val2; break; } } component.m_name = "Runic Skýla"; if ((Object)(object)val != (Object)null) { if (!val.m_pieces.Contains(prefab)) { val.m_pieces.Add(prefab); } val.m_pieces.Remove(ZNetScene.instance.GetPrefab("guard_stone").gameObject); } ((Behaviour)ZNetScene.instance.GetPrefab("guard_stone").GetComponent<Piece>()).enabled = false; } } [BepInPlugin("Asbjorn.Skyla", "Skyla", "0.7.2")] public class Mod : BaseUnityPlugin { public const string ModGuid = "Asbjorn.Skyla"; private const string AuthorName = "Asbjorn"; private const string ModName = "Skyla"; private const string ModVer = "0.7.2"; private readonly ConfigSync configSync = new ConfigSync("Skyla") { DisplayName = "Skyla", CurrentVersion = "0.7.2", MinimumRequiredVersion = "0.7.2" }; private Harmony _harmony; private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown SkylaConfig.SetupConfig(this); configSync.IsLocked = true; SetupWatcher(); _harmony = new Harmony("Asbjorn.Skyla"); _harmony.PatchAll(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (ZNet.instance.IsServer() && File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { ((BaseUnityPlugin)this).Config.Reload(); } } public ConfigEntry<T> SyncedConfig<T>(string group, string name, T defaultVal, string desc) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultVal, new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty<object>())); configSync.AddConfigEntry<T>(val).SynchronizedConfig = true; return val; } } } namespace Tyrenheim_Skyla.GUI { public class SkylaGUI { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__45_0; public static UnityAction <>9__45_1; public static UnityAction <>9__45_2; public static UnityAction<float> <>9__45_3; internal void <Init>b__45_0() { PrevWeather(); } internal void <Init>b__45_1() { NextWeather(); } internal void <Init>b__45_2() { HideGUI(); } internal void <Init>b__45_3(float <p0>) { UpdateText(); } } private const string s_GUIprefabName = "SkylaGUI"; private static GameObject s_wardGUI; private static Text s_titleText; private static string s_titleTextName = "AegisRoot/AegisCanvas/Aegis/Title"; private static Slider s_radiusSlider; private static string s_radiusSliderName = "AegisRoot/AegisCanvas/Aegis/Zone/RadiusSegment/RadiusSlider"; private static Text s_radiusText; private static string s_radiusTextName = "AegisRoot/AegisCanvas/Aegis/Zone/RadiusSegment/RadiusText"; private static Text s_limitText; private static string s_limitTextName = "AegisRoot/AegisCanvas/Aegis/Zone/LimitSegment/LimitText"; private static Toggle s_containerToggle; private static string s_containerToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/ContainerToggle"; private static Toggle s_doorToggle; private static string s_doorToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/DoorToggle"; private static Toggle s_signToggle; private static string s_signToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/SignToggle"; private static Toggle s_itemStandToggle; private static string s_itemStandToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/ItemStandToggle"; private static Toggle s_harvestableToggle; private static string s_harvestableToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/HarvestableToggle"; private static Toggle s_fermenterToggle; private static string s_fermenterToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/FermenterToggle"; private static Toggle s_beehiveToggle; private static string s_beehiveToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/BeehiveToggle"; private static Toggle s_productsToggle; private static string s_productsToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/ProductsToggle"; private static Toggle s_cartsToggle; private static string s_cartsToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/CartsToggle"; private static Toggle s_shipsToggle; private static string s_shipsToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/ShipsToggle"; private static Toggle s_weatherProtectionToggle; private static string s_weatherToggleName = "AegisRoot/AegisCanvas/Aegis/Protections/WeatherProtectionToggle"; private static GameObject s_stormChimePanel; private static string s_stormChimePanelName = "AegisRoot/AegisCanvas/StormChime"; private static Text s_stormChimeText; private static string s_stormChimeTextName = "AegisRoot/AegisCanvas/StormChime/Weather/bkg/Text"; private static Button s_stormChimePrevButton; private static string s_stormChimePrevButtonName = "AegisRoot/AegisCanvas/StormChime/Weather/Left"; private static Button s_stormChimeNextButton; private static string s_stormChimeNextButtonName = "AegisRoot/AegisCanvas/StormChime/Weather/Right"; private static int s_weatherModeIndex = 0; private static List<PerkConfig.WeatherMode> s_availableWeatherModes = new List<PerkConfig.WeatherMode>(); private static Button s_doneButton; private static string s_doneButtonName = "AegisRoot/AegisCanvas/Aegis/Done_Button_Panel/Done"; private static Skyla s_activeWard; public static void Init() { //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Expected O, but got Unknown //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Expected O, but got Unknown GameObject[] s_prefabs = Assets.s_prefabs; foreach (GameObject val in s_prefabs) { val.SetActive(false); if (((Object)val).name == "SkylaGUI") { s_wardGUI = Object.Instantiate<GameObject>(val); break; } } Object.DontDestroyOnLoad((Object)(object)s_wardGUI); s_wardGUI.SetActive(false); s_titleText = ((Component)s_wardGUI.transform.Find(s_titleTextName)).gameObject.GetComponent<Text>(); s_radiusSlider = ((Component)s_wardGUI.transform.Find(s_radiusSliderName)).gameObject.GetComponent<Slider>(); s_radiusText = ((Component)s_wardGUI.transform.Find(s_radiusTextName)).gameObject.GetComponent<Text>(); s_limitText = ((Component)s_wardGUI.transform.Find(s_limitTextName)).gameObject.GetComponent<Text>(); s_containerToggle = ((Component)s_wardGUI.transform.Find(s_containerToggleName)).gameObject.GetComponent<Toggle>(); s_doorToggle = ((Component)s_wardGUI.transform.Find(s_doorToggleName)).gameObject.GetComponent<Toggle>(); s_signToggle = ((Component)s_wardGUI.transform.Find(s_signToggleName)).gameObject.GetComponent<Toggle>(); s_itemStandToggle = ((Component)s_wardGUI.transform.Find(s_itemStandToggleName)).gameObject.GetComponent<Toggle>(); s_harvestableToggle = ((Component)s_wardGUI.transform.Find(s_harvestableToggleName)).gameObject.GetComponent<Toggle>(); s_fermenterToggle = ((Component)s_wardGUI.transform.Find(s_fermenterToggleName)).gameObject.GetComponent<Toggle>(); s_beehiveToggle = ((Component)s_wardGUI.transform.Find(s_beehiveToggleName)).gameObject.GetComponent<Toggle>(); s_productsToggle = ((Component)s_wardGUI.transform.Find(s_productsToggleName)).gameObject.GetComponent<Toggle>(); s_cartsToggle = ((Component)s_wardGUI.transform.Find(s_cartsToggleName)).gameObject.GetComponent<Toggle>(); s_shipsToggle = ((Component)s_wardGUI.transform.Find(s_shipsToggleName)).gameObject.GetComponent<Toggle>(); s_weatherProtectionToggle = ((Component)s_wardGUI.transform.Find(s_weatherToggleName)).gameObject.GetComponent<Toggle>(); s_stormChimePanel = ((Component)s_wardGUI.transform.Find(s_stormChimePanelName)).gameObject; s_stormChimeText = ((Component)s_wardGUI.transform.Find(s_stormChimeTextName)).gameObject.GetComponent<Text>(); s_stormChimePrevButton = ((Component)s_wardGUI.transform.Find(s_stormChimePrevButtonName)).gameObject.GetComponent<Button>(); s_stormChimeNextButton = ((Component)s_wardGUI.transform.Find(s_stormChimeNextButtonName)).gameObject.GetComponent<Button>(); ButtonClickedEvent onClick = s_stormChimePrevButton.onClick; object obj = <>c.<>9__45_0; if (obj == null) { UnityAction val2 = delegate { PrevWeather(); }; <>c.<>9__45_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); ButtonClickedEvent onClick2 = s_stormChimeNextButton.onClick; object obj2 = <>c.<>9__45_1; if (obj2 == null) { UnityAction val3 = delegate { NextWeather(); }; <>c.<>9__45_1 = val3; obj2 = (object)val3; } ((UnityEvent)onClick2).AddListener((UnityAction)obj2); s_doneButton = ((Component)s_wardGUI.transform.Find(s_doneButtonName)).gameObject.GetComponent<Button>(); ButtonClickedEvent onClick3 = s_doneButton.onClick; object obj3 = <>c.<>9__45_2; if (obj3 == null) { UnityAction val4 = delegate { HideGUI(); }; <>c.<>9__45_2 = val4; obj3 = (object)val4; } ((UnityEvent)onClick3).AddListener((UnityAction)obj3); ((UnityEvent<float>)(object)s_radiusSlider.onValueChanged).AddListener((UnityAction<float>)delegate { UpdateText(); }); } public static void ToggleGUI(Skyla ward) { if (s_wardGUI.activeSelf) { HideGUI(); } else { ShowGUI(ward); } } private static void EnableMouseEtc(bool enable) { if (enable) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; ((Behaviour)GameCamera.instance).enabled = false; ((Behaviour)((Component)Player.m_localPlayer).GetComponent<PlayerController>()).enabled = false; } else { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; ((Behaviour)GameCamera.instance).enabled = true; ((Behaviour)((Component)Player.m_localPlayer).GetComponent<PlayerController>()).enabled = true; } } private static void UpdateText() { s_radiusSlider.SetValueWithoutNotify(Math.Min(s_radiusSlider.value, LocalManager.GetMaxRadiusForSkyla(s_activeWard))); s_radiusText.text = $"{s_radiusSlider.value:0.0} m"; float remainingArea = LocalManager.GetRemainingArea(); float radius = s_activeWard.GetRadius(); float num = (float)Math.PI * radius * radius; float value = s_radiusSlider.value; float num2 = (float)Math.PI * value * value; float num3 = remainingArea + num - num2; s_limitText.text = $"{num3:0,0.0} m²"; } private static void SetupWeatherOptions() { List<Skyla.ChimeType> weatherChimes = s_activeWard.GetWeatherChimes(); s_availableWeatherModes.Clear(); s_weatherModeIndex = 0; s_availableWeatherModes.Add(PerkConfig.WeatherMode.WEATHER_NONE); PerkConfig.WeatherMode stormChimeWeatherMode = s_activeWard.GetStormChimeWeatherMode(); foreach (Skyla.ChimeType item in weatherChimes) { PerkConfig.WeatherMode weatherMode = Skyla.s_weatherChimeMap[item]; s_availableWeatherModes.Add(weatherMode); if (weatherMode == stormChimeWeatherMode) { s_weatherModeIndex = s_availableWeatherModes.Count - 1; } } } private static void UpdateStormChimeWeather() { if (PerkConfig.s_weatherNameMap.TryGetValue(s_availableWeatherModes[s_weatherModeIndex], out var value)) { s_stormChimeText.text = value; } } private static void NextWeather() { s_weatherModeIndex++; if (s_weatherModeIndex >= s_availableWeatherModes.Count) { s_weatherModeIndex = 0; } UpdateStormChimeWeather(); } private static void PrevWeather() { s_weatherModeIndex--; if (s_weatherModeIndex < 0) { s_weatherModeIndex = s_availableWeatherModes.Count - 1; } UpdateStormChimeWeather(); } private static void ShowGUI(Skyla ward) { s_activeWard = ward; s_radiusSlider.SetValueWithoutNotify(ward.GetRadius()); s_titleText.text = string.Format("{0} Configuration", "Skýla"); s_radiusSlider.maxValue = SkylaConfig.MaxSkylaRadius(); s_containerToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_CONTAINER)); s_doorToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_DOOR)); s_signToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_SIGN)); s_itemStandToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_ITEMSTAND)); s_harvestableToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_PICKABLE)); s_fermenterToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_FERMENTER)); s_beehiveToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_BEEHIVE)); s_productsToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_PICKUP_FACTORY_OUTPUT)); s_cartsToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_WAGON)); s_shipsToggle.SetIsOnWithoutNotify(!ward.CheckPublicAccess(Skyla.ActionType.ACTION_USE_SHIP)); s_weatherProtectionToggle.SetIsOnWithoutNotify(ward.CheckPublicAccess(Skyla.ActionType.PROTECTION_WEATHER)); s_stormChimePanel.SetActive(ward.NumWeatherChimes() > 0); SetupWeatherOptions(); UpdateStormChimeWeather(); UpdateText(); s_wardGUI.SetActive(true); EnableMouseEtc(enable: true); } private static void HideGUI() { if (Object.op_Implicit((Object)(object)s_activeWard)) { s_activeWard.SetRadius(s_radiusSlider.value); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_CONTAINER, !s_containerToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_DOOR, !s_doorToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_SIGN, !s_signToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_ITEMSTAND, !s_itemStandToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_PICKABLE, !s_harvestableToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_FERMENTER, !s_fermenterToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_BEEHIVE, !s_beehiveToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_PICKUP_FACTORY_OUTPUT, !s_productsToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_WAGON, !s_cartsToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.ACTION_USE_SHIP, !s_shipsToggle.isOn); s_activeWard.SetPublicAccess(Skyla.ActionType.PROTECTION_WEATHER, s_weatherProtectionToggle.isOn); s_activeWard.SetStormChimeWeatherMode(s_availableWeatherModes[s_weatherModeIndex]); s_activeWard.Broadcast(); } s_wardGUI.SetActive(false); s_activeWard = null; EnableMouseEtc(enable: false); } } } namespace Tyrenheim_Skyla.Patches { internal class Humanoid_Patch { [HarmonyPatch(typeof(Humanoid), "Pickup")] public static class Humanoid_Pickup_Patch { public static bool Prefix(Humanoid __instance, GameObject go, bool autoequip, bool autoPickupDelay, ref bool __result) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)go == (Object)null) { return true; } ZNetView component = go.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("ProtectedItem", false)) { __result = Skyla.CheckAccess((Character)(object)__instance, go.transform.position, Skyla.ActionType.ACTION_PICKUP_FACTORY_OUTPUT); return __result; } return true; } } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ServerSync { [PublicAPI] internal abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] internal class SyncedConfigEntry<T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] internal class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = configSyncs.First(); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = (from p in ZNet.instance.GetPeers() where adminList.Contains(p.m_rpc.GetSocket().GetHostName()) select p).ToList(); List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>(); public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return