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
def advance(self, tick, pbmsg): packet = i.construct(p_io.construct(pbmsg.data)) all_ust = packet.find_all(pb_n.svc_UpdateStringTable) for _pbmsg in [p_io.parse(p.kind, m) for p, m in all_ust]: key = self.string_tables.keys()[_pbmsg.table_id] _st = self.string_tables[key] bs = b_io.construct(_pbmsg.string_data) ne = _pbmsg.num_changed_entries eb, sf, sb = _st.entry_bits, _st.size_fixed, _st.size_bits for entry in u_st.construct(bs, ne, eb, sf, sb): _st.update(entry) p, m = packet.find(pb_n.svc_PacketEntities) pe = p_io.parse(p.kind, m) ct = pe.updated_entries bs = b_io.construct(pe.entity_data) class_bits = self.prologue.class_bits recv_tables = self.prologue.recv_tables unpacker = u_ent.construct(bs, -1, ct, False, class_bits, self.world) for index, mode, context in unpacker: if mode & u_ent.PVS.Entering: cls, serial, diff = context data = self.string_tables['instancebaseline'].get(cls)[1] bs = b_io.construct(data) unpacker = u_ent.construct(bs, -1, 1, False, class_bits, self.world) state = unpacker.unpack_baseline(self.prologue.recv_tables[cls]) state.update(diff) self.world.create(cls, index, serial, state) elif mode & u_ent.PVS.Deleting: self.world.delete(index) elif mode ^ u_ent.PVS.Leaving: state = {} if self.sparse else dict(self.world.find_index(index)) state.update(context) self.world.update(index, state) all_um = packet.find_all(pb_n.svc_UserMessage) user_messages = [e_um.parse(p_io.parse(p.kind, m)) for p, m in all_um] all_ge = packet.find_all(pb_n.svc_GameEvent) gel = self.prologue.game_event_list game_events = [e_ge.parse(p_io.parse(p.kind, m), gel) for p, m in all_ge] modifiers = self.string_tables['ActiveModifiers'].observer _, gamerules = self.world.find_by_dt('DT_DOTAGamerulesProxy') modifiers.expire(gamerules[('DT_DOTAGamerules', 'm_fGameTime')]) return tick, user_messages, game_events, self.world, modifiers
def reconstitute(full_packets, class_bits, recv_tables, string_tables): w = e_w.construct(recv_tables) st = copy.deepcopy(string_tables) st_mn = st['ModifierNames'] st_am = st['ActiveModifiers'] m = e_m.construct(st_mn, baseline=st_am) for _, fp in full_packets: for table in fp.string_table.tables: assert not table.items_clientside entries = [(_i, e.str, e.data) for _i, e in enumerate(table.items)] st[table.table_name].update_all(entries) if table.table_name == 'ActiveModifiers': m.reset() [m.note(e) for e in entries] if full_packets: _, fp = full_packets[-1] packet = ie_packet.construct(p_io.construct(fp.packet.data)) _, pe = packet.svc_packet_entities ct = pe.updated_entries bs = b_io.construct(pe.entity_data) unpacker = u_ent.construct(bs, -1, ct, False, class_bits, w) for index, mode, (cls, serial, diff) in unpacker: data = st['instancebaseline'].get(cls)[1] bs = b_io.construct(data) unpacker = u_ent.construct(bs, -1, 1, False, class_bits, w) state = unpacker.unpack_baseline(recv_tables[cls]) state.update(diff) w.create(cls, index, serial, state) return w, m, st
def advance(self, tick, pbmsg): packet = i.construct(p_io.construct(pbmsg.data)) all_ust = packet.find_all(pb_n.svc_UpdateStringTable) for _pbmsg in [p_io.parse(p.kind, m) for p, m in all_ust]: key = self.string_tables.keys()[_pbmsg.table_id] _st = self.string_tables[key] bs = b_io.construct(_pbmsg.string_data) ne = _pbmsg.num_changed_entries eb, sf, sb = _st.entry_bits, _st.size_fixed, _st.size_bits for entry in u_st.construct(bs, ne, eb, sf, sb): _st.update(entry) p, m = packet.find(pb_n.svc_PacketEntities) pe = p_io.parse(p.kind, m) ct = pe.updated_entries bs = b_io.construct(pe.entity_data) class_bits = self.prologue.class_bits recv_tables = self.prologue.recv_tables unpacker = u_ent.construct(bs, -1, ct, False, class_bits, self.world) for index, mode, context in unpacker: if mode & u_ent.PVS.Entering: cls, serial, diff = context data = self.string_tables['instancebaseline'].get(cls)[1] bs = b_io.construct(data) unpacker = u_ent.construct(bs, -1, 1, False, class_bits, self.world) state = unpacker.unpack_baseline( self.prologue.recv_tables[cls]) state.update(diff) self.world.create(cls, index, serial, state) elif mode & u_ent.PVS.Deleting: self.world.delete(index) elif mode ^ u_ent.PVS.Leaving: state = {} if self.sparse else dict( self.world.find_index(index)) state.update(context) self.world.update(index, state) all_um = packet.find_all(pb_n.svc_UserMessage) user_messages = [e_um.parse(p_io.parse(p.kind, m)) for p, m in all_um] all_ge = packet.find_all(pb_n.svc_GameEvent) gel = self.prologue.game_event_list game_events = [ e_ge.parse(p_io.parse(p.kind, m), gel) for p, m in all_ge ] modifiers = self.string_tables['ActiveModifiers'].observer _, gamerules = self.world.find_by_dt('DT_DOTAGamerulesProxy') modifiers.expire(gamerules[('DT_DOTAGamerules', 'm_fGameTime')]) return tick, user_messages, game_events, self.world, modifiers