示例#1
0
 public Packet(Packet packet)
 {
     Type = packet.Type;
     Data.Clear();
     Data.AddRange(packet.Data.ToArray());
     Checksum = packet.Checksum;
 }
        public void TransmitPacket(Packet packet)
        {
            var e = new PacketSendingEventArgs(packet);
            OnPacketSending(e);
            if (e.Cancel) return;

            Log.Add(Log.Severity.Debug, "TX {0}: {1}", packet.Type.ToString(), packet);
            TransmitSignature(packet.Signatures);
        }
示例#3
0
        public static Packet AssignPlayerFailed(UInt16 gameId, UInt16 taggerId)
        {
            var packet = new Packet();
            packet.Type = PacketType.AssignPlayerFailed;
            packet.Data.Add(new Signature(SignatureType.Data, gameId));
            packet.Data.Add(new Signature(SignatureType.Data, taggerId));
            packet.PopulateChecksum();

            return packet;
        }
示例#4
0
        public static Packet AnnounceGame(GameDefinition gameDefinition)
        {
            var packet = new Packet();
            packet.Type = gameDefinition.GameTypeInfo.PacketType;
            packet.Data.Add(new Signature(SignatureType.Data, gameDefinition.GameId));
            packet.Data.Add(new Signature(SignatureType.Data, BinaryCodedDecimal.FromDecimal((byte)gameDefinition.GameTimeMinutes)));
            packet.Data.Add(new Signature(SignatureType.Data, BinaryCodedDecimal.FromDecimal((byte)gameDefinition.Tags)));
            packet.Data.Add(new Signature(SignatureType.Data, BinaryCodedDecimal.FromDecimal((byte)gameDefinition.Reloads)));
            packet.Data.Add(new Signature(SignatureType.Data, BinaryCodedDecimal.FromDecimal((byte)gameDefinition.Shields)));
            packet.Data.Add(new Signature(SignatureType.Data, BinaryCodedDecimal.FromDecimal((byte)gameDefinition.Mega)));

            var flags1 = (byte) ((gameDefinition.ExtendedTagging ? 1 : 0) << 7 |
                                 (gameDefinition.LimitedReloads ? 1 : 0) << 6 |
                                 (gameDefinition.LimitedMega ? 1 : 0) << 5 |
                                 (gameDefinition.TeamTags ? 1 : 0) << 4 |
                                 (gameDefinition.MedicMode ? 1 : 0) << 3 |
                                 (gameDefinition.SlowTags ? 1 : 0) << 2 |
                                 (gameDefinition.GameTypeInfo.HuntThePrey ? 1 : 0) << 1 |
                                 (gameDefinition.GameTypeInfo.ReverseHuntDirection ? 1 : 0) << 0);

            var flags2 = (byte) ((gameDefinition.GameTypeInfo.Zones ? 1 : 0) << 7 |
                                 (gameDefinition.GameTypeInfo.TeamZones ? 1 : 0) << 6 |
                                 (gameDefinition.GameTypeInfo.NeutralizePlayersTaggedInZone ? 1 : 0) << 5 |
                                 (gameDefinition.GameTypeInfo.ZonesRevivePlayers ? 1 : 0) << 4 |
                                 (gameDefinition.GameTypeInfo.HospitalZones ? 1 : 0) << 3 |
                                 (gameDefinition.GameTypeInfo.ZonesTagPlayers ? 1 : 0) << 2 |
                                 (gameDefinition.TeamCount & 0x03));

            // hard code these here for now
            switch (gameDefinition.GameType)
            {
                case GameType.Respawn: // RESP
                case GameType.RespawnTwoTeams: // 2TRS
                case GameType.RespawnThreeTeams: // 3TRS
                    flags1 |= 0x80;
                    flags2 |= 0x30;
                    break;
            }

            packet.Data.Add(new Signature(SignatureType.Data, flags1));
            packet.Data.Add(new Signature(SignatureType.Data, flags2));

            if (gameDefinition.GameTypeInfo.PacketType == PacketType.AnnounceGameSpecial)
            {
                packet.Data.AddRange(gameDefinition.GameTypeInfo.Name.GetSignatures(4, true));
            }

            packet.PopulateChecksum();

            return packet;
        }
