Decompiled source of SpawnTweaks v1.1.0

SpawnTweaks.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModHub;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SpawnTweaks
{
	internal static class SpawnMenu
	{
		private const string Id = "spawntweaks";

		private const float W = 660f;

		private const float H = 600f;

		private const float Pad = 48f;

		private const float RowH = 34f;

		private const float Gap = 12f;

		private static bool _enabled;

		private static bool _fixed;

		private static bool _dirty;

		private static float _stars;

		private static float _rate;

		private static float _maxMobs;

		private static string _status;

		private static float _statusUntil;

		public static bool IsOpen { get; private set; }

		public static void Open()
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				LoadDraft();
				IsOpen = true;
				ModHubAPI.SetInputBlock("spawntweaks", true);
			}
		}

		public static void Close()
		{
			IsOpen = false;
			ModHubAPI.SetInputBlock("spawntweaks", false);
		}

		public static void Update()
		{
			if (IsOpen && (Object)(object)Player.m_localPlayer == (Object)null)
			{
				Close();
			}
			else if (IsOpen && Input.GetKeyDown((KeyCode)27))
			{
				Close();
			}
		}

		private static void LoadDraft()
		{
			_enabled = SpawnTweaksPlugin.Enabled;
			_stars = SpawnTweaksPlugin.StarChance;
			_rate = SpawnTweaksPlugin.SpawnRate;
			_maxMobs = SpawnTweaksPlugin.MaxMobs;
			_fixed = SpawnTweaksPlugin.AffectCreatureSpawners;
			_dirty = false;
		}

		public static void Draw()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				return;
			}
			if (!_dirty)
			{
				LoadDraft();
			}
			Vector2 screen = HubUI.BeginScaled();
			try
			{
				DrawWindow(screen);
			}
			finally
			{
				HubUI.EndScaled();
			}
		}

		private static void DrawWindow(Vector2 screen)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			Rect val = HubUI.Centered(screen, 660f, 600f);
			HubUI.Window(val, "Spawn", false);
			if (HubUI.CloseButton(val))
			{
				Close();
				return;
			}
			if (GUI.Button(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 22f, 30f, 30f), "<", HubUI.ButtonStyle))
			{
				Close();
				ModHubAPI.OpenHub();
				return;
			}
			bool canEdit = SpawnTweaksPlugin.CanEdit;
			float num = ((Rect)(ref val)).x + 48f;
			float num2 = 564f;
			float num3 = ((Rect)(ref val)).y + 92f;
			string text = (HubNet.IsServer ? "Ты хост — настройки применяются ко всем игрокам." : ((!SpawnTweaksPlugin.HasServerValues) ? "На сервере нет SpawnTweaks — меняется только твой конфиг." : (SpawnTweaksPlugin.sIsAdmin ? "Ты админ — изменения уйдут на сервер всем игрокам." : "<color=#B03A34>Настройки сервера. Менять может только админ.</color>")));
			GUI.Label(new Rect(num, num3, num2, 26f), text, HubUI.LabelDimStyle);
			num3 += 38f;
			bool enabled = GUI.enabled;
			GUI.enabled = canEdit;
			bool flag = HubUI.Toggle(new Rect(num, num3, num2, 34f), _enabled, "Мод включён");
			if (flag != _enabled)
			{
				_enabled = flag;
				_dirty = true;
			}
			num3 += 52f;
			HubUI.Header(new Rect(num, num3, num2, 28f), "Звёзды");
			num3 += 34f;
			float num4 = HubUI.SliderText(new Rect(num, num3, num2, 34f), "Шанс звезды", _stars, 0f, 100f, $"{_stars:0}%", "0.##", -1f);
			num4 = Mathf.Round(num4);
			if (!Mathf.Approximately(num4, _stars))
			{
				_stars = num4;
				_dirty = true;
			}
			num3 += 38f;
			float num5 = _stars / 100f;
			GUI.Label(new Rect(num, num3, num2, 24f), $"1+ звезда: {num5 * 100f:0.#}%    2 звезды: {num5 * num5 * 100f:0.#}%    (ваниль: 10%)", HubUI.LabelDimStyle);
			num3 += 42f;
			HubUI.Header(new Rect(num, num3, num2, 28f), "Спавн");
			num3 += 34f;
			float num6 = HubUI.SliderText(new Rect(num, num3, num2, 34f), "Частота спавна", _rate, 0.1f, 10f, $"x{_rate:0.0}", "0.##", -1f);
			num6 = Mathf.Round(num6 * 10f) / 10f;
			if (!Mathf.Approximately(num6, _rate))
			{
				_rate = num6;
				_dirty = true;
			}
			num3 += 46f;
			float num7 = HubUI.SliderText(new Rect(num, num3, num2, 34f), "Макс. мобов рядом", _maxMobs, 0.1f, 10f, $"x{_maxMobs:0.0}", "0.##", -1f);
			num7 = Mathf.Round(num7 * 10f) / 10f;
			if (!Mathf.Approximately(num7, _maxMobs))
			{
				_maxMobs = num7;
				_dirty = true;
			}
			num3 += 46f;
			bool flag2 = HubUI.Toggle(new Rect(num, num3, num2, 34f), _fixed, "Лагеря и деревни (звёзды и скорость респавна)");
			if (flag2 != _fixed)
			{
				_fixed = flag2;
				_dirty = true;
			}
			float num8 = ((Rect)(ref val)).yMax - 96f;
			float num9 = (num2 - 24f) / 3f;
			if (HubUI.Button(new Rect(num, num8, num9, 40f), "Ванилла"))
			{
				_stars = 10f;
				_rate = 1f;
				_maxMobs = 1f;
				_dirty = true;
			}
			GUI.enabled = enabled && _dirty;
			if (HubUI.Button(new Rect(num + num9 + 12f, num8, num9, 40f), "Отменить"))
			{
				LoadDraft();
			}
			GUI.enabled = enabled && canEdit && _dirty;
			if (HubUI.Button(new Rect(num + (num9 + 12f) * 2f, num8, num9, 40f), _dirty ? "Применить *" : "Применить"))
			{
				Apply();
			}
			GUI.enabled = enabled;
			string text2 = ((Time.unscaledTime < _statusUntil) ? _status : "Esc — закрыть");
			GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).yMax - 46f, ((Rect)(ref val)).width - 48f, 22f), text2, HubUI.LabelCenterStyle);
		}

		private static void Apply()
		{
			if (HubNet.IsServer || !SpawnTweaksPlugin.HasServerValues)
			{
				ConfigSync.ApplyLocal(_enabled, _stars, _rate, _maxMobs, _fixed);
				SetStatus("Сохранено");
			}
			else
			{
				if (!ConfigSync.SendToServer(_enabled, _stars, _rate, _maxMobs, _fixed))
				{
					SetStatus("Нет связи с сервером");
					return;
				}
				SetStatus("Отправлено на сервер");
			}
			_dirty = false;
		}

		private static void SetStatus(string text)
		{
			_status = text;
			_statusUntil = Time.unscaledTime + 3f;
		}
	}
	[BepInPlugin("kaefchik.spawntweaks", "SpawnTweaks", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SpawnTweaksPlugin : BaseUnityPlugin
	{
		public const string GUID = "kaefchik.spawntweaks";

		public const string NAME = "SpawnTweaks";

		public const string VERSION = "1.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> cEnabled;

		internal static ConfigEntry<float> cStarChance;

		internal static ConfigEntry<float> cSpawnRate;

		internal static ConfigEntry<float> cMaxMobs;

		internal static ConfigEntry<bool> cAffectCreatureSpawners;

		internal static bool HasServerValues;

		internal static bool sEnabled;

		internal static bool sAffectCreatureSpawners;

		internal static float sStarChance;

		internal static float sSpawnRate;

		internal static float sMaxMobs;

		internal static bool sIsAdmin;

		private FileSystemWatcher _watcher;

		private volatile bool _reloadPending;

		private bool _dirty;

		public static bool CanEdit => HubNet.IsServer || !HasServerValues || sIsAdmin;

		public static bool Enabled => HasServerValues ? sEnabled : cEnabled.Value;

		public static float StarChance => HasServerValues ? sStarChance : cStarChance.Value;

		public static float SpawnRate => HasServerValues ? sSpawnRate : cSpawnRate.Value;

		public static float MaxMobs => HasServerValues ? sMaxMobs : cMaxMobs.Value;

		public static bool AffectCreatureSpawners => HasServerValues ? sAffectCreatureSpawners : cAffectCreatureSpawners.Value;

		private void Awake()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			cEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Enable the mod. Server config overrides clients.");
			cStarChance = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Stars", "StarChancePercent", 25f, new ConfigDescription("Chance (%) for a mob to get each next star. Vanilla = 10. 25 = ~1 of 4 mobs has 1+ star, ~1 of 16 has 2 stars. Only mobs that can have stars in vanilla are affected.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			cSpawnRate = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Spawn", "SpawnRateMultiplier", 1f, new ConfigDescription("How often ALL mobs spawn. 2 = twice as often. 1 = vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			cMaxMobs = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Spawn", "MaxMobsMultiplier", 1f, new ConfigDescription("Multiplier for the max amount of ALL mobs around the player. 2 = twice as many. 1 = vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			cAffectCreatureSpawners = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Spawn", "AffectFixedSpawners", true, "Also affect fixed spawners (camps, dungeons, villages): star chance and respawn speed.");
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				_dirty = true;
			};
			_watcher = new FileSystemWatcher(Paths.ConfigPath, "kaefchik.spawntweaks.cfg");
			_watcher.Changed += delegate
			{
				_reloadPending = true;
			};
			_watcher.Created += delegate
			{
				_reloadPending = true;
			};
			_watcher.IncludeSubdirectories = false;
			_watcher.EnableRaisingEvents = true;
			SpawnApplier.Init();
			new Harmony("kaefchik.spawntweaks").PatchAll();
			Action action = SpawnMenu.Open;
			Action action2 = SpawnMenu.Close;
			ModHubAPI.Register("spawntweaks", "Spawn", action, "TrophyGreydwarf", (Sprite)null, (Color?)null, "Частота спавна мобов и шанс звёзд", 40, (Func<bool>)null, action2, (Func<bool>)(() => SpawnMenu.IsOpen));
			Log.LogInfo((object)"SpawnTweaks 1.1.0 loaded");
		}

		private void Update()
		{
			SpawnMenu.Update();
			if (_reloadPending)
			{
				_reloadPending = false;
				try
				{
					((BaseUnityPlugin)this).Config.Reload();
					_dirty = true;
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Config reload failed: " + ex.Message));
				}
			}
			if (_dirty)
			{
				_dirty = false;
				ConfigSync.BroadcastIfServer();
				if (!HasServerValues)
				{
					SpawnApplier.ReapplyAll();
				}
			}
		}

		private void OnGUI()
		{
			SpawnMenu.Draw();
		}

		private void OnDestroy()
		{
			_watcher?.Dispose();
		}
	}
	internal static class SpawnApplier
	{
		private class SpawnOrig
		{
			public float Interval;

			public int MaxSpawned;

			public float LevelChance;
		}

		private class FixedOrig
		{
			public float LevelChance;

			public float Respawn;
		}

		private static readonly Dictionary<SpawnData, SpawnOrig> _spawnData = new Dictionary<SpawnData, SpawnOrig>();

		private static readonly ConditionalWeakTable<CreatureSpawner, FixedOrig> _fixed = new ConditionalWeakTable<CreatureSpawner, FixedOrig>();

		private static FieldInfo fOverrideLevelup;

		private static FieldInfo fFixedLevelup;

		private static FieldInfo fFixedRespawn;

		public static void Init()
		{
			fOverrideLevelup = AccessTools.Field(typeof(SpawnData), "m_overrideLevelupChance");
			fFixedLevelup = AccessTools.Field(typeof(CreatureSpawner), "m_levelupChance");
			fFixedRespawn = AccessTools.Field(typeof(CreatureSpawner), "m_respawnTimeMinuts");
			if (fOverrideLevelup == null)
			{
				SpawnTweaksPlugin.Log.LogWarning((object)"SpawnData.m_overrideLevelupChance not found — star chance for world spawns won't work on this game version.");
			}
			if (fFixedLevelup == null)
			{
				SpawnTweaksPlugin.Log.LogWarning((object)"CreatureSpawner.m_levelupChance not found — star chance for fixed spawners won't work.");
			}
			if (fFixedRespawn == null)
			{
				SpawnTweaksPlugin.Log.LogWarning((object)"CreatureSpawner.m_respawnTimeMinuts not found — respawn speed for fixed spawners won't work.");
			}
		}

		private static bool CanHaveStars(int maxLevel)
		{
			return maxLevel > 1;
		}

		public static void Apply(SpawnData d)
		{
			if (d == null)
			{
				return;
			}
			if (!_spawnData.TryGetValue(d, out var value))
			{
				value = new SpawnOrig
				{
					Interval = d.m_spawnInterval,
					MaxSpawned = d.m_maxSpawned,
					LevelChance = ((fOverrideLevelup != null) ? ((float)fOverrideLevelup.GetValue(d)) : (-1f))
				};
				_spawnData[d] = value;
			}
			d.m_spawnInterval = value.Interval;
			d.m_maxSpawned = value.MaxSpawned;
			fOverrideLevelup?.SetValue(d, value.LevelChance);
			if (SpawnTweaksPlugin.Enabled)
			{
				float num = Mathf.Max(0.1f, SpawnTweaksPlugin.SpawnRate);
				d.m_spawnInterval = Mathf.Max(1f, value.Interval / num);
				d.m_maxSpawned = Mathf.Max(1, Mathf.RoundToInt((float)value.MaxSpawned * SpawnTweaksPlugin.MaxMobs));
				if (CanHaveStars(d.m_maxLevel))
				{
					fOverrideLevelup?.SetValue(d, SpawnTweaksPlugin.StarChance);
				}
			}
		}

		public static void Apply(CreatureSpawner cs)
		{
			if ((Object)(object)cs == (Object)null)
			{
				return;
			}
			if (!_fixed.TryGetValue(cs, out var value))
			{
				value = new FixedOrig
				{
					LevelChance = ((fFixedLevelup != null) ? ((float)fFixedLevelup.GetValue(cs)) : 10f),
					Respawn = ((fFixedRespawn != null) ? ((float)fFixedRespawn.GetValue(cs)) : 0f)
				};
				_fixed.Add(cs, value);
			}
			fFixedLevelup?.SetValue(cs, value.LevelChance);
			fFixedRespawn?.SetValue(cs, value.Respawn);
			if (SpawnTweaksPlugin.Enabled && SpawnTweaksPlugin.AffectCreatureSpawners)
			{
				if (CanHaveStars(cs.m_maxLevel))
				{
					fFixedLevelup?.SetValue(cs, SpawnTweaksPlugin.StarChance);
				}
				if (value.Respawn > 0f)
				{
					float num = Mathf.Max(0.1f, SpawnTweaksPlugin.SpawnRate);
					fFixedRespawn?.SetValue(cs, Mathf.Max(0.5f, value.Respawn / num));
				}
			}
		}

		public static void ReapplyAll()
		{
			foreach (SpawnData item in _spawnData.Keys.ToList())
			{
				Apply(item);
			}
			CreatureSpawner[] array = Object.FindObjectsOfType<CreatureSpawner>();
			foreach (CreatureSpawner cs in array)
			{
				Apply(cs);
			}
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Awake")]
	internal static class Patch_SpawnSystem_Awake
	{
		private static void Postfix(SpawnSystem __instance)
		{
			if (__instance.m_spawnLists == null)
			{
				return;
			}
			foreach (SpawnSystemList spawnList in __instance.m_spawnLists)
			{
				if ((Object)(object)spawnList == (Object)null || spawnList.m_spawners == null)
				{
					continue;
				}
				foreach (SpawnData spawner in spawnList.m_spawners)
				{
					SpawnApplier.Apply(spawner);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CreatureSpawner), "Awake")]
	internal static class Patch_CreatureSpawner_Awake
	{
		private static void Postfix(CreatureSpawner __instance)
		{
			SpawnApplier.Apply(__instance);
		}
	}
	internal static class ConfigSync
	{
		public const string RPC = "SpawnTweaks_SyncConfig";

		public const string RPC_SET = "SpawnTweaks_SetConfig";

		private const int ProtocolVersion = 2;

		public static ZPackage Build(bool receiverIsAdmin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(2);
			val.Write(receiverIsAdmin);
			val.Write(SpawnTweaksPlugin.cEnabled.Value);
			val.Write(SpawnTweaksPlugin.cStarChance.Value);
			val.Write(SpawnTweaksPlugin.cSpawnRate.Value);
			val.Write(SpawnTweaksPlugin.cMaxMobs.Value);
			val.Write(SpawnTweaksPlugin.cAffectCreatureSpawners.Value);
			return val;
		}

		public static void Receive(ZRpc rpc, ZPackage p)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer())
			{
				int num = p.ReadInt();
				if (num != 2)
				{
					SpawnTweaksPlugin.Log.LogWarning((object)$"Server SpawnTweaks protocol {num} != {2}. Update the mod on both sides.");
					return;
				}
				SpawnTweaksPlugin.sIsAdmin = p.ReadBool();
				SpawnTweaksPlugin.sEnabled = p.ReadBool();
				SpawnTweaksPlugin.sStarChance = p.ReadSingle();
				SpawnTweaksPlugin.sSpawnRate = p.ReadSingle();
				SpawnTweaksPlugin.sMaxMobs = p.ReadSingle();
				SpawnTweaksPlugin.sAffectCreatureSpawners = p.ReadBool();
				SpawnTweaksPlugin.HasServerValues = true;
				SpawnTweaksPlugin.Log.LogInfo((object)$"Server config: stars {SpawnTweaksPlugin.sStarChance}%, spawn rate x{SpawnTweaksPlugin.sSpawnRate}, max mobs x{SpawnTweaksPlugin.sMaxMobs}");
				SpawnApplier.ReapplyAll();
			}
		}

		public static void BroadcastIfServer()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer != null)
				{
					ZRpc rpc = peer.m_rpc;
					if (rpc != null)
					{
						rpc.Invoke("SpawnTweaks_SyncConfig", new object[1] { Build(HubNet.IsAdmin(peer)) });
					}
				}
			}
		}

		public static bool SendToServer(bool enabled, float stars, float rate, float maxMobs, bool fixedSpawners)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			ZRpc val = HubNet.ServerRpc();
			if (val == null)
			{
				return false;
			}
			ZPackage val2 = new ZPackage();
			val2.Write(2);
			val2.Write(enabled);
			val2.Write(stars);
			val2.Write(rate);
			val2.Write(maxMobs);
			val2.Write(fixedSpawners);
			val.Invoke("SpawnTweaks_SetConfig", new object[1] { val2 });
			return true;
		}

		public static void ReceiveSet(ZRpc rpc, ZPackage p)
		{
			if (HubNet.IsServer)
			{
				ZNetPeer val = HubNet.FindPeer(rpc);
				if (!HubNet.IsAdmin(val))
				{
					SpawnTweaksPlugin.Log.LogWarning((object)("Ignored SpawnTweaks settings from non-admin " + (val?.m_playerName ?? "?")));
				}
				else if (p.ReadInt() == 2)
				{
					ApplyLocal(p.ReadBool(), p.ReadSingle(), p.ReadSingle(), p.ReadSingle(), p.ReadBool());
					SpawnTweaksPlugin.Log.LogInfo((object)("SpawnTweaks settings changed by admin " + val.m_playerName));
				}
			}
		}

		public static void ApplyLocal(bool enabled, float stars, float rate, float maxMobs, bool fixedSpawners)
		{
			SpawnTweaksPlugin.cEnabled.Value = enabled;
			SpawnTweaksPlugin.cStarChance.Value = Mathf.Clamp(stars, 0f, 100f);
			SpawnTweaksPlugin.cSpawnRate.Value = Mathf.Clamp(rate, 0.1f, 10f);
			SpawnTweaksPlugin.cMaxMobs.Value = Mathf.Clamp(maxMobs, 0.1f, 10f);
			SpawnTweaksPlugin.cAffectCreatureSpawners.Value = fixedSpawners;
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	internal static class Patch_ZNet_OnNewConnection
	{
		private static void Postfix(ZNetPeer peer)
		{
			if (peer != null)
			{
				ZRpc rpc = peer.m_rpc;
				if (rpc != null)
				{
					rpc.Register<ZPackage>("SpawnTweaks_SyncConfig", (Action<ZRpc, ZPackage>)ConfigSync.Receive);
				}
			}
			if (peer != null)
			{
				ZRpc rpc2 = peer.m_rpc;
				if (rpc2 != null)
				{
					rpc2.Register<ZPackage>("SpawnTweaks_SetConfig", (Action<ZRpc, ZPackage>)ConfigSync.ReceiveSet);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	internal static class Patch_ZNet_RPC_PeerInfo
	{
		private static void Postfix(ZNet __instance, ZRpc rpc)
		{
			if (__instance.IsServer() && rpc != null)
			{
				rpc.Invoke("SpawnTweaks_SyncConfig", new object[1] { ConfigSync.Build(HubNet.IsAdmin(HubNet.FindPeer(rpc))) });
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnDestroy")]
	internal static class Patch_ZNet_OnDestroy
	{
		private static void Postfix()
		{
			SpawnTweaksPlugin.HasServerValues = false;
			SpawnTweaksPlugin.sIsAdmin = false;
		}
	}
}