packetparser.py 8.64 KB
#!/usr/bin/python

import sys

# Packet
#         |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F      | 0123456789ABCDEF
#     -----------------------------------------------------  ----------------------
#       0 | 0E 1C DD 27 0B B2 05 01 0B 02 07 C0 BE DF 85 43    0 | ...'...........C
#       1 | 5E BA C9 40 E1 3A 40 43 8B 0A 00 00 28 28 55 01    1 | ^..@.:@C....((U.
#       2 | 01 81 00 00 00 0C 00 00 20 00 00 00 B1 9E 03 00    2 | ........ .......
#       3 | 00 00 4E 08 00 00 00 00 -- -- -- -- -- -- -- --    3 | ..N.....--------

# Packet
#         |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F      | 0123456789ABCDEF
#     -----------------------------------------------------  ----------------------
#       0 | 0E 1C DD 27 51 B8 05 01 51 07 01 5A FE F4 86 43    0 | ...'Q...Q..Z...C
#       1 | BE 9F FA 40 60 05 43 43 65 02 00 00 7D 32 00 00    1 | ...@`.CCe...}2..
#       2 | 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00    2 | ................
#       3 | 00 00 CA 0B 00 00 00 00 -- -- -- -- -- -- -- --    3 | ........--------

# Packet
#         |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F      | 0123456789ABCDEF
#     -----------------------------------------------------  ----------------------
#       0 | 0E 24 0A 1D 22 82 05 01 22 02 09 79 0E 9D 05 C4    0 | .$.."..."..y....
#       1 | BE 1F 26 42 F8 D3 A2 42 DA 00 00 00 28 28 00 00    1 | ..&B...B....((..
#       2 | 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    2 | ................
#       3 | 00 00 4E 08 42 65 61 64 65 61 75 78 56 61 6E 67    3 | ..N.BeadeauxVang
#       4 | 75 61 00 00 00 00 00 00 -- -- -- -- -- -- -- --    4 | ua......--------


# 0x00 - 0x03 = Packet Header
#       0x04 - 0x07 = MobNpC ID (Reversed Hex->Dec)
#       0x08 - 0x09 = TargetID (Reversed Hex->Dec)
#       0x0A - 0x0B = Flags / Moving
#       0x0C - 0x0F = X position Converted
#       0x10 - 0x13 = Y position Converted
#       0x14 - 0x17 = Z Position Converted I'd have to find my notes I cant remember the converstion right off
#       0x18 - 0x19 = Flags
#       0x1A = Unknown would leave Raw if possible
#       0x1B = Unknown would leave Raw if possible
#       0x1C = Speed
#       0x1D = SpeedSub
#       0x1E = HP %
#       0x1F = Animation
#       0x20 = Status
#       0x21 - 0x22 = Flags2 (Reversed Hex->Dec)
#       0x23 = Unknown would leave Raw if possible
#       0x24 = Unknown would leave Raw if possible
#       0x25 = Unknown would leave Raw if possible
#       0x26 = Unknown would leave Raw if possible
#       0x27 = name prefix
#       0x28 = StatusEffect(terror)
#       0x29 = Allegiance
#       0x2A = AnimationSub
#       0x2B = NameVis
#       0x2C = OwnerID
#       0x2D = Unknown would leave Raw if possible
#       0x2E = Unknown would leave Raw if possible
#       0x2F = Unknown would leave Raw if possible
#       0x30 - 0x33 = ModelID (In some cases geared NPCs continue past this but can manually check those)
#       0x34 - 0x40 = Name (posted sample below)

