public void Tick() { CurrentTick++; GameEvents.Tick(CurrentTick); if (AnnounceSelf && DateTime.Now.Subtract(_lastAnnounceDateTime).TotalMinutes >= 5) { AnnounceToMaster(); } //throw new Exception("test"); NetIncomingMessage msg; while ((msg = Server.ReadMessage()) != null) { Client client = null; lock (Clients) { foreach (var c in Clients) { if (c?.NetConnection == null || c.NetConnection.RemoteUniqueIdentifier == 0 || msg.SenderConnection == null || c.NetConnection.RemoteUniqueIdentifier != msg.SenderConnection.RemoteUniqueIdentifier) { continue; } client = c; break; } } if (client == null) { logger.LogDebug("Client not found for remote ID " + msg.SenderConnection?.RemoteUniqueIdentifier + ", creating client. Current number of clients: " + Clients.Count()); client = new Client(msg.SenderConnection); } // Plugin event: OnIncomingPacket var pluginPacketHandlerResult = PacketEvents.IncomingPacket(client, msg); msg = pluginPacketHandlerResult.Data; if (!pluginPacketHandlerResult.ContinueServerProc) { Server.Recycle(msg); return; } //logger.LogInformation("Packet received - type: " + ((NetIncomingMessageType)msg.MessageType).ToString()); switch (msg.MessageType) { case NetIncomingMessageType.UnconnectedData: var ucType = msg.ReadString(); // ReSharper disable once ConvertIfStatementToSwitchStatement if (ucType == "ping") { if (!PacketEvents.Ping(client, msg).ContinueServerProc) { Server.Recycle(msg); return; } logger.LogInformation("Ping received from " + msg.SenderEndPoint.Address.ToString()); var reply = Server.CreateMessage("pong"); Server.SendMessage(reply, client.NetConnection, NetDeliveryMethod.ReliableOrdered); } else if (ucType == "query") { if (!PacketEvents.Query(client, msg).ContinueServerProc) { Server.Recycle(msg); return; } var playersOnline = 0; lock (Clients) playersOnline = Clients.Count; logger.LogInformation("Query received from " + msg.SenderEndPoint.Address.ToString()); var reply = Server.CreateMessage($"{Name}%{PasswordProtected}%{playersOnline}%{MaxPlayers}%{GamemodeName}"); Server.SendMessage(reply, client.NetConnection, NetDeliveryMethod.ReliableOrdered); } break; case NetIncomingMessageType.VerboseDebugMessage: case NetIncomingMessageType.DebugMessage: logger.LogDebug("Network (Verbose)DebugMessage: " + msg.ReadString()); break; case NetIncomingMessageType.WarningMessage: logger.LogWarning("Network WarningMessage: " + msg.ReadString()); break; case NetIncomingMessageType.ErrorMessage: logger.LogError("Network ErrorMessage: " + msg.ReadString()); break; case NetIncomingMessageType.ConnectionLatencyUpdated: client.Latency = msg.ReadFloat(); break; case NetIncomingMessageType.ConnectionApproval: var connectionApprovalPacketResult = PacketEvents.IncomingConnectionApproval(client, msg); msg = connectionApprovalPacketResult.Data; if (!connectionApprovalPacketResult.ContinueServerProc) { Server.Recycle(msg); return; } HandleClientConnectionApproval(client, msg); break; case NetIncomingMessageType.StatusChanged: pluginPacketHandlerResult = PacketEvents.IncomingStatusChange(client, msg); msg = pluginPacketHandlerResult.Data; if (!pluginPacketHandlerResult.ContinueServerProc) { Server.Recycle(msg); return; } HandleClientStatusChange(client, msg); break; case NetIncomingMessageType.DiscoveryRequest: pluginPacketHandlerResult = PacketEvents.IncomingDiscoveryRequest(client, msg); msg = pluginPacketHandlerResult.Data; if (!pluginPacketHandlerResult.ContinueServerProc) { Server.Recycle(msg); return; } HandleClientDiscoveryRequest(client, msg); break; case NetIncomingMessageType.Data: pluginPacketHandlerResult = PacketEvents.IncomingData(client, msg); msg = pluginPacketHandlerResult.Data; if (!pluginPacketHandlerResult.ContinueServerProc) { Server.Recycle(msg); return; } HandleClientIncomingData(client, msg); break; default: // We shouldn't get packets reaching this, so throw warnings when it happens. logger.LogWarning("Unknown packet received: " + msg.MessageType.ToString()); break; } Server.Recycle(msg); } }