aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMosder <xmosder12@gmail.com>2026-07-16 16:09:12 +0200
committerMosder <xmosder12@gmail.com>2026-07-16 16:09:12 +0200
commit640532f1d0b42323333cabc029af91da6d982d42 (patch)
tree4149a53fd0eae1b6bb7d53fec49e20982a585480
parenta848493f01e4fe0ff3ca48a3180f80fd7a7c1ccc (diff)
feat: added "prettier" printing of fight results. still need to better parse items, drifs and gear
-rw-r--r--Makefile5
-rw-r--r--analyzer/analyzer.c33
-rw-r--r--analyzer/parser/fight_results.c4
-rw-r--r--analyzer/render.c142
-rw-r--r--analyzer/render.h60
5 files changed, 211 insertions, 33 deletions
diff --git a/Makefile b/Makefile
index cb40a5a..dcdabe2 100644
--- a/Makefile
+++ b/Makefile
@@ -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);