示例#1
0
        protected CommandResponsePacket SendRequestAndWaitForResponse(Server server, byte[] command, string message)
        {
            CommandResponsePacket commandResponsePacket = new CommandResponsePacket();

            server.Send(command);
            int  num  = commandResponsePacket.Read(server.Stream);
            bool flag = num >= 0;
            CommandResponsePacket result;

            if (flag)
            {
                Log.Write("Command {0} executed: result = {1}", new object[]
                {
                    message,
                    (commandResponsePacket.Result == 0) ? "success" : "failure"
                });
                result = commandResponsePacket;
            }
            else
            {
                Log.Write("Command {0} sent: result did not arrived", new object[]
                {
                    message
                });
                result = null;
            }
            return(result);
        }
示例#2
0
        protected void MainThreadRun(object arg)
        {
            this.Broadcast(Packet.DiscoverRequest, this.BroadcastPort);

            Thread.Sleep(10);
            Packet packet = new Packet();
            CommandResponsePacket commandResponsePacket = new CommandResponsePacket();

            packet.ReadHeader(this.Stream);
            packet = Packet.DeriveAndLoadData(packet, this.Stream);
            bool flag = packet is DiscoverResponsePacket;

            if (flag)
            {
                DiscoverResponsePacket discoverResponsePacket = packet as DiscoverResponsePacket;
                Log.Write("Got discover response: {0}", new object[]
                {
                    packet
                });
                Log.Write("Sending port select request..");
                byte portFromMask = this.GetPortFromMask(discoverResponsePacket.PortMask);
                Packet.PortSelectRequest[6] = portFromMask;
                this.Broadcast(Packet.PortSelectRequest, this.BroadcastPort);
                commandResponsePacket.Read(this.Stream);
                Log.Write("Got port select response: {0}", new object[]
                {
                    commandResponsePacket
                });
                Client.CurrentServer.RemoteAddress.Port = 61576 + (int)portFromMask;
                this.SendRequestAndWaitForResponse(Client.CurrentServer, Packet.CheckConnectionRequest, "check connection");
                this.SendRequestAndWaitForResponse(Client.CurrentServer, Packet.InitCANTranslationRequest, "init CAN");
                Thread.Sleep(1000);
            }
        }
示例#3
0
        /// <summary>
        /// Records when a command response packet was received, to update the cooresponding state and release another blocking call.
        /// </summary>
        public void ResponseReceived(CommandResponsePacket packet)
        {
            lock (_commands)
            {
                Command command = _commands
                                  .Where(c => c.Sequence == packet.Sequence)
                                  .OrderBy(c => c.Elapsed)
                                  .FirstOrDefault();

                if (command == null)
                {
                    ErrorHandler.LogError(new Exception($"Error processing response.. command with sequence '{packet.Sequence}' not found"));
                    return;
                }

                if ((packet.Code == ResultCode.Accept) || (packet.Code == ResultCode.Reject))
                {
                    command.Code           = packet.Code;
                    command.ResponsePacket = packet;
                }
                else if (packet.Code == ResultCode.Timeout)
                {
                    command.Code = ResultCode.Timeout;
                }
                else
                {
                    command.Code = ResultCode.Error;
                }
            }
        }
示例#4
0
        /// <summary>
        /// Answers a 'GetPlayers' request, responds with a list of connected players (of same game).
        /// </summary>
        private void Answer_GetPlayers(Client sourceClient, CommandRequestPacket packet)
        {
            try
            {
                //get source player
                NetworkPlayer player = NetworkPlayer.FromPacket(packet);

                //get list of connected players (not source player)
                List <NetworkPlayer> otherPlayers = GetMatchingPlayers(player.GameTitle, player.GameVersion)
                                                    .Where(p => p.PlayerKey != player.PlayerKey)
                                                    .ToList();

                //message
                Log.Write($"Sending '{packet.CommandType}' ({otherPlayers.Count} player{(otherPlayers.Count != 1 ? "s" : "")}) response to '{player.IP}'");

                //serialize list to bytes
                PacketBuilder builder = new PacketBuilder();
                builder.AddUInt16((ushort)otherPlayers.Count);
                foreach (NetworkPlayer p in otherPlayers)
                {
                    builder.AddBytes(p.ToBytes());
                }

                //create packet
                CommandResponsePacket response = new CommandResponsePacket(
                    gameTitle: player.GameTitle,
                    gameVersion: player.GameVersion,
                    sourceIP: _ip,
                    destinationIP: player.IP,
                    playerName: player.Name,
                    commandType: CommandType.GetPlayers,
                    sequence: packet.Sequence,
                    code: ResultCode.Accept,
                    data: builder.ToBytes());

                //send response back to source
                sourceClient.SendPacket(response);
            }
            catch (Exception ex)
            {
                Log.Write("Answer_GetPlayers: Error returning player list");
                ErrorHandler.LogError(ex);
            }
        }
