From 6fdaf3be9070a92b6f4fcc49a976d5441bfc0299 Mon Sep 17 00:00:00 2001 From: ChillerDragon Date: Fri, 18 Nov 2022 10:59:59 +0100 Subject: [PATCH] I think this snap item format is okayish --- lib/snap_items/character.rb | 118 ++++++++++++++++++++++++++++++++++++ lib/snap_items/game_data.rb | 16 ++++- lib/snapshot.rb | 14 +++-- 3 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 lib/snap_items/character.rb diff --git a/lib/snap_items/character.rb b/lib/snap_items/character.rb new file mode 100644 index 0000000..3197d7a --- /dev/null +++ b/lib/snap_items/character.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +require_relative '../packer' + +class NetObj + class Character + attr_accessor :tick, :x, :y, :vel_x, :vel_y, :angle, :direction, :jumped, :hooked_player, :hook_state, :hook_tick, + :hook_x, :hook_y, :hook_dx, :hook_dy, + :health, :armor, :ammo_count, :weapon, :emote, :attack_tick, :triggered_events + attr_reader :notes, :name, :id + + def initialize(hash_or_raw) + @field_names = %i[ + tick + x + y + vel_x + vel_y + angle + direction + jumped + hooked_player + hook_state + hook_tick + hook_x + hook_y + hook_dx + hook_dy + health + armor + ammo_count + weapon + emote + attack_tick + triggered_events + ] + @fields = @field_names.map do |_| + 0 + end + @size = @fields.count + @name = self.class.name + @notes = [] # hexdump annotation notes + if hash_or_raw.instance_of?(Hash) + init_hash(hash_or_raw) + elsif hash_or_raw.instance_of?(Unpacker) + init_unpacker(hash_or_raw) + else + init_raw(hash_or_raw) + end + end + + def self.match_type?(type) + type == NETOBJTYPE_CHARACTER + end + + def validate + @fields.select(&:nil?).empty? + end + + def init_unpacker(u) + @id = u.get_int + p = u.parsed.last + @notes.push([:cyan, p[:pos], p[:len], "id=#{@id}"]) + i = 0 + @fields.map! do |_| + # TODO: as of right now it can get nil values here + # the fix would be "u.get_int || 0" + # but fixing it would probably make it harder + # to debug invalid data + # + # but do rethink this in a later point please :) + # for now call .validate() everywhere + val = u.get_int + + p = u.parsed.last + color = (i % 2).zero? ? :yellow : :pink + desc = @field_names[i] + @notes.push([color, p[:pos], p[:len], "data[#{i}]=#{val} #{desc}"]) + i += 1 + + val + end + end + + def init_raw(data) + u = Unpacker.new(data) + init_unpacker(u) + end + + def init_hash(attr) + @fields_names.each do |name| + instance_variable_set("@#{name}", attr[name] || 0) + end + end + + def to_h + hash = {} + @field_names.each_with_index do |name, index| + hash[name] = @fields[index] + end + hash + end + + # basically to_network + # int array the server sends to the client + def to_a + arr = [] + @fields.each do |value| + arr += Packer.pack_int(value) + end + arr + end + + def to_s + to_h + end + end +end diff --git a/lib/snap_items/game_data.rb b/lib/snap_items/game_data.rb index b2e1c8a..8e09f77 100644 --- a/lib/snap_items/game_data.rb +++ b/lib/snap_items/game_data.rb @@ -5,6 +5,7 @@ require_relative '../packer' class NetObj class GameData attr_accessor :game_start_tick, :game_state_flags, :game_state_end_tick + attr_reader :notes, :name, :id def initialize(hash_or_raw) @field_names = %i[ @@ -17,6 +18,7 @@ class NetObj end @size = @fields.count @name = self.class.name + @notes = [] # hexdump annotation notes if hash_or_raw.instance_of?(Hash) init_hash(hash_or_raw) elsif hash_or_raw.instance_of?(Unpacker) @@ -35,6 +37,10 @@ class NetObj end def init_unpacker(u) + @id = u.get_int + p = u.parsed.last + @notes.push([:cyan, p[:pos], p[:len], "id=#{@id}"]) + i = 0 @fields.map! do |_| # TODO: as of right now it can get nil values here # the fix would be "u.get_int || 0" @@ -43,7 +49,15 @@ class NetObj # # but do rethink this in a later point please :) # for now call .validate() everywhere - u.get_int + val = u.get_int + + p = u.parsed.last + color = (i % 2).zero? ? :yellow : :pink + desc = @field_names[i] + @notes.push([color, p[:pos], p[:len], "data[#{i}]=#{val} #{desc}"]) + i += 1 + + val end end diff --git a/lib/snapshot.rb b/lib/snapshot.rb index f05dea3..a164c72 100644 --- a/lib/snapshot.rb +++ b/lib/snapshot.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative 'snap_items/game_data' +require_relative 'snap_items/character' require_relative 'packer' class SnapshotUnpacker @@ -146,16 +147,21 @@ class SnapshotUnpacker obj = nil if NetObj::GameData.match_type?(item_type) obj = NetObj::GameData.new(u) - p obj - else - # puts "no match #{item_type}" + notes += obj.notes + # p obj + elsif NetObj::Character.match_type?(item_type) + obj = NetObj::Character.new(u) + notes += obj.notes + # p obj + elsif @verbose + puts "no match #{item_type}" end if obj notes.push([ :green, id_parsed[:pos], id_parsed[:len], - "type=#{item_type}" + "type=#{item_type} #{obj.name}" ]) else notes.push([