コード例 #1
0
        public void DataReceived(object sender, PacketDataReceivedEventArgs e)
        {
            Log4netLogger.Info(MethodBase.GetCurrentMethod().DeclaringType, $"Get {e.TotalBytesRead} byte(s): 0x{e.DataRead} from {e.DestinationTuple.RemoteEndPoint}");
            if (e.TotalBytesRead == 8 && e.DataRead.Substring(0, 6) == "AB0106" && e.DataRead.Substring(14, 2) == "00")
            {
                try
                {
                    byte[] ImeiStream = e.BytesRead.Skip(3).Take(4).ToArray();
                    int    ImeiInt    = BitConverter.ToInt32(ImeiStream.Reverse().ToArray(), 0);
                    string ImeiWithLeadingZerosLength20 = ImeiInt.ToString("00000000000000000000");
                    Log4netLogger.Info(MethodBase.GetCurrentMethod().DeclaringType, $"Imei: {ImeiInt}. With leading zeros: {ImeiWithLeadingZerosLength20}");
                    string key   = $"Product_{ImeiWithLeadingZerosLength20}_Heartbeat";
                    string value = _connector.StringGet(key);

                    //if found the key (value == null)
                    if (value != null)
                    {
                        _connector.StringSet(key, DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                        PacketConnection.Send(new byte[] { 0xAB, 0xFF, 0x06, e.BytesRead[3], e.BytesRead[4], e.BytesRead[5], e.BytesRead[6], 0x01, 0x01 }, e.DestinationTuple);
                    }
                }
                catch (Exception ex)
                {
                    LogUtil.Log4netLogger.Error(MethodBase.GetCurrentMethod().DeclaringType, $"Error during DataReceived (UDP)", ex);
                }
            }
        }
コード例 #2
0
        private Task FireAndSendResponse(PacketConnection context, Coordinate coordinate, out Ship ship)
        {
            if (_game.LocalPlayer.Board.IsShotAt(in coordinate))
            {
                throw new ProtocolException(ResponseCode.SequenceError, $"Sequence error: {coordinate} has already been fired upon.");
            }

            ship = _game.LocalPlayer.Board.ShootAtInternal(coordinate);

            if (ship is null)
            {
                return(context.SendResponseAsync(ResponseCode.FireMiss, "Miss!"));
            }

            if (ship.Health > 0)
            {
                return(context.SendResponseAsync(GetResponseCode(ship.Type, sunk: false), $"You hit my {ship.Name}"));
            }

            if (_game.LocalPlayer.Board.Ships.All(s => s.Health == 0))
            {
                // Game over
                _game.GameState = GameState.Idle;
                return(context.SendResponseAsync(ResponseCode.FireYouWin, "You win!"));
            }

            return(context.SendResponseAsync(GetResponseCode(ship.Type, sunk: true), $"You sunk my {ship.Name}"));
        }
コード例 #3
0
    public PacketManager()
    {
        _Connection          = new PacketConnection();
        _Connection.listener = new InternalPacketListener(this);

        _Mapper = new Dictionary <int, RecvCallback>();
    }
コード例 #4
0
        /// <inheritdoc />
        public Task OnResponseAsync(PacketConnection context, Response response)
        {
            _game.ThrowIfHost(response.Code);

            _game.GameState = GameState.Disconnected;
            context.Dispose();
            return(Task.CompletedTask);
        }
コード例 #5
0
        /// <inheritdoc />
        public Task OnResponseAsync(PacketConnection context, Response response)
        {
            _game.ThrowIfHost(response.Code);
            _game.ThrowIfWrongState(response.Code, GameState.Handshake);

            SetNameFromArgument(response.Message);
            _game.GameState = GameState.Idle;
            return(Task.CompletedTask);
        }
コード例 #6
0
        /// <inheritdoc />
        public Task OnResponseAsync(PacketConnection context, Response response)
        {
            _game.ThrowIfHost(response.Code);
            _game.ThrowIfWrongState(response.Code, GameState.Idle);

            _game.GameState    = GameState.InGame;
            _game.IsLocalsTurn = response.Code == ResponseCode.StartClient;

            return(Task.CompletedTask);
        }
コード例 #7
0
        /// <inheritdoc />
        public async Task OnCommandAsync(PacketConnection context, string argument)
        {
            _game.ThrowIfNotHost(Command);
            _game.ThrowIfWrongState(Command, GameState.Handshake);

            SetNameFromArgument(argument);

            await context.SendResponseAsync(ResponseCode.Handshake, _game.LocalPlayer.Name);

            _game.GameState = GameState.Idle;
        }
コード例 #8
0
        /// <inheritdoc />
        public Task OnResponseAsync(PacketConnection context, Response response)
        {
            _game.ThrowIfWrongState(response.Code, GameState.InGame);
            _game.ThrowIfNotLocalsTurn();

            if (WaitingForResponseAt is null)
            {
                throw new ProtocolException(ResponseCode.SequenceError, $"Sequence error: Awaiting {Command} command.");
            }

            RegisterShot(WaitingForResponseAt.Value, in response);

            return(Task.CompletedTask);
        }
コード例 #9
0
        public static async Task EnsureVersionGreeting(this PacketConnection stream, string version, CancellationToken cancellationToken)
        {
            Response response = await EnsureResponse(stream, ResponseCode.VersionGreeting, cancellationToken);

            if (string.IsNullOrWhiteSpace(response.Message))
            {
                throw new ProtocolException(ResponseCode.SyntaxError,
                                            $"Missing version. Expected {version}.");
            }

            if (!response.Message.Equals(version, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new ProtocolException(ResponseCode.SyntaxError,
                                            $"Expected {version}, got {response.Message}");
            }
        }
コード例 #10
0
        /// <inheritdoc />
        public Task OnCommandAsync(PacketConnection context, string argument)
        {
            _game.ThrowIfNotHost(Command);
            _game.ThrowIfWrongState(Command, GameState.Idle);

            _game.GameState    = GameState.InGame;
            _game.IsLocalsTurn = _random.NextBool();

            if (_game.IsLocalsTurn)
            {
                return(context.SendResponseAsync(ResponseCode.StartHost, "Host starts"));
            }
            else
            {
                return(context.SendResponseAsync(ResponseCode.StartClient, "Client starts"));
            }
        }
コード例 #11
0
        public static async Task <Response> EnsureResponse(this PacketConnection stream, ResponseCode code, CancellationToken cancellationToken)
        {
            Response response;

            try
            {
                response = await stream.ExpectResponseAsync(cancellationToken);
            }
            catch (ProtocolException error)
            {
                throw new ProtocolException(error.ErrorCode,
                                            $"{error.ErrorMessage} Expected {(short)code}.", error);
            }

            if (response.Code != code)
            {
                throw new ProtocolException(ResponseCode.SequenceError,
                                            $"Expected {(short)code}, got {(short)response.Code}.");
            }

            return(response);
        }
コード例 #12
0
        /// <inheritdoc />
        public Task OnCommandAsync(PacketConnection context, string argument)
        {
            _game.ThrowIfWrongState(Command, GameState.InGame);
            _game.ThrowIfLocalsTurn();
            if (WaitingForResponseAt.HasValue)
            {
                throw new ProtocolException(ResponseCode.SequenceError, $"Sequence error: Awaiting FIRE response for {WaitingForResponseAt}");
            }

            (Coordinate coordinate, string message) = GetCoordinate(argument);

            Task responseTask = FireAndSendResponse(context, coordinate, out Ship ship);

            _game.IsLocalsTurn = true;

            OnTakenFire(new FireOutcome(coordinate, ship));
            if (!string.IsNullOrEmpty(message))
            {
                OnTakenFireMessage(message);
            }

            return(responseTask);
        }
コード例 #13
0
        /// <inheritdoc />
        public Task OnCommandAsync(PacketConnection context, string argument)
        {
            _game.ThrowIfNotHost(Command);

            return(_game.Disconnect());
        }
コード例 #14
0
 public void PacketReceived(PacketConnection conn, int packet_id, byte[] content)
 {
     _PacketManager.PacketReceived(packet_id, content);
 }
コード例 #15
0
 public void ConnectionLost(PacketConnection conn)
 {
     UnityEngine.Debug.Log("------------------------------ ConnectionLost");
     _PacketManager.OnDisconnected();
 }
コード例 #16
0
 public void ConnectionFailed(PacketConnection conn)
 {
     // todo: display error
     _PacketManager.OnFailed();
 }
コード例 #17
0
 public void ConnectionMade(PacketConnection conn)
 {
     _PacketManager.OnConnected();
 }
コード例 #18
0
 /// <inheritdoc />
 public Task OnResponseAsync(PacketConnection context, Response response)
 {
     throw new NotSupportedException();
 }
コード例 #19
0
        /// <inheritdoc />
        public async Task OnCommandAsync(PacketConnection context, string argument)
        {
            var sb = new StringBuilder();

            sb.AppendLine($"Current version: {BattleGame.ProtocolVersion}");
            sb.AppendLine("## Available command:");
            sb.AppendLine("- START");
            sb.AppendLine("\tStarts a new game session.");
            sb.AppendLine("\tSent by: client");
            sb.AppendLine($"\tResponse {221}: Client has first turn");
            sb.AppendLine($"\tResponse {222}: Host has first turn");
            sb.AppendLine();
            sb.AppendLine("- FIRE <coordinate> [message]");
            sb.AppendLine("\tFire at a coordinate, and give optional message.");
            sb.AppendLine("\tCoordinate shall be formatted <letter><number>.");
            sb.AppendLine("\tCoordinate ranges from A1 to J10.");
            sb.AppendLine("\tSent by: both");
            sb.AppendLine($"\tResponse {230}: you missed");
            sb.AppendLine($"\tResponse {241}-{245}: you hit a ship");
            sb.AppendLine($"\tResponse {251}-{255}: you sunk a ship");
            sb.AppendLine($"\tResponse {260}: you sunk the last ship, and won");
            sb.AppendLine();
            sb.AppendLine("- HELO <name>");
            sb.AppendLine("\tGreeting containing name of client.");
            sb.AppendLine("\tSent by: client");
            sb.AppendLine($"\tResponse {220} <name>: reply containing host name");
            sb.AppendLine();
            sb.AppendLine("- HELP");
            sb.AppendLine("\tSends this help text.");
            sb.AppendLine();
            sb.AppendLine("- QUIT");
            sb.AppendLine("\tOrders host to disconnect.");
            sb.AppendLine("\tExpect to be disconnected when response arrives.");
            sb.AppendLine("\tSent by: client");
            sb.AppendLine($"\tResponse {270}: host has closed connection");
            sb.AppendLine();
            sb.AppendLine("## Rules:");
            sb.AppendLine("\tBefore issuing START, prepare a 10x10 grid for");
            sb.AppendLine("\tyou and your opponent. Designate your 5 boats on");
            sb.AppendLine("\tyour grid.");
            sb.AppendLine();
            sb.AppendLine("\tWhen its your turn, send a FIRE at a coordinate not");
            sb.AppendLine("\tyet shot at. Record the result on your opponents grid.");
            sb.AppendLine("\tWhen your opponent sends a FIRE, if the coordinate is on");
            sb.AppendLine("\tone of your ships then mark your grid and respond with");
            sb.AppendLine("\tthe appropriate hit response code (241-255).");
            sb.AppendLine("\tSee table below.");
            sb.AppendLine();
            sb.AppendLine("\tWhen all coordinates of your ship is fired upon,");
            sb.AppendLine("\tthat ships is sunk, and shall give appropriate response");
            sb.AppendLine("\tcode (251-255). See table below.");
            sb.AppendLine("\tWhen all your ships are sunk, you lose, and shall give");
            sb.AppendLine("\tresponse code 240.");
            sb.AppendLine();
            sb.AppendLine("## Ships:");
            sb.AppendLine("\tList of the ships with their lengths and response codes.");
            sb.AppendLine();
            sb.AppendLine("\tName        | Length | Hit | Sunk");
            sb.AppendLine("\t------------|--------|-----|------");
            sb.AppendLine("\tCarrier     |      5 | 241 |  251");
            sb.AppendLine("\tBattleship  |      4 | 242 |  252");
            sb.AppendLine("\tDestroyer   |      3 | 243 |  253");
            sb.AppendLine("\tSubmarine   |      3 | 244 |  254");
            sb.AppendLine("\tPatrol boat |      2 | 245 |  255");
            sb.AppendLine();
            sb.AppendLine("Good luck, and have fun!");

            await context.SendTextAsync(sb.ToString());
        }
コード例 #20
0
 public void ConnectionFailed(PacketConnection conn)
 {
     // todo: display error
 }
コード例 #21
0
 public void ConnectionLost(PacketConnection conn)
 {
     _PacketManager.OnDisconnected();
 }