diff options
Diffstat (limited to 'analyzer/analyzer.c')
| -rw-r--r-- | analyzer/analyzer.c | 132 |
1 files changed, 117 insertions, 15 deletions
diff --git a/analyzer/analyzer.c b/analyzer/analyzer.c index 7b80328..b3468d6 100644 --- a/analyzer/analyzer.c +++ b/analyzer/analyzer.c @@ -1,11 +1,119 @@ #include "analyzer.h" #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "parser/parser.h" #include "render.h" #include "utils/tcp.h" +// cleanup TotalRewards to be used with HashMap +void cleanup_total_rewards(void *rewards) { + TotalRewards *r = rewards; + hashmap_free(r->saturations); + for (size_t i = 0; i < MAX_ITEM_TYPE; i++) + array_destroy(r->items[i]); +} + +// cleanup char** to be used in DynArray +void cleanup_str_pointer(void *str_pointer) { + char **p_str = str_pointer; + free(*p_str); +} + +// initalize new total rewards +TotalRewards new_total_rewards() { + HashMap *saturations = hashmap_new(sizeof(const char *), sizeof(int), hash_str, compare_strs, NULL, NULL); + // clang-format off + TotalRewards rewards = { + .exp = 0, + .gold = 0, + .psycho = 0, + .saturations = saturations + }; + // clang-format on + for (size_t i = 0; i < MAX_ITEM_TYPE; i++) + rewards.items[i] = array_new(sizeof(char **), 16, cleanup_str_pointer); + return rewards; +} + +// initalize file analysis state +FileAnalState init_file_anal_state() { + HashMap *characters = hashmap_new(sizeof(char *), sizeof(TotalRewards), hash_str, compare_strs, NULL, cleanup_total_rewards); + FileAnalState state = {.fight_count = 0, .curr_character = {0}, .characters = characters}; + return state; +} + +// destroy FileAnalState +void destroy_file_anal_state(FileAnalState state) { + hashmap_free(state.characters); +} + +// add data from FriendlyResults into TotalRewards +void add_to_total_rewards(TotalRewards *rewards, FriendlyResults *results) { + rewards->exp += results->exp; + rewards->gold += results->gold; + rewards->psycho += results->psycho; + + Item *it = NULL; + while ((it = array_next(results->items, it))) { + char *data = strdup(it->data); + array_append(&rewards->items[it->type], &data); + } + + if (results->saturation > 0) { + int *old_sat = hashmap_get(rewards->saturations, (char *)results->saturation_type); + int new_sat = results->saturation + (old_sat ? *old_sat : 0); + hashmap_put(rewards->saturations, (char *)results->saturation_type, &new_sat); + } +} + +// file analyzer parsed data handler +void file_parsed_data_handler(void *state, DynArray parsed_data) { + FileAnalState *st = state; + ParsedData *data = NULL; + while ((data = array_next(parsed_data, data))) { + switch (data->data_type) { + case TYPE_FIGHT_RESULTS: { + FightResults *res = data->data; + + // if only one friendly - it's the player + if (res->friendly_results.count == 1) { + FriendlyResults *player = array_get(res->friendly_results, 0); + strcpy(st->curr_character, player->name); + } + + // find the current player + FriendlyResults *friendly = NULL; + int found = 0; + while (!found && (friendly = array_next(res->friendly_results, friendly))) { + if (!strcmp(st->curr_character, friendly->name)) + found = 1; + } + + // if found - save the rewards + if (found) { + TotalRewards *r = hashmap_get(st->characters, st->curr_character); + if (r) { + add_to_total_rewards(r, friendly); + } + else { + TotalRewards rewards = new_total_rewards(); + add_to_total_rewards(&rewards, friendly); + hashmap_put(st->characters, st->curr_character, &rewards); + } + } + + // print fight results + printf("\nFIGHT %zu:\n", ++st->fight_count); + render_fight_results(*(FightResults *)data->data); + break; + } + } + } +} + // loop through packets received from pcap_handle and analyze the TCP streams void analyzer_loop( TCPStream *server_stream, TCPStream *client_stream, pcap_t *pcap_handle, void *state, void (*parsed_data_handler)(void *state, DynArray parsed_data) @@ -41,20 +149,6 @@ void analyzer_loop( } } -// file analyzer parsed data handler -void file_parsed_data_handler(void *state, DynArray parsed_data) { - int *fights_count = state; - ParsedData *data = NULL; - while ((data = array_next(parsed_data, data))) { - switch (data->data_type) { - case TYPE_FIGHT_RESULTS: - printf("\nFIGHT %d:\n", ++*fights_count); - render_fight_results(*(FightResults *)data->data); - break; - } - } -} - void analyze_file(char *path) { // open the file char errbuf[PCAP_ERRBUF_SIZE]; @@ -69,9 +163,17 @@ void analyze_file(char *path) { // analyze the file TCPStream server_stream = new_stream(SERVER); TCPStream client_stream = new_stream(CLIENT); - int state = 0; + FileAnalState state = init_file_anal_state(); analyzer_loop(&server_stream, &client_stream, handle, &state, file_parsed_data_handler); + + // TODO: replace this + TotalRewards *r = hashmap_get(state.characters, "Denem"); + if (r) + render_total_rewards(*r); + + // free everything destroy_stream(server_stream); destroy_stream(client_stream); + destroy_file_anal_state(state); pcap_close(handle); } |