示例#5
0
        /// <summary>
        /// Answers a 'QuitGame' request, responds with acceptance.
        /// </summary>
        private void Answer_QuitGame(Client sourceClient, CommandRequestPacket packet)
        {
            try
            {
                //get source player
                NetworkPlayer player = NetworkPlayer.FromPacket(packet);
                player = GetPlayerByKey(player.PlayerKey);

                //set quit flag
                player.QuitGame = true;

                //remove expired players
                RemoveExpiredPlayers();

                //remove expired sessions
                RemoveExpiredSessions();

                //message
                Log.Write($"Sending '{packet.CommandType}' ({ResultCode.Accept}) response to '{player.IP}'");

                //create packet
                CommandResponsePacket response = new CommandResponsePacket(
                    gameTitle: player.GameTitle,
                    gameVersion: player.GameVersion,
                    sourceIP: _ip,
                    destinationIP: player.IP,
                    playerName: player.Name,
                    commandType: CommandType.QuitGame,
                    sequence: packet.Sequence,
                    code: ResultCode.Accept,
                    data: null);

                //send response back to source
                sourceClient.SendPacket(response);
            }
            catch (Exception ex)
            {
                Log.Write("Answer_QuitGame: Unknown error");
                ErrorHandler.LogError(ex);
            }
        }
示例#6
0
        /// <summary>
        /// Sends command response.  Data is optional.
        /// </summary>
        public bool SendCommandResponse(IPAddress destinationIP, CommandType type, int sequence, ResultCode code, byte[] data = null)
        {
            try
            {
                //disabled?
                if (_connectionState == ConnectionState.Disabled)
                {
                    return(false);
                }

                //create packet
                CommandResponsePacket packet = new CommandResponsePacket(
                    gameTitle: _config.GameTitle,
                    gameVersion: _config.GameVersion,
                    sourceIP: _config.LocalIP,
                    destinationIP: destinationIP,
                    playerName: _localPlayer.Name,
                    commandType: type,
                    sequence: sequence,
                    code: code,
                    data: data);

                //send packet
                _client.SendPacket(packet);
                _commandResponsesSent++;

                //success
                return(true);
            }
            catch (Exception ex)
            {
                _tcpErrors++;
                Log.Write("SendCommandResponse: Error sending data");
                ErrorHandler.LogError(ex);
                return(false);
            }
        }
示例#7
0
 public CommandResult(ResultCode code, CommandResponsePacket responsePacket = null)
 {
     Code           = code;
     ResponsePacket = responsePacket;
 }
