Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TempBed v1.3.0
plugins/TempBed.dll
Decompiled 15 hours agousing System; using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace TempBed; [BepInPlugin("flo.tempbed", "TempBed", "1.3.0")] public class TempBedPlugin : BaseUnityPlugin { internal class ConfigurationManagerAttributes { public bool? ReadOnly; } public const string GUID = "flo.tempbed"; public const string NAME = "TempBed"; public const string VERSION = "1.3.0"; private const string RpcName = "TempBed_Cfg"; internal const string RpcSet = "TempBed_Set"; private const float PushInterval = 2f; internal const string ZdoSince = "flo_tb_since"; internal const string ZdoMark = "flo_tb_mark"; internal static ManualLogSource Log; internal static ConfigEntry<bool> cfgEnabled; internal static ConfigEntry<bool> cfgAllowPlacement; internal static ConfigEntry<float> cfgDecayMinutes; internal static ConfigEntry<bool> cfgAnyStation; internal static ConfigEntry<string> cfgStationNames; internal static ConfigEntry<bool> cfgOnlyUnsupportedPlaced; internal static ConfigEntry<bool> cfgPermanentWhenStationBuilt; internal static ConfigEntry<bool> cfgDropResources; internal static ConfigEntry<bool> cfgShowTimer; internal static ConfigEntry<string> cfgTimerText; internal static ConfigEntry<bool> cfgIgnoreRoof; internal static ConfigEntry<bool> cfgIgnoreWet; internal static ConfigEntry<bool> cfgIgnoreFire; internal static ConfigEntry<bool> cfgServerSync; internal static bool ServerOverride; internal static bool IsAdminHere; private static bool applyingFromServer; internal static TempBedPlugin Instance; private static bool sEnabled = true; private static bool sAllowPlacement = true; private static float sDecayMinutes = 15f; private static bool sAnyStation; private static string sStationNames = "$piece_workbench"; private static bool sOnlyUnsupportedPlaced = true; private static bool sPermanent = true; private static bool sDropResources; private static bool sIgnoreRoof = true; private static bool sIgnoreWet = true; private static bool sIgnoreFire; private static readonly List<ConfigurationManagerAttributes> LockAttributes = new List<ConfigurationManagerAttributes>(); private Harmony harmony; internal float pushTimer; private int lastPeerCount = -1; private static readonly Dictionary<string, CraftingStation> OriginalStations = new Dictionary<string, CraftingStation>(); internal static bool IsRemoteClient => (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer(); internal static bool EffEnabled { get { if (ServerOverride) { return sEnabled; } if (IsRemoteClient) { return false; } return cfgEnabled.Value; } } internal static bool EffAllowPlacement => (!ServerOverride) ? cfgAllowPlacement.Value : sAllowPlacement; internal static float EffDecayMinutes => (!ServerOverride) ? cfgDecayMinutes.Value : sDecayMinutes; internal static bool EffAnyStation => (!ServerOverride) ? cfgAnyStation.Value : sAnyStation; internal static string EffStationNames => (!ServerOverride) ? cfgStationNames.Value : sStationNames; internal static bool EffOnlyUnsupportedPlaced => (!ServerOverride) ? cfgOnlyUnsupportedPlaced.Value : sOnlyUnsupportedPlaced; internal static bool EffPermanent => (!ServerOverride) ? cfgPermanentWhenStationBuilt.Value : sPermanent; internal static bool EffDropResources => (!ServerOverride) ? cfgDropResources.Value : sDropResources; internal static bool EffIgnoreRoof => (!ServerOverride) ? cfgIgnoreRoof.Value : sIgnoreRoof; internal static bool EffIgnoreWet => (!ServerOverride) ? cfgIgnoreWet.Value : sIgnoreWet; internal static bool EffIgnoreFire => (!ServerOverride) ? cfgIgnoreFire.Value : sIgnoreFire; private static ConfigDescription Desc(string text, AcceptableValueBase range) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes(); configurationManagerAttributes.ReadOnly = false; ConfigurationManagerAttributes configurationManagerAttributes2 = configurationManagerAttributes; LockAttributes.Add(configurationManagerAttributes2); return (range != null) ? new ConfigDescription(text, range, new object[1] { configurationManagerAttributes2 }) : new ConfigDescription(text, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes2 }); } private static void SetLocked(bool locked) { for (int i = 0; i < LockAttributes.Count; i++) { LockAttributes[i].ReadOnly = locked; } } private void Awake() { //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; cfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Allgemein", "Enabled", true, Desc("Mod aktiv. false = alles bleibt Vanilla (Bett braucht wieder eine Werkbank).\nAuf Clients ohne Wirkung - dort gilt immer die Server-Einstellung.", null)); cfgAllowPlacement = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Bauen", "AllowPlacementWithoutStation", true, Desc("Betten können ohne Werkbank in Reichweite gebaut werden.", null)); cfgDecayMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Verfall", "DecayMinutes", 15f, Desc("Minuten, die ein Bett ohne Werkbank in Reichweite überlebt. Danach wird es abgebaut.\nDer Timer läuft über die Weltzeit, ein Server-Neustart verlängert ihn also nicht.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 1440f))); cfgOnlyUnsupportedPlaced = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Verfall", "OnlyBedsPlacedWithoutStation", true, Desc("true = nur Betten verfallen, die ohne Werkbank gesetzt wurden (bestehende Betten sind sicher).\nfalse = jedes Bett ohne Werkbank in Reichweite verfällt, auch älteres.", null)); cfgPermanentWhenStationBuilt = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Verfall", "PermanentWhenStationBuilt", true, Desc("Stellt jemand nachträglich eine Werkbank dazu, wird das Bett dauerhaft und verfällt auch später nicht mehr.", null)); cfgDropResources = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Verfall", "DropResources", false, Desc("true = beim Verfall fallen die Baumaterialien heraus.", null)); cfgAnyStation = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Werkbank", "AnyCraftingStation", false, Desc("true = jede Handwerksstation zählt (Werkbank, Schmiede, Steinschneider ...).\nfalse = nur die unter StationNames genannten.", null)); cfgStationNames = ((BaseUnityPlugin)this).Config.Bind<string>("4 - Werkbank", "StationNames", "$piece_workbench", Desc("Kommagetrennte Liste der Stationen, die ein Bett stützen. Vanilla-Werkbank ist $piece_workbench.", null)); cfgIgnoreRoof = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Schlafen", "IgnoreRoofRequirement", true, Desc("Bett darf unter freiem Himmel benutzt werden - hebt \"Das Bett braucht ein Dach\" und \"zu ungeschützt\" auf.\nGilt auch fürs Setzen des Spawnpunkts.", null)); cfgIgnoreWet = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Schlafen", "IgnoreWetRequirement", true, Desc("Nass sein verhindert das Schlafen nicht mehr. Ohne Dach wird man im Regen sonst sofort nass\nund könnte trotz IgnoreRoofRequirement nicht schlafen.", null)); cfgIgnoreFire = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Schlafen", "IgnoreFireRequirement", false, Desc("Feuer in der Nähe wird nicht mehr verlangt. Vanilla verlangt es ohnehin nicht -\nnur relevant, wenn eine andere Mod das ändert.", null)); cfgShowTimer = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Anzeige", "ShowTimerInHoverText", true, Desc("Restzeit im Hover-Text des Bettes anzeigen.", null)); cfgTimerText = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Anzeige", "TimerText", "Ohne Werkbank - verfällt in {0}", Desc("{0} wird durch die Restzeit ersetzt (mm:ss).", null)); cfgServerSync = ((BaseUnityPlugin)this).Config.Bind<bool>("7 - Server", "ServerSync", true, "Nur serverseitig relevant: true = der Server erzwingt seine Werte bei allen Clients."); ((BaseUnityPlugin)this).Config.SettingChanged += OnLocalSettingChanged; harmony = new Harmony("flo.tempbed"); harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"TempBed 1.3.0 geladen."); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown if ((Object)(object)ZNet.instance == (Object)null) { if (ServerOverride) { ServerOverride = false; IsAdminHere = false; SetLocked(locked: false); } } else { if (!ZNet.instance.IsServer() || !cfgServerSync.Value || ZRoutedRpc.instance == null) { return; } int count = ZNet.instance.GetPeers().Count; pushTimer -= Time.deltaTime; if (pushTimer > 0f && count == lastPeerCount) { return; } lastPeerCount = count; pushTimer = 2f; try { string text = Serialize(); List<ZNetPeer> peers = ZNet.instance.GetPeers(); for (int i = 0; i < peers.Count; i++) { ZNetPeer val = peers[i]; if (val != null) { bool flag = val.m_socket != null && ZNet.instance.IsAdmin(val.m_socket.GetHostName()); ZPackage val2 = new ZPackage(); val2.Write(text + "|" + ((!flag) ? "0" : "1")); ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "TempBed_Cfg", new object[1] { val2 }); } } } catch (Exception ex) { Log.LogWarning((object)("Config-Push fehlgeschlagen: " + ex.Message)); } } } private static string Serialize() { return string.Join("|", "1", (!EffEnabled) ? "0" : "1", (!EffAllowPlacement) ? "0" : "1", EffDecayMinutes.ToString(CultureInfo.InvariantCulture), (!EffAnyStation) ? "0" : "1", (!EffOnlyUnsupportedPlaced) ? "0" : "1", (!EffPermanent) ? "0" : "1", (!EffDropResources) ? "0" : "1", EffStationNames.Replace('|', ','), (!EffIgnoreRoof) ? "0" : "1", (!EffIgnoreWet) ? "0" : "1", (!EffIgnoreFire) ? "0" : "1"); } internal static void RPC_Config(long sender, ZPackage pkg) { try { if (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) || pkg == null) { return; } string text = pkg.ReadString(); if (string.IsNullOrEmpty(text)) { return; } string[] array = text.Split('|'); if (array.Length >= 12 && !(array[0] != "1")) { bool flag = !ServerOverride; sEnabled = array[1] == "1"; sAllowPlacement = array[2] == "1"; sDecayMinutes = float.Parse(array[3], CultureInfo.InvariantCulture); sAnyStation = array[4] == "1"; sOnlyUnsupportedPlaced = array[5] == "1"; sPermanent = array[6] == "1"; sDropResources = array[7] == "1"; sStationNames = array[8]; sIgnoreRoof = array[9] == "1"; sIgnoreWet = array[10] == "1"; sIgnoreFire = array[11] == "1"; ServerOverride = true; IsAdminHere = array.Length > 12 && array[12] == "1"; SetLocked(!IsAdminHere); if (IsAdminHere) { MirrorToConfig(); } ApplyPrefabs(); if (flag) { Log.LogInfo((object)("Server-Konfiguration übernommen: Verfall nach " + sDecayMinutes + " min.")); } } } catch (Exception ex) { Log.LogWarning((object)("Server-Config konnte nicht gelesen werden: " + ex.Message)); } } private static string ConfigString() { return string.Join("|", (!cfgEnabled.Value) ? "0" : "1", (!cfgAllowPlacement.Value) ? "0" : "1", cfgDecayMinutes.Value.ToString(CultureInfo.InvariantCulture), (!cfgAnyStation.Value) ? "0" : "1", (!cfgOnlyUnsupportedPlaced.Value) ? "0" : "1", (!cfgPermanentWhenStationBuilt.Value) ? "0" : "1", (!cfgDropResources.Value) ? "0" : "1", cfgStationNames.Value.Replace('|', ','), (!cfgIgnoreRoof.Value) ? "0" : "1", (!cfgIgnoreWet.Value) ? "0" : "1", (!cfgIgnoreFire.Value) ? "0" : "1"); } private static void MirrorToConfig() { applyingFromServer = true; try { cfgEnabled.Value = sEnabled; cfgAllowPlacement.Value = sAllowPlacement; cfgDecayMinutes.Value = sDecayMinutes; cfgAnyStation.Value = sAnyStation; cfgOnlyUnsupportedPlaced.Value = sOnlyUnsupportedPlaced; cfgPermanentWhenStationBuilt.Value = sPermanent; cfgDropResources.Value = sDropResources; cfgStationNames.Value = sStationNames; cfgIgnoreRoof.Value = sIgnoreRoof; cfgIgnoreWet.Value = sIgnoreWet; cfgIgnoreFire.Value = sIgnoreFire; } catch (Exception ex) { Log.LogWarning((object)("Spiegeln: " + ex.Message)); } finally { applyingFromServer = false; } } private void OnLocalSettingChanged(object sender, SettingChangedEventArgs e) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (applyingFromServer || !IsRemoteClient || !IsAdminHere) { return; } try { if (ZRoutedRpc.instance != null) { ZPackage val = new ZPackage(); val.Write(ConfigString()); ZRoutedRpc.instance.InvokeRoutedRPC("TempBed_Set", new object[1] { val }); } } catch (Exception ex) { Log.LogWarning((object)("Senden an Server fehlgeschlagen: " + ex.Message)); } } private static bool SenderIsAdmin(long sender) { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null) { return false; } ZNetPeer peer = instance.GetPeer(sender); if (peer == null || peer.m_socket == null) { return false; } return instance.IsAdmin(peer.m_socket.GetHostName()); } internal static void RPC_SetConfig(long sender, ZPackage pkg) { try { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || pkg == null) { return; } if (!SenderIsAdmin(sender)) { Log.LogWarning((object)("Konfigurationsänderung von Nicht-Admin abgelehnt (Peer " + sender + ").")); return; } string[] array = pkg.ReadString().Split('|'); if (array.Length < 8) { return; } applyingFromServer = true; try { cfgEnabled.Value = array[0] == "1"; cfgAllowPlacement.Value = array[1] == "1"; cfgDecayMinutes.Value = float.Parse(array[2], CultureInfo.InvariantCulture); cfgAnyStation.Value = array[3] == "1"; cfgOnlyUnsupportedPlaced.Value = array[4] == "1"; cfgPermanentWhenStationBuilt.Value = array[5] == "1"; cfgDropResources.Value = array[6] == "1"; cfgStationNames.Value = array[7]; if (array.Length > 10) { cfgIgnoreRoof.Value = array[8] == "1"; cfgIgnoreWet.Value = array[9] == "1"; cfgIgnoreFire.Value = array[10] == "1"; } } finally { applyingFromServer = false; } Log.LogInfo((object)("Konfiguration durch Admin geändert (Peer " + sender + ").")); ApplyPrefabs(); if ((Object)(object)Instance != (Object)null) { Instance.pushTimer = 0f; } } catch (Exception ex) { Log.LogWarning((object)("Adminänderung konnte nicht übernommen werden: " + ex.Message)); } } internal static void ApplyPrefabs() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || instance.m_prefabs == null) { return; } bool flag = EffEnabled && EffAllowPlacement; int num = 0; foreach (GameObject prefab in instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } Bed component = prefab.GetComponent<Bed>(); if ((Object)(object)component == (Object)null) { continue; } Piece component2 = prefab.GetComponent<Piece>(); if ((Object)(object)component2 != (Object)null) { CraftingStation value; if (flag) { if ((Object)(object)component2.m_craftingStation != (Object)null) { OriginalStations[((Object)prefab).name] = component2.m_craftingStation; component2.m_craftingStation = null; } } else if ((Object)(object)component2.m_craftingStation == (Object)null && OriginalStations.TryGetValue(((Object)prefab).name, out value)) { component2.m_craftingStation = value; } } if ((Object)(object)prefab.GetComponent<BedDecay>() == (Object)null) { prefab.AddComponent<BedDecay>(); } num++; } Log.LogInfo((object)(num + " Bett-Prefabs angepasst (ohne Werkbank baubar: " + flag + ").")); } internal static bool HasSupportingStation(Vector3 pos) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) try { if (EffAnyStation) { List<IMonoUpdater> instances = CraftingStation.Instances; if (instances == null) { return false; } for (int i = 0; i < instances.Count; i++) { IMonoUpdater obj = instances[i]; CraftingStation val = (CraftingStation)(object)((obj is CraftingStation) ? obj : null); if (!((Object)(object)val == (Object)null) && Vector3.Distance(pos, ((Component)val).transform.position) <= val.GetStationBuildRange()) { return true; } } return false; } string[] array = EffStationNames.Split(','); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length != 0 && (Object)(object)CraftingStation.HaveBuildStationInRange(text2, pos) != (Object)null) { return true; } } return false; } catch (Exception ex) { Log.LogWarning((object)("Stationsprüfung: " + ex.Message)); return true; } } internal static float RemainingSeconds(ZDO zdo) { if (zdo == null || (Object)(object)ZNet.instance == (Object)null) { return -1f; } long num = zdo.GetLong("flo_tb_since", 0L); if (num == 0) { return -1f; } double timeSeconds = ZNet.instance.GetTimeSeconds(); float num2 = (float)((double)EffDecayMinutes * 60.0 - (timeSeconds - (double)num)); return (!(num2 < 0f)) ? num2 : 0f; } } public class BedDecay : MonoBehaviour { private ZNetView nview; private float timer; private void Awake() { nview = ((Component)this).GetComponent<ZNetView>(); timer = Random.Range(0f, 1f); } private void Update() { timer -= Time.deltaTime; if (!(timer > 0f)) { timer = 1f; Tick(); } } private void Tick() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) if (!TempBedPlugin.EffEnabled || (Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner() || (Object)(object)ZNet.instance == (Object)null) { return; } ZDO zDO = nview.GetZDO(); if (zDO == null || (TempBedPlugin.EffOnlyUnsupportedPlaced && zDO.GetInt("flo_tb_mark", 0) == 0)) { return; } bool flag = TempBedPlugin.HasSupportingStation(((Component)this).transform.position); long num = (long)ZNet.instance.GetTimeSeconds(); if (flag) { if (zDO.GetLong("flo_tb_since", 0L) != 0) { zDO.Set("flo_tb_since", 0L); } if (TempBedPlugin.EffPermanent && zDO.GetInt("flo_tb_mark", 0) != 0) { zDO.Set("flo_tb_mark", 0); } return; } long num2 = zDO.GetLong("flo_tb_since", 0L); if (num2 == 0 || num2 > num) { zDO.Set("flo_tb_since", num); } else if (num - num2 >= (long)(TempBedPlugin.EffDecayMinutes * 60f)) { TempBedPlugin.Log.LogInfo((object)("Bett ohne Werkbank verfallen bei " + ((Component)this).transform.position)); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null) { component.Remove(!TempBedPlugin.EffDropResources); } else { nview.Destroy(); } } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class Patch_ZNetScene_Awake { private static void Postfix() { TempBedPlugin.ApplyPrefabs(); } } [HarmonyPatch(typeof(Piece), "OnPlaced")] internal static class Patch_Piece_OnPlaced { private static void Postfix(Piece __instance) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!TempBedPlugin.EffEnabled || (Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).GetComponent<Bed>() == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } ZDO zDO = component.GetZDO(); if (zDO != null) { bool flag = TempBedPlugin.HasSupportingStation(((Component)__instance).transform.position); zDO.Set("flo_tb_mark", (!flag) ? 1 : 0); if (!flag && (Object)(object)ZNet.instance != (Object)null) { zDO.Set("flo_tb_since", (long)ZNet.instance.GetTimeSeconds()); } } } } [HarmonyPatch(typeof(Bed), "GetHoverText")] internal static class Patch_Bed_GetHoverText { private static void Postfix(Bed __instance, ref string __result) { try { if (!TempBedPlugin.EffEnabled || !TempBedPlugin.cfgShowTimer.Value) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO != null && (!TempBedPlugin.EffOnlyUnsupportedPlaced || zDO.GetInt("flo_tb_mark", 0) != 0)) { float num = TempBedPlugin.RemainingSeconds(zDO); if (!(num < 0f)) { int num2 = (int)(num / 60f); int num3 = (int)(num % 60f); string arg = num2 + ":" + num3.ToString("00"); __result = __result + "\n<color=#ff8080>" + string.Format(TempBedPlugin.cfgTimerText.Value, arg) + "</color>"; } } } catch { } } } [HarmonyPatch(typeof(Bed), "CheckExposure")] internal static class Patch_Bed_CheckExposure { private static bool Prefix(ref bool __result) { if (!TempBedPlugin.EffEnabled || !TempBedPlugin.EffIgnoreRoof) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Bed), "CheckWet")] internal static class Patch_Bed_CheckWet { private static bool Prefix(ref bool __result) { if (!TempBedPlugin.EffEnabled || !TempBedPlugin.EffIgnoreWet) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Bed), "CheckFire")] internal static class Patch_Bed_CheckFire { private static bool Prefix(ref bool __result) { if (!TempBedPlugin.EffEnabled || !TempBedPlugin.EffIgnoreFire) { return true; } __result = true; return false; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class Patch_ZRoutedRpc_Ctor { private static void Postfix(ZRoutedRpc __instance) { __instance.Register<ZPackage>("TempBed_Cfg", (Action<long, ZPackage>)TempBedPlugin.RPC_Config); __instance.Register<ZPackage>("TempBed_Set", (Action<long, ZPackage>)TempBedPlugin.RPC_SetConfig); } }