private void PacketProcessingStack() { CancellationToken token = TokenSource.Token; NeutronPacket packet = _dataForProcessing.Pull(); //* Take the packet from the queue and block the thread until there is a packet. if (packet != null) { RunPacket(packet); } }
public static NeutronPacket PollPacket(byte[] buffer, NeutronPlayer owner, NeutronPlayer sender, Protocol protocol) { NeutronPacket neutronPacket = Neutron.PooledNetworkPackets.Pull(); neutronPacket.Buffer = buffer; neutronPacket.Owner = owner; neutronPacket.Sender = sender; neutronPacket.Protocol = protocol; return(neutronPacket); }
private void CreateUdpPacket(NeutronPlayer player) { byte[] datagram = player.StateObject.SlicedDatagram; //* Get the datagram. byte[] pBuffer = datagram.Decompress(); //* Decompress the packet. NeutronPacket neutronPacket = Helper.PollPacket(pBuffer, player, player, Protocol.Udp); //* Create the packet. _dataForProcessing.Push(neutronPacket); //* Add the packet to the queue. NeutronStatistics.ServerUDP.AddIncoming(datagram.Length); //* Add the incoming bytes to the statistics. }
public void AddPacket(NeutronPacket packet) { lock (Encapsulate.BeginLock) { if (Encapsulate.Sender != null) { packet.Sender = Encapsulate.Sender; //* Set the sender. } packet.IsServerSide = true; //* Set the packet as server side. _dataForProcessing.Push(packet); //* Add the packet to the queue. } }
private void RunPacket(NeutronPacket neutronPacket) { byte[] pBuffer = neutronPacket.Buffer; //* Get the packet buffer. bool isServer = neutronPacket.IsServerSide; //* Get the packet is server side. Protocol protocol = neutronPacket.Protocol; //* Get the packet protocol. NeutronPlayer owner = neutronPacket.Owner; //* Get the packet owner. NeutronPlayer sender = neutronPacket.Sender; //* Get the packet sender. using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IReader reader = stream.Reader; reader.SetBuffer(pBuffer); //* Set the buffer. Packet outPacket = (Packet)reader.ReadPacket(); //* Read the packet. if (OnReceivePacket(outPacket) || isServer) { switch (outPacket) { case Packet.TcpKeepAlive: { using (NeutronStream tcpStream = Neutron.PooledNetworkStreams.Pull()) { NeutronStream.IWriter writer = tcpStream.Writer; writer.WritePacket((byte)Packet.TcpKeepAlive); owner.Write(writer); } } break; case Packet.Handshake: { var appId = reader.ReadString(); //* Read the app id. var time = reader.ReadDouble(); //* Read the time. var authentication = reader.ReadWithInteger <Authentication>(); //* Read the authentication. if (appId.Decrypt(out appId)) { //* Decrypt the app id. if (Helper.GetSettings().GlobalSettings.AppId == appId) { HandshakeHandler(owner, time, authentication); //* Handshake the player. } else { owner.Error(Packet.Handshake, "Update your game version, it does not match the current server version."); Task.Run(async() => { await Task.Delay(150); //* Submit the disconnect after receiving the error message. DisconnectHandler(owner); //* Disconnect the player. }); } } else if (!LogHelper.Error("Failed to verify handshake!")) { DisconnectHandler(owner); //* Disconnect the player. } } break; case Packet.Nickname: { var nickname = reader.ReadString(); //* Read the nickname. SetNicknameHandler(owner, nickname); } break; case Packet.Chat: { var matchmakingTo = default(MatchmakingTo); //* Create the matchmaking to. var viewId = default(int); //* Read the view id. var chatPacket = (ChatMode)reader.ReadPacket(); //* Read the chat mode. switch (chatPacket) { case ChatMode.Global: matchmakingTo = (MatchmakingTo)reader.ReadPacket(); //* Read the matchmaking to. break; case ChatMode.Private: viewId = reader.ReadInt(); //* Read the view id. break; } string message = reader.ReadString(); ChatHandler(owner, chatPacket, matchmakingTo, viewId, message); } break; case Packet.iRPC: { var registerType = (RegisterMode)reader.ReadPacket(); //* Read the register mode. var targetTo = (TargetTo)reader.ReadPacket(); //* Read the target to. var cache = (CacheMode)reader.ReadPacket(); //* Read the cache mode. short viewId = reader.ReadShort(); //* Read the view id. var rpcId = reader.ReadByte(); //* Read the rpc id. var instanceId = reader.ReadByte(); //* Read the instance id. var buffer = reader.ReadNext(); //* Read the buffer. iRPCHandler(owner, sender, viewId, rpcId, instanceId, buffer, registerType, targetTo, cache, protocol); //* Handle the iRPC. } break; case Packet.gRPC: { var id = reader.ReadByte(); //* Read the id. var buffer = reader.ReadNext(); //* Read the buffer. gRPCHandler(owner, sender, id, buffer, protocol); //* Handle the gRPC. } break; case Packet.GetChannels: { GetChannelsHandler(owner); //* Handle the get channels. } break; case Packet.JoinChannel: { var channelId = reader.ReadInt(); //* Read the channel id. JoinChannelHandler(owner, channelId); //* Handle the join channel. } break; case Packet.GetCache: { var cachedPacket = (CachedPacket)reader.ReadPacket(); //* Read the cached packet. var Id = reader.ReadByte(); //* Read the id. var includeMe = reader.ReadBool(); //* Send packets to me? GetCacheHandler(owner, cachedPacket, Id, includeMe); //* Handle the get cache. } break; case Packet.CreateRoom: { var password = reader.ReadString(); //* Read the password. var room = reader.ReadWithInteger <NeutronRoom>(); //* Read the room. CreateRoomHandler(owner, room, password); //* Handle the create room. } break; case Packet.GetRooms: { GetRoomsHandler(owner); //* Handle the get rooms. } break; case Packet.JoinRoom: { var roomId = reader.ReadInt(); //* Read the room id. var password = reader.ReadString(); //* Read the password. JoinRoomHandler(owner, roomId, password); //* Handle the join room. } break; case Packet.Leave: { var packet = (MatchmakingMode)reader.ReadPacket(); //* Read the matchmaking mode. if (packet == MatchmakingMode.Room) { LeaveRoomHandler(owner); //* Handle the leave room. } else if (packet == MatchmakingMode.Channel) { LeaveChannelHandler(owner); //* Handle the leave channel. } } break; case Packet.Destroy: { DestroyPlayerHandler(owner); //* Handle the destroy player. } break; case Packet.SetPlayerProperties: { var properties = reader.ReadString(); //* Read the properties. SetPlayerPropertiesHandler(owner, properties); //* Handle the set player properties. } break; case Packet.SetRoomProperties: { var properties = reader.ReadString(); //* Read the properties. SetRoomPropertiesHandler(owner, properties); //* Handle the set room properties. } break; case Packet.UdpKeepAlive: { var time = reader.ReadDouble(); //* Read the time. PingHandler(owner, time); //* Handle the ping. } break; case Packet.CustomPacket: { // var isMine; // TargetTo targetTo = default(TargetTo); // MatchmakingTo matchmakingTo = default(MatchmakingTo); // int viewId = reader.ReadInt(); // byte packet = reader.ReadPacket(); // if ((isMine = PlayerHelper.IsMine(owner, viewId))) // { // targetTo = (TargetTo)reader.ReadPacket(); // matchmakingTo = (MatchmakingTo)reader.ReadPacket(); // } // byte[] buffer = reader.ReadWithInteger(); // CustomPacketHandler(owner, isMine, viewId, buffer, packet, targetTo, matchmakingTo, protocol); } break; case Packet.AutoSync: { var registerMode = (RegisterMode)reader.ReadPacket(); //* Read the register mode. var viewId = reader.ReadShort(); //* Read the view id. var instanceId = reader.ReadByte(); //* Read the instance id. var parameters = reader.ReadNext(); //* Read the parameters. OnAutoSyncHandler(neutronPacket, viewId, instanceId, parameters, registerMode); //* Handle the auto sync. } break; case Packet.Synchronize: { SynchronizeHandler(owner, protocol); //* Handle the synchronize. } break; } } else { LogHelper.Error("Client is not allowed to run this packet."); } } }
private async void OnReceivingDataLoop(Stream networkStream, NeutronPlayer player, Protocol protocol) { CancellationToken token = player.TokenSource.Token; try { bool whileOn = false; //* stop the while loop. byte[] hBuffer = new byte[NeutronModule.HeaderSize]; //* Create the header buffer. while ((!TokenSource.Token.IsCancellationRequested && !token.IsCancellationRequested) && !whileOn) { switch (protocol) { case Protocol.Tcp: { if (await SocketHelper.ReadAsyncBytes(networkStream, hBuffer, 0, NeutronModule.HeaderSize, token)) { //* Read the header. int size = ByteHelper.ReadSize(hBuffer); //* Get the packet size. if (size > Helper.GetConstants().Tcp.MaxTcpPacketSize || size <= 0) { //* Check if the packet size is valid. if (!LogHelper.Error($"Invalid tcp message size! size: {size}")) { DisconnectHandler(player); //* Disconnect the player. } } else { byte[] packetBuffer = new byte[size]; //* Create the packet buffer with the size. if (await SocketHelper.ReadAsyncBytes(networkStream, packetBuffer, 0, size, token)) { //* Read the packet. packetBuffer = packetBuffer.Decompress(); //* Decompress the packet. NeutronPacket neutronPacket = Helper.PollPacket(packetBuffer, player, player, Protocol.Tcp); //* Create the packet. _dataForProcessing.Push(neutronPacket); //* Add the packet to the queue. NeutronStatistics.ServerTCP.AddIncoming(size + hBuffer.Length); //* Add the incoming bytes to the statistics. } else { DisconnectHandler(player); //* Desconecta o cliente caso a leitura falhe, a leitura falhará em caso de desconexão...etc. } } } else { DisconnectHandler(player); //* Desconecta o cliente caso a leitura falhe, a leitura falhará em caso de desconexão...etc. } } break; case Protocol.Udp: { switch (Helper.GetConstants().ReceiveAsyncPattern) { case AsynchronousType.TAP: if (await SocketHelper.ReadAsyncBytes(player.UdpClient, player.StateObject)) { CreateUdpPacket(player); //* Create the packet. } break; default: UdpApmReceive(player); //* Receive the data. whileOn = true; //* stop the while loop. break; } } break; } } } catch (SocketException) { } catch (ObjectDisposedException) { } catch (OperationCanceledException) { } catch (Exception ex) { LogHelper.Stacktrace(ex); if (!token.IsCancellationRequested) { DisconnectHandler(player); //* Disconnect the player. } } }
private IEnumerator OnReceivingDataCoroutine(CancellationToken token, Protocol protocol) { byte[] hBuffer = new byte[NeutronModule.HeaderSize]; //* Create the header buffer. while (!token.IsCancellationRequested) { foreach (NeutronPlayer player in PlayersBySocket.Values) { Stream networkStream = player.NetworkStream; switch (protocol) { case Protocol.Tcp: { var headerTask = SocketHelper.ReadAsyncBytes(networkStream, hBuffer, 0, NeutronModule.HeaderSize, token).AsCoroutine(); yield return(headerTask); if (headerTask.Result) { //* Read the header. int size = ByteHelper.ReadSize(hBuffer); //* Get the packet size. if (size > Helper.GetConstants().Tcp.MaxTcpPacketSize || size <= 0) { //* Check if the packet size is valid. if (!LogHelper.Error($"Invalid tcp message size! size: {size}")) { DisconnectHandler(player); //* Disconnect the player. } } else { byte[] packetBuffer = new byte[size]; //* Create the packet buffer with the size. var packetTask = SocketHelper.ReadAsyncBytes(networkStream, packetBuffer, 0, size, token).AsCoroutine(); yield return(packetTask); if (packetTask.Result) { //* Read the packet. packetBuffer = packetBuffer.Decompress(); //* Decompress the packet. NeutronPacket neutronPacket = Helper.PollPacket(packetBuffer, player, player, Protocol.Tcp); //* Create the packet. _dataForProcessing.Push(neutronPacket); //* Add the packet to the queue. NeutronStatistics.ServerTCP.AddIncoming(size + hBuffer.Length); //* Add the incoming bytes to the statistics. } else { DisconnectHandler(player); //* Desconecta o cliente caso a leitura falhe, a leitura falhará em caso de desconexão...etc. } } } else { DisconnectHandler(player); //* Desconecta o cliente caso a leitura falhe, a leitura falhará em caso de desconexão...etc. } } break; case Protocol.Udp: { switch (Helper.GetConstants().ReceiveAsyncPattern) { case AsynchronousType.TAP: { var datagramTask = SocketHelper.ReadAsyncBytes(player.UdpClient, player.StateObject).AsCoroutine(); yield return(datagramTask); if (datagramTask.Result) { CreateUdpPacket(player); //* Create the packet. } } break; default: UdpApmReceive(player); //* Receive the data. break; } } break; } } yield return(null); } }
//* Aqui os dados são enviados aos seus clientes. public void OnSendingData(NeutronPlayer player, NeutronPacket neutronPacket) { try { using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) { var playerId = (short)neutronPacket.Sender.Id; //* Get the player id. byte[] pBuffer = neutronPacket.Buffer.Compress(); //* Compress the packet. switch (neutronPacket.Protocol) { case Protocol.Tcp: { NeutronStream.IWriter wHeader = stream.Writer; wHeader.WriteByteArrayWithAutoSize(pBuffer); //* Write the packet and its size. wHeader.Write(playerId); //* Write the player id in header. byte[] hBuffer = wHeader.ToArray(); //* Get the header buffer. wHeader.Write(); //* End the header. NetworkStream networkStream = player.TcpClient.GetStream(); //* Get the network stream. switch (Helper.GetConstants().SendModel) { case SendType.Synchronous: networkStream.Write(hBuffer, 0, hBuffer.Length); //* Send the header. break; default: if (Helper.GetConstants().SendAsyncPattern == AsynchronousType.APM) { networkStream.Write(hBuffer, 0, hBuffer.Length); //* Send the header. } else { SocketHelper.SendTcpAsync(networkStream, hBuffer, player.TokenSource.Token); //* Send the header. } break; } NeutronStatistics.ServerTCP.AddOutgoing(hBuffer.Length); //* Add the outgoing bytes to the statistics. } break; case Protocol.Udp: { NeutronStream.IWriter wHeader = stream.Writer; wHeader.Write(playerId); //* Write the player id in header. wHeader.WriteNext(pBuffer); //* Write the packet and its size. byte[] hBuffer = wHeader.ToArray(); //* Get the header buffer. wHeader.Write(); //* End the header. player.StateObject.SendDatagram = hBuffer; //* Set the datagram to send. if (player.StateObject.UdpIsReady()) //* Check if the player is ready to send. { NonAllocEndPoint remoteEp = (NonAllocEndPoint)player.StateObject.NonAllocEndPoint; //* Get the remote end point, prevent GC pressure/allocations. switch (Helper.GetConstants().SendModel) { case SendType.Synchronous: SocketHelper.SendBytes(player.UdpClient, hBuffer, remoteEp); //* Send the datagram. break; default: { switch (Helper.GetConstants().SendAsyncPattern) { case AsynchronousType.APM: { SocketHelper.BeginSendBytes(player.UdpClient, hBuffer, remoteEp, (ar) => { SocketHelper.EndSendBytes(player.UdpClient, ar); //* End the send. }); //* Begin the send. break; } default: SocketHelper.SendUdpAsync(player.UdpClient, player.StateObject, remoteEp); //* Send the datagram. break; } break; } } NeutronStatistics.ServerUDP.AddOutgoing(hBuffer.Length); //* Add the outgoing bytes to the statistics. } else { LogHelper.Error($"{player.StateObject.TcpRemoteEndPoint} Cannot receive UDP data. trying... if you are running on WSL2, change the ip from \"localhost\" to the IP address of WSL2 on the client."); } } break; } } } catch (ThreadAbortException) { } catch (SocketException) { } catch (ObjectDisposedException) { } catch (OperationCanceledException) { } catch (Exception) { } }
protected virtual void OnCustomTarget(NeutronPlayer player, NeutronPacket packet, TargetTo targetTo, NeutronPlayer[] players) { throw new NotImplementedException("Ué cara???"); }