mirror of https://github.com/basinserver/basin/
refactor command
This commit is contained in:
parent
e25393c295
commit
abf5ffec00
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
void init_base_commands();
|
void init_base_commands();
|
||||||
|
|
||||||
void registerCommand(char* command, void (*callback)(struct player* player, char** args, size_t args_count));
|
typedef void (*command_callback)(struct server* server, struct player* player, char** args, size_t args_count);
|
||||||
|
|
||||||
void callCommand(struct player* player, struct mempool* pool, char* command);
|
void command_register(char* called_by, command_callback callback);
|
||||||
|
|
||||||
|
void command_call(struct server* server, struct player* player, char* command);
|
||||||
|
|
||||||
#endif /* BASIN_COMMAND_H_ */
|
#endif /* BASIN_COMMAND_H_ */
|
||||||
|
|
149
src/command.c
149
src/command.c
|
@ -97,22 +97,23 @@ void command_motd(struct server* server, struct player* player, char** args, siz
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_list(struct server* server, struct player* player, char** args, size_t args_count) {
|
void command_list(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
char* plist = pmalloc();
|
char message[4096];
|
||||||
char* cptr = plist;
|
message[0] = 0;
|
||||||
BEGIN_HASHMAP_ITERATION (players);
|
pthread_rwlock_rdlock(&server->players_by_entity_id->rwlock);
|
||||||
if (cptr > plist) {
|
ITER_MAP(server->players_by_entity_id) {
|
||||||
*cptr++ = ',';
|
if (message[0] != 0) {
|
||||||
*cptr++ = ' ';
|
strncat(message, ", ", 4096);
|
||||||
|
}
|
||||||
|
struct player* iter_player = (struct player*) value;
|
||||||
|
strncat(message, iter_player->name, 4096);
|
||||||
|
ITER_MAP_END();
|
||||||
}
|
}
|
||||||
struct player* player = (struct player*) value;
|
snprintf(message + strlen(message), 4096 - strlen(message), " (%lu players total)", server->players_by_entity_id->entry_count);
|
||||||
cptr = xstrncat(cptr, 16, player->name);
|
pthread_rwlock_unlock(&server->players_by_entity_id->rwlock);
|
||||||
END_HASHMAP_ITERATION (players);
|
player_send_message(player, "gray", "%s", message);
|
||||||
snprintf(cptr, 32, " (%lu players_by_entity_id total)", players->entry_count);
|
|
||||||
player_send_message(player, "gray", "%s", plist);
|
|
||||||
xfree(plist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_spawn(struct player* player, char** args, size_t args_count) {
|
void command_spawn(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (!player) {
|
if (!player) {
|
||||||
player_send_message(player, "red", "Must be run as player");
|
player_send_message(player, "red", "Must be run as player");
|
||||||
return;
|
return;
|
||||||
|
@ -130,23 +131,23 @@ void command_spawn(struct player* player, char** args, size_t args_count) {
|
||||||
(double) player->world->spawnpos.z + .5);
|
(double) player->world->spawnpos.z + .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_printprofile(struct player* player, char** args, size_t args_count) {
|
void command_printprofile(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
printProfiler();
|
printProfiler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_clearprofile(struct player* player, char** args, size_t args_count) {
|
void command_clearprofile(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (player != NULL) return;
|
if (player != NULL) return;
|
||||||
clearProfiler();
|
clearProfiler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_kill(struct player* player, char** args, size_t args_count) {
|
void command_kill(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
if (!player) {
|
if (!player) {
|
||||||
if (args_count != 1) {
|
if (args_count != 1) {
|
||||||
player_send_message(player, "red", "Usage: /kill <player>");
|
player_send_message(player, "red", "Usage: /kill <player>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player = player_get_by_name(args[0]);
|
player = player_get_by_name(server, args[0]);
|
||||||
if (player == NULL) {
|
if (player == NULL) {
|
||||||
player_send_message(player, "red", "[ERROR] No such player found.");
|
player_send_message(player, "red", "[ERROR] No such player found.");
|
||||||
return;
|
return;
|
||||||
|
@ -155,90 +156,92 @@ void command_kill(struct player* player, char** args, size_t args_count) {
|
||||||
damageEntity(player->entity, player->entity->maxHealth * 10., 0);
|
damageEntity(player->entity, player->entity->maxHealth * 10., 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_tps(struct player* player, char** args, size_t args_count) {
|
void command_tps(struct server* server, struct player* player, char** args, size_t args_count) {
|
||||||
player_broadcast("light_purple", "%f tps", player->world->tps);
|
player_broadcast(server->players_by_entity_id, "light_purple", "%f tps", player == NULL ? server->overworld->tps : player->world->tps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_base_commands() {
|
void init_base_commands() {
|
||||||
registerCommand("gamemode", &command_gamemode);
|
command_register("gamemode", &command_gamemode);
|
||||||
registerCommand("gm", &command_gamemode);
|
command_register("gm", &command_gamemode);
|
||||||
registerCommand("tp", &command_tp);
|
command_register("tp", &command_tp);
|
||||||
registerCommand("spawn", &command_spawn);
|
command_register("spawn", &command_spawn);
|
||||||
registerCommand("kick", &command_kick);
|
command_register("kick", &command_kick);
|
||||||
registerCommand("say", &command_say);
|
command_register("say", &command_say);
|
||||||
registerCommand("printprofile", &command_printprofile);
|
command_register("printprofile", &command_printprofile);
|
||||||
registerCommand("pp", &command_printprofile);
|
command_register("pp", &command_printprofile);
|
||||||
registerCommand("clearprofile", &command_clearprofile);
|
command_register("clearprofile", &command_clearprofile);
|
||||||
registerCommand("cp", &command_clearprofile);
|
command_register("cp", &command_clearprofile);
|
||||||
registerCommand("motd", &command_motd);
|
command_register("motd", &command_motd);
|
||||||
registerCommand("list", &command_list);
|
command_register("list", &command_list);
|
||||||
registerCommand("ls", &command_list);
|
command_register("ls", &command_list);
|
||||||
registerCommand("who", &command_list);
|
command_register("who", &command_list);
|
||||||
registerCommand("kill", &command_kill);
|
command_register("kill", &command_kill);
|
||||||
registerCommand("tps", &command_tps);
|
command_register("tps", &command_tps);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*command_callback)(struct player* player, char** args, size_t args_count);
|
|
||||||
|
|
||||||
struct command {
|
struct command {
|
||||||
char* command;
|
char* command;
|
||||||
command_callback callback;
|
command_callback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct collection* registered_commands;
|
struct hashmap* registered_commands;
|
||||||
|
|
||||||
void registerCommand(char* command, command_callback callback) {
|
void command_register(char* called_by, command_callback callback) {
|
||||||
if (registered_commands == NULL) registered_commands = new_collection(16, 0);
|
if (registered_commands == NULL) {
|
||||||
struct command* com = xmalloc(sizeof(struct command));
|
registered_commands = hashmap_thread_new(16, global_pool);
|
||||||
com->command = xstrdup(command, 0);
|
}
|
||||||
com->callback = callback;
|
struct command* command = pmalloc(registered_commands->pool, sizeof(struct command));
|
||||||
add_collection(registered_commands, com);
|
command->command = str_dup(called_by, 0, registered_commands->pool);
|
||||||
|
command->callback = callback;
|
||||||
|
hashmap_put(registered_commands, command->command, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void callCommand(struct player* player, struct mempool* pool, char* command) {
|
void command_call(struct server* server, struct player* player, char* command) {
|
||||||
if (registered_commands == NULL) return;
|
if (registered_commands == NULL) {
|
||||||
size_t sl = strlen(command);
|
return;
|
||||||
|
}
|
||||||
|
size_t command_length = strlen(command);
|
||||||
size_t arg_count = 0;
|
size_t arg_count = 0;
|
||||||
int iq = 0;
|
int in_quote = 0;
|
||||||
int eq = 0;
|
int escaped = 0;
|
||||||
for (size_t i = 0; i < sl; i++) {
|
for (size_t i = 0; i < command_length; i++) {
|
||||||
int cl = 0;
|
int add_character = 0;
|
||||||
if (command[i] == ' ' && !iq) {
|
if (command[i] == ' ' && !in_quote) {
|
||||||
command[i] = 0;
|
command[i] = 0;
|
||||||
arg_count++;
|
arg_count++;
|
||||||
} else if (command[i] == '\"' && !eq) {
|
} else if (command[i] == '\"' && !escaped) {
|
||||||
iq = !iq;
|
in_quote = !in_quote;
|
||||||
eq = 0;
|
escaped = 0;
|
||||||
cl = 1;
|
add_character = 1;
|
||||||
} else if (command[i] == '\\') {
|
} else if (command[i] == '\\') {
|
||||||
eq = !eq;
|
escaped = !escaped;
|
||||||
cl = eq;
|
add_character = escaped;
|
||||||
} else eq = 0;
|
} else escaped = 0;
|
||||||
if (cl) {
|
if (add_character) {
|
||||||
memmove(command + i, command + i + 1, sl - i);
|
memmove(command + i, command + i + 1, command_length - i);
|
||||||
i--;
|
i--;
|
||||||
sl--;
|
command_length--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* args[arg_count];
|
char* args[arg_count];
|
||||||
char* rc = command;
|
char* real_command = command;
|
||||||
size_t i = strlen(command) + 1;
|
size_t i = strlen(command) + 1;
|
||||||
command += i;
|
command += i;
|
||||||
size_t i2 = 0;
|
size_t i2 = 0;
|
||||||
while (i < sl) {
|
while (i < command_length) {
|
||||||
args[i2] = command;
|
args[i2] = command;
|
||||||
i += strlen(command) + 1;
|
i += strlen(command) + 1;
|
||||||
command += strlen(command) + 1;
|
command += strlen(command) + 1;
|
||||||
args[i2] = trim(args[i2]);
|
args[i2] = str_trim(args[i2]);
|
||||||
i2++;
|
i2++;
|
||||||
}
|
}
|
||||||
for (size_t i3 = 0; i3 < registered_commands->size; i3++) {
|
if (arg_count == 0) {
|
||||||
struct command* com = (struct command*) registered_commands->data[i3];
|
return;
|
||||||
if (com == NULL) continue;
|
|
||||||
if (streq_nocase(com->command, rc)) {
|
|
||||||
(*com->callback)(player, args, arg_count);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
player_send_message(player, "red", "[ERROR] Invalid Command!");
|
struct command* com = (struct command*) hashmap_get(registered_commands, args[0]);
|
||||||
|
if (com == NULL) {
|
||||||
|
player_send_message(player, "red", "[ERROR] Command \"/%s\" not found!", args[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(*com->callback)(server, player, args, arg_count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,12 +417,12 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
//TODO: start wake thread
|
//TODO: start wake thread
|
||||||
char line[4096];
|
char line[4096];
|
||||||
while (sr > 0) {
|
while (servers->count > 0 && sr > 0) {
|
||||||
if (readLine(STDIN_FILENO, line, 4096) < 0) {
|
if (readLine(STDIN_FILENO, line, 4096) < 0) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
callCommand(NULL, line);
|
command_call(servers->data[0], NULL, line);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ void player_packet_handle_chatmessage(struct player* player, struct mempool* poo
|
||||||
char* msg = packet->message;
|
char* msg = packet->message;
|
||||||
if (ac_chat(player, msg)) return;
|
if (ac_chat(player, msg)) return;
|
||||||
if (str_prefixes(msg, "/")) {
|
if (str_prefixes(msg, "/")) {
|
||||||
callCommand(player, pool, msg + 1);
|
command_call(player->server, player, pool, msg + 1);
|
||||||
} else {
|
} else {
|
||||||
size_t max_size = strlen(msg) + 128;
|
size_t max_size = strlen(msg) + 128;
|
||||||
char* broadcast_str = pmalloc(pool, max_size);
|
char* broadcast_str = pmalloc(pool, max_size);
|
||||||
|
|
Loading…
Reference in New Issue