From 7697e5f4516f3b391cd948d1d61dd5848bd5ae83 Mon Sep 17 00:00:00 2001 From: ChillerDragon Date: Wed, 16 Nov 2022 12:40:52 +0100 Subject: [PATCH] color annotate hexdumps Thanks to the legend @Learath2 --- lib/bytes.rb | 68 ++++++++++++++++++++++++++++++++++++++++++++-- lib/game_client.rb | 5 +++- lib/string.rb | 4 +++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/lib/bytes.rb b/lib/bytes.rb index 38e26ed..4ebd224 100644 --- a/lib/bytes.rb +++ b/lib/bytes.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative 'array' +require_relative 'string' # turn byte array into hex string def str_hex(data) @@ -15,17 +16,61 @@ def data_to_ascii(data) ascii end -def hexdump_lines(data, width = 2) +def hexdump_lines(data, width = 2, notes = [], opts = {}) byte_groups = data.unpack1('H*').scan(/../).groups_of(4) lines = [] hex = '' ascii = '' w = 0 + byte = 0 + legend = [] + notes.each do |info| + color = info.first + raise "Invalid color '#{color}' valid ones: #{AVAILABLE_COLORS}" unless AVAILABLE_COLORS.include? color + + legend.push([color, info.last.send(color)]) + end + unless legend.empty? + if opts[:long_legend] + legend.each do |leg| + lines.push("#{leg.first}: #{leg.last}".send(leg.first)) + end + else + lines.push(legend.map(&:last).join(' ')) + end + end byte_groups.each do |byte_group| hex += ' ' unless hex.empty? - hex += byte_group.join(' ') ascii += data_to_ascii(str_bytes(byte_group.join).pack('C*')) w += 1 + notes.each do |info| + color = info.first + # p color + # p info + from = info[1] + to = info[1] + (info[2] - 1) + + if from > byte + 3 + # puts "a" + next + end + if to < byte + # puts "to: #{to} < byte: #{byte}" + next + end + + from -= byte + to -= byte + from = 0 if from.negative? + to = 3 if to > 3 + + # puts "from: #{from} to: #{to}" + (from..to).each do |i| + byte_group[i] = byte_group[i].send(color) + end + end + byte += 4 + hex += byte_group.join(' ') next unless w >= width w = 0 @@ -50,3 +95,22 @@ end def get_byte(data, start = 0, num = 1) data[start...(start + num)].unpack('H*').join.upcase end + +def todo_make_this_a_unit_test + notes = [ + [:red, 0, 1, 'foo'], + [:green, 1, 1, 'bar'], + [:yellow, 2, 1, 'baz'], + [:pink, 3, 1, 'bang'], + [:green, 4, 1, 'bär'], + [:yellow, 6, 6, 'yee'] + ] + + hexdump_lines("\x01\x41\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\xef", 40, notes).each do |l| + puts l + end + + hexdump_lines("\x01\x41\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\xef", 40, notes, long_legend: true).each do |l| + puts l + end +end diff --git a/lib/game_client.rb b/lib/game_client.rb index c11950f..0897f16 100644 --- a/lib/game_client.rb +++ b/lib/game_client.rb @@ -182,7 +182,10 @@ class GameClient # TODO: add get_raw(size) data = u.get_raw puts 'snap:' - hexdump_lines(data.pack('C*')).each do |hex| + notes = [ + [:green, 0, 4, 'who dis?'] + ] + hexdump_lines(data.pack('C*'), 2, notes, long_legend: true).each do |hex| puts hex end diff --git a/lib/string.rb b/lib/string.rb index 4c77ff8..f3eaee4 100644 --- a/lib/string.rb +++ b/lib/string.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true +AVAILABLE_COLORS = %i[ + red green yellow pink +].freeze + # String color class String def colorize(color_code)