First workin snap item parser

Thanks a lot to @Learath2 for explaining in irc
And for the awesome libtw2 docs by @heinrich5991

48a2573af6/doc/snapshot.md
This commit is contained in:
ChillerDragon 2022-11-17 15:43:27 +01:00
parent f98ad6ae30
commit 948aafb749
3 changed files with 36 additions and 26 deletions

View file

@ -300,34 +300,36 @@ class GameClient
end
item_delta = u.get_int
item_bits = item_delta.to_s(2).rjust(32, '0')
item_id_bits = item_bits[0...16]
item_type_bits = item_bits[16..]
item_id = item_id_bits.to_i(2)
item_type = item_type_bits.to_i(2)
item_meta = @snap_items[item_type]
item_name = item_meta[:name]
# { name: 'obj_game_data', size: 3, fields: [
# { type: 'int', name: 'start_tick' },
while item_delta
# item_bits = item_delta.to_s(2).rjust(32, '0')
item_type = item_delta
# item_id_bits = item_bits[0...16]
# item_type_bits = item_bits[16..]
# item_id = item_id_bits.to_i(2)
# item_type = item_type_bits.to_i(2)
item_meta = @snap_items[item_type]
item_name = item_meta[:name]
# { name: 'obj_game_data', size: 3, fields: [
# { type: 'int', name: 'start_tick' },
p = u.parsed.last
notes.push([:green, p[:pos], p[:len],
"\n id = #{item_id_bits} -> #{item_id}" \
"\n type = #{item_type_bits} -> #{item_type} #{item_name}"])
who = u.get_int
p = u.parsed.last
notes.push([:cyan, p[:pos], p[:len], "who are you mr #{who} ?"])
size = item_meta[:size]
(0...size).each do |i|
val = u.get_int
p = u.parsed.last
color = (i % 2).zero? ? :yellow : :pink
fields = item_meta[:fields]
desc = ''
desc = fields[i][:name] unless fields.nil? || fields[i].nil?
notes.push([color, p[:pos], p[:len], "data[#{i}]=#{val} #{desc}"])
notes.push([:green, p[:pos], p[:len], "type = #{item_type} #{item_name}"])
item_id = u.get_int
p = u.parsed.last
notes.push([:cyan, p[:pos], p[:len], "id=#{item_id}"])
size = item_meta[:size]
(0...size).each do |i|
val = u.get_int
p = u.parsed.last
color = (i % 2).zero? ? :yellow : :pink
fields = item_meta[:fields]
desc = ''
desc = fields[i][:name] unless fields.nil? || fields[i].nil?
notes.push([color, p[:pos], p[:len], "data[#{i}]=#{val} #{desc}"])
end
item_delta = u.get_int
end
# skip = 0

View file

@ -135,6 +135,7 @@ class Unpacker
def get_int
return nil if @data.nil?
return nil if @data.empty?
# TODO: make this more performant
# it should not read in ALL bytes

View file

@ -49,6 +49,13 @@ describe 'Unpacker', :unpacker do
expect(u.get_int).to eq(2)
end
it 'Should return nil if no more int is found' do
u = Unpacker.new([0x01, 0x02])
expect(u.get_int).to eq(1)
expect(u.get_int).to eq(2)
expect(u.get_int).to eq(nil)
end
it 'Should unpack negative integers' do
u = Unpacker.new([0x40, 0x41, 0x42])
# 0x40 => 1000 0000