Exemple #1
0
def fast_forward(prologue, demo_io, tick=None):
    full_packets, remaining_packets = [], []

    world = w.construct(prologue.recv_tables)
    string_tables = copy.deepcopy(prologue.string_tables)

    if tick:
        iter_bootstrap = iter(demo_io)

        try:
            while True:
                p, m = next(iter_bootstrap)

                if p.kind == pb_d.DEM_FullPacket:
                    full_packets.append((p, m))
                    remaining_packets = []
                else:
                    remaining_packets.append((p, m))

                if p.tick > tick - 2:  # hack?
                    break
        except StopIteration:
            raise EOFError()

    if full_packets:
        for peek, message in full_packets:
            full_packet = d_io.parse(peek.kind, peek.compressed, message)

            for table in full_packet.string_table.tables:
                assert not table.items_clientside

                entries = [(_i, e.str, e.data)
                           for _i, e in enumerate(table.items)]
                string_tables[table.table_name].update_all(entries)

        peek, message = full_packets[-1]
        pbmsg = d_io.parse(peek.kind, peek.compressed, message)
        packet = i.construct(p_io.construct(pbmsg.packet.data))

        peek, message = packet.find(pb_n.svc_PacketEntities)
        pe = p_io.parse(peek.kind, message)
        ct = pe.updated_entries
        bs = b_io.construct(pe.entity_data)
        unpacker = u_ent.construct(bs, -1, ct, False, prologue.class_bits,
                                   world)

        for index, mode, (cls, serial, diff) in unpacker:
            data = string_tables['instancebaseline'].get(cls)[1]
            bs = b_io.construct(data)
            unpacker = u_ent.construct(bs, -1, 1, False, prologue.class_bits,
                                       world)

            state = unpacker.unpack_baseline(prologue.recv_tables[cls])
            state.update(diff)

            try:
                world.create(cls, index, serial, state)
            except AssertionError, e:
                # TODO: log here.
                pass
Exemple #2
0
def scan(prologue, demo_io, tick=None):
    full_packets, remaining_packets = [], []

    if tick is not None:
        iter_bootstrap = iter(demo_io)

        try:
            p, m = next(iter_bootstrap)
            item = (p, d_io.parse(p.kind, p.compressed, m))

            while True:
                if p.kind == pb_d.DEM_FullPacket:
                    full_packets.append(item)
                    remaining_packets = []
                else:
                    remaining_packets.append(item)

                if p.tick >= tick:
                    break

                p, m = next(iter_bootstrap)
                item = (p, d_io.parse(p.kind, p.compressed, m))
        except StopIteration:
            raise EOFError()

    return full_packets, remaining_packets
Exemple #3
0
def scan(prologue, demo_io, tick=None):
  full_packets, remaining_packets = [], []

  if tick is not None:
    iter_bootstrap = iter(demo_io)

    try:
      p, m = next(iter_bootstrap)
      item = (p, d_io.parse(p.kind, p.compressed, m))

      while True:
        if p.kind == pb_d.DEM_FullPacket:
          full_packets.append(item)
          remaining_packets = []
        else:
          remaining_packets.append(item)

        if p.tick >= tick:
          break

        p, m = next(iter_bootstrap)
        item = (p, d_io.parse(p.kind, p.compressed, m))
    except StopIteration:
      raise EOFError()

  return full_packets, remaining_packets