示例#8
0
        /// <summary>
        /// Forwards a command request packet to destination player, waits for response (or timeout),
        /// responds to source player with answer.
        /// </summary>
        private void Passthrough_Command(Client sourceClient, CommandRequestPacket requestPacket)
        {
            CommandResult result            = new CommandResult(ResultCode.Unspecified);
            NetworkPlayer sourcePlayer      = null;
            NetworkPlayer destinationPlayer = null;
            bool          sessionEnded      = false;

            try
            {
                //get source player
                sourcePlayer = NetworkPlayer.FromPacket(requestPacket);
                if (sourcePlayer == null)
                {
                    Log.Write($"Passthrough_Command: Unable to parse packet");
                    result.Code = ResultCode.Error;
                    return;
                }

                //get destination player
                destinationPlayer = GetMatchingPlayer(requestPacket.DestinationIP, requestPacket.GameTitle, requestPacket.GameVersion);
                if (destinationPlayer == null)
                {
                    Log.Write($"Passthrough_Command: Cannot find destination player at '{requestPacket.DestinationIP}'");
                    result.Code = ResultCode.Error;
                    return;
                }

                //create session?
                if (requestPacket.CommandType == CommandType.ConnectToPlayer)
                {
                    CreateSession(sourcePlayer.PlayerKey, destinationPlayer.PlayerKey);
                }

                //get session
                Session session = GetSession(sourcePlayer.PlayerKey, destinationPlayer.PlayerKey);
                if ((session == null) && (requestPacket.CommandType != CommandType.ConnectToPlayer))
                {
                    Log.Write($"Passthrough_Command: Live session does not exist between '{sourcePlayer.IP}' and '{destinationPlayer.IP}'");
                    result.Code  = ResultCode.Error;
                    sessionEnded = true;
                    return;
                }

                //get destination client
                Client destinationClient = GetClientByPlayer(destinationPlayer);
                if (destinationClient == null)
                {
                    Log.Write($"Passthrough_Command: Destination player at {destinationClient.RemoteIP} does not have assigned TCP client");
                    result.Code = ResultCode.Error;
                    return;
                }

                //message
                Log.Write($"Forwarding '{requestPacket.CommandType}' request from '{sourcePlayer.IP}' to '{destinationPlayer.IP}'");

                //record command request being sent
                _commandManager.RequestSent(requestPacket);

                //forward request to destination
                destinationClient.SendPacket(requestPacket);

                //wait for response or timeout
                while (true)
                {
                    //get current status
                    result = _commandManager.GetCommandStatus(requestPacket.Sequence);

                    //have answer or timeout?  return!
                    if (result.Code != ResultCode.Unspecified)
                    {
                        return;
                    }

                    //sleep
                    Thread.Sleep(15);
                }
            }
            catch (Exception ex)
            {
                Log.Write("Passthrough_Command: Error forwarding request or waiting for response");
                ErrorHandler.LogError(ex);
            }
            finally
            {
                try
                {
                    //create response packet
                    CommandResponsePacket responsePacket;
                    if ((result.Code.In(ResultCode.Accept, ResultCode.Reject)) && (result.ResponsePacket != null))
                    {
                        ////create session?
                        //if ((requestPacket.CommandType == CommandType.ConnectToPlayer) && (result.Code == ResultCode.Accept))
                        //    CreateSession(sourcePlayer.UniqueKey, destinationPlayer.UniqueKey);

                        //confirm session?
                        if ((requestPacket.CommandType == CommandType.ConnectToPlayer) && (result.Code == ResultCode.Accept))
                        {
                            ConfirmSession(sourcePlayer.PlayerKey, destinationPlayer.PlayerKey);
                        }

                        //get original packet
                        responsePacket = result.ResponsePacket;

                        //message
                        Log.Write($"Forwarding '{result.ResponsePacket.CommandType}' ({result.ResponsePacket.Code}) response from '{destinationPlayer.IP}' to '{sourcePlayer.IP}'");
                    }
                    else
                    {
                        //create new timeout/error packet
                        responsePacket = new CommandResponsePacket(
                            gameTitle: requestPacket.GameTitle,
                            gameVersion: requestPacket.GameVersion,
                            sourceIP: requestPacket.DestinationIP,
                            destinationIP: requestPacket.SourceIP,
                            playerName: "",
                            commandType: requestPacket.CommandType,
                            sequence: requestPacket.Sequence,
                            code: result.Code,
                            data: null);

                        //message
                        Log.Write($"Sending '{responsePacket.CommandType}' ({responsePacket.Code}) response to '{sourceClient.RemoteIP}'");
                    }

                    //send response to source
                    sourceClient.SendPacket(responsePacket);

                    //send session-ended command?
                    if (sessionEnded)
                    {
                        SendEndSessionCommand(sourceClient, sourcePlayer);
                    }
                }
                catch (Exception ex)
                {
                    Log.Write("Passthrough_Command: Error sending command response to source");
                    ErrorHandler.LogError(ex);
                }
            }
        }