Merge branch 'unstable' into coop

This commit is contained in:
MysterD 2022-05-09 23:13:19 -07:00
commit 367f672af7
10 changed files with 243 additions and 33 deletions

View file

@ -4,16 +4,12 @@
#include "pc/djui/djui_chat_message.h"
#include "chat_commands.h"
#include "pc/network/ban_list.h"
#include "pc/network/moderator_list.h"
#include "pc/debuglog.h"
#include "level_table.h"
enum ChatConfirmCommand {
CCC_NONE,
CCC_KICK,
CCC_BAN,
CCC_PERMBAN,
};
extern int gIsModerator;
static enum ChatConfirmCommand sConfirming = CCC_NONE;
static u8 sConfirmPlayerIndex = 0;
@ -49,27 +45,39 @@ bool exec_chat_command(char* command) {
sConfirming = CCC_NONE;
if (ccc != CCC_NONE && strcmp("/confirm", command) == 0) {
if (gNetworkType == NT_SERVER && ccc == CCC_KICK) {
if (gNetworkType == NT_SERVER || gIsModerator == 1) {
if (ccc == CCC_KICK) {
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
if (!np->connected) { return true; }
char message[256] = { 0 };
snprintf(message, 256, "\\#fff982\\Kicking '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name);
djui_chat_message_create(message);
if (gNetworkType == NT_SERVER) {
network_send_kick(np->localIndex, EKT_KICKED);
network_player_disconnected(np->localIndex);
} else {
network_send_chat_command(np->globalIndex, CCC_KICK);
}
return true;
}
if (gNetworkType == NT_SERVER && ccc == CCC_BAN) {
}
if (gNetworkType == NT_SERVER || gIsModerator == 1) {
if (ccc == CCC_BAN) {
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
if (!np->connected) { return true; }
char message[256] = { 0 };
snprintf(message, 256, "\\#fff982\\Banning '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name);
djui_chat_message_create(message);
if (gNetworkType == NT_SERVER) {
network_send_kick(np->localIndex, EKT_BANNED);
ban_list_add(gNetworkSystem->get_id_str(np->localIndex), false);
network_player_disconnected(np->localIndex);
} else {
network_send_chat_command(np->globalIndex, CCC_BAN);
}
return true;
}
}
if (gNetworkType == NT_SERVER && ccc == CCC_PERMBAN) {
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
if (!np->connected) { return true; }
@ -81,6 +89,16 @@ bool exec_chat_command(char* command) {
network_player_disconnected(np->localIndex);
return true;
}
if (gNetworkType == NT_SERVER && ccc == CCC_MODERATOR) {
struct NetworkPlayer* np = &gNetworkPlayers[sConfirmPlayerIndex];
if (!np->connected) { return true; }
char message[256] = { 0 };
snprintf(message, 256, "\\#fff982\\Adding '%s%s\\#fff982\\' as a Moderator!", network_get_player_text_color_string(np->localIndex), np->name);
djui_chat_message_create(message);
network_send_moderator(np->localIndex);
moderator_list_add(gNetworkSystem->get_id_str(np->localIndex), true);
return true;
}
}
if (strcmp("/players", command) == 0) {
@ -102,8 +120,8 @@ bool exec_chat_command(char* command) {
}
if (str_starts_with("/kick ", command)) {
if (gNetworkType != NT_SERVER) {
djui_chat_message_create("Only the server can use this command.");
if (gNetworkType != NT_SERVER && gIsModerator == 0) {
djui_chat_message_create("You do not have permission to use this command.");
return true;
}
@ -129,8 +147,8 @@ bool exec_chat_command(char* command) {
}
if (str_starts_with("/ban ", command)) {
if (gNetworkType != NT_SERVER) {
djui_chat_message_create("Only the server can use this command.");
if (gNetworkType != NT_SERVER && gIsModerator == 0) {
djui_chat_message_create("You do not have permission to use this command.");
return true;
}
@ -156,8 +174,8 @@ bool exec_chat_command(char* command) {
}
if (str_starts_with("/permban ", command)) {
if (gNetworkType != NT_SERVER) {
djui_chat_message_create("Only the server can use this command.");
if (gNetworkType != NT_SERVER && gIsModerator == 0) {
djui_chat_message_create("You do not have permission to use this command.");
return true;
}
@ -182,6 +200,32 @@ bool exec_chat_command(char* command) {
return true;
}
if (str_starts_with("/moderator ", command)) {
if (gNetworkType != NT_SERVER) {
djui_chat_message_create("Only the server can use this command.");
return true;
}
struct NetworkPlayer* np = chat_get_network_player(&command[11]);
if (np == NULL) {
djui_chat_message_create("Could not find player.");
return true;
}
if (np->localIndex == 0) {
djui_chat_message_create("Can not make yourself a moderator.");
return true;
}
char message[256] = { 0 };
snprintf(message, 256, "\\#fff982\\Are you sure you want to make '%s%s\\#fff982\\' a moderator?\nType '\\#a0ffa0\\/confirm\\#fff982\\' to moderate.", network_get_player_text_color_string(np->localIndex), np->name);
djui_chat_message_create(message);
sConfirming = CCC_MODERATOR;
sConfirmPlayerIndex = np->localIndex;
return true;
}
#if defined(DEBUG) && defined(DEVELOPMENT)
if (gNetworkSystem == &gNetworkSystemSocket && str_starts_with("/warp ", command)) {
static const struct { const char *name; s32 num; } sLevelNumByName[] = {
@ -269,10 +313,11 @@ bool exec_chat_command(char* command) {
void display_chat_commands(void) {
djui_chat_message_create("/players - List all players and their IDs");
if (gNetworkType == NT_SERVER) {
if (gNetworkType == NT_SERVER || gIsModerator == 1) {
djui_chat_message_create("/kick [NAME|ID] - Kick this player from the current game");
djui_chat_message_create("/ban [NAME|ID] - Ban this player from the current game");
djui_chat_message_create("/permban [NAME|ID] - Ban this player from any game you host");
djui_chat_message_create("/moderator [NAME|ID] - Make this player able to use commands like /kick, /ban, /permban on any game you host");
}
#if defined(DEBUG) && defined(DEVELOPMENT)
djui_chat_message_create("/warp [LEVEL] [AREA] [ACT] - Level can be either a numeric value or a shorthand name");

View file

@ -16,6 +16,8 @@
#include "pc/mods/mods.h"
#include "pc/network/ban_list.h"
#include "pc/crash_handler.h"
#include "pc/network/moderator_list.h"
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
@ -258,6 +260,19 @@ static void ban_write(FILE* file) {
}
}
static void moderator_read(char** tokens, UNUSED int numTokens) {
moderator_list_add(tokens[1], true);
}
static void moderator_write(FILE* file) {
for (unsigned int i = 0; i < gModeratorCount; i++) {
if (gModeratorAddresses == NULL) { break; }
if (gModeratorAddresses[i] == NULL) { continue; }
if (!gModerator[i]) { continue; }
fprintf(file, "%s %s\n", "moderator:", gModeratorAddresses[i]);
}
}
static void dynos_pack_read(char** tokens, int numTokens) {
if (numTokens < 3) { return; }
char fullPackName[256] = { 0 };
@ -290,6 +305,7 @@ static void dynos_pack_write(FILE* file) {
static const struct FunctionConfigOption functionOptions[] = {
{ .name = "enable-mod:", .read = enable_mod_read, .write = enable_mod_write },
{ .name = "ban:", .read = ban_read, .write = ban_write },
{ .name = "moderator:", .read = moderator_read, .write = moderator_write },
{ .name = "dynos-pack:", .read = dynos_pack_read, .write = dynos_pack_write },
};

View file

@ -0,0 +1,47 @@
#include <stdlib.h>
#include <string.h>
#include "PR/ultratypes.h"
#include "moderator_list.h"
#include "pc/debuglog.h"
char** gModeratorAddresses = NULL;
bool* gModerator = NULL;
u16 gModeratorCount = 0;
void moderator_list_add(char* address, bool perm) {
u16 index = gModeratorCount++;
if (gModeratorAddresses == NULL) {
gModeratorAddresses = malloc(sizeof(char*) * gModeratorCount);
gModerator = malloc(sizeof(bool) * gModeratorCount);
} else {
gModeratorAddresses = realloc(gModeratorAddresses, sizeof(char*) * gModeratorCount);
assert(gModeratorAddresses != NULL);
gModerator = realloc(gModerator, sizeof(bool) * gModeratorCount);
assert(gModerator != NULL);
}
if (gModeratorAddresses == NULL) {
LOG_ERROR("Failed to allocate gModeratorAddresses");
return;
}
if (gModerator == NULL) {
LOG_ERROR("Failed to allocate gModerator");
return;
}
gModeratorAddresses[index] = strdup(address);
gModerator[index] = perm;
}
bool moderator_list_contains(char* address) {
if (gModeratorAddresses == NULL || address == NULL) {
return false;
}
for (s32 i = 0; i < gModeratorCount; i++) {
if (gModeratorAddresses[i] == NULL) { continue; }
if (strcmp(address, gModeratorAddresses[i]) == 0) {
return true;
}
}
return false;
}

View file

@ -0,0 +1,13 @@
#ifndef MODERATOR_LIST_H
#define MODERATOR_LIST_H
#include <stdbool.h>
extern char** gModeratorAddresses;
extern bool* gModerator;
extern u16 gModeratorCount;
void moderator_list_add(char* address, bool perm);
bool moderator_list_contains(char* address);
#endif

View file

@ -192,7 +192,7 @@ void network_send_to(u8 localIndex, struct Packet* p) {
if (gNetworkSystem == NULL) { LOG_ERROR("no network system attached"); return; }
if (localIndex == 0 && !network_allow_unknown_local_index(p->buffer[0])) {
LOG_ERROR("\n####################\nsending to myself, packetType: %d\n####################\n", p->packetType);
SOFT_ASSERT(false);
// SOFT_ASSERT(false); - Crash?
return;
}

View file

@ -264,6 +264,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
smlua_call_event_hooks_mario_param(HOOK_ON_PLAYER_CONNECTED, &gMarioStates[localIndex]);
return localIndex;
}

View file

@ -51,6 +51,8 @@ void packet_process(struct Packet* p) {
case PACKET_JOIN: network_receive_join(p); break;
case PACKET_CHAT: network_receive_chat(p); break;
case PACKET_KICK: network_receive_kick(p); break;
case PACKET_COMMAND: network_recieve_chat_command(p); break;
case PACKET_MODERATOR: network_recieve_moderator(); break;
case PACKET_KEEP_ALIVE: network_receive_keep_alive(p); break;
case PACKET_LEAVING: network_receive_leaving(p); break;
case PACKET_SAVE_FILE: network_receive_save_file(p); break;

View file

@ -71,6 +71,9 @@ enum PacketType {
PACKET_LUA_CUSTOM,
PACKET_COMMAND,
PACKET_MODERATOR,
///
PACKET_CUSTOM = 255,
};
@ -113,6 +116,14 @@ enum KickReasonType {
EKT_BANNED,
};
enum ChatConfirmCommand {
CCC_NONE,
CCC_KICK,
CCC_BAN,
CCC_PERMBAN,
CCC_MODERATOR,
};
struct LSTNetworkType {
enum {
LST_NETWORK_TYPE_INTEGER,
@ -230,6 +241,14 @@ void network_receive_chat(struct Packet* p);
void network_send_kick(u8 localIndex, enum KickReasonType kickReason);
void network_receive_kick(struct Packet* p);
// packet_command_mod.c
void network_send_chat_command(u8 localIndex, enum ChatConfirmCommand CCC);
void network_recieve_chat_command(struct Packet* p);
// packet_moderator.c
void network_send_moderator(u8 localIndex);
void network_recieve_moderator(void);
// packet_keep_alive.c
void network_send_keep_alive(u8 localIndex);
void network_receive_keep_alive(struct Packet* p);

View file

@ -0,0 +1,61 @@
#include <stdio.h>
#include "../network.h"
#include "pc/djui/djui_chat_message.h"
#include "pc/network/ban_list.h"
#include "pc/network/moderator_list.h"
int gIsModerator;
void network_send_chat_command(u8 globalIndex, enum ChatConfirmCommand ccc) {
if (gIsModerator == 1) {
u8 cccType = ccc;
struct Packet p = { 0 };
packet_init(&p, PACKET_COMMAND, false, PLMT_NONE);
packet_write(&p, &globalIndex, sizeof(u8));
packet_write(&p, &cccType, sizeof(u8));
network_send_to(gNetworkPlayerServer->localIndex, &p);
}
}
void network_recieve_chat_command(struct Packet* p) {
if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) {
return;
}
enum ChatConfirmCommand CCC;
u8 player;
packet_read(p, &player, sizeof(u8));
packet_read(p, &CCC, sizeof(u8));
if (gNetworkType == NT_SERVER && CCC == CCC_KICK) {
struct NetworkPlayer* np = &gNetworkPlayers[player];
if (!np->connected) { return; }
network_send_kick(np->localIndex, EKT_KICKED);
network_player_disconnected(np->localIndex);
char message[256] = { 0 };
snprintf(message, 256, "\\#fff982\\Kicked '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name);
djui_chat_message_create(message);
}
if (gNetworkType == NT_SERVER && CCC == CCC_BAN) {
struct NetworkPlayer* np = &gNetworkPlayers[player];
if (!np->connected) { return; }
network_send_kick(np->localIndex, EKT_BANNED);
ban_list_add(gNetworkSystem->get_id_str(np->localIndex), false);
network_player_disconnected(np->localIndex);
char message[256] = { 0 };
snprintf(message, 256, "\\#fff982\\Banned '%s%s\\#fff982\\'!", network_get_player_text_color_string(np->localIndex), np->name);
djui_chat_message_create(message);
}
}
void network_send_moderator(u8 localIndex) {
struct Packet p = { 0 };
packet_init(&p, PACKET_MODERATOR, false, PLMT_NONE);
network_send_to(localIndex, &p);
}
void network_recieve_moderator(void) {
if (gIsModerator == 1) {
return;
}
gIsModerator = 1;
djui_chat_message_create("\\#fff982\\You are now a Moderator.");
}

View file

@ -5,6 +5,7 @@
#include "src/game/behavior_actions.h"
#include "pc/debuglog.h"
#include "pc/configfile.h"
#include "pc/network/moderator_list.h"
static void network_send_to_network_players(u8 sendToLocalIndex) {
SOFT_ASSERT(gNetworkType == NT_SERVER);
@ -57,6 +58,11 @@ void network_receive_network_players_request(struct Packet* p) {
return;
}
network_send_to_network_players(localIndex);
if (moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) {
LOG_INFO("sending moderator packet to localIndex: %d", p->localIndex);
network_send_moderator(p->localIndex);
}
}
void network_send_network_players(u8 exceptLocalIndex) {