mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 21:40:05 +00:00
added basic command handler
This commit is contained in:
parent
f82d203377
commit
f5939353b1
@ -3,22 +3,79 @@
|
|||||||
#include "ChatManager.hpp"
|
#include "ChatManager.hpp"
|
||||||
#include "PlayerManager.hpp"
|
#include "PlayerManager.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
std::map<std::string, ChatCommand> ChatManager::commands;
|
||||||
|
|
||||||
|
std::vector<std::string> parseArgs(std::string full) {
|
||||||
|
std::stringstream ss(full);
|
||||||
|
std::istream_iterator<std::string> begin(ss);
|
||||||
|
std::istream_iterator<std::string> end;
|
||||||
|
return std::vector<std::string>(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runCmd(std::string full, std::vector<std::string> args, CNSocket* sock) {
|
||||||
|
std::string cmd = args[0].substr(1, args[0].size() - 1);
|
||||||
|
|
||||||
|
if (ChatManager::commands.find(cmd) != ChatManager::commands.end()) {
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
ChatCommand command = ChatManager::commands[cmd];
|
||||||
|
|
||||||
|
if (plr != nullptr && plr->accountLevel <= command.requiredAccLevel) {
|
||||||
|
command.handlr(full, args, sock);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
ChatManager::sendServerMessage(sock, "You don't have access to that command!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatManager::sendServerMessage(sock, "Unknown command!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void testCommand(std::string full, std::vector<std::string> args, CNSocket* sock) {
|
||||||
|
ChatManager::sendServerMessage(sock, "Test command is working!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void accessCommand(std::string full, std::vector<std::string> args, CNSocket* sock) {
|
||||||
|
ChatManager::sendServerMessage(sock, "Your access level is " + std::to_string(PlayerManager::getPlayer(sock)->accountLevel));
|
||||||
|
}
|
||||||
|
|
||||||
void ChatManager::init() {
|
void ChatManager::init() {
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_FREECHAT_MESSAGE, chatHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_FREECHAT_MESSAGE, chatHandler);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_MENUCHAT_MESSAGE, menuChatHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_MENUCHAT_MESSAGE, menuChatHandler);
|
||||||
|
|
||||||
|
registerCommand("test", 1, testCommand);
|
||||||
|
registerCommand("access", 100, accessCommand);
|
||||||
|
// TODO: add help command
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatManager::registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr) {
|
||||||
|
commands[cmd] = ChatCommand(requiredLevel, handlr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatManager::chatHandler(CNSocket* sock, CNPacketData* data) {
|
void ChatManager::chatHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE))
|
if (data->size != sizeof(sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE))
|
||||||
return; // malformed packet
|
return; // malformed packet
|
||||||
|
|
||||||
sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE* chat = (sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE*)data->buf;
|
sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE* chat = (sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE*)data->buf;
|
||||||
PlayerView& plr = PlayerManager::players[sock];
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
std::string fullChat = U16toU8(chat->szFreeChat);
|
||||||
|
std::vector<std::string> args = parseArgs(fullChat);
|
||||||
|
|
||||||
|
if (args.size() > 0 && args[0][0] == CMD_PREFIX) { // PREFIX
|
||||||
|
runCmd(fullChat, args, sock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// send to client
|
// send to client
|
||||||
INITSTRUCT(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, resp);
|
||||||
memcpy(resp.szFreeChat, chat->szFreeChat, sizeof(chat->szFreeChat));
|
memcpy(resp.szFreeChat, chat->szFreeChat, sizeof(chat->szFreeChat));
|
||||||
resp.iPC_ID = plr.plr->iID;
|
resp.iPC_ID = plr->iID;
|
||||||
resp.iEmoteCode = chat->iEmoteCode;
|
resp.iEmoteCode = chat->iEmoteCode;
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC));
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC));
|
||||||
|
|
||||||
@ -49,14 +106,25 @@ void ChatManager::emoteHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
// you can dance with friends!!!!!!!!
|
// you can dance with friends!!!!!!!!
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT* emote = (sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT*)data->buf;
|
sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT* emote = (sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT*)data->buf;
|
||||||
PlayerView& plr = PlayerManager::players[sock];
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
// send to client
|
// send to client
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_AVATAR_EMOTES_CHAT, resp);
|
INITSTRUCT(sP_FE2CL_REP_PC_AVATAR_EMOTES_CHAT, resp);
|
||||||
resp.iEmoteCode = emote->iEmoteCode;
|
resp.iEmoteCode = emote->iEmoteCode;
|
||||||
resp.iID_From = plr.plr->iID;
|
resp.iID_From = plr->iID;
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_AVATAR_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_AVATAR_EMOTES_CHAT));
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_AVATAR_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_AVATAR_EMOTES_CHAT));
|
||||||
|
|
||||||
// send to visible players (players within render distance)
|
// send to visible players (players within render distance)
|
||||||
PlayerManager::sendToViewable(sock, (void*)&resp, P_FE2CL_REP_PC_AVATAR_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_AVATAR_EMOTES_CHAT));
|
PlayerManager::sendToViewable(sock, (void*)&resp, P_FE2CL_REP_PC_AVATAR_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_AVATAR_EMOTES_CHAT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatManager::sendServerMessage(CNSocket* sock, std::string msg) {
|
||||||
|
INITSTRUCT(sP_FE2CL_PC_MOTD_LOGIN, motd);
|
||||||
|
|
||||||
|
motd.iType = 1;
|
||||||
|
// convert string to u16 and write it to the buffer (TODO: add sanity check to prevent buffer overflow)
|
||||||
|
U8toU16(msg, (char16_t*)motd.szSystemMsg);
|
||||||
|
|
||||||
|
// send the packet :)
|
||||||
|
sock->sendPacket((void*)&motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN));
|
||||||
|
}
|
||||||
|
@ -2,10 +2,26 @@
|
|||||||
|
|
||||||
#include "CNShardServer.hpp"
|
#include "CNShardServer.hpp"
|
||||||
|
|
||||||
|
#define CMD_PREFIX '/'
|
||||||
|
|
||||||
|
typedef void (*CommandHandler)(std::string fullString, std::vector<std::string> args, CNSocket* sock);
|
||||||
|
|
||||||
|
struct ChatCommand {
|
||||||
|
int requiredAccLevel;
|
||||||
|
CommandHandler handlr;
|
||||||
|
|
||||||
|
ChatCommand(int r, CommandHandler h): requiredAccLevel(r), handlr(h) {}
|
||||||
|
ChatCommand(): ChatCommand(0, nullptr) {}
|
||||||
|
};
|
||||||
|
|
||||||
namespace ChatManager {
|
namespace ChatManager {
|
||||||
|
extern std::map<std::string, ChatCommand> commands;
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
void registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr);
|
||||||
|
|
||||||
void chatHandler(CNSocket* sock, CNPacketData* data);
|
void chatHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void emoteHandler(CNSocket* sock, CNPacketData* data);
|
void emoteHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void menuChatHandler(CNSocket* sock, CNPacketData* data);
|
void menuChatHandler(CNSocket* sock, CNPacketData* data);
|
||||||
|
void sendServerMessage(CNSocket* sock, std::string msg); // uses MOTD
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "CNShared.hpp"
|
#include "CNShared.hpp"
|
||||||
#include "MissionManager.hpp"
|
#include "MissionManager.hpp"
|
||||||
#include "ItemManager.hpp"
|
#include "ItemManager.hpp"
|
||||||
|
#include "ChatManager.hpp"
|
||||||
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
@ -217,7 +218,6 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
sP_CL2FE_REQ_PC_ENTER* enter = (sP_CL2FE_REQ_PC_ENTER*)data->buf;
|
sP_CL2FE_REQ_PC_ENTER* enter = (sP_CL2FE_REQ_PC_ENTER*)data->buf;
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_ENTER_SUCC, response);
|
INITSTRUCT(sP_FE2CL_REP_PC_ENTER_SUCC, response);
|
||||||
INITSTRUCT(sP_FE2CL_PC_MOTD_LOGIN, motd);
|
|
||||||
|
|
||||||
// TODO: check if serialkey exists, if it doesn't send sP_FE2CL_REP_PC_ENTER_FAIL
|
// TODO: check if serialkey exists, if it doesn't send sP_FE2CL_REP_PC_ENTER_FAIL
|
||||||
Player plr = CNSharedData::getPlayer(enter->iEnterSerialKey);
|
Player plr = CNSharedData::getPlayer(enter->iEnterSerialKey);
|
||||||
@ -311,9 +311,6 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
plr.SerialKey = enter->iEnterSerialKey;
|
plr.SerialKey = enter->iEnterSerialKey;
|
||||||
plr.instanceID = INSTANCE_OVERWORLD; // TODO: load this from the database (as long as it's not a unique instance)
|
plr.instanceID = INSTANCE_OVERWORLD; // TODO: load this from the database (as long as it's not a unique instance)
|
||||||
|
|
||||||
motd.iType = 1;
|
|
||||||
U8toU16(settings::MOTDSTRING, (char16_t*)motd.szSystemMsg);
|
|
||||||
|
|
||||||
sock->setEKey(CNSocketEncryption::createNewKey(response.uiSvrTime, response.iID + 1, response.PCLoadData2CL.iFusionMatter + 1));
|
sock->setEKey(CNSocketEncryption::createNewKey(response.uiSvrTime, response.iID + 1, response.PCLoadData2CL.iFusionMatter + 1));
|
||||||
sock->setFEKey(plr.FEKey);
|
sock->setFEKey(plr.FEKey);
|
||||||
sock->setActiveKey(SOCKETKEY_FE); // send all packets using the FE key from now on
|
sock->setActiveKey(SOCKETKEY_FE); // send all packets using the FE key from now on
|
||||||
@ -321,7 +318,7 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ENTER_SUCC, sizeof(sP_FE2CL_REP_PC_ENTER_SUCC));
|
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ENTER_SUCC, sizeof(sP_FE2CL_REP_PC_ENTER_SUCC));
|
||||||
|
|
||||||
// transmit MOTD after entering the game, so the client hopefully changes modes on time
|
// transmit MOTD after entering the game, so the client hopefully changes modes on time
|
||||||
sock->sendPacket((void*)&motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN));
|
ChatManager::sendServerMessage(sock, settings::MOTDSTRING);
|
||||||
|
|
||||||
addPlayer(sock, plr);
|
addPlayer(sock, plr);
|
||||||
//check if there is an expiring vehicle
|
//check if there is an expiring vehicle
|
||||||
|
Loading…
Reference in New Issue
Block a user