class PacketParser(object):
    """A Packet Parser"""

    def parse_file(self, filename, output_filename):
        lines_to_ignore = ["Packet",
                            "|  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F      | 0123456789ABCDEF",
                            "-----------------------------------------------------  ----------------------"]
        output = []
        with open(output_filename, 'w') as f_out:
            with open(filename) as f:
                line_count = 0
                packet_count = 0
                for line in f:
                    line_count+=1
                    line = line.strip()
                    if line == 'Packet':
                        packet_count+=1
                        packet_data = []
                    elif line not in lines_to_ignore:
                        packet_data.append(line)
                    if line == "":
                        f_out.write(",".join(map(str, self.parse_packet(packet_data))) + '\n')

        print("Lines Parsed: " + str(line_count) + "\nPackets Parsed: " + str(packet_count))

    def get_byte(self, packet, byte):
        return str(packet[byte])

    def parse_packet(self, packet_data):
        packet = []
        for packet_line in packet_data:
            for byte in packet_line[4:51].split(' '):
                packet.append(byte)

        # print("Parsing packet: ")
        # print(packet)

        header = int(self.get_byte(packet, 0x00) + self.get_byte(packet, 0x01) + self.get_byte(packet, 0x02), 16)
        # print("header: " + str(header))
        mob_npc_id = int(self.get_byte(packet, 0x07) + self.get_byte(packet, 0x06) + self.get_byte(packet, 0x05) + self.get_byte(packet, 0x04), 16)
        # print("MobNPC ID: " + str(mob_npc_id))
        target_id = int(self.get_byte(packet, 0x09) + self.get_byte(packet, 0x08), 16)
        # print("Target ID: " + str(target_id))
        flags_moving = int(self.get_byte(packet, 0x0A) + self.get_byte(packet, 0x0B), 16)
        # print("Flags: " + str(flags_moving))
        x_pos = int(self.get_byte(packet, 0x0C) + self.get_byte(packet, 0x0D) + self.get_byte(packet, 0x0E) + self.get_byte(packet, 0x0F), 16)
        # print("X Position: " + str(x_pos))
        y_pos = int(self.get_byte(packet, 0x10) + self.get_byte(packet, 0x11) + self.get_byte(packet, 0x12) + self.get_byte(packet, 0x13), 16)
        # print("Y Position: " + str(y_pos))
        z_pos = int(self.get_byte(packet, 0x14) + self.get_byte(packet, 0x15) + self.get_byte(packet, 0x16) + self.get_byte(packet, 0x17), 16)
        # print("Z Position: " + str(z_pos))
        flags = int(self.get_byte(packet, 0x18) + self.get_byte(packet, 0x19), 16)
        # print("Flags: " + str(flags))
        raw_1 = self.get_byte(packet, 0x1A)
        # print("Raw 1: " + str(raw_1))
        raw_2 = self.get_byte(packet, 0x1B)
        # print("Raw 2: " + str(raw_2))
        speed = int(self.get_byte(packet, 0x1C), 16)
        # print("Speed: " + str(speed))
        speed_sub = int(self.get_byte(packet, 0x1D), 16)
        # print("SpeedSub: " + str(speed_sub))
        hp_percent = int(self.get_byte(packet, 0x1E), 16)
        # print("HP %: " + str(hp_percent))
        animation = int(self.get_byte(packet, 0x1F), 16)
        # print("Animation: " + str(animation))
        status = int(self.get_byte(packet, 0x20), 16)
        # print("Status: " + str(status))
        flags2 = int(self.get_byte(packet, 0x22) + self.get_byte(packet, 0x21), 16)
        # print("Flags2: " + str(flags2))
        raw_3 = self.get_byte(packet, 0x23)
        # print("Raw 3: " + str(raw_3))
        raw_4 = self.get_byte(packet, 0x24)
        # print("Raw 4: " + str(raw_4))
        raw_5 = self.get_byte(packet, 0x25)
        # print("Raw 5: " + str(raw_5))
        raw_6 = self.get_byte(packet, 0x26)
        # print("Raw 6: " + str(raw_6))
        name_prefix = int(self.get_byte(packet, 0x27), 16)
        # print("Name Prefix: " + str(name_prefix))
        status_effect = int(self.get_byte(packet, 0x28), 16)
        # print("Status Effect(terror): " + str(status_effect))
        allegiance = int(self.get_byte(packet, 0x29), 16)
        # print("Allegiance: " + str(allegiance))
        animation_sub = int(self.get_byte(packet, 0x2A), 16)
        # print("AnimationSub: " + str(animation_sub))
        name_vis = int(self.get_byte(packet, 0x2B), 16)
        # print("NameVis: " + str(name_vis))
        owner_id = int(self.get_byte(packet, 0x2C), 16)
        # print("OwnerID: " + str(owner_id))
        raw_7 = self.get_byte(packet, 0x2D)
        # print("Raw 7: " + str(raw_7))
        raw_8 = self.get_byte(packet, 0x2E)
        # print("Raw 8: " + str(raw_8))
        raw_9 = self.get_byte(packet, 0x2F)
        # print("Raw 9: " + str(raw_9))
        model_id = int(self.get_byte(packet, 0x30) + self.get_byte(packet, 0x31) + self.get_byte(packet, 0x32) + self.get_byte(packet, 0x33), 16)
        # print("ModelID: " + str(model_id))
        name = ""
        for byte in packet[0x34:]:
            if byte == "--" or byte == "00":
                break
            name += byte.decode("hex")
        # print("Name: " + str(name))

        return [header, mob_npc_id, target_id, flags, raw_1, raw_2, speed, speed_sub, hp_percent, animation, status, flags2, raw_3,
                raw_4, raw_5, raw_6, name_prefix, status_effect, allegiance, animation_sub, name_vis, owner_id, raw_7, raw_8, raw_9, 
                model_id, name]


if __name__ == '__main__':
    if len(sys.argv) < 3:
        print('Please provide the packet file you wish to convert along with the output file.\n    Example: python packetparser 0x00E.log 0x00e-output.csv')
    else:
        print('Reading File: ' + sys.argv[1] + "\nWriting File: " + sys.argv[2])
        PacketParser().parse_file(sys.argv[1], sys.argv[2])
        print('Completed parsing')