Exemple #4
0
def fast_forward(prologue, demo_io, tick=None):
  full_packets, remaining_packets = [], []

  world = w.construct(prologue.recv_tables)
  string_tables = copy.deepcopy(prologue.string_tables)

  if tick:
    iter_bootstrap = iter(demo_io)

    try:
      while True:
        p, m = next(iter_bootstrap)

        if p.kind == pb_d.DEM_FullPacket:
          full_packets.append((p, m))
          remaining_packets = []
        else:
          remaining_packets.append((p, m))

        if p.tick > tick - 2: # hack?
          break
    except StopIteration:
      raise EOFError()

  if full_packets:
    for peek, message in full_packets:
      full_packet = d_io.parse(peek.kind, peek.compressed, message)

      for table in full_packet.string_table.tables:
        assert not table.items_clientside

        entries = [(_i, e.str, e.data) for _i, e in enumerate(table.items)]
        string_tables[table.table_name].update_all(entries)

    peek, message = full_packets[-1]
    pbmsg = d_io.parse(peek.kind, peek.compressed, message)
    packet = i.construct(p_io.construct(pbmsg.packet.data))

    peek, message = packet.find(pb_n.svc_PacketEntities)
    pe = p_io.parse(peek.kind, message)
    ct = pe.updated_entries
    bs = b_io.construct(pe.entity_data)
    unpacker = u_ent.construct(bs, -1, ct, False, prologue.class_bits, world)

    for index, mode, (cls, serial, diff) in unpacker:
      data = string_tables['instancebaseline'].get(cls)[1]
      bs = b_io.construct(data)
      unpacker = u_ent.construct(bs, -1, 1, False, prologue.class_bits, world)

      state = unpacker.unpack_baseline(prologue.recv_tables[cls])
      state.update(diff)

      try:
        world.create(cls, index, serial, state)
      except AssertionError, e:
        # TODO: log here.
        pass
Exemple #5
0
  def __init__(self, abspath):
    if hasattr(abspath, "read"):
        infile = abspath
    elif abspath.lower().endswith(".bz2"):
        infile = bz2.BZ2File(abspath, "r")
    else:
        infile = _io.open(abspath, 'r+b')
    if infile.read(8) != "PBUFDEM\0":
      raise InvalidDemo('malformed header')

    gio = bytearray(infile.read(4)) # LE uint file offset
    gio = sum(gio[i] << (i * 8) for i in range(4))

    try:
      tell = infile.tell()
      infile.seek(gio)
      p, m = d_io.construct(infile).read()
      self.file_info = d_io.parse(p.kind, p.compressed, m)
      assert p.kind == pb_d.DEM_FileInfo
      infile.seek(tell)
    except EOFError:
      raise InvalidDemo('no end game summary')

    self.prologue = load(infile)
    self.io = infile
    self._tell = infile.tell()
Exemple #6
0
    def iterfullticks(self):
        iter_entries = iter(self.demo_io)

        while True:
            peek, message = next(iter_entries)

            if peek.kind == pb_d.DEM_Stop:
                raise StopIteration()
            elif peek.kind != pb_d.DEM_FullPacket:
                continue

            pro = self.prologue

            full_packet = (peek, d_io.parse(peek.kind, peek.compressed,
                                            message))
            self.world, self.modifiers, self.string_tables = reconstitute(
                [full_packet], pro.class_bits, pro.recv_tables,
                self.string_tables)
            self.tick = peek.tick
            self.user_messages = []
            self.game_events = []
            yield [
                self.tick, self.user_messages, self.game_events, self.world,
                self.modifiers
            ]
Exemple #7
0
  def __init__(self, prologue, io, world, string_tables, rem, sparse=False):
    self.prologue = prologue
    self.demo_io = d_io.construct(io)
    self.world = world
    self.string_tables = string_tables
    self.sparse = sparse

    for peek, message in rem:
      pbmsg = d_io.parse(peek.kind, peek.compressed, message)
      self.advance(peek.tick, pbmsg)
Exemple #8
0
    def __init__(self, prologue, io, world, string_tables, rem, sparse=False):
        self.prologue = prologue
        self.demo_io = d_io.construct(io)
        self.world = world
        self.string_tables = string_tables
        self.sparse = sparse

        for peek, message in rem:
            pbmsg = d_io.parse(peek.kind, peek.compressed, message)
            self.advance(peek.tick, pbmsg)
Exemple #9
0
        def advance():
            try:
                peek, message = next(iter_entries)

                if peek.kind == pb_d.DEM_FullPacket:
                    return advance()  # skip
                elif peek.kind == pb_d.DEM_Stop:
                    raise StopIteration()

                pbmsg = d_io.parse(peek.kind, peek.compressed, message)

                return self.advance(peek.tick, pbmsg)
            except StopIteration:
                return None
