302 lines
No EOL
6.4 KiB
C
302 lines
No EOL
6.4 KiB
C
#include "map.h"
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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 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;
|
|
} |