using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; using BombRushMP.Common; using BombRushMP.Common.Networking; using BombRushMP.Common.Packets; using BombRushMP.Server.Gamemodes; using Microsoft.CodeAnalysis; using Newtonsoft.Json; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("BombRushMP.Server")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BombRushMP.Server")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("dda80519-ac3f-4803-bf1f-0f1aed6887d5")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyVersion("1.0.0.0")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BombRushMP.Server { public static class AprilServer { public const string AprilTag = "april"; public static bool GetAprilEventEnabled() { return BRCServer.Instance.ServerState.Tags.Contains("april"); } } public class AuthKeys { public Dictionary Users = new Dictionary(); private AuthUser _defaultUser = new AuthUser(); public void MakeExample() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Users["Default"] = new AuthUser((UserKinds)0, Array.Empty(), Array.Empty(), "Default user"); } public AuthUser GetUser(string key, string challenge) { foreach (KeyValuePair user in Users) { if (AuthUser.HashPassword(user.Key, challenge) == key) { return user.Value; } } if (Users.TryGetValue("Default", out var value)) { return value; } return _defaultUser; } } public class BannedUser { public string NameAtTimeOfBan = ""; public string Reason = ""; public string HWID = ""; public string GUID = ""; } public class BannedUsers { public Dictionary Users = new Dictionary(); public void MakeExample() { Users["Example"] = new BannedUser { NameAtTimeOfBan = "Goofiest Gooner", Reason = "Being annoying" }; } public bool IsBanned(string address) { return Users.ContainsKey(address); } public bool IsBannedByHWID(string hwid) { if (string.IsNullOrWhiteSpace(hwid)) { return false; } return Users.Values.Any((BannedUser x) => x.HWID == hwid); } public bool IsBannedByGUID(string guid) { if (string.IsNullOrWhiteSpace(guid) || !Guid.TryParse(guid, out var _)) { return false; } return Users.Values.Any((BannedUser x) => x.GUID == guid); } public void Ban(string address, string hwid = "", string guid = "", string name = "None", string reason = "None") { Users[address] = new BannedUser { NameAtTimeOfBan = name, Reason = reason, HWID = hwid, GUID = guid }; } public void Unban(string address) { if (Users.TryGetValue(address, out var _)) { Users.Remove(address); } } } public class BRCServer : IDisposable { public Random RNG = new Random(); public ServerLobbyManager ServerLobbyManager; public static Action ClientHandshook; public static Action ClientDisconnected; public static Action PacketReceived; public static Action OnTick; public Action RestartAction; public Dictionary Players = new Dictionary(); public INetServer Server; private float _tickRate = 1f / 32f; private Stopwatch _tickStopWatch; private HashSet _activeStages; private float _playerCountTickTimer; private IServerDatabase _database; public bool LogMessagesToFile; public bool LogMessages = true; public bool AllowNameChanges = true; public float ChatCooldown = 0.5f; public SendModes ClientAnimationSendMode = (SendModes)2; public string MOTD = ""; public bool AlwaysShowMOTD; public ServerState ServerState = new ServerState(); private double _nextTick; private readonly ConcurrentQueue _commandQueue = new ConcurrentQueue(); private const int MaxVisualUpdates = 5; public static BRCServer Instance { get; private set; } private INetworkingInterface NetworkingInterface => NetworkingEnvironment.NetworkingInterface; public Task RunOnMainThreadAsync(Func func) { TaskCompletionSource tcs = new TaskCompletionSource(); _commandQueue.Enqueue(delegate { try { T result = func(); tcs.SetResult(result); } catch (Exception exception) { tcs.SetException(exception); } }); return tcs.Task; } public void RunOnMainThread(Action action) { _commandQueue.Enqueue(action); } public BRCServer(int port, ushort maxPlayers, float tickRate, IServerDatabase database) { //IL_003c: 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_0057: Expected O, but got Unknown Instance = this; _database = database; _tickRate = tickRate; NetworkingInterface.MaxPayloadSize = 10000; ServerLobbyManager = new ServerLobbyManager(); _tickStopWatch = Stopwatch.StartNew(); Server = NetworkingInterface.CreateServer(); Server.TimeoutTime = 10000; INetServer server = Server; server.ClientConnected = (EventHandler)Delegate.Combine(server.ClientConnected, new EventHandler(OnClientConnected)); INetServer server2 = Server; server2.ClientDisconnected = (EventHandler)Delegate.Combine(server2.ClientDisconnected, new EventHandler(OnClientDisconnected)); INetServer server3 = Server; server3.MessageReceived = (EventHandler)Delegate.Combine(server3.MessageReceived, new EventHandler(OnMessageReceived)); Server.Start((ushort)port, maxPlayers); ServerLogger.Log($"Starting server on port {port} with max players {maxPlayers}, using Network Interface {NetworkingInterface}"); } public void DisconnectClient(ushort id) { Server.DisconnectClient(id); } public void Update() { double totalSeconds = _tickStopWatch.Elapsed.TotalSeconds; if (totalSeconds >= _nextTick) { Tick(_tickRate); _nextTick += _tickRate; return; } double num = (_nextTick - totalSeconds) * 1000.0; if (num > 1.0) { Thread.Sleep((int)num); } } private void Tick(float deltaTime) { Server.Update(); foreach (KeyValuePair player in Players) { player.Value.Tick(deltaTime); } _activeStages = GetActiveStages(); foreach (int activeStage in _activeStages) { TickStage(activeStage); } TickPlayerCount(deltaTime); Action result; while (_commandQueue.TryDequeue(out result)) { result(); } OnTick?.Invoke(deltaTime); } private void TickPlayerCount(float deltaTime) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown _playerCountTickTimer += deltaTime; if (!(_playerCountTickTimer >= 1f)) { return; } _playerCountTickTimer = 0f; Dictionary dictionary = new Dictionary(); foreach (KeyValuePair player in Players) { if (player.Value.ClientState != null && !player.Value.Invisible) { if (dictionary.TryGetValue(player.Value.ClientState.Stage, out var value)) { dictionary[player.Value.ClientState.Stage] = value + 1; } else { dictionary[player.Value.ClientState.Stage] = 1; } } } SendPacket((Packet)new ServerPlayerCount(dictionary), (SendModes)0, (NetChannels)0); } private void TickStage(int stage) { foreach (ServerClientVisualStates item in CreateClientVisualStatesPacket(stage)) { SendPacketToStage((Packet)(object)item, (SendModes)0, stage, (NetChannels)3); } } private HashSet GetActiveStages() { HashSet hashSet = new HashSet(); foreach (KeyValuePair player in Players) { if (player.Value.ClientState != null) { hashSet.Add(player.Value.ClientState.Stage); } } return hashSet; } public void Dispose() { Server.Stop(); } public void SendPacket(Packet packet, SendModes sendMode, NetChannels channel, ushort[] except = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel); foreach (KeyValuePair player in Players) { if (player.Value.ClientState != null && (except == null || !except.Contains(player.Key))) { player.Value.Client.Send(val); } } } public void SendPacketToStage(Packet packet, SendModes sendMode, int stage, NetChannels channel, ushort[] except = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel); foreach (KeyValuePair player in Players) { if (player.Value.ClientState != null && player.Value.ClientState.Stage == stage && (except == null || !except.Contains(player.Key))) { player.Value.Client.Send(val); } } } public void SendPacketToClient(Packet packet, SendModes sendMode, INetConnection client, NetChannels channel) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel); client.Send(val); } private void SendEliteNagChat(int stage) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown SendPacketToStage((Packet)new ServerChat("Beat a Freesoul Elite in any gamemode to unlock a skateboard skin.", (ChatMessageTypes)2), (SendModes)2, stage, (NetChannels)4); } public void SendMessageToPlayer(string message, Player player) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown SendPacketToClient((Packet)new ServerChat(message, (ChatMessageTypes)2), (SendModes)2, player.Client, (NetChannels)4); } private void ReloadAllUsers() { foreach (KeyValuePair player in Players) { player.Value.ClientState.User = _database.AuthKeys.GetUser(player.Value.Auth.AuthKey, player.Value.Challenge); } foreach (int activeStage in GetActiveStages()) { ServerClientStates packet = CreateClientStatesPacket(activeStage); SendPacketToStage((Packet)(object)packet, (SendModes)1, activeStage, (NetChannels)2); } } private void ProcessCommand(string message, Player player) { //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_09aa: Expected O, but got Unknown //IL_0ebe: Unknown result type (might be due to invalid IL or missing references) //IL_0ed0: Expected O, but got Unknown //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Expected O, but got Unknown //IL_0c9e: Unknown result type (might be due to invalid IL or missing references) //IL_0ca1: Unknown result type (might be due to invalid IL or missing references) //IL_0ca3: Unknown result type (might be due to invalid IL or missing references) //IL_0cb5: Expected O, but got Unknown //IL_0c5c: Unknown result type (might be due to invalid IL or missing references) //IL_0c6e: Expected O, but got Unknown //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Expected O, but got Unknown //IL_0d0e: Unknown result type (might be due to invalid IL or missing references) //IL_0d21: Expected O, but got Unknown //IL_0d40: Unknown result type (might be due to invalid IL or missing references) //IL_0d58: Expected O, but got Unknown //IL_0d77: Unknown result type (might be due to invalid IL or missing references) //IL_0d84: Expected O, but got Unknown //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_0634: Expected O, but got Unknown //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Expected O, but got Unknown //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Expected O, but got Unknown //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06e2: Expected O, but got Unknown //IL_0bdf: Unknown result type (might be due to invalid IL or missing references) //IL_0bf2: Expected O, but got Unknown //IL_0c46: Unknown result type (might be due to invalid IL or missing references) //IL_0c59: Expected O, but got Unknown //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Expected O, but got Unknown //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Expected O, but got Unknown //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05dd: Expected O, but got Unknown string[] array = message.Split(new char[1] { ' ' }); string text = array[0].Substring(1, array[0].Length - 1); if (text == null) { return; } switch (text.Length) { case 13: switch (text[0]) { case 'g': { if (!(text == "getservertags") || !player.ClientState.User.IsModerator) { break; } string text2 = "Current server tags:\n"; foreach (string tag in ServerState.Tags) { text2 = text2 + tag + "\n"; } SendPacketToClient((Packet)new ServerChat(text2, (ChatMessageTypes)2), (SendModes)2, player.Client, (NetChannels)4); break; } case 'm': { if (text == "makeminecraft" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result2) && Players.TryGetValue(result2, out var value2)) { SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)8), (SendModes)2, value2.Client, (NetChannels)0); } break; } } break; case 12: switch (text[4]) { case 'e': if (text == "setservertag" && player.ClientState.User.IsModerator && array.Length > 1) { ServerState.Tags.Add(array[1]); SendPacket((Packet)new ServerServerStateUpdate(ServerState), (SendModes)1, (NetChannels)2); } break; case 'd': { if (!(text == "getaddresses") || !player.ClientState.User.IsModerator) { break; } string text5 = ""; foreach (KeyValuePair player2 in Players) { if (player2.Value.ClientState.Stage == player.ClientState.Stage) { text5 += $"{player2.Value.Client.Address} - {TMPFilter.CloseAllTags(player2.Value.ClientState.Name)} ({player2.Key})\n"; } } SendMessageToPlayer(text5, player); break; } case 'k': if (text == "ph_skipsetup") { Lobby lobbyPlayerIsIn3 = ServerLobbyManager.GetLobbyPlayerIsIn(player.Client.Id); if (lobbyPlayerIsIn3 != null && lobbyPlayerIsIn3.LobbyState.HostId == player.Client.Id && lobbyPlayerIsIn3.LobbyState.InGame && lobbyPlayerIsIn3.CurrentGamemode is PropHunt propHunt) { propHunt.SetState(PropHunt.States.Main); } } break; case 'a': { if (!(text == "ph_makeprops")) { break; } Lobby lobbyPlayerIsIn2 = ServerLobbyManager.GetLobbyPlayerIsIn(player.Client.Id); if (lobbyPlayerIsIn2 == null || lobbyPlayerIsIn2.LobbyState.HostId != player.Client.Id) { break; } foreach (KeyValuePair player3 in lobbyPlayerIsIn2.LobbyState.Players) { player3.Value.Team = 1; } ServerLobbyManager.QueueStageUpdate(lobbyPlayerIsIn2.LobbyState.Stage); break; } } break; case 9: switch (text[4]) { case 's': { if (text == "makesteve" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result11) && Players.TryGetValue(result11, out var value9)) { SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)6), (SendModes)2, value9.Client, (NetChannels)0); } break; } case 'c': { if (text == "makechibi" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result10) && Players.TryGetValue(result10, out var value8)) { SendPacketToClient((Packet)new ServerSetChibi(true), (SendModes)2, value8.Client, (NetChannels)0); } break; } } break; case 3: switch (text[0]) { case 'n': if (text == "nag" && player.ClientState.User.HasTag("elite")) { SendEliteNagChat(player.ClientState.Stage); } break; case 'r': if (text == "rtd" && AprilServer.GetAprilEventEnabled()) { SpecialSkins[] array4 = new SpecialSkins[4]; RuntimeHelpers.InitializeArray(array4, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); SpecialSkins[] array5 = (SpecialSkins[])(object)array4; SpecialSkins val = array5[RNG.Next(array5.Length)]; SendPacketToClient((Packet)new ServerSetSpecialSkin(val), (SendModes)2, player.Client, (NetChannels)0); } break; case 's': if (text == "say" && player.ClientState.User.IsAdmin) { SendPacketToStage((Packet)new ServerChat(message.Substring(5), (ChatMessageTypes)2), (SendModes)2, player.ClientState.Stage, (NetChannels)4); } break; } break; case 5: switch (text[0]) { case 'b': { if (!(text == "banid") || !player.ClientState.User.IsModerator) { break; } string[] array2 = CommandUtility.ParseArgs(message, 2); if (!string.IsNullOrWhiteSpace(array2[0])) { if (string.IsNullOrWhiteSpace(array2[1])) { array2[1] = "None"; } if (ushort.TryParse(array2[0], out var result8) && BanPlayerById(result8, array2[1])) { SendMessageToPlayer("Player has been banned.", player); } } break; } case 'u': if (text == "unban" && player.ClientState.User.IsModerator && array.Length > 1 && Unban(array[1])) { SendMessageToPlayer("Player has been unbanned.", player); } break; case 'c': if (text == "chibi") { SendPacketToClient((Packet)new ServerSetChibi(true), (SendModes)2, player.Client, (NetChannels)0); } break; case 's': { if (!(text == "stats") || !player.ClientState.User.IsModerator) { break; } int count = Players.Count; int count2 = ServerLobbyManager.Lobbies.Count; int num = 0; foreach (KeyValuePair lobby in ServerLobbyManager.Lobbies) { if (lobby.Value.LobbyState.InGame) { num++; } } SendMessageToPlayer($"Players: {count}\nLobbies: {count2}\nLobbies in game: {num}", player); break; } } break; case 6: switch (text[0]) { case 'g': { if (!(text == "getids") || !player.ClientState.User.IsModerator) { break; } string text4 = ""; foreach (KeyValuePair player4 in Players) { if (player4.Value.ClientState.Stage == player.ClientState.Stage) { text4 += $"{player4.Key} - {TMPFilter.CloseAllTags(player4.Value.ClientState.Name)}\n"; } } SendMessageToPlayer(text4, player); break; } case 'd': { if (text == "damage" && player.ClientState.User.IsModerator && array.Length > 2 && ushort.TryParse(array[1], out var result6) && int.TryParse(array[2], out var result7) && Players.TryGetValue(result6, out var value6)) { SendPacketToClient((Packet)new ServerDamage(result7), (SendModes)2, value6.Client, (NetChannels)0); } break; } case 's': if (text == "sayall" && player.ClientState.User.IsAdmin) { SendPacket((Packet)new ServerChat(message.Substring(8), (ChatMessageTypes)2), (SendModes)2, (NetChannels)4); } break; case 'r': if (text == "reload" && player.ClientState.User.IsAdmin) { SendMessageToPlayer("Reloading server database.", player); _database.Load(); ReloadAllUsers(); } break; case 'c': if (text == "cancel") { Lobby lobbyPlayerIsIn = ServerLobbyManager.GetLobbyPlayerIsIn(player.Client.Id); if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == player.Client.Id && lobbyPlayerIsIn.LobbyState.InGame) { ServerLobbyManager.EndGame(lobbyPlayerIsIn.LobbyState.Id, cancelled: true); } } break; } break; case 4: switch (text[0]) { case 'h': if (text == "help") { char c = '/'; string text3 = "\nAvailable commands:\n"; text3 += $"{c}ph_skipsetup - Skips setup in a prop hunt lobby.\n{c}ph_makeprops - Makes everyone into a prop in a prop hunt lobby.\n{c}cancel - Cancels current gamemode if lobby host.\n{c}chibi - Turn into a chibi\n{c}emojis - Shows available chat emojis\n{c}hide - Hide chat\n{c}show - Show chat\n{c}clear - Clear chat\n"; if (player.ClientState.User.IsModerator) { text3 += $"{c}makeredxmas (id) - Turn player into Xmas Red.\n{c}makesteve (id) - Turn player into Steve.\n{c}prophunt - Switch current lobby to prop hunt.\n{c}prop (id) - Copies your current prop hunt disguise to another player.\n{c}damage (id) (amount) - Damages a player.\n{c}parent (id) - Parents yourself to a player. 0 to reset.\n{c}tp (id) - Teleports player to you\n{c}banlist - Downloads the ban list from the server\n{c}banaddress (ip) (reason) - Bans player by IP\n{c}banid (id) (reason) - Bans player by ID\n{c}unban (ip) - Unbans player by IP\n{c}getids - Gets IDs of players in current stage\n{c}getaddresses - Gets IP addresses of players in current stage\n{c}help\n{c}stats - Shows global player and lobby stats\n{c}makechibi (id)\n{c}makeseankingston (id)\n{c}makeforkliftcertified (id)\n{c}setservertag (tag)\n{c}removeservertag (tag)\n{c}getservertags\n{c}clearall - Clears everyones chats\n"; } if (player.ClientState.User.IsAdmin) { text3 += $"{c}reload - Reloads server auth keys and banned users\n{c}restart - Restarts the server\n{c}say (announcement for stage)\n{c}sayall (global announcement)\n"; } if (AprilServer.GetAprilEventEnabled()) { text3 += $"{c}rtd - Turn into a random special character\n"; } SendMessageToPlayer(text3, player); } break; case 'p': { if (text == "prop" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result5) && Players.TryGetValue(result5, out var value5)) { SendPacketToClient((Packet)new ServerSetProp(player.ClientVisualState.Disguised, player.ClientVisualState.DisguiseId), (SendModes)2, value5.Client, (NetChannels)0); } break; } } break; case 7: switch (text[0]) { case 'r': if (text == "restart" && player.ClientState.User.IsAdmin) { SendMessageToPlayer("Restarting server.", player); RestartAction?.Invoke(); } break; case 'b': if (text == "banlist" && player.ClientState.User.IsModerator) { SendPacketToClient((Packet)new ServerBanList(JsonConvert.SerializeObject((object)_database.BannedUsers, (Formatting)1)), (SendModes)2, player.Client, (NetChannels)0); } break; } break; case 15: if (text == "removeservertag" && player.ClientState.User.IsModerator && array.Length > 1) { ServerState.Tags.Remove(array[1]); SendPacket((Packet)new ServerServerStateUpdate(ServerState), (SendModes)1, (NetChannels)2); } break; case 16: { if (text == "makeseankingston" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result4) && Players.TryGetValue(result4, out var value4)) { SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)3), (SendModes)2, value4.Client, (NetChannels)0); } break; } case 11: { if (text == "makeredxmas" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result9) && Players.TryGetValue(result9, out var value7)) { SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)7), (SendModes)2, value7.Client, (NetChannels)0); } break; } case 21: { if (text == "makeforkliftcertified" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result3) && Players.TryGetValue(result3, out var value3)) { SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)4), (SendModes)2, value3.Client, (NetChannels)0); } break; } case 10: { if (!(text == "banaddress") || !player.ClientState.User.IsModerator) { break; } string[] array3 = CommandUtility.ParseArgs(message, 2); if (!string.IsNullOrWhiteSpace(array3[0])) { if (string.IsNullOrWhiteSpace(array3[1])) { array3[1] = "None"; } if (BanPlayerByAddress(array3[0], array3[1])) { SendMessageToPlayer("Player has been banned.", player); } } break; } case 8: if (text == "clearall" && player.ClientState.User.IsModerator) { SendPacketToStage((Packet)new ServerChat((ChatMessageTypes)4), (SendModes)2, player.ClientState.Stage, (NetChannels)4); } break; case 2: { if (text == "tp" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result) && Players.TryGetValue(result, out var value)) { SendPacketToClient((Packet)new ServerTeleportPlayer(player.ClientVisualState.Position, player.ClientVisualState.Rotation), (SendModes)2, value.Client, (NetChannels)0); } break; } case 14: case 17: case 18: case 19: case 20: break; } } private void OnPacketReceived(INetConnection client, Packets packetId, Packet packet) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Invalid comparison between Unknown and I4 //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Expected O, but got Unknown //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Expected O, but got Unknown //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Expected I4, but got Unknown //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_077a: Unknown result type (might be due to invalid IL or missing references) //IL_077d: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Unknown result type (might be due to invalid IL or missing references) //IL_07b1: Unknown result type (might be due to invalid IL or missing references) //IL_0788: Unknown result type (might be due to invalid IL or missing references) //IL_078a: Unknown result type (might be due to invalid IL or missing references) //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Invalid comparison between Unknown and I4 //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Expected O, but got Unknown //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0735: Unknown result type (might be due to invalid IL or missing references) //IL_073c: Expected O, but got Unknown //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Expected O, but got Unknown //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Expected O, but got Unknown Player player = Players[client.Id]; if (_database.BannedUsers.IsBanned(client.Address)) { Server.DisconnectClient(client.Id); return; } if ((int)packetId <= 3) { if ((int)packetId == 0) { goto IL_0069; } if ((int)packetId == 3) { ClientState clientState = player.ClientState; ClientVisualState val = (ClientVisualState)packet; ClientVisualState clientVisualState = player.ClientVisualState; player.ClientVisualState = val; if (clientVisualState != null && clientVisualState.AFK != val.AFK && !player.Invisible) { if (val.AFK) { SendPacketToStage((Packet)new ServerChat(clientState.Name, "{0} is now AFK.", clientState.ShowBadges ? clientState.User.Badges : null, (ChatMessageTypes)3), (SendModes)2, clientState.Stage, (NetChannels)4); } else { SendPacketToStage((Packet)new ServerChat(clientState.Name, "{0} is no longer AFK.", clientState.ShowBadges ? clientState.User.Badges : null, (ChatMessageTypes)3), (SendModes)2, clientState.Stage, (NetChannels)4); } } return; } } else { if ((int)packetId == 31) { ClientChat val2 = (ClientChat)packet; string message = val2.Message; message = TMPFilter.Sanitize(message); if (message.Length > 256) { message = message.Substring(0, 256); } string text = player.ClientState.Name + "/" + TMPFilter.RemoveAllTags(player.ClientState.Name) + " (" + player.Client.Address + "): " + message; if (LogMessages) { ServerLogger.Log($"[Stage: {player.ClientState.Stage}] {text}"); } if (LogMessagesToFile) { _database.LogChatMessage("[" + DateTime.Now.ToShortTimeString() + "] " + text, player.ClientState.Stage); } if (!TMPFilter.IsValidChatMessage(message)) { return; } DateTime lastChatTime = player.LastChatTime; DateTime utcNow = DateTime.UtcNow; if (!((utcNow - lastChatTime).TotalSeconds <= (double)ChatCooldown)) { player.LastChatTime = utcNow; if (val2.Message[0] == '/') { ProcessCommand(message, player); } else if (player.ClientState != null) { ServerChat packet2 = new ServerChat(player.ClientState.Name, message, player.ClientState.ShowBadges ? player.ClientState.User.Badges : null, (ChatMessageTypes)0); SendPacketToStage((Packet)(object)packet2, (SendModes)2, player.ClientState.Stage, (NetChannels)4); } } return; } if ((int)packetId == 34) { goto IL_0069; } if ((int)packetId == 64) { ClientCustomPacket val3 = (ClientCustomPacket)packet; val3.Sender = player.Client.Id; if (player.ClientState == null) { return; } SendTargets targetMode = val3.TargetMode; switch ((int)targetMode) { case 0: SendPacketToStage((Packet)(object)val3, val3.SendMode, player.ClientState.Stage, (NetChannels)6); break; case 1: { Lobby lobbyPlayerIsIn = ServerLobbyManager.GetLobbyPlayerIsIn(player.Client.Id); if (lobbyPlayerIsIn != null) { ServerLobbyManager.SendPacketToLobby((Packet)(object)val3, val3.SendMode, lobbyPlayerIsIn.LobbyState.Id, (NetChannels)6); } break; } case 2: { ushort[] targets = val3.Targets; foreach (ushort key in targets) { if (Players.TryGetValue(key, out var value)) { SendPacketToClient((Packet)(object)val3, val3.SendMode, value.Client, (NetChannels)6); } } break; } } return; } } if (!(packet is PlayerPacket)) { return; } PlayerPacket val4 = (PlayerPacket)(object)((packet is PlayerPacket) ? packet : null); val4.ClientId = client.Id; if (player.ClientState != null) { NetChannels channel = (NetChannels)0; SendModes sendMode = (SendModes)2; if (packet is PlayerAnimation) { channel = (NetChannels)5; sendMode = PlayerAnimation.ServerSendMode; } SendPacketToStage((Packet)(object)val4, sendMode, Players[client.Id].ClientState.Stage, channel); } return; IL_0069: ClientAuth val5 = (ClientAuth)(object)((packet is ClientAuth) ? packet : null); ClientState val6 = (ClientState)(object)((packet is ClientState) ? packet : null); if (val5 != null) { val6 = val5.State; if (player.Auth != null) { val5 = null; } else { player.Auth = val5; } } if (val6.Name.Length > 64) { val6.Name = val6.Name.Substring(0, 64); } if (val6.CrewName.Length > 32) { val6.CrewName = val6.CrewName.Substring(0, 32); } ClientState clientState2 = player.ClientState; if (clientState2 != null) { if (!AllowNameChanges && (int)clientState2.User.UserKind == 0) { val6.Name = clientState2.Name; } val6.Stage = clientState2.Stage; } if (val5 != null) { if (_database.BannedUsers.IsBannedByGUID(val5.GUID) || _database.BannedUsers.IsBannedByHWID(val5.HWID)) { Server.DisconnectClient(client.Id); return; } if ((val6.User = _database.AuthKeys.GetUser(val5.AuthKey, player.Challenge)).CanLurk) { player.Invisible = val5.Invisible; } } else if (clientState2 != null) { val6.User = clientState2.User; } if (val6.User.HasTag("elite")) { val6.Name = "Freesoul Elite"; val6.CrewName = "Freesoul"; } else if ((int)val6.SpecialSkin == 2) { val6.SpecialSkin = (SpecialSkins)(-1); } player.ClientState = val6; ServerClientStates val7 = CreatePlayerClientState(player); if (val7 != null) { SendPacketToStage((Packet)(object)val7, (SendModes)1, val6.Stage, (NetChannels)2); } if (clientState2 == null) { if (LogMessagesToFile) { string text2 = "Player Connected: " + val6.Name + "/" + TMPFilter.RemoveAllTags(val6.Name) + " (" + client.Address + ") (HWID: " + player.Auth.HWID + "), (GUID: " + player.Auth.GUID + ")"; _database.LogChatMessage("[" + DateTime.Now.ToShortTimeString() + "] " + text2, val6.Stage); } ServerLogger.Log($"Player from {client.Address} (ID: {client.Id}) connected as {val6.Name} in stage {val6.Stage} (HWID: {player.Auth.HWID}), (GUID: {player.Auth.GUID})"); SendPacketToClient((Packet)new ServerConnectionResponse { LocalClientId = client.Id, TickRate = _tickRate, ClientAnimationSendMode = ClientAnimationSendMode, User = val6.User, ServerState = ServerState, MOTD = MOTD, AlwaysShowMOTD = AlwaysShowMOTD }, (SendModes)1, client, (NetChannels)0); ServerClientStates packet3 = CreateClientStatesPacket(val6.Stage); SendPacketToClient((Packet)(object)packet3, (SendModes)1, client, (NetChannels)2); string text3 = "{0} Connected."; if (val6.User.HasTag("elite")) { text3 = "A {0} has entered the stage!"; } if (!player.Invisible) { SendPacketToStage((Packet)new ServerChat(val6.Name, text3, val6.ShowBadges ? val6.User.Badges : null, (ChatMessageTypes)1), (SendModes)2, val6.Stage, (NetChannels)4); } ClientHandshook?.Invoke(client); } } private void OnMessageReceived(object sender, MessageReceivedEventArgs e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) try { Packets val = (Packets)e.MessageId; Packet val2 = PacketFactory.PacketFromMessage(val, e.Message); if (val2 != null && Players.TryGetValue(e.FromConnection.Id, out var _)) { PacketReceived?.Invoke(e.FromConnection, val, val2); OnPacketReceived(e.FromConnection, val, val2); } } catch (Exception arg) { ServerLogger.Log($"Dropped client from {e.FromConnection} (ID: {e.FromConnection.Id}) because they sent a faulty packet. Exception:\n{arg}"); Server.DisconnectClient(e.FromConnection); } } public bool BanPlayerById(ushort id, string reason = "None") { if (Players.TryGetValue(id, out var value)) { return BanPlayerByAddress(value.Client.Address, reason); } return false; } public bool Unban(string address) { _database.Load(); if (!_database.BannedUsers.IsBanned(address)) { return false; } _database.BannedUsers.Unban(address); ServerLogger.Log("Unbanned IP " + address); _database.Save(); return true; } public bool BanPlayerByAddress(string address, string reason = "None") { _database.Load(); string text = ""; string text2 = ""; string text3 = "None"; ushort num = 0; foreach (KeyValuePair player in Players) { if (player.Value.Client.Address == address) { text3 = player.Value.ClientState.Name; num = player.Key; text2 = player.Value.Auth.HWID; text = player.Value.Auth.GUID; if (string.IsNullOrWhiteSpace(text2) || !Guid.TryParse(text2, out var _)) { text2 = ""; } if (string.IsNullOrWhiteSpace(text)) { text = ""; } break; } } _database.BannedUsers.Ban(address, text2, text, text3, reason); ServerLogger.Log("Banned IP " + address + ", player name: " + text3 + ", reason: " + reason + ", HWID: " + text2 + ", GUID: " + text); if (num != 0) { Server.DisconnectClient(num); } _database.Save(); return true; } private void OnClientConnected(object sender, ServerConnectedEventArgs e) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown if (!_database.BannedUsers.IsBanned(e.Client.Address)) { ServerLogger.Log($"Client connected from {e.Client.Address}. ID: {e.Client.Id}. Players: {Players.Count + 1}"); } Player player = new Player(); player.Client = e.Client; player.Server = this; player.Challenge = Guid.NewGuid().ToString(); Players[e.Client.Id] = player; e.Client.CanQualityDisconnect = false; if (_database.BannedUsers.IsBanned(e.Client.Address)) { Server.DisconnectClient(e.Client.Id); } else { SendPacketToClient((Packet)new ServerChallenge(player.Challenge), (SendModes)1, player.Client, (NetChannels)0); } } private void OnClientDisconnected(object sender, ServerDisconnectedEventArgs e) { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown if (!_database.BannedUsers.IsBanned(e.Client.Address)) { ServerLogger.Log($"Client disconnected from {e.Client.Address}. ID: {e.Client.Id}. Reason: {e.Reason}. Players: {Players.Count - 1}"); } ClientState val = null; if (Players.TryGetValue(e.Client.Id, out var value)) { ClientDisconnected?.Invoke(e.Client); Players.Remove(e.Client.Id); val = value.ClientState; } if (val != null) { if (LogMessagesToFile) { string text = "Player Disconnected: " + value.ClientState.Name + "/" + TMPFilter.RemoveAllTags(value.ClientState.Name) + " (" + value.Client.Address + ")"; _database.LogChatMessage("[" + DateTime.Now.ToShortTimeString() + "] " + text, value.ClientState.Stage); } SendPacketToStage((Packet)new ServerClientDisconnected(e.Client.Id), (SendModes)1, val.Stage, (NetChannels)2); AuthUser user = val.User; string text2 = "{0} Disconnected."; if (user.HasTag("elite")) { text2 = "A {0} has left!"; } if (!value.Invisible) { SendPacketToStage((Packet)new ServerChat(val.Name, text2, val.ShowBadges ? val.User.Badges : null, (ChatMessageTypes)1), (SendModes)2, val.Stage, (NetChannels)4); } } } private ServerClientStates CreatePlayerClientState(Player player) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (player.Invisible) { return null; } if (player.ClientState == null) { return null; } return new ServerClientStates { Full = false, ClientStates = { [player.Client.Id] = player.ClientState } }; } private ServerClientStates CreateClientStatesPacket(int stage) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ServerClientStates val = new ServerClientStates(); val.Full = true; foreach (KeyValuePair player in Players) { if (!player.Value.Invisible && player.Value.ClientState != null && player.Value.ClientState.Stage == stage) { val.ClientStates[player.Key] = player.Value.ClientState; } } return val; } private List CreateClientVisualStatesPacket(int stage) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown List list = new List(); ListExtensions.Shuffle((IList)list); int num = 0; ServerClientVisualStates val = new ServerClientVisualStates(); foreach (KeyValuePair player in Players) { if (num >= 5) { list.Add(val); val = new ServerClientVisualStates(); } if (!player.Value.Invisible && player.Value.ClientState != null && player.Value.ClientState.Stage == stage && player.Value.ClientVisualState != null) { val.ClientVisualStates[player.Key] = player.Value.ClientVisualState; num++; } } list.Add(val); return list; } } public interface IServerDatabase { BannedUsers BannedUsers { get; } AuthKeys AuthKeys { get; } void Load(); void Save(); void LogChatMessage(string message, int stage); } public class Lobby { public LobbyState LobbyState; public Gamemode CurrentGamemode; public Lobby(LobbyState lobbyState) { LobbyState = lobbyState; } public void Tick(float deltaTime) { if (CurrentGamemode != null && LobbyState.InGame) { CurrentGamemode.Tick(deltaTime); } } } public class Player { private const float SecondsToKickPlayerWithoutClientState = 5f; public BRCServer Server; public ClientAuth Auth; public ClientState ClientState; public ClientVisualState ClientVisualState; public float SecondsWithoutSendingClientState; public INetConnection Client; public DateTime LastChatTime = DateTime.UtcNow; public bool Invisible; public string Challenge = ""; public void Tick(float deltaTime) { if (ClientState == null) { SecondsWithoutSendingClientState += deltaTime; if (SecondsWithoutSendingClientState > 5f) { ServerLogger.Log($"Rejecting player from {Client} (ID: {Client.Id}) because they took longer than {5f} seconds to send ClientState."); Server.DisconnectClient(Client.Id); } } else { SecondsWithoutSendingClientState = 0f; } } } public static class ServerConstants { public const string JoinMessage = "{0} Connected."; public const string LeaveMessage = "{0} Disconnected."; public const string AFKMessage = "{0} is now AFK."; public const string LeaveAFKMessage = "{0} is no longer AFK."; public const float PlayerCountTickRate = 1f; } public class ServerLobbyManager : IDisposable { public Dictionary Lobbies = new Dictionary(); private BRCServer _server; private UIDProvider _uidProvider = new UIDProvider(); private HashSet _queuedStageUpdates = new HashSet(); private List _queuedActions = new List(); public ServerLobbyManager() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown _server = BRCServer.Instance; BRCServer.PacketReceived = (Action)Delegate.Combine(BRCServer.PacketReceived, new Action(OnPacketReceived)); BRCServer.OnTick = (Action)Delegate.Combine(BRCServer.OnTick, new Action(OnTick)); BRCServer.ClientDisconnected = (Action)Delegate.Combine(BRCServer.ClientDisconnected, new Action(OnClientDisconnected)); BRCServer.ClientHandshook = (Action)Delegate.Combine(BRCServer.ClientHandshook, new Action(OnClientHandshook)); } public void Dispose() { BRCServer.PacketReceived = (Action)Delegate.Remove(BRCServer.PacketReceived, new Action(OnPacketReceived)); BRCServer.OnTick = (Action)Delegate.Remove(BRCServer.OnTick, new Action(OnTick)); BRCServer.ClientDisconnected = (Action)Delegate.Remove(BRCServer.ClientDisconnected, new Action(OnClientDisconnected)); BRCServer.ClientHandshook = (Action)Delegate.Remove(BRCServer.ClientHandshook, new Action(OnClientHandshook)); } public void StartGame(uint lobbyId) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown Lobby lobby = Lobbies[lobbyId]; lobby.CurrentGamemode = GamemodeFactory.GetGamemode(lobby.LobbyState.Gamemode); lobby.CurrentGamemode.Lobby = lobby; lobby.LobbyState.InGame = true; foreach (KeyValuePair player in lobby.LobbyState.Players) { player.Value.Score = 0f; player.Value.Ready = false; } ClearAllInvitesForLobby(lobbyId); SendLobbiesToStage(lobby.LobbyState.Stage); SendPacketToLobby((Packet)new ServerLobbyStart(), (SendModes)1, lobbyId, (NetChannels)1); lobby.CurrentGamemode.OnStart(); } public void EndGame(uint lobbyId, bool cancelled) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Lobby lobby = Lobbies[lobbyId]; lobby.LobbyState.InGame = false; Gamemode currentGamemode = lobby.CurrentGamemode; lobby.CurrentGamemode = null; SendLobbiesToStage(lobby.LobbyState.Stage); SendPacketToLobby((Packet)new ServerLobbyEnd(cancelled), (SendModes)1, lobbyId, (NetChannels)1); currentGamemode.OnEnd(cancelled); } public void SetPlayerScore(ushort clientId, float score) { Lobby lobbyPlayerIsIn = GetLobbyPlayerIsIn(clientId); lobbyPlayerIsIn.LobbyState.Players[clientId].Score = score; SendLobbySoftUpdate(lobbyPlayerIsIn, clientId, score); } public void AddPlayerWin(ushort clientId) { LobbyPlayer obj = GetLobbyPlayerIsIn(clientId).LobbyState.Players[clientId]; obj.Wins++; } public void ResetPlayerWins(uint lobbyId) { Lobby lobby = Lobbies[lobbyId]; foreach (KeyValuePair player in lobby.LobbyState.Players) { player.Value.Wins = 0; } SendLobbiesToStage(lobby.LobbyState.Stage); } public Lobby GetLobbyPlayerIsIn(ushort clientId) { foreach (KeyValuePair lobby in Lobbies) { if (lobby.Value.LobbyState.Players.Keys.Contains(clientId)) { return lobby.Value; } } return null; } public void DeleteLobby(uint lobbyId) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (Lobbies.TryGetValue(lobbyId, out var value)) { if (value.CurrentGamemode != null) { EndGame(lobbyId, cancelled: true); } Lobbies.Remove(lobbyId); _uidProvider.FreeUID(lobbyId); ServerLogger.Log($"Deleted Lobby with UID {lobbyId}"); _server.SendPacketToStage((Packet)new ServerLobbyDeleted(value.LobbyState.Id), (SendModes)1, value.LobbyState.Stage, (NetChannels)2); } } public void AddPlayer(uint lobbyId, ushort clientId) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (Lobbies.TryGetValue(lobbyId, out var value)) { value.LobbyState.Players[clientId] = new LobbyPlayer(lobbyId, clientId, (byte)0); UninvitePlayer(lobbyId, clientId); QueueStageUpdate(value.LobbyState.Stage); } } public void RemovePlayer(uint lobbyId, ushort clientId) { if (Lobbies.TryGetValue(lobbyId, out var value)) { value.LobbyState.Players.Remove(clientId); if (value.LobbyState.HostId == clientId) { DeleteLobby(lobbyId); } QueueStageUpdate(value.LobbyState.Stage); } } public bool InvitePlayer(uint lobbyId, ushort inviteeId) { if (Lobbies.TryGetValue(lobbyId, out var value)) { if (value.LobbyState.Players.ContainsKey(inviteeId)) { return false; } if (value.LobbyState.InGame) { return false; } if (!value.LobbyState.InvitedPlayers.ContainsKey(inviteeId)) { value.LobbyState.InvitedPlayers[inviteeId] = DateTime.UtcNow; QueueStageUpdate(value.LobbyState.Stage); return true; } } return false; } public void UninvitePlayer(uint lobbyId, ushort inviteeId) { if (Lobbies.TryGetValue(lobbyId, out var value) && value.LobbyState.InvitedPlayers.ContainsKey(inviteeId)) { value.LobbyState.InvitedPlayers.Remove(inviteeId); QueueStageUpdate(value.LobbyState.Stage); } } public void ClearAllInvitesForLobby(uint lobbyId) { if (Lobbies.TryGetValue(lobbyId, out var value)) { value.LobbyState.InvitedPlayers.Clear(); QueueStageUpdate(value.LobbyState.Stage); } } public void ClearAllInvitesForPlayer(ushort playerId) { foreach (KeyValuePair lobby in Lobbies) { if (lobby.Value.LobbyState.InvitedPlayers.ContainsKey(playerId)) { lobby.Value.LobbyState.InvitedPlayers.Remove(playerId); QueueStageUpdate(lobby.Value.LobbyState.Stage); } } } private void OnTick(float deltaTime) { foreach (int queuedStageUpdate in _queuedStageUpdates) { SendLobbiesToStage(queuedStageUpdate); } _queuedStageUpdates.Clear(); foreach (Action queuedAction in _queuedActions) { queuedAction(); } _queuedActions.Clear(); foreach (KeyValuePair lobby in Lobbies) { lobby.Value.Tick(deltaTime); } } private void OnClientHandshook(INetConnection client) { SendLobbiesToClient(client); } private void OnClientDisconnected(INetConnection client) { ClearAllInvitesForPlayer(client.Id); Lobby lobbyPlayerIsIn = GetLobbyPlayerIsIn(client.Id); if (lobbyPlayerIsIn != null) { RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, client.Id); } } private void VerifyLobbyTeams(Lobby lobby) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 int num = 4; if ((int)lobby.LobbyState.Gamemode == 6) { num = 2; } foreach (KeyValuePair player in lobby.LobbyState.Players) { if (player.Value.Team >= num) { player.Value.Team = (byte)(num - 1); QueueStageUpdate(lobby.LobbyState.Stage); } else if (player.Value.Team <= 0) { player.Value.Team = 0; QueueStageUpdate(lobby.LobbyState.Stage); } } } private void OnPacketReceived(INetConnection client, Packets packetId, Packet packet) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected I4, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Expected O, but got Unknown //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected I4, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Invalid comparison between Unknown and I4 //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Expected O, but got Unknown //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Expected O, but got Unknown //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Expected O, but got Unknown //IL_05fa: Unknown result type (might be due to invalid IL or missing references) //IL_0601: Expected O, but got Unknown //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Expected O, but got Unknown ushort id = client.Id; Player player = _server.Players[id]; if (player.ClientState == null) { return; } Lobby lobbyPlayerIsIn = GetLobbyPlayerIsIn(client.Id); if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.CurrentGamemode != null) { lobbyPlayerIsIn.CurrentGamemode.OnPacketFromLobbyReceived(packetId, packet, id); } switch (packetId - 10) { case 13: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && !lobbyPlayerIsIn.LobbyState.InGame && lobbyPlayerIsIn.CurrentGamemode == null) { lobbyPlayerIsIn.LobbyState.Gamemode = ((ClientLobbySetGamemode)packet).Gamemode; lobbyPlayerIsIn.LobbyState.GamemodeSettings = ((ClientLobbySetGamemode)packet).GamemodeSettings; VerifyLobbyTeams(lobbyPlayerIsIn); QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage); } return; case 0: { ClientLobbyCreate val3 = (ClientLobbyCreate)packet; if (lobbyPlayerIsIn != null) { RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, client.Id); } Lobby lobby = new Lobby(new LobbyState(player.ClientState.Stage, _uidProvider.RequestUID(), client.Id)); lobby.LobbyState.Gamemode = val3.GamemodeID; lobby.LobbyState.GamemodeSettings = val3.Settings; Lobbies[lobby.LobbyState.Id] = lobby; AddPlayer(lobby.LobbyState.Id, client.Id); ServerLogger.Log($"Created Lobby with UID {lobby.LobbyState.Id} with host {player.ClientState.Name}"); QueueAction(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown _server.SendPacketToClient((Packet)new ServerLobbyCreateResponse(), (SendModes)2, client, (NetChannels)2); }); return; } case 1: { ClientLobbyJoin val4 = (ClientLobbyJoin)packet; if (Lobbies.TryGetValue(val4.LobbyId, out var value) && !value.LobbyState.InGame && lobbyPlayerIsIn != value) { if (lobbyPlayerIsIn != null) { RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, id); } AddPlayer(val4.LobbyId, id); ServerLogger.Log($"{_server.Players[id].ClientState.Name} joined lobby UID {value.LobbyState.Id}. Now at {value.LobbyState.Players.Count} players. Hosted by {_server.Players[value.LobbyState.HostId].ClientState.Name}."); } return; } case 2: if (lobbyPlayerIsIn != null) { RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, id); } return; case 6: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && !lobbyPlayerIsIn.LobbyState.InGame) { StartGame(lobbyPlayerIsIn.LobbyState.Id); } return; case 11: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && lobbyPlayerIsIn.LobbyState.InGame) { EndGame(lobbyPlayerIsIn.LobbyState.Id, cancelled: true); } return; case 15: if (lobbyPlayerIsIn != null) { lobbyPlayerIsIn.LobbyState.Players[id].Ready = ((ClientLobbySetReady)packet).Ready; QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage); } return; case 16: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id) { ClientLobbyInvite val2 = (ClientLobbyInvite)packet; if (InvitePlayer(lobbyPlayerIsIn.LobbyState.Id, val2.InviteeId)) { _server.SendPacketToClient((Packet)new ServerLobbyInvite(val2.InviteeId, id, lobbyPlayerIsIn.LobbyState.Id), (SendModes)2, _server.Players[val2.InviteeId].Client, (NetChannels)2); } } return; case 18: { ClientLobbyDeclineInvite val = (ClientLobbyDeclineInvite)packet; UninvitePlayer(val.LobbyId, id); return; } case 19: ClearAllInvitesForPlayer(id); return; case 20: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id) { ushort playerId = ((ClientLobbyKick)packet).PlayerId; if (lobbyPlayerIsIn.LobbyState.Players.ContainsKey(playerId)) { RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, playerId); } } return; case 3: case 4: case 5: case 7: case 8: case 9: case 10: case 12: case 14: case 17: return; } switch (packetId - 41) { default: if ((int)packetId == 63 && lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && !lobbyPlayerIsIn.LobbyState.InGame && lobbyPlayerIsIn.CurrentGamemode == null) { ResetPlayerWins(lobbyPlayerIsIn.LobbyState.Id); } break; case 0: if (lobbyPlayerIsIn != null && !lobbyPlayerIsIn.LobbyState.InGame && (lobbyPlayerIsIn.LobbyState.AllowTeamSwitching || lobbyPlayerIsIn.LobbyState.HostId == id)) { ClientSetTeam val6 = (ClientSetTeam)packet; lobbyPlayerIsIn.LobbyState.Players[id].Team = val6.Team; VerifyLobbyTeams(lobbyPlayerIsIn); QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage); } break; case 3: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id) { ClientLobbySetAllowTeamSwitching val8 = (ClientLobbySetAllowTeamSwitching)packet; lobbyPlayerIsIn.LobbyState.AllowTeamSwitching = val8.Set; QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage); } break; case 4: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id) { ClientLobbySetPlayerTeam val7 = (ClientLobbySetPlayerTeam)packet; if (lobbyPlayerIsIn.LobbyState.Players.ContainsKey(val7.PlayerId)) { lobbyPlayerIsIn.LobbyState.Players[val7.PlayerId].Team = val7.TeamId; VerifyLobbyTeams(lobbyPlayerIsIn); QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage); } } break; case 5: if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id) { ClientLobbySetChallenge val5 = (ClientLobbySetChallenge)packet; lobbyPlayerIsIn.LobbyState.Challenge = val5.Set; QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage); } break; case 1: case 2: break; } } public void SendPacketToLobby(Packet packet, SendModes sendMode, uint lobbyId, NetChannels channel) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!Lobbies.TryGetValue(lobbyId, out var value)) { return; } foreach (KeyValuePair player in value.LobbyState.Players) { _server.SendPacketToClient(packet, sendMode, _server.Players[player.Key].Client, channel); } } private void SendLobbiesToClient(INetConnection client) { Player player = _server.Players[client.Id]; if (!_queuedStageUpdates.Contains(player.ClientState.Stage)) { Packet packet = CreateServerLobbyStatesPacket(player.ClientState.Stage); _server.SendPacketToClient(packet, (SendModes)1, client, (NetChannels)2); } } public void QueueStageUpdate(int stage) { _queuedStageUpdates.Add(stage); } private void QueueAction(Action action) { _queuedActions.Add(action); } private void SendLobbySoftUpdate(Lobby lobby, ushort playerId, float score) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown ServerLobbySoftUpdate packet = new ServerLobbySoftUpdate(lobby.LobbyState.Id, playerId, score); SendPacketToLobby((Packet)(object)packet, (SendModes)1, lobby.LobbyState.Id, (NetChannels)2); } private void SendLobbiesToStage(int stage) { Packet packet = CreateServerLobbyStatesPacket(stage); _server.SendPacketToStage(packet, (SendModes)1, stage, (NetChannels)2); } private List GetLobbyStatesForStage(int stage) { List list = new List(); foreach (KeyValuePair lobby in Lobbies) { if (lobby.Value.LobbyState.Stage == stage) { list.Add(lobby.Value.LobbyState); } } return list; } private Packet CreateServerLobbyStatesPacket(int stage) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown return (Packet)new ServerLobbies(GetLobbyStatesForStage(stage)); } } public static class ServerLogger { public static void Log(string message) { Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] " + message); } } } namespace BombRushMP.Server.Gamemodes { public abstract class Gamemode { public bool TeamBased; public Lobby Lobby; protected int CountdownTime = 10; protected BRCServer Server; protected ServerLobbyManager ServerLobbyManager; public Gamemode() { Server = BRCServer.Instance; ServerLobbyManager = Server.ServerLobbyManager; } public virtual void OnStart() { } public virtual void OnEnd(bool cancelled) { } public virtual void Tick(float deltaTime) { } public virtual void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)packetId == 37 && playerId == Lobby.LobbyState.HostId) { CountdownTime = ((ClientGamemodeCountdown)((packet is ClientGamemodeCountdown) ? packet : null)).CountdownSeconds; } } } public static class GamemodeFactory { private static Dictionary Gamemodes = new Dictionary { { (GamemodeIDs)0, typeof(ScoreBattle) }, { (GamemodeIDs)1, typeof(GraffitiRace) }, { (GamemodeIDs)2, typeof(TeamGraffitiRace) }, { (GamemodeIDs)3, typeof(ProSkaterScoreBattle) }, { (GamemodeIDs)4, typeof(TeamScoreBattle) }, { (GamemodeIDs)5, typeof(TeamProSkaterScoreBattle) }, { (GamemodeIDs)6, typeof(PropHunt) } }; public static Gamemode GetGamemode(GamemodeIDs gameModeID) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Activator.CreateInstance(Gamemodes[gameModeID]) as Gamemode; } } public class GraffitiRace : Gamemode { public enum States { Countdown, Main, Finished } private States _state; private float _countdownTimer; private float _maxScore; private Dictionary> _graffitisCompletedByTeam = new Dictionary>(); public override void OnEnd(bool cancelled) { base.OnEnd(cancelled); _maxScore = 0f; } public override void OnStart() { base.OnStart(); _maxScore = 0f; _graffitisCompletedByTeam = new Dictionary>(); } private bool SetTagCompleted(byte team, int tag) { HashSet hashSet; if (_graffitisCompletedByTeam.TryGetValue(team, out var value)) { hashSet = value; } else { hashSet = new HashSet(); _graffitisCompletedByTeam[team] = hashSet; } if (hashSet.Contains(tag)) { return false; } hashSet.Add(tag); return true; } public override void Tick(float deltaTime) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if (_state == States.Countdown && _countdownTimer > (float)CountdownTime) { ServerLobbyManager.SendPacketToLobby((Packet)new ServerGamemodeBegin(), (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1); _state = States.Main; } _countdownTimer += deltaTime; } public override void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown base.OnPacketFromLobbyReceived(packetId, packet, playerId); if ((int)packetId <= 22) { if ((int)packetId != 20) { if ((int)packetId == 22 && playerId == Lobby.LobbyState.HostId) { ClientGraffitiRaceGSpots val = (ClientGraffitiRaceGSpots)packet; ServerLobbyManager.SendPacketToLobby((Packet)(object)val, (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1); _maxScore += val.GraffitiSpots.Count; } } else if (!TeamBased && _state == States.Main) { ClientGamemodeScore val2 = (ClientGamemodeScore)packet; ServerLobbyManager.SetPlayerScore(playerId, val2.Score); if (val2.Score >= _maxScore) { ServerLobbyManager.AddPlayerWin(playerId); ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); _state = States.Finished; } } } else { if ((int)packetId != 36) { if ((int)packetId != 42 || !TeamBased) { return; } LobbyPlayer lobbyPlayer = Lobby.LobbyState.Players[playerId]; if (_state != States.Main) { return; } ClientTeamGraffRaceScore val3 = (ClientTeamGraffRaceScore)packet; if (!SetTagCompleted(lobbyPlayer.Team, val3.TagHash)) { return; } ServerLobbyManager.SetPlayerScore(playerId, lobbyPlayer.Score + 1f); if (Lobby.LobbyState.GetScoreForTeam(Lobby.LobbyState.Players[playerId].Team) >= _maxScore) { ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); _state = States.Finished; } IEnumerable> enumerable = Lobby.LobbyState.Players.Where((KeyValuePair x) => x.Value.Team == lobbyPlayer.Team && x.Value.Id != lobbyPlayer.Id); ServerTeamGraffRaceScore packet2 = new ServerTeamGraffRaceScore(playerId, val3.TagHash); { foreach (KeyValuePair item in enumerable) { Server.SendPacketToClient((Packet)(object)packet2, (SendModes)1, Server.Players[item.Key].Client, (NetChannels)1); } return; } } if (playerId == Lobby.LobbyState.HostId) { ServerLobbyManager.SendPacketToLobby(packet, (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1); } } } } public class PropHunt : Gamemode { public enum States { Setup, Main, Finished } private States _state; private float _stateTimer; private float _pingTimer; private float _setupTime = 9999f; private float _matchTime = 9999f; private float _pingInterval = 99999f; private int _stageHash; private bool _validatedHashes; private bool _becomeHunterOnKill; private bool _respawnOnKill; private float _respawnTime = 5f; private Dictionary _stageHashes = new Dictionary(); private HashSet _deadPlayers = new HashSet(); private List> _playersToRespawn = new List>(); public PropHunt() { TeamBased = true; } public override void OnStart() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown Player player = Server.Players[Lobby.LobbyState.HostId]; ServerPropHuntSpawn packet = new ServerPropHuntSpawn(player.ClientVisualState.Position, player.ClientVisualState.Rotation); ServerLobbyManager.SendPacketToLobby((Packet)(object)packet, (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1); } public override void Tick(float deltaTime) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown switch (_state) { case States.Setup: if (_stateTimer >= 10f && !_validatedHashes) { ValidateStageHashes(); } if (_stateTimer >= _setupTime) { SetState(States.Main); } CheckForSetupCancellation(); break; case States.Main: if (_pingTimer >= _pingInterval) { _pingTimer = 0f; ServerLobbyManager.SendPacketToLobby((Packet)new ServerPropHuntPing(), (SendModes)2, Lobby.LobbyState.Id, (NetChannels)1); } if (_stateTimer >= _matchTime) { SendSystemMessage("Props win!"); ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); SetState(States.Finished); } _pingTimer += deltaTime; CheckWinConditions(); UpdatePlayerRespawn(deltaTime); break; } _stateTimer += deltaTime; } private void CheckWinConditions() { int num = 0; int num2 = 0; foreach (KeyValuePair player in Lobby.LobbyState.Players) { if (!_deadPlayers.Contains(player.Key)) { if (player.Value.Team == 0) { num++; } else if (player.Value.Team == 1) { num2++; } } } if (num2 == 0) { ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); SendSystemMessage("Hunters win!"); } else if (num == 0) { ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); SendSystemMessage("Props win!"); } } private void ValidateStageHashes() { foreach (KeyValuePair player in Lobby.LobbyState.Players) { if (player.Key == Lobby.LobbyState.HostId) { continue; } if (_stageHashes.TryGetValue(player.Key, out var value)) { if (value != _stageHash) { SendPlayerMessage(player.Key, "{0} has been removed due to a stage mismatch."); ServerLobbyManager.RemovePlayer(Lobby.LobbyState.Id, player.Key); } } else { SendPlayerMessage(player.Key, "{0} timed out of sending stage info."); ServerLobbyManager.RemovePlayer(Lobby.LobbyState.Id, player.Key); } } _validatedHashes = true; } private void SendSystemMessage(string txt) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown ServerLobbyManager.SendPacketToLobby((Packet)new ServerChat("" + txt + "", (ChatMessageTypes)2), (SendModes)2, Lobby.LobbyState.Id, (NetChannels)4); } private void SendPlayerMessage(ushort playerId, string txt) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown ServerChat packet = new ServerChat(TMPFilter.CloseAllTags(Server.Players[playerId].ClientState.Name), "" + txt + "", Server.Players[playerId].ClientState.ShowBadges ? Server.Players[playerId].ClientState.User.Badges : null, (ChatMessageTypes)2); ServerLobbyManager.SendPacketToLobby((Packet)(object)packet, (SendModes)2, Lobby.LobbyState.Id, (NetChannels)4); } private void CheckForSetupCancellation() { int num = 0; int num2 = 0; foreach (KeyValuePair player in Lobby.LobbyState.Players) { if (player.Value.Team == 0) { num++; } else if (player.Value.Team == 1) { num2++; } } if (num == 0 || num2 == 0) { ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: true); SendSystemMessage("Game cancelled due to lack of players."); } } private void UpdatePlayerRespawn(float deltaTime) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown List> list = new List>(); foreach (Tuple item in _playersToRespawn) { float num = item.Item1 - deltaTime; if (num <= 0f) { Server.SendPacketToClient((Packet)new ServerPropHuntRespawn(), (SendModes)1, Server.Players[item.Item2].Client, (NetChannels)1); } else { list.Add(new Tuple(num, item.Item2)); } } _playersToRespawn = list; } public override void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown switch (packetId - 54) { case 0: if (playerId == Lobby.LobbyState.HostId) { ClientPropHuntSettings val2 = (ClientPropHuntSettings)(object)((packet is ClientPropHuntSettings) ? packet : null); _setupTime = val2.SetupLength; _matchTime = val2.MatchLength; _pingInterval = val2.PingInterval; _stageHash = val2.StageHash; _becomeHunterOnKill = val2.PropsBecomeHuntersOnDeath; _respawnOnKill = val2.HuntersRespawnOnDeath; _respawnTime = val2.RespawnTime; } break; case 2: { ClientPropHuntStageHash val3 = (ClientPropHuntStageHash)(object)((packet is ClientPropHuntStageHash) ? packet : null); _stageHashes[playerId] = val3.StageHash; break; } case 5: if (Lobby.LobbyState.Players[playerId].Team == 0) { SendPlayerMessage(playerId, "{0} has perished."); if (_respawnOnKill) { _playersToRespawn.Add(new Tuple(_respawnTime, playerId)); } else { _deadPlayers.Add(playerId); } break; } SendPlayerMessage(playerId, "{0} was hunted!"); if (_becomeHunterOnKill) { Lobby.LobbyState.Players[playerId].Team = 0; ServerLobbyManager.QueueStageUpdate(Lobby.LobbyState.Stage); _playersToRespawn.Add(new Tuple(_respawnTime, playerId)); } else { _deadPlayers.Add(playerId); } break; case 6: { ClientPropHuntShoot val = (ClientPropHuntShoot)(object)((packet is ClientPropHuntShoot) ? packet : null); val.Attacker = playerId; Server.SendPacketToClient((Packet)(object)val, (SendModes)1, Server.Players[val.Target].Client, (NetChannels)1); break; } case 1: case 3: case 4: break; } } public void SetState(States newState) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (_state != newState) { if (newState == States.Main) { ServerLobbyManager.SendPacketToLobby((Packet)new ServerPropHuntBegin(), (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1); } _state = newState; _stateTimer = 0f; } } } public class ProSkaterScoreBattle : ScoreBattle { public ProSkaterScoreBattle() { ComboBased = true; } } public class ScoreBattle : Gamemode { public enum States { Countdown, Main, Finished } private States _state; private float _stateTimer; private DateTime _startTime = DateTime.UtcNow; public bool ComboBased; private HashSet _clientsFinishedCombo = new HashSet(); private float _timeElapsed; private float _timeLeft = 1f; private int _durationMinutes = 3; public override void Tick(float deltaTime) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown switch (_state) { case States.Countdown: if (_stateTimer > (float)CountdownTime) { ServerLobbyManager.SendPacketToLobby((Packet)new ServerGamemodeBegin(), (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1); _state = States.Main; _startTime = DateTime.UtcNow; } break; case States.Main: { _timeElapsed = (float)(DateTime.UtcNow - _startTime).TotalSeconds; float num = (float)_durationMinutes * 60f; _timeLeft = num - _timeElapsed; if (!ComboBased) { if (_timeLeft <= 0f) { ushort highestScoringPlayer = GetHighestScoringPlayer(); if (highestScoringPlayer != 0) { ServerLobbyManager.AddPlayerWin(highestScoringPlayer); } ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); _state = States.Finished; } } else if (EveryoneFinishedComboing() && _timeLeft <= 0f) { ushort highestScoringPlayer2 = GetHighestScoringPlayer(); if (highestScoringPlayer2 != 0) { ServerLobbyManager.AddPlayerWin(highestScoringPlayer2); } ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false); _state = States.Finished; } break; } } _stateTimer += deltaTime; } private ushort GetHighestScoringPlayer() { ushort num = 0; float num2 = 0f; foreach (KeyValuePair player in Lobby.LobbyState.Players) { if (num == 0) { num = player.Key; num2 = player.Value.Score; } else if (player.Value.Score > num2) { num = player.Key; num2 = player.Value.Score; } } return num; } private bool EveryoneFinishedComboing() { foreach (KeyValuePair player in Lobby.LobbyState.Players) { if (!_clientsFinishedCombo.Contains(player.Key)) { return false; } } return true; } public override void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) base.OnPacketFromLobbyReceived(packetId, packet, playerId); if ((int)packetId == 38 && playerId == Lobby.LobbyState.HostId) { _durationMinutes = ((ClientScoreBattleLength)((packet is ClientScoreBattleLength) ? packet : null)).Minutes; } if (_state != States.Main) { return; } if ((int)packetId != 20) { if ((int)packetId == 33 && ComboBased && !_clientsFinishedCombo.Contains(playerId)) { ServerLobbyManager.SendPacketToLobby((Packet)new ServerChat(TMPFilter.CloseAllTags(BRCServer.Instance.Players[playerId].ClientState.Name), "{0} landed their combo!", BRCServer.Instance.Players[playerId].ClientState.ShowBadges ? BRCServer.Instance.Players[playerId].ClientState.User.Badges : null, (ChatMessageTypes)2), (SendModes)2, Lobby.LobbyState.Id, (NetChannels)1); _clientsFinishedCombo.Add(playerId); ServerLobbyManager.SetPlayerScore(playerId, ((ClientComboOver)packet).Score); } } else if (!_clientsFinishedCombo.Contains(playerId)) { ClientGamemodeScore val = (ClientGamemodeScore)packet; ServerLobbyManager.SetPlayerScore(playerId, val.Score); } } } public class TeamGraffitiRace : GraffitiRace { public TeamGraffitiRace() { TeamBased = true; } } public class TeamProSkaterScoreBattle : ProSkaterScoreBattle { public TeamProSkaterScoreBattle() { TeamBased = true; } } public class TeamScoreBattle : ScoreBattle { public TeamScoreBattle() { TeamBased = true; } } }