Пример #1
0
 protected async void HandshakeHandler(NeutronPlayer player, double clientTime, Authentication authentication)
 {
     if (authentication.Pass.Decrypt(out string phrase))
     {
         authentication = new Authentication(authentication.User, phrase, false);
         try
         {
             if (await OnAuthentication.Invoke(player, authentication))             //* First packet
             {
                 using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull()) //* Second First packet
                 {
                     NeutronStream.IWriter writer = stream.Writer;
                     writer.WritePacket((byte)Packet.Handshake);
                     writer.Write(LocalTime);
                     writer.Write(clientTime);
                     writer.Write(player.StateObject.UdpLocalEndPoint.Port);
                     writer.WriteWithInteger(player);
                     player.Write(writer);
                 }
                 OnPlayerConnected?.Invoke(player); //* Three packet
             }
         }
         catch (Exception ex) // Tasks manual catch exception.
         {
             LogHelper.Stacktrace(ex);
         }
     }
     else if (!LogHelper.Error("Auth decrypt failed!"))
     {
         DisconnectHandler(player);
     }
 }
Пример #2
0
 public static void Disconnect(NeutronPlayer player, string reason)
 {
     using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
     {
         NeutronStream.IWriter writer = stream.Writer;
         writer.WritePacket((byte)Packet.Disconnection);
         writer.Write(player.Id);
         writer.Write(reason);
         player.Write(writer, Helper.GetHandlers().OnPlayerDisconnected);
     }
 }
Пример #3
0
 /// <summary>
 ///* Envia uma mensagem para o jogador.<br/>
 ///* (Server-Side).
 /// </summary>
 /// <param name="player"></param>
 /// <param name="packet"></param>
 /// <param name="message"></param>
 public static void Error(this NeutronPlayer player, Packet packet, string message, int errorCode = 0)
 {
     using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
     {
         NeutronStream.IWriter writer = stream.Writer;
         writer.WritePacket((byte)Packet.Error);
         writer.WritePacket((byte)packet);
         writer.Write(message);
         writer.Write(errorCode);
         player.Write(writer);
     }
 }
Пример #4
0
#pragma warning disable IDE1006
        protected void iRPCHandler(NeutronPlayer owner, NeutronPlayer sender, short viewId, byte rpcId, byte instanceId, byte[] buffer, RegisterMode registerType, TargetTo targetTo, CacheMode cache, Protocol protocol)