示例#5
0
        public bool ProcessPacket(Packet packet)
        {
            var packetType = (PacketType) packet.PacketTypeSignature.Data;
            switch (packetType)
            {
                case PacketType.SingleTagReport:
                    if (packet.Data.Count != 4) break;
                    var isReply = ((packet.Data[1].Data & 0x80) & (packet.Data[2].Data & 0x80)) != 0;
                    var teamPlayerId1 = TeamPlayerId.FromPacked34(packet.Data[1].Data);
                    var teamPlayerId2 = TeamPlayerId.FromPacked34(packet.Data[2].Data);
                    var tagsReceived = packet.Data[3].Data;
                    var replyText = isReply ? "replied to tag count request from" : "requested tag count from";
                    Log.Add(Log.Severity.Information, "Player {0} {1} player {2}. Player {0} received {3} tags from player {2}.",
                        teamPlayerId1, replyText, teamPlayerId2, tagsReceived);
                    return true;
                case PacketType.TextMessage:
                    var message = new StringBuilder();
                    var i = 0;
                    while (i < packet.Data.Count &&
                            packet.Data[i].Data >= 0x20 &&
                            packet.Data[i].Data <= 0x7e &&
                            packet.Data[i].BitCount == 8)
                    {
                        message.Append(Convert.ToChar(packet.Data[i].Data));
                        i++;
                    }
                    Log.Add(Log.Severity.Information, "Received Text Message: {0}", message);
                    return true;
                case PacketType.SpecialAttack:
                    var type = "Unknown Type";
                    if (packet.Data.Count == 4)
                    {
                        switch (packet.Data[2].Data)
                        {
                            case 0x77:
                                type = "EM Peacemaker";
                                break;
                            case 0xb1:
                                type = "Talus Airstrike";
                                break;
                        }
                    }
                    Log.Add(Log.Severity.Information, "Special Attack: {0} - {1}", type, packet);
                    AssertUnknownBits("Special Attack Flags 1", packet.Data[1], 0xff);
                    AssertUnknownBits("Special Attack Flags 2", packet.Data[2], 0xff);
                    AssertUnknownBits("Special Attack Flags 3", packet.Data[3], 0xff);
                    AssertUnknownBits("Special Attack Flags 4", packet.Data[4], 0xff);
                    return true;
            }

            switch (HostingState)
            {
                case HostingStates.Idle:
                    return true;
                case HostingStates.Adding:
                case HostingStates.AcknowledgePlayerAssignment:
                    if (packet.Data.Count < 2) return false;

                    var gameId = packet.Data[0].Data;
                    var taggerId = packet.Data[1].Data;

                    switch (packet.Type)
                    {
                        case PacketType.RequestJoinGame:
                            if (packet.Data.Count < 3) return false;
                            var requestedTeam = (UInt16) (packet.Data[2].Data & 0x03);
                            return ProcessRequestJoinGame(gameId, taggerId, requestedTeam);
                        case PacketType.AcknowledgePlayerAssignment:
                            return ProcessAcknowledgePlayerAssignment(gameId, taggerId);
                        default:
                            Log.Add(Log.Severity.Warning, "Unexpected packet: {0}", packet);
                            return false;
                    }
                case HostingStates.Summary:
                    switch (packet.Type)
                    {
                        case PacketType.TagSummary:
                            return ProcessTagSummary(packet);
                        case PacketType.TeamOneTagReport:
                        case PacketType.TeamTwoTagReport:
                        case PacketType.TeamThreeTagReport:
                            return ProcessTeamTagReport(packet);
                    }
                    break;
            }

            return false;
        }
示例#6
0
        private bool ProcessTeamTagReport(Packet packet)
        {
            if (packet.Data.Count < 4) return false;

            var gameId = packet.Data[0].Data;
            if (gameId != _gameDefinition.GameId)
            {
                Log.Add(Log.Severity.Warning, "Wrong game ID.");
                return false;
            }

            // what team do the scores relate to hits from
            var taggedByTeamNumber = (int)(packet.PacketTypeSignature.Data - PacketType.TeamOneTagReport + 1);

            var teamPlayerId = TeamPlayerId.FromPacked44(packet.Data[1].Data);

            var player = Players.Player(teamPlayerId);
            if (player == null) return false;

            if (player.TagSummaryReceived && !player.TeamTagReportsExpected[taggedByTeamNumber - 1])
            {
                Log.Add(Log.Severity.Warning, "A tag report from player {0} for team {1} was not expected.",
                    player.TeamPlayerId, taggedByTeamNumber);
            }

            if (player.TeamTagReportsReceived[taggedByTeamNumber - 1])
            {
                Log.Add(Log.Severity.Warning, "A tag report from player {0} for team {1} was already received. Discarding.",
                    player.TeamPlayerId, taggedByTeamNumber);
                return false;
            }

            player.TeamTagReportsReceived[taggedByTeamNumber - 1] = true;

            var scoreBitmask = packet.Data[2].Data;

            var packetIndex = 3;
            var mask = scoreBitmask;
            for (var taggedByTeamPlayerNumber = 1; taggedByTeamPlayerNumber <= 8; taggedByTeamPlayerNumber++)
            {
                var taggedByTeamPlayerId = new TeamPlayerId(taggedByTeamNumber, taggedByTeamPlayerNumber);
                var hasTags = ((mask >> (taggedByTeamPlayerNumber - 1)) & 0x1) != 0;
                if (!hasTags) continue;

                if (packet.Data.Count <= packetIndex)
                {
                    Log.Add(Log.Severity.Warning, "Ran off end of score report");
                    return false;
                }

                var tagsTaken = BinaryCodedDecimal.ToDecimal(packet.Data[packetIndex].Data);

                player.TaggedByPlayerCounts[taggedByTeamPlayerId.PlayerNumber - 1] = tagsTaken;

                var taggedByPlayer = Players.Player(taggedByTeamPlayerId);
                if (taggedByPlayer == null) continue;
                taggedByPlayer.TaggedPlayerCounts[player.TeamPlayerId.PlayerNumber - 1] = tagsTaken;

                packetIndex++;
            }

            OnPlayerListChanged(new PlayerListChangedEventArgs(Players));

            return true;
        }
