mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 21:45:12 +00:00
Merge branch 'unstable' into coop
This commit is contained in:
commit
367f672af7
10 changed files with 243 additions and 33 deletions
|
@ -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");
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
|
47
src/pc/network/moderator_list.c
Normal file
47
src/pc/network/moderator_list.c
Normal 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;
|
||||
}
|
13
src/pc/network/moderator_list.h
Normal file
13
src/pc/network/moderator_list.h
Normal 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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
61
src/pc/network/packets/packet_command_mod.c
Normal file
61
src/pc/network/packets/packet_command_mod.c
Normal 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.");
|
||||
}
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue