#include "map.h" #include #include #include #include #include #include "main.h" // huge cleanup operation soon struct pager { int page; int i; int is_poll; hashmap *cmd; }; struct verifier { char *name; char *sugg; }; struct succ { char *sugg; int *points; }; long stoi(const char *s) { long i; i = 0; while (*s >= '0' && *s <= '9') { i = i * 10 + (*s - '0'); s++; } return i; } int fix_delim(char *command, char *needle) { char *delim = strstr(command, needle); if (!delim) return 0; delim[0] = ';'; return 1; } int sort_comp(const void *a, const void *b) { return strcmp(*(char **)a, *(char **)b); } int inv_handler(const void *key, size_t size, uintptr_t val, void *usr) { struct pager *i = usr; if (val == 0) return 0; char *key2 = (char *)key; char *val2 = (char *)val; if (i->is_poll) { char *key3 = calloc(strlen(key2) + 1, sizeof(char)); memcpy(key3, key2, strstr(key2, "_") - key2); char *val3 = strstr(val2, ";") + 1; uintptr_t result; hashmap_get(i->cmd, val3, strlen(val3) - 1, &result); if (result != 0) { free(key3); return 1; } i->i++; if (i->i < i->page * 10 || i->i >= (i->page + 1) * 10) { return 0; } if (val2[strlen(val2) - 1] == '\n') { printf("- user:%s suggested %s", key3, val2); } else { printf("- user:%s suggested %s\n", key3, val2); } free(key3); return 1; } i->i++; if (i->i < i->page * 10 || i->i >= (i->page + 1) * 10) { return 0; } if (strlen(key2) > 0 && key2[strlen(key2) - 1] == '\n') { printf("- %s", key2); } else { printf("- %s\n", key2); } return 1; } int polls_handler(const void *key, size_t size, uintptr_t val, void *usr) { struct verifier *verified = (struct verifier *)usr; if (((char *)val)[strlen(((char *)val)) - 1] == '\n') { ((char *)val)[strlen(((char *)val)) - 1] = '\0'; } if (strncmp(verified->name, key, strlen(verified->name)) == 0 && strcmp(verified->sugg, (char *)val) == 0) return -1; return 0; } int success_handler(const void *key, size_t size, uintptr_t val, void *usr) { struct succ *verified = (struct succ *)usr; if ((char *)val != verified->sugg) { //((char *)val)[strlen(((char *)val)) - 1] = '\0'; } if (strcmp(verified->sugg, (char *)val) == 0) { verified->points[0]++; } return 0; } char *handle_pages(char *command, char *invs) { if (strncmp(command, invs, strlen(invs)) == 0) { return &command[strlen(invs)]; } else { return 0; } } int handle_pages_int(char *command, char *invs) { if (strncmp(command, invs, strlen(invs)) == 0) { return stoi(&command[strlen(invs)]); } else if (strncmp(command, invs, strlen(invs) - 1) == 0) { return 1; } else { return 0; } } int suggest_command(char *command, char *command_re, hashmap *polls, char *name) { char *page = handle_pages(command, "/suggest "); if (!page) return 0; page[strlen(page) - 1] = '\0'; if (strstr(page, "\n") || strstr(page, ";") || strstr(page, ",") || strstr(page, "+")) { printf("This element contains illegal characters.\n"); return 1; } char *val = calloc(MAX_BUF_LENGTH, sizeof(char)); sprintf(val, "%s;%s", page, command_re); char *key = calloc(MAX_BUF_LENGTH, sizeof(char)); sprintf(key, "%s_%i", name, (int)rand()); struct verifier verified = {.name = name, .sugg = val}; if (hashmap_iterate(polls, polls_handler, (void *)&verified) == -1) { printf("You already suggested this!\n"); return 1; } hashmap_set(polls, key, strlen(key), (uintptr_t)val, 1); int point_thing = 0; struct succ succer = {.sugg = val, .points = &point_thing}; hashmap_iterate(polls, success_handler, (void *)&succer); if (point_thing == UPVOTE_IN) { printf("Poll was added into the game!\n"); FILE *fptr; fptr = fopen("../elem_data/" combo_file, "a"); if (fptr == NULL) return 1; fwrite(val, sizeof(char), strlen(val), fptr); fwrite("\n", sizeof(char), 1, fptr); fclose(fptr); return 1; } printf("Suggested %s = %s.\n", command_re, page); // todo: clean old polls FILE *fptr; fptr = fopen("../elem_data/" poll_file, "a"); if (fptr == NULL) return 1; fwrite(key, sizeof(char), strlen(key), fptr); fwrite(";", sizeof(char), 1, fptr); fwrite(val, sizeof(char), strlen(val), fptr); fwrite("\n", sizeof(char), 1, fptr); fclose(fptr); return 1; } int help_command(char *command) { char *page = handle_pages(command, "/help"); if (!page) return 0; printf("Available " "commands:\n- elem1;elem2...\n- elem1+elem2...\n- elem1,elem2...\n- " "/help\n- /inv [page]\n- /suggest [combo]\n- /polls [page]\n"); return 1; } int polls_command(char *command, hashmap *polls, hashmap *cmd) { int page = handle_pages_int(command, "/polls "); if (page == 0) return 0; printf("Current polls (page %i):\n", page); struct pager i = {.page = page - 1, .i = -1, .is_poll = 1, .cmd = cmd}; hashmap_iterate(polls, inv_handler, &i); printf("Total: %i\n", i.i + 1); return 1; } int path_command(char *command, hashmap *elements_rev, hashmap *already_done, int top, hashmap* inv) { char *page2; if (top) { page2 = handle_pages(command, "/path "); if (page2 == 0) return 0; } else { page2 = command; } char *page = malloc(strlen(page2) + 1); strcpy(page, page2); if (page[strlen(page) - 1] == '\n') { page[strlen(page) - 1] = '\0'; } if (strlen(page) == 0) { return 1; } if (top) { printf("Path of %s:\n", page); hashmap_free(already_done); already_done = hashmap_create(); } uintptr_t result; hashmap_get(inv, page, strlen(page), &result); if (top && result != 1) { printf("You don't have %s.\n", page); return 1; } hashmap_get(already_done, page, strlen(page), &result); if (result != 0) { return 1; } hashmap_set(already_done, page, strlen(page), (uintptr_t)1, 0); hashmap_get(elements_rev, page, strlen(page) - 1, &result); if (result == 0 || strlen((char *)result) < 1) { return 1; } // todo: refactor; char *tmp = (char *)result, *tmp2 = 0; if (tmp[strlen(tmp)-1] == '\n') { tmp[strlen(tmp) - 1] = '\0'; } int combos = 0; for (int i = 1; i < MAX_COMBO_LENGTH; i++) { combos = i; tmp2 = tmp; if (tmp2[0] == ';') { tmp2++; } tmp = strstr(tmp2, ";"); if (tmp == 0) { tmp = &tmp2[strlen(tmp2)]; } char *tmp23 = malloc(strlen(tmp2) - strlen(tmp) + 2); memcpy(tmp23, &tmp2[0], strlen(tmp2) - strlen(tmp) + 2); tmp23[strlen(tmp2) - strlen(tmp) + 1] = '\0'; char *strstrd = strstr(tmp23, ";"); if (strstrd != 0) { strstrd[0] = '\0'; } path_command(tmp23, elements_rev, already_done, 0, inv); if (strlen(tmp23) < 1) { break; } free(tmp23); } printf("<- %s\n-> %s\n", (char*) result, (char *)page); return 1; } int slash_command(char *command, hashmap *inv) { int page = handle_pages_int(command, "/inv "); if (page == 0) return 0; printf("Your inventory (page %i):\n", page); struct pager i = {.page = page - 1, .i = -1, .is_poll = 0}; hashmap_iterate(inv, inv_handler, &i); printf("Total: %i\n", i.i + 1); return 1; } int get_command(char *command, char *command_re, char **sort_tmp) { while (1) { int get_out = 0; get_out |= fix_delim(command, "+"); get_out |= fix_delim(command, ","); if (!get_out) break; } if (command[0] == ';') { command++; } int cl = strlen(command); if (cl < 2) return 0; command[cl - 1] = '\0'; sort_tmp[0] = command; int combos = 0; for (int i = 1; i < MAX_COMBO_LENGTH; i++) { combos = i; sort_tmp[i] = strstr(sort_tmp[i - 1], ";"); if (sort_tmp[i] == 0 || sort_tmp[i] == sort_tmp[i - 1]) break; if (strlen(sort_tmp[i]) < 2) { sort_tmp[i][0] = '\0'; break; } sort_tmp[i][0] = '\0'; sort_tmp[i]++; } qsort(sort_tmp, combos, sizeof(char *), sort_comp); char *command_re_tmp = command_re; for (int i = 0; i < combos; i++) { if (i != 0) { command_re_tmp[0] = ';'; command_re_tmp++; } char *last = sort_tmp[i]; strcpy(command_re_tmp, last); command_re_tmp += strlen(last); } return combos; }