示例#7
0
        private bool ProcessTagSummary(Packet packet)
        {
            if (packet.Type != PacketType.TagSummary)
            {
                Log.Add(Log.Severity.Warning, "Unexpected packet: {0}", packet);
                return false;
            }

            if (packet.Data.Count != 8)
            {
                return false;
            }

            var gameId = packet.Data[0].Data;
            if (gameId != _gameDefinition.GameId)
            {
                Log.Add(Log.Severity.Warning, "Wrong game ID.");
                return false;
            }

            var teamPlayerId = TeamPlayerId.FromPacked44(packet.Data[1].Data);
            var tagsTaken = packet.Data[2].Data; // Hex Coded Decimal
            var surviveTimeMinutes = packet.Data[3].Data;
            var surviveTimeSeconds = packet.Data[4].Data;
            var zoneTimeMinutes = packet.Data[5].Data;
            var zoneTimeSeconds = packet.Data[6].Data;

            var teamTagReports = packet.Data[7];
            AssertUnknownBits("teamTagReports", teamTagReports, 0xf1);

            var player = _players.Player(teamPlayerId);
            if (player == null)
            {
                Log.Add(Log.Severity.Warning, "Unable to find player for score report.");
                return false;
            }

            player.SurviveTime = new TimeSpan(0, 0, BinaryCodedDecimal.ToDecimal(surviveTimeMinutes), BinaryCodedDecimal.ToDecimal(surviveTimeSeconds));
            player.Survived = player.SurviveTime.TotalMinutes >= GameDefinition.GameTimeMinutes;
            player.TagsTaken = BinaryCodedDecimal.ToDecimal(tagsTaken);
            player.TeamTagReportsExpected[0] = (teamTagReports.Data & 0x2) != 0;
            player.TeamTagReportsExpected[1] = (teamTagReports.Data & 0x4) != 0;
            player.TeamTagReportsExpected[2] = (teamTagReports.Data & 0x8) != 0;
            player.ZoneTime = new TimeSpan(0, 0, BinaryCodedDecimal.ToDecimal(zoneTimeMinutes), BinaryCodedDecimal.ToDecimal(zoneTimeSeconds));

            player.TagSummaryReceived = true;

            Log.Add(Log.Severity.Information, "Received tag summary from {0}.", player.NameAndNumber);

            OnPlayerListChanged(new PlayerListChangedEventArgs(Players));

            return true;
        }
示例#8
0
        private static Signature CalculateChecksum(Packet packet)
        {
            var checksum = (byte) packet.PacketTypeSignature.Data;

            foreach (var signature in packet.Data)
            {
                if (signature.Type != SignatureType.Data) continue;
                checksum += (byte) signature.Data;
            }

            return new Signature(SignatureType.Checksum, checksum);
        }
 public PacketSendingEventArgs(Packet packet)
 {
     Cancel = false;
     Packet = packet;
 }