Exemple #10
0
    def advance():
      try:
        peek, message = next(iter_entries)

        if peek.kind == pb_d.DEM_FullPacket:
          return advance() # skip
        elif peek.kind == pb_d.DEM_Stop:
          raise StopIteration()

        pbmsg = d_io.parse(peek.kind, peek.compressed, message)

        return self.advance(peek.tick, pbmsg)
      except StopIteration:
        return None
Exemple #11
0
    def __init__(self, abspath):
        infile = _io.open(abspath, 'r+b')
        if infile.read(8) != "PBUFDEM\0":
            raise InvalidDemo('malformed header')

        gio = bytearray(infile.read(4))  # LE uint file offset
        gio = sum(gio[i] << (i * 8) for i in range(4))

        try:
            tell = infile.tell()
            infile.seek(gio)
            p, m = d_io.construct(infile).read()
            self.file_info = d_io.parse(p.kind, p.compressed, m)
            assert p.kind == pb_d.DEM_FileInfo
            infile.seek(tell)
        except EOFError:
            raise InvalidDemo('no end game summary')

        self.prologue = load(infile)
        self.io = infile
        self._tell = infile.tell()
Exemple #12
0
  def iterfullticks(self):
    iter_entries = iter(self.demo_io)

    while True:
      peek, message = next(iter_entries)

      if peek.kind == pb_d.DEM_Stop:
        raise StopIteration()
      elif peek.kind != pb_d.DEM_FullPacket:
        continue

      pro = self.prologue

      full_packet = (peek, d_io.parse(peek.kind, peek.compressed, message))
      self.world, self.modifiers, self.string_tables = reconstitute(
        [full_packet], pro.class_bits, pro.recv_tables, self.string_tables)
      self.tick = peek.tick
      self.user_messages = []
      self.game_events = []
      yield [self.tick, self.user_messages, self.game_events, self.world,
             self.modifiers]
Exemple #13
0
  def __iter__(self):
    iter_entries = iter(self.demo_io)

    if self.tick is not None:
      t = self.tick
      um, ge = self.user_messages, self.game_events
      w, m = self.world, self.modifiers
      yield [t, um, ge, w, m]

    while True:
      peek, message = next(iter_entries)

      if peek.kind == pb_d.DEM_FullPacket:
        continue
      elif peek.kind == pb_d.DEM_Stop:
        raise StopIteration()
      else:
        pbmsg = d_io.parse(peek.kind, peek.compressed, message)
        self.advance(peek.tick, pbmsg)

      t = self.tick
      um, ge = self.user_messages, self.game_events
      w, m = self.world, self.modifiers
      yield [t, um, ge, w, m]
Exemple #14
0
    def __iter__(self):
        iter_entries = iter(self.demo_io)

        if self.tick is not None:
            t = self.tick
            um, ge = self.user_messages, self.game_events
            w, m = self.world, self.modifiers
            yield [t, um, ge, w, m]

        while True:
            peek, message = next(iter_entries)

            if peek.kind == pb_d.DEM_FullPacket:
                continue
            elif peek.kind == pb_d.DEM_Stop:
                raise StopIteration()
            else:
                pbmsg = d_io.parse(peek.kind, peek.compressed, message)
                self.advance(peek.tick, pbmsg)

            t = self.tick
            um, ge = self.user_messages, self.game_events
            w, m = self.world, self.modifiers
            yield [t, um, ge, w, m]
Exemple #15
0
 def all_dem_signon_packet(self):
     kind = pb_d.DEM_SignonPacket
     ee = self.find_all(kind)
     return ((p, d_io.parse(kind, p.compressed, m)) for p, m in ee)
Exemple #16
0
 def dem_send_tables(self):
     kind = pb_d.DEM_SendTables
     p, m = self.find(kind)
     return p, d_io.parse(kind, p.compressed, m)
Exemple #17
0
 def dem_class_info(self):
     kind = pb_d.DEM_ClassInfo
     p, m = self.find(kind)
     return p, d_io.parse(kind, p.compressed, m)
