elemental-on-terminal/src/command.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;
}