示例#10
0
        private void ProcessDataSignature(UInt16 data, byte bitCount)
        {
            if (bitCount == 9)
            {
                if ((data & 0x100) == 0) // packet type
                {
                    _incomingPacket = new Packet
                    {
                        PacketTypeSignature = new Signature(SignatureType.Packet, data),
                    };
                }
                else // checksum
                {
                    if (_incomingPacket == null)
                    {
                        Log.Add(Log.Severity.Debug, "Stray checksum signature received.");
                        return;
                    }

                    if (!(_incomingPacket.PacketTypeSignatureValid && _incomingPacket.DataValid))
                    {
                        Log.Add(Log.Severity.Debug, "Checksum received for invalid packet: {0}", _incomingPacket);
                        _incomingPacket = null;
                        return;
                    }

                    _incomingPacket.Checksum = new Signature(SignatureType.Checksum, data);

                    if (_incomingPacket.ChecksumValid)
                    {
                        Log.Add(Log.Severity.Debug, "RX {0}: {1}", _incomingPacket.Type.ToString(), _incomingPacket);

                        // TODO: Make this event driven
                        if (!_hostGun.ProcessPacket(_incomingPacket))
                        {
                            Log.Add(Log.Severity.Warning, "ProcessPacket() failed: {0}", _incomingPacket);
                        }
                    }
                    else
                    {
                        Log.Add(Log.Severity.Debug, "Invalid checksum received. {0}", _incomingPacket);
                    }

                    _incomingPacket = null;
                }
            }
            else if (bitCount == 8) // data
            {
                if (_incomingPacket == null || !_incomingPacket.PacketTypeSignatureValid)
                {
                    Log.Add(Log.Severity.Debug, "Stray data packet received. 0x{0:X2} ({1})", data, bitCount);
                    _incomingPacket = null;
                    return;
                }

                _incomingPacket.Data.Add(new Signature(SignatureType.Data, data));
            }
            else if (bitCount == 7) // tag
            {
                _incomingPacket = null;
                ProcessTag(new Signature(SignatureType.Tag, data, bitCount));
            }
            else
            {
                Log.Add(Log.Severity.Debug, "Stray data packet received. 0x{0:X2} ({1})", data, bitCount);
            }
        }
示例#11
0
        public static Packet Countdown(UInt16 gameId, byte remainingSeconds, int playerCountTeam1, int playerCountTeam2, int playerCountTeam3)
        {
            var packet = new Packet();
            packet.Type = PacketType.AnnounceCountdown;
            packet.Data.Add(new Signature(SignatureType.Data, gameId));
            packet.Data.Add(new Signature(SignatureType.Data, BinaryCodedDecimal.FromDecimal(remainingSeconds)));
            packet.Data.Add(new Signature(SignatureType.Data, (UInt16)(playerCountTeam1 & 0xff)));
            packet.Data.Add(new Signature(SignatureType.Data, (UInt16)(playerCountTeam2 & 0xff)));
            packet.Data.Add(new Signature(SignatureType.Data, (UInt16)(playerCountTeam3 & 0xff)));
            packet.PopulateChecksum();

            return packet;
        }
示例#12
0
        public static Packet TextMessage(String message)
        {
            var packet = new Packet();
            packet.Type = PacketType.TextMessage;

            if (message.Length > 10) message = message.Substring(0, 10);
            var messageChars = message.ToCharArray();
            foreach (var character in messageChars)
            {
                packet.Data.Add(new Signature(SignatureType.Data, character));
            }

            packet.Data.Add(new Signature(SignatureType.Data, 0)); // null terminator

            packet.PopulateChecksum();

            return packet;
        }
示例#13
0
        public static Packet RequestTagReport(UInt16 gameId, TeamPlayerId teamPlayerId)
        {
            var packet = new Packet();
            packet.Type = PacketType.RequestTagReport;
            packet.Data.Add(new Signature(SignatureType.Data, gameId));
            packet.Data.Add(new Signature(SignatureType.Data, teamPlayerId.Packed44));
            packet.Data.Add(new Signature(SignatureType.Data, 0x0f)); // TODO: Magic Number
            packet.PopulateChecksum();

            return packet;
        }
示例#14
0
        public static Packet RequestJoinGame(UInt16 gameId, UInt16 taggerId, int preferredTeamNumber)
        {
            var packet = new Packet();
            packet.Type = PacketType.RequestJoinGame;
            packet.Data.Add(new Signature(SignatureType.Data, gameId));
            packet.Data.Add(new Signature(SignatureType.Data, taggerId));
            packet.Data.Add(new Signature(SignatureType.Data, (UInt16)(preferredTeamNumber & 0x3)));
            packet.PopulateChecksum();

            return packet;
        }
示例#15
0
        public static Packet RankReport(UInt16 gameId, int teamNumber, int teamRank, int[] playerRanks)
        {
            var packet = new Packet();
            packet.Type = PacketType.RankReport;
            packet.Data.Add(new Signature(SignatureType.Data, gameId));

            var flags = (UInt16) (((teamNumber & 0xf) << 4) | (teamRank & 0xf));
            packet.Data.Add(new Signature(SignatureType.Data, flags));

            for (int i = 0; i < 8; i++)
            {
                if (playerRanks.Length > i)
                {
                    packet.Data.Add(new Signature(SignatureType.Data, (UInt16) (playerRanks[i] & 0xff)));
                }
                else
                {
                    packet.Data.Add(new Signature(SignatureType.Data, 0));
                }
            }
            packet.PopulateChecksum();

            return packet;
        }