Decompiled source of FixedMistRNG v1.0.0

FixedMistRNG.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using FixedMistRNG.SSMPAddon;
using FixedMistRNG.SSMPAddon.Command.Server;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using Microsoft.CodeAnalysis;
using SSMP.Api.Client;
using SSMP.Api.Client.Networking;
using SSMP.Api.Command;
using SSMP.Api.Command.Server;
using SSMP.Api.Server;
using SSMP.Api.Server.Networking;
using SSMP.Networking.Packet;
using Silksong.FsmUtil;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Models;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("FixedMistRNG")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+710638c33c6de87593a304104594aa2018e75c21")]
[assembly: AssemblyProduct("FixedMistRNG")]
[assembly: AssemblyTitle("FixedMistRNG")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Vitaxses/FixedMistRNG")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class UpdateSeedPacketData : IPacketData
{
	public bool IsReliable => true;

	public bool DropReliableDataIfNewerExists => true;

	public int Seed { get; set; }

	public bool AdjustSeed { get; set; }

	public void ReadData(IPacket packet)
	{
		Seed = packet.ReadInt();
		AdjustSeed = packet.ReadBool();
	}

	public void WriteData(IPacket packet)
	{
		packet.Write(Seed);
		packet.Write(AdjustSeed);
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace FixedMistRNG
{
	[HarmonyPatch(typeof(ActivateRandomChildren), "OnEnable")]
	internal static class ActivateRandomChildrenPatch
	{
		[HarmonyPrefix]
		public static bool Prefix_OnEnable(ActivateRandomChildren __instance)
		{
			//IL_000d: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			if (FixedMistClientAddon.IsConnected())
			{
				Scene scene = ((Component)__instance).gameObject.scene;
				if (((Scene)(ref scene)).name.StartsWith("Dust_Maze"))
				{
					foreach (Transform item in ((Component)__instance).transform)
					{
						((Component)item).gameObject.SetActive(false);
					}
					Random random = new Random(FixedMistClientAddon.Instance.GetSeed());
					int num = random.Next(__instance.amountMin, __instance.amountMax);
					while ((float)num > 0f)
					{
						int num2 = random.Next(0, ((Component)__instance).transform.childCount);
						((Component)((Component)__instance).transform.GetChild(num2)).gameObject.SetActive(true);
						num--;
					}
					return false;
				}
			}
			return true;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("io.github.vitaxses.fixedmistrng", "FixedMistRNG", "1.0.0")]
	public class FixedMistPlugin : BaseUnityPlugin, IModMenuCustomMenu, IModMenuInterface
	{
		public const string Id = "io.github.vitaxses.fixedmistrng";

		public static string Name => "FixedMistRNG";

		public static string Version => "1.0.0";

		private void Awake()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			ClientAddon.RegisterAddon((ClientAddon)(object)new FixedMistClientAddon());
			ServerAddon.RegisterAddon((ServerAddon)(object)new FixedMistServerAddon());
			new Harmony("io.github.vitaxses.fixedmistrng").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (io.github.vitaxses.fixedmistrng) v" + Version + " has loaded!"));
		}

		public LocalizedText ModMenuName()
		{
			return LocalizedText.op_Implicit("Fixed Mist RNG");
		}

		public AbstractMenuScreen BuildCustomMenu()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(ModMenuName(), 8);
			string adjustSeedDescription = "Randomize the seed if a player leaves The Mist or respawns at the entrance while no one else is inside";
			ChoiceElement<bool> adjustSeedElement = new ChoiceElement<bool>(LocalizedText.Raw("Randomize Seed"), (IChoiceModel<bool>)(object)ChoiceModels.ForBool("No", "Yes"));
			SliderElement<int> seedElement = new SliderElement<int>(LocalizedText.Raw("Seed"), (SliderModel<int>)(object)SliderModels.ForInts(0, 1000));
			val.Add((MenuElement)(object)adjustSeedElement);
			val.Add((MenuElement)(object)seedElement);
			PaginatedMenuScreen obj = val.Build();
			((AbstractMenuScreen)obj).OnShow += delegate
			{
				Text descriptionText = adjustSeedElement.DescriptionText;
				SliderElement<int> obj2 = seedElement;
				bool flag2 = (((SelectableElement)adjustSeedElement).Interactable = FixedMistClientAddon.IsConnected());
				bool flag4 = (((SelectableElement)obj2).Interactable = flag2);
				descriptionText.text = (flag4 ? adjustSeedDescription : "");
				((SelectableValueElement<bool>)(object)adjustSeedElement).Value = FixedMistClientAddon.Instance != null && FixedMistClientAddon.Instance.AdjustSeed;
				((SelectableValueElement<int>)(object)seedElement).Value = ((FixedMistClientAddon.Instance == null) ? (-1) : FixedMistClientAddon.Instance.CurrentSeed);
			};
			((AbstractMenuScreen)obj).OnHide += delegate
			{
				if (FixedMistClientAddon.IsConnected())
				{
					FixedMistClientAddon.Instance.SendOptionUpdate(((SelectableValueElement<int>)(object)seedElement).Value, ((SelectableValueElement<bool>)(object)adjustSeedElement).Value);
				}
			};
			return (AbstractMenuScreen)(object)obj;
		}
	}
	[HarmonyPatch(typeof(MazeController))]
	internal static class MazeControllerPatches
	{
		private static Random? rng;

		[HarmonyPatch("LinkDoors")]
		[HarmonyPrefix]
		private static bool LinkDoors(MazeController __instance, IReadOnlyList<TransitionPoint> totalDoors)
		{
			MazeController __instance2 = __instance;
			if (!FixedMistClientAddon.IsConnected() || rng == null)
			{
				return true;
			}
			__instance2.correctDoors.Clear();
			var list = (from x in totalDoors.Select(delegate(TransitionPoint door)
				{
					if ((Object)(object)door == (Object)null)
					{
						return null;
					}
					string name = ((Object)door).name;
					string doorDirMatch = __instance2.GetDoorDirMatch(name);
					return string.IsNullOrEmpty(doorDirMatch) ? null : new
					{
						Door = door,
						DoorName = name,
						TargetDoorMatch = doorDirMatch
					};
				})
				where x != null
				select x).ToList();
			Dictionary<string, SceneInfo> teleportMap = SceneTeleportMap.GetTeleportMap();
			List<KeyValuePair<string, SceneInfo>> list2 = teleportMap.Where(delegate(KeyValuePair<string, SceneInfo> kvp)
			{
				//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)
				string key = kvp.Key;
				Scene scene = ((Component)__instance2).gameObject.scene;
				return key != ((Scene)(ref scene)).name && __instance2.sceneNames.Contains(kvp.Key);
			}).ToList();
			PlayerData instance = PlayerData.instance;
			int num = list.Count;
			int num2 = (instance.hasNeedolin ? rng.Next(0, num) : (-1));
			list.Shuffle(rng);
			int num3 = __instance2.neededCorrectDoors - 1;
			if (!__instance2.isCapScene)
			{
				__instance2.specialLinkDoors.Clear();
				string text;
				if (instance.CorrectMazeDoorsEntered >= num3)
				{
					text = __instance2.exitSceneName;
					if (__instance2.forceExit)
					{
						__instance2.specialLinkDoors.AddRange(teleportMap[__instance2.exitSceneName].TransitionGates);
					}
					else
					{
						EntryMatch exitMatch = __instance2.GetExitMatch();
						if (exitMatch != null)
						{
							__instance2.specialLinkDoors.AddRange(teleportMap[__instance2.exitSceneName].TransitionGates.Where((string gate) => gate.StartsWith(exitMatch.ExitDoorDir)).ToList());
						}
						else
						{
							__instance2.specialLinkDoors.AddRange(teleportMap[__instance2.exitSceneName].TransitionGates);
						}
					}
				}
				else
				{
					if (instance.CorrectMazeDoorsEntered < __instance2.restScenePoint - 1 || instance.EnteredMazeRestScene)
					{
						goto IL_02fe;
					}
					text = __instance2.restSceneName;
					__instance2.specialLinkDoors.AddRange(teleportMap[__instance2.restSceneName].TransitionGates);
				}
				__instance2.specialLinkDoors.Shuffle(rng);
				for (int num4 = list.Count - 1; num4 >= 0; num4--)
				{
					var anon = list[num4];
					TransitionPoint door2 = anon.Door;
					string doorName = anon.DoorName;
					if (string.IsNullOrEmpty(instance.PreviousMazeTargetDoor) || instance.PreviousMazeTargetDoor != doorName)
					{
						bool flag = false;
						foreach (string specialLinkDoor in __instance2.specialLinkDoors)
						{
							if (__instance2.TryMatchDoor(text, specialLinkDoor, anon.TargetDoorMatch, door2, true))
							{
								flag = true;
								break;
							}
						}
						if (flag)
						{
							num2 = -1;
							list.RemoveAt(num4);
							num--;
							break;
						}
					}
				}
				goto IL_02fe;
			}
			goto IL_030e;
			IL_02fe:
			__instance2.specialLinkDoors.Clear();
			goto IL_030e;
			IL_030e:
			for (int i = 0; i < num; i++)
			{
				var anon2 = list[i];
				TransitionPoint door3 = anon2.Door;
				string doorName2 = anon2.DoorName;
				if (!string.IsNullOrEmpty(instance.PreviousMazeTargetDoor) && doorName2 == instance.PreviousMazeTargetDoor)
				{
					door3.SetTargetScene(instance.PreviousMazeScene);
					door3.entryPoint = instance.PreviousMazeDoor;
					if (instance.PreviousMazeScene == __instance2.exitSceneName)
					{
						num2 = i;
						__instance2.correctDoors.Clear();
					}
					else if (instance.DidEnterPreviousMazeDoor)
					{
						num2 = i;
						__instance2.correctDoors.Clear();
					}
					else if (num > 1)
					{
						while (num2 == i)
						{
							num2 = rng.Next(0, num);
						}
					}
					if (num2 == i)
					{
						__instance2.correctDoors.Add(door3);
					}
					continue;
				}
				list2.Shuffle(rng);
				if (!string.IsNullOrEmpty(instance.PreviousMazeScene))
				{
					for (int num5 = list2.Count - 1; num5 >= 0; num5--)
					{
						KeyValuePair<string, SceneInfo> item = list2[num5];
						if (item.Key == instance.PreviousMazeScene)
						{
							list2.RemoveAt(num5);
							list2.Add(item);
						}
					}
				}
				foreach (KeyValuePair<string, SceneInfo> item2 in list2)
				{
					if (__instance2.TryFindMatchingDoor(item2.Key, item2.Value.TransitionGates, anon2.TargetDoorMatch, door3, num2 == i))
					{
						break;
					}
				}
			}
			if (__instance2.isCapScene || __instance2.correctDoors.Count > 0 || num2 < 0)
			{
				return false;
			}
			__instance2.LinkDoors(totalDoors);
			return false;
		}

		[HarmonyPatch(typeof(MazeController), "Activate")]
		[HarmonyPrefix]
		private static void Prefix_Activate(MazeController __instance)
		{
			if (FixedMistClientAddon.IsConnected())
			{
				rng = new Random(FixedMistClientAddon.Instance.GetSeed());
			}
		}

		public static void Shuffle<T>(this IList<T> list, Random rng)
		{
			for (int num = list.Count - 1; num > 0; num--)
			{
				int num2 = rng.Next(num + 1);
				int index = num;
				int index2 = num2;
				T value = list[num2];
				T value2 = list[num];
				list[index] = value;
				list[index2] = value2;
			}
		}
	}
	[HarmonyPatch(typeof(PlayMakerFSM), "Start")]
	internal static class PlayMakerFSMPatch
	{
		[HarmonyPostfix]
		private static void Postfix_Start(PlayMakerFSM __instance)
		{
			if (FixedMistClientAddon.IsConnected())
			{
				MistMazeController(__instance);
				WraithSpawner(__instance);
			}
		}

		private static void SetNode(PlayMakerFSM fsm, FsmGameObject? nodes, Random rng)
		{
			if (nodes != null && !((Object)(object)nodes.Value == (Object)null))
			{
				Transform transform = nodes.Value.transform;
				if (transform.childCount != 0)
				{
					GameObject gameObject = ((Component)transform.GetChild(rng.Next(transform.childCount))).gameObject;
					FsmUtil.FindGameObjectVariable(fsm, "Next Node").Value = gameObject;
				}
			}
		}

		private static void MistMazeController(PlayMakerFSM fsm)
		{
			PlayMakerFSM fsm2 = fsm;
			if (!(fsm2.FsmName != "mist_maze_controller"))
			{
				Random rng = new Random(FixedMistClientAddon.Instance.GetSeed());
				FsmState state = FsmUtil.GetState(fsm2, "Set Silkflies");
				FsmUtil.DisableAction(state, 1);
				FsmGameObject silkFlyNodes = FsmUtil.FindGameObjectVariable(fsm2, "Silkfly Nodes");
				FsmUtil.InsertMethod(state, 1, (Action<FsmStateAction>)delegate
				{
					SetNode(fsm2, silkFlyNodes, rng);
				});
				FsmState state2 = FsmUtil.GetState(fsm2, "Set Traps");
				FsmUtil.DisableAction(state2, 0);
				FsmGameObject traps = FsmUtil.FindGameObjectVariable(fsm2, "Trap Sets");
				FsmUtil.InsertMethod(state2, 0, (Action<FsmStateAction>)delegate
				{
					SetNode(fsm2, traps, rng);
				});
				FsmState state3 = FsmUtil.GetState(fsm2, "Set Wraiths");
				FsmUtil.DisableAction(state3, 0);
				FsmGameObject wraithNodes = FsmUtil.FindGameObjectVariable(fsm2, "Wraith Nodes");
				FsmUtil.InsertMethod(state3, 0, (Action<FsmStateAction>)delegate
				{
					SetNode(fsm2, wraithNodes, rng);
				});
			}
		}

		private static void WraithSpawner(PlayMakerFSM fsm)
		{
			PlayMakerFSM fsm2 = fsm;
			if (fsm2.FsmName != "Control" || !((Object)fsm2).name.StartsWith("Wraith Summoner"))
			{
				return;
			}
			Random rng = new Random(FixedMistClientAddon.Instance.GetSeed());
			FsmState state = FsmUtil.GetState(fsm2, "Choose");
			SendRandomEvent action = FsmUtil.GetAction<SendRandomEvent>(state, 0);
			FsmEvent[] originalEvents = action.events;
			List<FsmEvent> remaining = originalEvents.ToList();
			FsmUtil.DisableAction(state, 0);
			FsmUtil.AddMethod(state, (Action)delegate
			{
				if (remaining.Count == 0)
				{
					remaining = originalEvents.ToList();
				}
				int index = rng.Next(remaining.Count);
				FsmEvent val = remaining[index];
				remaining.RemoveAt(index);
				fsm2.SendEvent(val.Name);
			}, false);
		}
	}
}
namespace FixedMistRNG.SSMPAddon
{
	internal static class AddonIdentifiers
	{
		public const string NAME = "Fixed Mist RNG";

		public static string VERSION => Assembly.GetExecutingAssembly().GetName().Version.ToString();
	}
	public class FixedMistClientAddon : ClientAddon
	{
		internal static FixedMistClientAddon? Instance;

		private IClientAddonNetworkSender<C2SPacketId>? sender;

		private IClientAddonNetworkReceiver<S2CPacketId>? receiver;

		public override bool NeedsNetwork => true;

		public override uint ApiVersion => 1u;

		protected override string Name => "Fixed Mist RNG";

		protected override string Version => AddonIdentifiers.VERSION;

		public int CurrentSeed { get; private set; }

		public bool AdjustSeed { get; private set; }

		public override void Initialize(IClientApi clientApi)
		{
			Instance = this;
			sender = clientApi.NetClient.GetNetworkSender<C2SPacketId>((ClientAddon)(object)this);
			receiver = clientApi.NetClient.GetNetworkReceiver<S2CPacketId>((ClientAddon)(object)this, (Func<S2CPacketId, IPacketData>)InstantiatePacket);
			RegisterPacketHandlers();
		}

		private void RegisterPacketHandlers()
		{
			receiver?.RegisterPacketHandler<UpdateSeedPacketData>(S2CPacketId.UpdateSeed, (GenericClientPacketHandler<UpdateSeedPacketData>)delegate(UpdateSeedPacketData packetData)
			{
				CurrentSeed = packetData.Seed;
				AdjustSeed = packetData.AdjustSeed;
			});
		}

		public static IPacketData? InstantiatePacket(S2CPacketId id)
		{
			if (id == S2CPacketId.UpdateSeed)
			{
				return (IPacketData?)(object)new UpdateSeedPacketData();
			}
			return null;
		}

		public void SendOptionUpdate(int Seed, bool AdjustSeed)
		{
			if ((CurrentSeed != Seed || this.AdjustSeed != AdjustSeed) && sender != null && IsConnected())
			{
				sender.SendSingleData(C2SPacketId.UpdateSettings, (IPacketData)(object)new UpdateSeedPacketData
				{
					Seed = Seed,
					AdjustSeed = AdjustSeed
				});
			}
		}

		internal static bool IsConnected()
		{
			if (Instance != null && ((ClientAddon)Instance).ClientApi != null)
			{
				return ((ClientAddon)Instance).ClientApi.NetClient.IsConnected;
			}
			return false;
		}

		internal int GetSeed()
		{
			//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)
			int currentSeed = CurrentSeed;
			Scene activeScene = SceneManager.GetActiveScene();
			return currentSeed ^ ((Scene)(ref activeScene)).name.GetHashCode();
		}
	}
	public class FixedMistServerAddon : ServerAddon
	{
		internal static FixedMistServerAddon? Instance;

		private IServerApi? api;

		private IServerAddonNetworkSender<S2CPacketId>? sender;

		private IServerAddonNetworkReceiver<C2SPacketId>? receiver;

		private readonly List<ushort> playersInMist = new List<ushort>();

		private Random? rng;

		public override bool NeedsNetwork => true;

		public override uint ApiVersion => 1u;

		protected override string Name => "Fixed Mist RNG";

		protected override string Version => AddonIdentifiers.VERSION;

		public int CurrentSeed { get; private set; }

		public bool AdjustSeed { get; private set; }

		public override void Initialize(IServerApi Api)
		{
			Instance = this;
			api = Api;
			((ICommandManager<IServerCommand>)(object)api.CommandManager).RegisterCommand((IServerCommand)(object)new SetSeedCommand(this));
			sender = api.NetServer.GetNetworkSender<S2CPacketId>((ServerAddon)(object)this);
			receiver = api.NetServer.GetNetworkReceiver<C2SPacketId>((ServerAddon)(object)this, (Func<C2SPacketId, IPacketData>)InstantiatePacket);
			RegisterPacketHandlers();
			api.ServerManager.PlayerDisconnectEvent += delegate(IServerPlayer player)
			{
				playersInMist.Remove(player.Id);
			};
			api.ServerManager.PlayerConnectEvent += OnPlayerConnect;
			api.ServerManager.PlayerEnterSceneEvent += OnPlayerEnterScene;
			SetSeed(GenerateNewSeed());
		}

		private void OnPlayerEnterScene(IServerPlayer player)
		{
			string currentScene = player.CurrentScene;
			if (IsMist(currentScene) && !playersInMist.Contains(player.Id))
			{
				playersInMist.Add(player.Id);
			}
			else if (!IsMist(currentScene) && playersInMist.Remove(player.Id))
			{
				CheckForMistUpdate();
			}
		}

		private void OnPlayerConnect(IServerPlayer player)
		{
			if (IsMist(player.CurrentScene) && !playersInMist.Contains(player.Id))
			{
				playersInMist.Add(player.Id);
			}
			sender?.SendSingleData(S2CPacketId.UpdateSeed, (IPacketData)(object)new UpdateSeedPacketData
			{
				Seed = CurrentSeed,
				AdjustSeed = AdjustSeed
			}, player.Id);
		}

		private void RegisterPacketHandlers()
		{
			receiver?.RegisterPacketHandler<UpdateSeedPacketData>(C2SPacketId.UpdateSettings, (GenericServerPacketHandler<UpdateSeedPacketData>)delegate(ushort id, UpdateSeedPacketData packetData)
			{
				IServerPlayer player = api.ServerManager.GetPlayer(id);
				if (!player.IsAuthorized)
				{
					api.ServerManager.SendMessage(player, "You have to be authorized for updating settings.");
				}
				else
				{
					CurrentSeed = packetData.Seed;
					AdjustSeed = packetData.AdjustSeed;
					api.ServerManager.BroadcastMessage(player.Username + " updated FixedMistRNG settings.");
					sender?.BroadcastSingleData(S2CPacketId.UpdateSeed, (IPacketData)(object)new UpdateSeedPacketData
					{
						Seed = CurrentSeed,
						AdjustSeed = AdjustSeed
					});
				}
			});
		}

		public static IPacketData? InstantiatePacket(C2SPacketId id)
		{
			if (id == C2SPacketId.UpdateSettings)
			{
				return (IPacketData?)(object)new UpdateSeedPacketData();
			}
			return null;
		}

		public void CheckForMistUpdate()
		{
			if (AdjustSeed && playersInMist.Count <= 0)
			{
				SetSeed(GenerateNewSeed());
			}
		}

		public int GenerateNewSeed()
		{
			if (rng == null)
			{
				rng = new Random(DateTime.UtcNow.Millisecond);
			}
			return rng.Next(1001);
		}

		public static void SetSeed(int value)
		{
			if (Instance != null)
			{
				Instance.CurrentSeed = value;
				Instance.sender?.BroadcastSingleData(S2CPacketId.UpdateSeed, (IPacketData)(object)new UpdateSeedPacketData
				{
					Seed = Instance.CurrentSeed,
					AdjustSeed = Instance.AdjustSeed
				});
			}
		}

		private static bool IsMist(string scene)
		{
			if (scene.StartsWith("Dust_Maze") && !scene.EndsWith("_Last_Hall"))
			{
				return !scene.EndsWith("_entrance");
			}
			return false;
		}
	}
	public enum S2CPacketId
	{
		UpdateSeed
	}
	public enum C2SPacketId
	{
		UpdateSettings
	}
}
namespace FixedMistRNG.SSMPAddon.Command.Server
{
	public class SetSeedCommand : IServerCommand, ICommand
	{
		[CompilerGenerated]
		private FixedMistServerAddon <addon>P;

		public bool AuthorizedOnly => false;

		public string Trigger => "/setMistSeed";

		public string[] Aliases => new string[5] { "/setmistseed", "/SetMistSeed", "/SETMISTSEED", "/mistseed", "/mistSeed" };

		public SetSeedCommand(FixedMistServerAddon addon)
		{
			<addon>P = addon;
			base..ctor();
		}

		public void Execute(ICommandSender commandSender, string[] arguments)
		{
			int result;
			if (!commandSender.IsAuthorized || arguments.Length < 2)
			{
				commandSender.SendMessage($"Current seed: {<addon>P.CurrentSeed}!");
			}
			else if (int.TryParse(arguments[1], out result))
			{
				FixedMistServerAddon.SetSeed(result);
				commandSender.SendMessage($"Successfully changed the seed to {<addon>P.CurrentSeed}!");
			}
			else
			{
				commandSender.SendMessage("Please provide an integer value.");
			}
		}
	}
}