Exemple #18
0
 def dem_file_header(self):
     kind = pb_d.DEM_FileHeader
     p, m = self.find(kind)
     return p, d_io.parse(kind, p.compressed, m)
Exemple #19
0
def load(io, tick=0):
    demo_io = d_io.construct(io)
    prologue = i_p.construct(demo_io)

    # mash all packet svc messages together, then index them
    signon_packets = list(prologue.signon_packets)
    pbmsgs = [d_io.parse(p.kind, p.compressed, m) for p, m in signon_packets]
    data = ''.join([p.data for p in pbmsgs])
    packet_io = p_io.construct(data)
    packet = i.construct(packet_io)

    # class info
    peek, message = prologue.class_info
    pbmsg = d_io.parse(peek.kind, peek.compressed, message)
    class_info = c.OrderedDict()

    for _c in pbmsg.classes:
        _id, dt, name = str(_c.class_id), _c.table_name, _c.network_name
        class_info[_id] = (dt, name)

    # send tables
    peek, message = prologue.send_tables
    pbmsg = d_io.parse(peek.kind, peek.compressed, message)
    send_tables = c.OrderedDict()

    for peek, message in p_io.construct(pbmsg.data):
        pbmsg = p_io.parse(peek.kind, message)
        if pbmsg.is_end:
            break

        send_table = _parse_cdemo_send_table(pbmsg)
        send_tables[send_table.dt] = send_table

    # recv tables
    flattener = Flattener(send_tables)
    recv_tables = c.OrderedDict()

    for st in filter(test_needs_decoder, send_tables.values()):
        props = flattener.flatten(st)
        cls = next(_id for _id, (dt, _) in class_info.items() if dt == st.dt)
        recv_tables[cls] = dt_r.construct(st.dt, props)

    # game event list
    peek, message = packet.find(pb_n.svc_GameEventList)
    pbmsg = p_io.parse(peek.kind, message)
    game_event_list = c.OrderedDict()

    for desc in pbmsg.descriptors:
        _id, name = desc.eventid, desc.name
        keys = [(k.type, k.name) for k in desc.keys]
        game_event_list[_id] = (name, keys)

    # string tables
    entries = packet.find_all(pb_n.svc_CreateStringTable)
    pbmsgs = [p_io.parse(p.kind, m) for p, m in entries]
    string_tables = _parse_all_csvc_create_string_tables(pbmsgs)

    # meta: file header
    peek, message = prologue.file_header
    pbmsg = d_io.parse(peek.kind, peek.compressed, message)
    file_header = FileHeader(*[getattr(pbmsg, a) for a in FileHeader._fields])

    # meta: server_info
    peek, message = packet.find(pb_n.svc_ServerInfo)
    pbmsg = p_io.parse(peek.kind, message)
    server_info = ServerInfo(*[getattr(pbmsg, a) for a in ServerInfo._fields])

    # meta: class bits
    class_bits = server_info.max_classes.bit_length()

    # meta: voice init
    peek, message = packet.find(pb_n.svc_VoiceInit)
    pbmsg = p_io.parse(peek.kind, message)
    voice_init = VoiceInit(*[getattr(pbmsg, a) for a in VoiceInit._fields])

    meta = Meta(file_header, server_info, voice_init)

    return Prologue(meta, recv_tables, string_tables, game_event_list,
                    class_bits)
Exemple #20
0
 def dem_file_header(self):
   kind = pb_d.DEM_FileHeader
   p, m = self.find(kind)
   return p, d_io.parse(kind, p.compressed, m)
Exemple #21
0
 def dem_class_info(self):
   kind = pb_d.DEM_ClassInfo
   p, m = self.find(kind)
   return p, d_io.parse(kind, p.compressed, m)
Exemple #22
0
 def dem_send_tables(self):
   kind = pb_d.DEM_SendTables
   p, m = self.find(kind)
   return p, d_io.parse(kind, p.compressed, m)
Exemple #23
0
 def all_dem_signon_packet(self):
   kind = pb_d.DEM_SignonPacket
   ee = self.find_all(kind)
   return ((p, d_io.parse(kind, p.compressed, m)) for p, m in ee)