diff options
| author | Mosder <xmosder12@gmail.com> | 2026-07-16 16:09:12 +0200 |
|---|---|---|
| committer | Mosder <xmosder12@gmail.com> | 2026-07-16 16:09:12 +0200 |
| commit | 640532f1d0b42323333cabc029af91da6d982d42 (patch) | |
| tree | 4149a53fd0eae1b6bb7d53fec49e20982a585480 | |
| parent | a848493f01e4fe0ff3ca48a3180f80fd7a7c1ccc (diff) | |
feat: added "prettier" printing of fight results. still need to better parse items, drifs and gear
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | analyzer/analyzer.c | 33 | ||||
| -rw-r--r-- | analyzer/parser/fight_results.c | 4 | ||||
| -rw-r--r-- | analyzer/render.c | 142 | ||||
| -rw-r--r-- | analyzer/render.h | 60 |
5 files changed, 211 insertions, 33 deletions
@@ -7,7 +7,7 @@ global: compile local: compile mv branal ${HOME}/.local/bin -compile: csv structures utils parser capture analyzer +compile: csv structures utils parser capture analyzer render $(CC) $(CFLAGS) -lpcap *.o main.c -o branal rm *.o @@ -36,5 +36,8 @@ capture: analyzer: $(CC) $(CFLAGS) -c analyzer/analyzer.c +render: + $(CC) $(CFLAGS) -c analyzer/render.c + .PHONY: analyzer .PHONY: csv diff --git a/analyzer/analyzer.c b/analyzer/analyzer.c index 7def1e6..9ca2d6a 100644 --- a/analyzer/analyzer.c +++ b/analyzer/analyzer.c @@ -4,6 +4,7 @@ #include <string.h> #include "parser/parser.h" +#include "render.h" #include "utils/tcp.h" // loop through packets received from pcap_handle and analyze the TCP stream @@ -36,41 +37,13 @@ void analyzer_loop(TCPStream *stream, pcap_t *pcap_handle, void (*parsed_data_ha } } -// prints fight resutls -void print_fight_results(FightResults results) { - printf("Enemies:\n\t"); - for (size_t i = 0; i < results.num_enemy; i++) { - EnemyResults enemy = results.enemy_results[i]; - printf("%s (%d)%s", enemy.name, enemy.level, i < results.num_enemy - 1 ? ", " : "\n"); - } - printf("Player rewards:\n"); - for (size_t i = 0; i < results.num_friendly; i++) { - FriendlyResults friendly = results.friendly_results[i]; - printf("\t%s (%d):\n", friendly.name, friendly.level); - printf("\t\texp: %d\n", friendly.exp); - printf("\t\tgold: %d\n", friendly.gold); - if (friendly.psycho > 0) - printf("\t\tpsycho: %d\n", friendly.psycho); - if (strlen(friendly.items) > 0) - printf("\t\titems: %s\n", friendly.items); - if (strlen(friendly.gear) > 0) - printf("\t\tgear: %s\n", friendly.gear); - if (strlen(friendly.drifs) > 0) - printf("\t\tdrifs: %s\n", friendly.drifs); - if (friendly.splinters > 0) - printf("\t\tsplinters: %d\n", friendly.splinters); - if (friendly.saturation > 0) - printf("\t\tsaturation: %d (%s)\n", friendly.saturation, friendly.saturation_type); - } - printf("\n"); -} - // file analyzer parsed data handler void file_parsed_data_handler(ParsedData *parsed_data, size_t n_parsed_data) { for (size_t i = 0; i < n_parsed_data; i++) { switch (parsed_data[i].data_type) { case TYPE_FIGHT_RESULTS: - print_fight_results(*(FightResults *)parsed_data[i].data); + printf("\nFIGHT:\n"); + render_fight_results(*(FightResults *)parsed_data[i].data); break; } } diff --git a/analyzer/parser/fight_results.c b/analyzer/parser/fight_results.c index b3227e2..603d66d 100644 --- a/analyzer/parser/fight_results.c +++ b/analyzer/parser/fight_results.c @@ -83,11 +83,11 @@ EntityResults get_entity_results(byte_t *data, size_t length) { } char *get_item_name(int item_id) { - return item_id < id_to_item_name_len ? id_to_item_name[item_id] : "item_id out of bounds"; + return item_id < id_to_item_name_len ? id_to_item_name[item_id] : "null"; } char *get_saturation_type(int saturation_id) { - return saturation_id < id_to_saturation_type_len ? id_to_saturation_type[saturation_id] : "saturation_id out of bounds"; + return saturation_id < id_to_saturation_type_len ? id_to_saturation_type[saturation_id] : "null"; } // parse EntityResults to FriendlyResults diff --git a/analyzer/render.c b/analyzer/render.c new file mode 100644 index 0000000..0c3df56 --- /dev/null +++ b/analyzer/render.c @@ -0,0 +1,142 @@ +#include "render.h" + +#include <stdio.h> +#include <string.h> + +// strlen counting utf-8 characters as one +size_t utf8_strlen(char *s) { + size_t len = 0; + while (*s) { + // if the byte is not a continuation byte (10xxxxxx), it's a new character + if ((*s & 0xC0) != 0x80) + len++; + s++; + } + return len; +} + +void print_row_separator() { + for (size_t i = 0; i < TABLE_LINE_WIDTH; i++) + printf("%c", TABLE_ROW_SEPARATOR_CHAR); + printf("\n"); +} + +// print string with given color +void print_color(char *str, int color) { + printf("\033[%dm%s\033[0m", color, str); +} + +void print_center(char *text, int color, size_t width, char padding_char) { + size_t post_char_count = (width - strlen(text)) / 2; + size_t pre_char_count = width - post_char_count - strlen(text); + + for (size_t i = 0; i < pre_char_count; i++) + printf("%c", padding_char); + + print_color(text, color); + + for (size_t i = 0; i < post_char_count; i++) + printf("%c", padding_char); +} + +void print_enemy_list(EnemyResults *results, size_t n_enemies) { + printf(TABLE_LINE_START); + size_t line_length = TABLE_LINE_START_WIDTH; + + for (size_t i = 0; i < n_enemies; i++) { + EnemyResults enemy = results[i]; + char enemy_buffer[TABLE_LINE_WIDTH + 1]; + sprintf(enemy_buffer, "%s (%d)%s", enemy.name, enemy.level, i < n_enemies - 1 ? ", " : ""); + + // break line if length would be too big + if (line_length + utf8_strlen(enemy_buffer) > TABLE_LINE_WIDTH - TABLE_LINE_END_WIDTH) { + printf("%*s\n", (int)(TABLE_LINE_WIDTH - line_length), TABLE_LINE_END); + printf(TABLE_LINE_START); + line_length = TABLE_LINE_START_WIDTH; + } + + printf("%s", enemy_buffer); + line_length += utf8_strlen(enemy_buffer); + } + + printf("%*s\n", (int)(TABLE_LINE_WIDTH - line_length), TABLE_LINE_END); +} + +void print_column_names() { + char *names[TABLE_COLUMN_COUNT] = TABLE_COLUMN_NAMES; + int colors[TABLE_COLUMN_COUNT] = TABLE_COLUMN_COLORS; + size_t widths[TABLE_COLUMN_COUNT] = TABLE_COLUMN_WIDTHS; + + printf(TABLE_LINE_START); + for (size_t i = 0; i < TABLE_COLUMN_COUNT; i++) { + print_center(names[i], colors[i], widths[i], ' '); + printf(i < TABLE_COLUMN_COUNT - 1 ? TABLE_LINE_SEPARATOR : TABLE_LINE_END); + } + printf("\n"); +} + +void print_player_rewards(FriendlyResults results) { + char buffers[TABLE_COLUMN_COUNT][TABLE_LINE_WIDTH]; + size_t widths[TABLE_COLUMN_COUNT] = TABLE_COLUMN_WIDTHS; + int colors[TABLE_COLUMN_COUNT] = TABLE_COLUMN_COLORS; + + sprintf(buffers[0], "%s (%d)", results.name, results.level); + sprintf(buffers[1], "%d", results.exp); + sprintf(buffers[2], "%d", results.gold); + + if (results.psycho > 0) + sprintf(buffers[3], "%d", results.psycho); + else + sprintf(buffers[3], "-"); + + if (results.saturation > 0) + sprintf(buffers[4], "%d (%s)", results.saturation, results.saturation_type); + else + sprintf(buffers[4], "-"); + + if (results.splinters > 0) + sprintf(buffers[5], "%d", results.splinters); + else + sprintf(buffers[5], "-"); + + printf(TABLE_LINE_START); + for (size_t i = 0; i < TABLE_COLUMN_COUNT; i++) { + char to_color[widths[i] + 1]; + sprintf(to_color, "%*s", (int)widths[i], buffers[i]); + print_color(to_color, colors[i]); + printf(i < TABLE_COLUMN_COUNT - 1 ? TABLE_LINE_SEPARATOR : TABLE_LINE_END); + } + printf("\n"); + + // TODO: change this when I parse the items etc. to a readable format + // needs to utilize utf8_strlen, because right now utf8 characters mess the table up + char big_buf[1024]; + sprintf(big_buf, "%s - %s - %s", results.items, results.gear, results.drifs); + if (strlen(big_buf) > 6) { + printf(TABLE_LINE_START); + print_center("ITEMS", COLOR_WHITE, TABLE_ITEMS_WIDTH, ' '); + printf(TABLE_LINE_END "\n"); + + for (size_t i = 0; i < strlen(big_buf); i += TABLE_ITEMS_WIDTH) { + printf(TABLE_LINE_START "%-*.*s" TABLE_LINE_END "\n", (int)TABLE_ITEMS_WIDTH, (int)TABLE_ITEMS_WIDTH, big_buf + i); + } + } +} + +void render_fight_results(FightResults results) { + print_center("ENEMIES", COLOR_RED, TABLE_LINE_WIDTH, TABLE_ROW_SEPARATOR_CHAR); + printf("\n"); + + print_enemy_list(results.enemy_results, results.num_enemy); + + print_center("PLAYER REWARDS", COLOR_GREEN, TABLE_LINE_WIDTH, TABLE_ROW_SEPARATOR_CHAR); + printf("\n"); + + print_column_names(); + print_row_separator(); + + for (size_t i = 0; i < results.num_friendly; i++) { + print_player_rewards(results.friendly_results[i]); + print_row_separator(); + } +} diff --git a/analyzer/render.h b/analyzer/render.h new file mode 100644 index 0000000..d54015a --- /dev/null +++ b/analyzer/render.h @@ -0,0 +1,60 @@ +// render.h +// functions for "rendering" data onto the terminal + +#include "parser/fight_results.h" + +// ANSI escape sequence colors +#define COLOR_RED 91 +#define COLOR_GREEN 92 +#define COLOR_WHITE 97 +#define COLOR_YELLOW 93 +#define COLOR_AQUA 96 +#define COLOR_BLUE 94 + +#define TABLE_ROW_SEPARATOR_CHAR '-' + +#define TABLE_LINE_START "| " +#define TABLE_LINE_END " |" +#define TABLE_LINE_SEPARATOR " | " +#define TABLE_LINE_START_WIDTH (sizeof(TABLE_LINE_START) - 1) +#define TABLE_LINE_END_WIDTH (sizeof(TABLE_LINE_END) - 1) +#define TABLE_LINE_SEPARATOR_WIDTH (sizeof(TABLE_LINE_SEPARATOR) - 1) + +#define TABLE_COLUMN_COUNT 6 + +#define TABLE_NAME_LVL_WIDTH 17 +#define TABLE_EXP_WIDTH 7 +#define TABLE_GOLD_WIDTH 7 +#define TABLE_PSYCHO_WIDTH 6 +#define TABLE_SATURATION_WIDTH 13 +#define TABLE_SPLINTERS_WIDTH 9 + +#define TABLE_COLUMN_NAMES {"Nick (LVL)", "EXP", "Gold", "Psycho", "Saturation", "Splinters"} +#define TABLE_COLUMN_COLORS {COLOR_WHITE, COLOR_WHITE, COLOR_YELLOW, COLOR_AQUA, COLOR_GREEN, COLOR_BLUE} +#define TABLE_COLUMN_WIDTHS { \ + TABLE_NAME_LVL_WIDTH, \ + TABLE_EXP_WIDTH, \ + TABLE_GOLD_WIDTH, \ + TABLE_PSYCHO_WIDTH, \ + TABLE_SATURATION_WIDTH, \ + TABLE_SPLINTERS_WIDTH \ +} + +#define TABLE_LINE_WIDTH ( \ + TABLE_LINE_START_WIDTH + \ + TABLE_NAME_LVL_WIDTH + \ + TABLE_EXP_WIDTH + \ + TABLE_GOLD_WIDTH + \ + TABLE_PSYCHO_WIDTH + \ + TABLE_SATURATION_WIDTH + \ + TABLE_SPLINTERS_WIDTH + \ + (TABLE_COLUMN_COUNT - 1) * TABLE_LINE_SEPARATOR_WIDTH + \ + TABLE_LINE_END_WIDTH \ +) + +#define TABLE_ITEMS_WIDTH (TABLE_LINE_WIDTH - TABLE_LINE_START_WIDTH - TABLE_LINE_END_WIDTH) + +// render fight results onto the terminal +// params: +// - results - fight results to render +extern void render_fight_results(FightResults results); |
