private void HandleClientIncomingData(Client client, NetIncomingMessage msg) { var packetType = (PacketType)msg.ReadInt32(); switch (packetType) { case PacketType.ChatData: { // TODO: This code really could use refactoring.. right now only trying to make sure this all works on .NET Core and fixing small issues. var len = msg.ReadInt32(); var chatData = Util.DeserializeBinary <ChatData>(msg.ReadBytes(len)); if (chatData != null) { // Plugin chat handling var chatPluginResult = GameEvents.ChatMessage(client, chatData); if (!chatPluginResult.ContinueServerProc) { return; } chatData = chatPluginResult.Data; // Command handling if (chatData.Message.StartsWith("/")) { var cmdArgs = chatData.Message.Split(' '); var cmdName = cmdArgs[0].Remove(0, 1); if (Commands.ContainsKey(cmdName)) { Commands[cmdName].OnCommandExec(client, chatData); return; } SendChatMessageToPlayer(client, "Command not found"); return; } var chatMsg = new ChatMessage(chatData, client); if (!chatMsg.Suppress) { chatData.Id = client.NetConnection.RemoteUniqueIdentifier; chatData.Sender = ""; if (!string.IsNullOrWhiteSpace(chatMsg.Prefix)) { chatData.Sender += "[" + chatMsg.Prefix + "] "; } chatData.Sender += chatMsg.Sender.DisplayName; if (!string.IsNullOrWhiteSpace(chatMsg.Suffix)) { chatData.Sender += $" ({chatMsg.Suffix}) "; } SendToAll(chatData, PacketType.ChatData, true); logger.LogInformation($"[Chat] <{chatData.Sender}>: {chatData.Message}"); } } } break; case PacketType.VehiclePositionData: { var len = msg.ReadInt32(); var vehicleData = Util.DeserializeBinary <VehicleData>(msg.ReadBytes(len)); if (vehicleData != null) { var vehiclePluginResult = GameEvents.VehicleDataUpdate(client, vehicleData); if (!vehiclePluginResult.ContinueServerProc) { return; } vehicleData = vehiclePluginResult.Data; vehicleData.Id = client.NetConnection.RemoteUniqueIdentifier; vehicleData.Name = client.Name; vehicleData.Latency = client.Latency; client.Health = vehicleData.PlayerHealth; client.LastKnownPosition = vehicleData.Position; client.IsInVehicle = false; SendToAll(vehicleData, PacketType.VehiclePositionData, false, client); } } break; case PacketType.PedPositionData: { var len = msg.ReadInt32(); var pedPosData = Util.DeserializeBinary <PedData>(msg.ReadBytes(len)); if (pedPosData != null) { var pedPluginResult = GameEvents.PedDataUpdate(client, pedPosData); if (!pedPluginResult.ContinueServerProc) { return; } pedPosData = pedPluginResult.Data; pedPosData.Id = client.NetConnection.RemoteUniqueIdentifier; pedPosData.Name = client.DisplayName; pedPosData.Latency = client.Latency; client.Health = pedPosData.PlayerHealth; client.LastKnownPosition = pedPosData.Position; client.IsInVehicle = false; SendToAll(pedPosData, PacketType.PedPositionData, false, client); } } break; case PacketType.NpcVehPositionData: { var len = msg.ReadInt32(); var vehData = Util.DeserializeBinary <VehicleData>(msg.ReadBytes(len)); if (vehData != null) { var pluginVehData = GameEvents.NpcVehicleDataUpdate(client, vehData); if (!pluginVehData.ContinueServerProc) { return; } vehData = pluginVehData.Data; vehData.Id = client.NetConnection.RemoteUniqueIdentifier; SendToAll(vehData, PacketType.NpcVehPositionData, false, client); } } break; case PacketType.NpcPedPositionData: { var len = msg.ReadInt32(); var pedData = Util.DeserializeBinary <PedData>(msg.ReadBytes(len)); if (pedData != null) { var pluginPedData = GameEvents.NpcPedDataUpdate(client, pedData); if (!pluginPedData.ContinueServerProc) { return; } pedData = pluginPedData.Data; pedData.Id = msg.SenderConnection.RemoteUniqueIdentifier; } SendToAll(pedData, PacketType.NpcPedPositionData, false, client); } break; case PacketType.WorldSharingStop: { GameEvents.WorldSharingStop(client); var dcObj = new PlayerDisconnect() { Id = client.NetConnection.RemoteUniqueIdentifier }; SendToAll(dcObj, PacketType.WorldSharingStop, true); } break; case PacketType.NativeResponse: { var len = msg.ReadInt32(); var nativeResponse = Util.DeserializeBinary <NativeResponse>(msg.ReadBytes(len)); if (nativeResponse == null || !_callbacks.ContainsKey(nativeResponse.Id)) { return; } object response = nativeResponse.Response; if (response is IntArgument) { response = ((IntArgument)response).Data; } else if (response is UIntArgument) { response = ((UIntArgument)response).Data; } else if (response is StringArgument) { response = ((StringArgument)response).Data; } else if (response is FloatArgument) { response = ((FloatArgument)response).Data; } else if (response is BooleanArgument) { response = ((BooleanArgument)response).Data; } else if (response is Vector3Argument) { var tmp = (Vector3Argument)response; response = new Vector3() { X = tmp.X, Y = tmp.Y, Z = tmp.Z }; } _callbacks[nativeResponse.Id].Invoke(response); _callbacks.Remove(nativeResponse.Id); } break; case PacketType.PlayerSpawned: { GameEvents.PlayerSpawned(client); logger.LogInformation("Player spawned: " + client.DisplayName); } break; // The following is normally only received on the client. case PacketType.PlayerDisconnect: break; case PacketType.DiscoveryResponse: break; case PacketType.ConnectionRequest: break; case PacketType.NativeCall: break; case PacketType.NativeTick: break; case PacketType.NativeTickRecall: break; case PacketType.NativeOnDisconnect: break; case PacketType.NativeOnDisconnectRecall: break; default: // ReSharper disable once NotResolvedInText // resharper wants to see a variable name in the below... w/e. throw new ArgumentOutOfRangeException("Received unknown packet type. Server out of date or modded client?"); } }