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); }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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; }
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; }
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; }
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; }