#pragma warning restore IDE1006
        {
            void Run((int, int, RegisterMode) key)
            {
                bool Send()
                {
                    MatchmakingTo matchmakingTo = MatchmakingTo.Auto;

                    if (targetTo == TargetTo.Me)
                    {
                        matchmakingTo = MatchmakingTo.Me;
                    }
                    using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
                    {
                        NeutronStream.IWriter writer = stream.Writer;
                        writer.WritePacket((byte)Packet.iRPC);
                        writer.WritePacket((byte)registerType);
                        writer.Write(viewId);
                        writer.Write(rpcId);
                        writer.Write(instanceId);
                        writer.WriteNext(buffer);
                        MatchmakingHelper.Internal.AddCache(rpcId, viewId, writer, owner, cache, CachedPacket.iRPC);
                        owner.Write(sender, writer, targetTo, matchmakingTo, protocol);
                    }
                    return(true);
                }

                if (MatchmakingHelper.Server.GetNetworkObject(key, owner, out NeutronView neutronView))
                {
                    if (neutronView.iRPCs.TryGetValue((rpcId, instanceId), out RPCInvoker remoteProceduralCall))
                    {
                        try
                        {
                            iRPCAttribute iRPCAttribute = remoteProceduralCall.iRPC;
                            if (ReflectionHelper.iRPC(buffer, remoteProceduralCall, owner))
                            {
                                Send();
                            }
                        }
                        catch (Exception ex)
                        {
                            LogHelper.Stacktrace(ex);
                        }
                    }
                    else
                    {
                        Send();
                    }
                }
Пример #5
0
 protected void ChatHandler(NeutronPlayer player, ChatMode packet, MatchmakingTo matchmakingTo, int viewId, string message)
 {
     if (OnMessageReceived.Invoke(player, message))
     {
         using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
         {
             NeutronStream.IWriter writer = stream.Writer;
             writer.WritePacket((byte)Packet.Chat);
             writer.Write(message);
             if (packet == ChatMode.Global)
             {
                 player.Write(writer, TargetTo.All, matchmakingTo, Protocol.Tcp);
             }
             else if (packet == ChatMode.Private)
             {
                 if (MatchmakingHelper.Server.GetPlayer(viewId, out NeutronPlayer playerFound))
                 {
                     playerFound.Write(player, writer, TargetTo.Me, MatchmakingTo.Me, Protocol.Tcp);
                 }
                 else
                 {
                     player.Error(Packet.Chat, "Player not found!", ErrorMessage.PLAYER_NOT_FOUND);
                 }
             }
         }
     }
 }
Пример #6
0
 protected void SetNicknameHandler(NeutronPlayer player, string nickname)
 {
     if (OnPlayerNicknameChanged.Invoke(player, nickname))
     {
         player.Nickname = nickname;
         using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
         {
             NeutronStream.IWriter writer = stream.Writer;
             writer.WritePacket((byte)Packet.Nickname);
             writer.Write(nickname);
             player.Write(writer, Helper.GetHandlers().OnPlayerNicknameChanged);
         }
     }
 }
Пример #7
0
        protected void SynchronizeHandler(NeutronPlayer player, Protocol protocol)
        {
            //* Envia todos os jogadores conectados para mim.
            using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
            {
                NeutronStream.IWriter writer  = stream.Writer;
                NeutronPlayer[]       players = MatchmakingHelper.Internal.GetPlayersByMatchmakingTo(player, MatchmakingTo.Auto);
                players = players.Where(x => x.Id != player.Id).ToArray();
                writer.WritePacket((byte)Packet.Synchronize);
                writer.Write((byte)1);
                writer.WriteNext(players.Serialize().Compress(CompressionMode.Deflate));
                player.Write(writer, TargetTo.Me, MatchmakingTo.Me, protocol);
            }

            //* Envia-me para todos os jogadores conectados.
            using (NeutronStream stream = Neutron.PooledNetworkStreams.Pull())
            {
                NeutronStream.IWriter writer = stream.Writer;
                writer.WritePacket((byte)Packet.Synchronize);
                writer.Write((byte)2);
                writer.WriteNext(player.Serialize().Compress(CompressionMode.Deflate));
                player.Write(writer, TargetTo.Others, MatchmakingTo.Auto, protocol);
            }
        }
Пример #8
0
        //* Usado para enviar os dados para o servidor.
        //* Client->Server
        protected void Send(NeutronStream stream, Protocol protocol = Protocol.Tcp)
        {
            try
            {
                if (IsServer)
                {
                    throw new NeutronException("To use this packet on the server side it is necessary to assign the \"Player\" parameter.");
                }
#if !UNITY_SERVER || UNITY_EDITOR
                if (This.IsConnected)
                {
                    NeutronStream.IWriter wHeader = stream.hWriter;
                    NeutronStream.IWriter wPacket = stream.Writer;
                    byte[] pBuffer = wPacket.ToArray().Compress(); //! Otimizado para evitar alocações, bom isso depende de como você usa o Neutron :p
                    switch (protocol)
                    {
                    //* ValueTask ainda não funciona na Unity, isso mesmo, em 2021 com .net 6 e standard 2.1, e a unity atrasada com essa merda de Mono, vê se pode?
                    case Protocol.Tcp:
                    {
                        if (wHeader.GetPosition() == 0)
                        {
                            wHeader.WriteByteArrayWithAutoSize(pBuffer);         //* Pre-fixa o tamanho da mensagem no cabeçalho, um inteiro/short/byte(4/2/1 bytes), e a mensagem.
                            byte[] hBuffer = wHeader.ToArray();
                            wHeader.Write();

                            NetworkStream networkStream = TcpClient.GetStream();
                            switch (Helper.GetConstants().SendModel)
                            {
                            case SendType.Synchronous:
                                networkStream.Write(hBuffer, 0, hBuffer.Length);             //* Envia os dados pro servidor de modo síncrono, esta opção é melhor, não aloca e tem performance de CPU.
                                break;

                            default:
                                if (Helper.GetConstants().SendAsyncPattern == AsynchronousType.APM)
                                {
                                    networkStream.Write(hBuffer, 0, hBuffer.Length);             //* Envia os dados pro servidor de modo assíncrono, mentira, envia da mesma forma de "SendType.Synchronous", preguiça mesmo. :p, porque BeginReceive e Endreceive é chato de fazer pro TCP :D
                                }
                                else
                                {
                                    SocketHelper.SendTcpAsync(networkStream, hBuffer, TokenSource.Token);             //* Envia os dados pro servidor de forma assíncrona., faz alocações pra caralho, no tcp não tanto, mas no UDP..... é foda. e usa muita cpu, evite, se souber como resolver, sinta-se a vontade para contribuir.
                                }
                                break;
                            }
                            //* Adiciona no profiler a quantidade de dados de saída(Outgoing).
                            NeutronStatistics.ClientTCP.AddOutgoing(hBuffer.Length);
                        }
                        else
                        {
                            throw new Exception($"Send(Tcp): Invalid position, is not zero! Pos -> {wHeader.GetPosition()} Capacity -> {wHeader.GetCapacity()}. You called Finish() ?");
                        }
                    }
                    break;

                    case Protocol.Udp:
                    {
                        if (UdpEndPoint == null)
                        {
                            LogHelper.Error("Unauthenticated!");
                        }
                        else
                        {
                            StateObject.SendDatagram = pBuffer;
                            switch (Helper.GetConstants().SendModel)
                            {
                            case SendType.Synchronous:
                                SocketHelper.SendBytes(UdpClient, pBuffer, UdpEndPoint);             //* envia de modo síncrono, evita alocações e performance boa.
                                break;

                            default:
                            {
                                switch (Helper.GetConstants().SendAsyncPattern)
                                {
                                case AsynchronousType.APM:
                                {
                                    //* aloca, mas não tanto, boa performance.
                                    SocketHelper.BeginSendBytes(UdpClient, pBuffer, UdpEndPoint, (ar) =>
                                                {
                                                    SocketHelper.EndSendBytes(UdpClient, ar);
                                                });
                                    break;
                                }

                                default:
                                    SocketHelper.SendUdpAsync(UdpClient, StateObject, UdpEndPoint);                     //* se foder, aloca pra caralho e usa cpu como a unreal engine, ValueTask poderia resolver, mas......
                                    break;
                                }
                                break;
                            }
                            }
                            //* Adiciona no profiler a quantidade de dados de saída(Outgoing).
                            NeutronStatistics.ClientUDP.AddOutgoing(pBuffer.Length);
                        }
                    }
                    break;
                    }
                }
                else
                {
                    LogHelper.Error("Non-connected socket, sending failed!");
                }
#else
                throw new Exception("To use this packet on the server side it is necessary to assign the \"Player\" parameter.");
#endif
            }
            catch (ObjectDisposedException) { }
            catch (SocketException) { }
            catch (Exception ex)
            {
                LogHelper.Stacktrace(ex);
            }
        }
Пример #9
0
        //* 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) { }
        }