mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 13:30:06 +00:00
Implement most of the remaining client-side GM commands
* Muting a player's freechat * Kicking players * Querying info about a player * Teleporting yourself to a player * Teleporting a player to yourself * Teleporting a player to another player * Teleporting a player to arbitrary coords * Teleporting a player to arbitrary coords in an arbitrary mapnum * /unstick Also: * Renamed misleading setSpecialPlayer() to setValuePlayer() * Revamped monitor logic * Added server-side checks to account level 50 commands * Made sure even trade chat is run through sanitizeText() * Moved setSpecialState() closer to its calling functions * Interpret client commands even in Buddy and Group chat (but not in Trade chat)
This commit is contained in:
parent
c78b3ca69f
commit
a12acbb68f
@ -138,28 +138,20 @@ void BuddyManager::reqBuddyByName(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC, resp);
|
||||||
|
|
||||||
CNSocket* otherSock = nullptr;
|
CNSocket* otherSock = PlayerManager::getSockFromName(U16toU8(pkt->szFirstName), U16toU8(pkt->szLastName));
|
||||||
|
|
||||||
for (auto& pair : PlayerManager::players) {
|
|
||||||
Player* plr = pair.second;
|
|
||||||
if (strcmp(U16toU8(plr->PCStyle.szFirstName).c_str(), U16toU8(pkt->szFirstName).c_str()) == 0
|
|
||||||
&& strcmp(U16toU8(plr->PCStyle.szLastName).c_str(), U16toU8(pkt->szLastName).c_str()) == 0
|
|
||||||
&& !playerHasBuddyWithID(plrReq, plr->iID)) {
|
|
||||||
otherSock = pair.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (otherSock == nullptr)
|
if (otherSock == nullptr)
|
||||||
return; // no player found
|
return; // no player found
|
||||||
|
|
||||||
|
Player *otherPlr = PlayerManager::getPlayer(otherSock);
|
||||||
|
if (playerHasBuddyWithID(plrReq, otherPlr->iID))
|
||||||
|
return;
|
||||||
|
|
||||||
resp.iPCUID = plrReq->PCStyle.iPC_UID;
|
resp.iPCUID = plrReq->PCStyle.iPC_UID;
|
||||||
resp.iNameCheckFlag = plrReq->PCStyle.iNameCheck;
|
resp.iNameCheckFlag = plrReq->PCStyle.iNameCheck;
|
||||||
|
|
||||||
memcpy(resp.szFirstName, plrReq->PCStyle.szFirstName, sizeof(plrReq->PCStyle.szFirstName));
|
memcpy(resp.szFirstName, plrReq->PCStyle.szFirstName, sizeof(plrReq->PCStyle.szFirstName));
|
||||||
memcpy(resp.szLastName, plrReq->PCStyle.szLastName, sizeof(plrReq->PCStyle.szLastName));
|
memcpy(resp.szLastName, plrReq->PCStyle.szLastName, sizeof(plrReq->PCStyle.szLastName));
|
||||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC, sizeof(sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC));
|
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC, sizeof(sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accepting buddy request
|
// Accepting buddy request
|
||||||
@ -317,11 +309,26 @@ void BuddyManager::reqBuddyFreechat(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (otherSock == nullptr)
|
if (otherSock == nullptr)
|
||||||
return; // buddy offline
|
return; // buddy offline
|
||||||
|
|
||||||
|
Player *otherPlr = PlayerManager::getPlayer(otherSock);
|
||||||
|
|
||||||
resp.iFromPCUID = plr->PCStyle.iPC_UID;
|
resp.iFromPCUID = plr->PCStyle.iPC_UID;
|
||||||
resp.iToPCUID = pkt->iBuddyPCUID;
|
resp.iToPCUID = pkt->iBuddyPCUID;
|
||||||
resp.iEmoteCode = pkt->iEmoteCode;
|
resp.iEmoteCode = pkt->iEmoteCode;
|
||||||
|
|
||||||
std::string fullChat = ChatManager::sanitizeText(U16toU8(pkt->szFreeChat));
|
std::string fullChat = ChatManager::sanitizeText(U16toU8(pkt->szFreeChat));
|
||||||
|
|
||||||
|
if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX
|
||||||
|
ChatManager::runCmd(fullChat, sock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__MUTE_FREECHAT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string logLine = "[BuddyChat] " + PlayerManager::getPlayerName(plr) + " (to " + PlayerManager::getPlayerName(otherPlr) + "): " + fullChat;
|
||||||
|
std::cout << logLine << std::endl;
|
||||||
|
ChatManager::dump.push_back(logLine);
|
||||||
|
|
||||||
U8toU16(fullChat, (char16_t*)&resp.szFreeChat, sizeof(resp.szFreeChat));
|
U8toU16(fullChat, (char16_t*)&resp.szFreeChat, sizeof(resp.szFreeChat));
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC)); // confirm send to sender
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC)); // confirm send to sender
|
||||||
@ -343,11 +350,18 @@ void BuddyManager::reqBuddyMenuchat(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (otherSock == nullptr)
|
if (otherSock == nullptr)
|
||||||
return; // buddy offline
|
return; // buddy offline
|
||||||
|
|
||||||
|
Player *otherPlr = PlayerManager::getPlayer(otherSock);
|
||||||
|
|
||||||
resp.iFromPCUID = plr->PCStyle.iPC_UID;
|
resp.iFromPCUID = plr->PCStyle.iPC_UID;
|
||||||
resp.iToPCUID = pkt->iBuddyPCUID;
|
resp.iToPCUID = pkt->iBuddyPCUID;
|
||||||
resp.iEmoteCode = pkt->iEmoteCode;
|
resp.iEmoteCode = pkt->iEmoteCode;
|
||||||
|
|
||||||
std::string fullChat = ChatManager::sanitizeText(U16toU8(pkt->szFreeChat));
|
std::string fullChat = ChatManager::sanitizeText(U16toU8(pkt->szFreeChat));
|
||||||
|
std::string logLine = "[BuddyMenuChat] " + PlayerManager::getPlayerName(plr) + " (to " + PlayerManager::getPlayerName(otherPlr) + "): " + fullChat;
|
||||||
|
|
||||||
|
std::cout << logLine << std::endl;
|
||||||
|
ChatManager::dump.push_back(logLine);
|
||||||
|
|
||||||
U8toU16(fullChat, (char16_t*)&resp.szFreeChat, sizeof(resp.szFreeChat));
|
U8toU16(fullChat, (char16_t*)&resp.szFreeChat, sizeof(resp.szFreeChat));
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC)); // confirm send to sender
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC)); // confirm send to sender
|
||||||
|
@ -214,7 +214,7 @@ void CNLoginServer::login(CNSocket* sock, CNPacketData* data) {
|
|||||||
sock->sendPacket((void*)&*it, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
|
sock->sendPacket((void*)&*it, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
|
||||||
|
|
||||||
DEBUGLOG(
|
DEBUGLOG(
|
||||||
std::string message = "Login Server: Loaded " + std::to_string(resp.iCharCount) + "character";
|
std::string message = "Login Server: Loaded " + std::to_string(resp.iCharCount) + " character";
|
||||||
if ((int)resp.iCharCount > 1)
|
if ((int)resp.iCharCount > 1)
|
||||||
message += "s";
|
message += "s";
|
||||||
std::cout << message << std::endl;
|
std::cout << message << std::endl;
|
||||||
|
@ -24,7 +24,7 @@ std::vector<std::string> parseArgs(std::string full) {
|
|||||||
return std::vector<std::string>(begin, end);
|
return std::vector<std::string>(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runCmd(std::string full, CNSocket* sock) {
|
bool ChatManager::runCmd(std::string full, CNSocket* sock) {
|
||||||
std::vector<std::string> args = parseArgs(full);
|
std::vector<std::string> args = parseArgs(full);
|
||||||
std::string cmd = args[0].substr(1, args[0].size() - 1);
|
std::string cmd = args[0].substr(1, args[0].size() - 1);
|
||||||
|
|
||||||
@ -851,15 +851,19 @@ void ChatManager::chatHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat));
|
std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat));
|
||||||
|
|
||||||
std::cout << "[FreeChat] " << PlayerManager::getPlayerName(plr, false) << ": " << fullChat << std::endl;
|
|
||||||
dump.push_back(PlayerManager::getPlayerName(plr, true) + ": " + fullChat);
|
|
||||||
|
|
||||||
if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX
|
if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX
|
||||||
runCmd(fullChat, sock);
|
runCmd(fullChat, sock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__MUTE_FREECHAT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string logLine = "[FreeChat] " + PlayerManager::getPlayerName(plr, true) + ": " + fullChat;
|
||||||
|
|
||||||
|
std::cout << logLine << std::endl;
|
||||||
|
dump.push_back(logLine);
|
||||||
|
|
||||||
// send to client
|
// send to client
|
||||||
INITSTRUCT(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, resp);
|
||||||
|
|
||||||
@ -881,9 +885,10 @@ void ChatManager::menuChatHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
Player *plr = PlayerManager::getPlayer(sock);
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat));
|
std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat));
|
||||||
|
std::string logLine = "[MenuChat] " + PlayerManager::getPlayerName(plr, true) + ": " + fullChat;
|
||||||
|
|
||||||
std::cout << "[MenuChat] " << PlayerManager::getPlayerName(plr, false) << ": " << fullChat << std::endl;
|
std::cout << logLine << std::endl;
|
||||||
dump.push_back(PlayerManager::getPlayerName(plr, true) + ": " + fullChat);
|
dump.push_back(logLine);
|
||||||
|
|
||||||
// send to client
|
// send to client
|
||||||
INITSTRUCT(sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC, resp);
|
||||||
@ -959,9 +964,10 @@ void ChatManager::announcementHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[Bcast " << announcement->iAreaType << "] " << PlayerManager::getPlayerName(plr, false) << ": " << U16toU8(msg.szAnnounceMsg) << std::endl;
|
std::string logLine = "[Bcast " + std::to_string(announcement->iAreaType) + "] " + PlayerManager::getPlayerName(plr, false) + ": " + U16toU8(msg.szAnnounceMsg);
|
||||||
dump.push_back("**" + PlayerManager::getPlayerName(plr, true) + ": " + U16toU8(msg.szAnnounceMsg) + "**");
|
std::cout << logLine << std::endl;
|
||||||
|
dump.push_back("**" + logLine + "**");
|
||||||
}
|
}
|
||||||
|
|
||||||
// we only allow plain ascii, at least for now
|
// we only allow plain ascii, at least for now
|
||||||
|
@ -21,6 +21,7 @@ namespace ChatManager {
|
|||||||
extern std::vector<std::string> dump;
|
extern std::vector<std::string> dump;
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
bool runCmd(std::string full, CNSocket* sock);
|
||||||
void registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr, std::string help = "");
|
void registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr, std::string help = "");
|
||||||
|
|
||||||
void chatHandler(CNSocket* sock, CNPacketData* data);
|
void chatHandler(CNSocket* sock, CNPacketData* data);
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
/* enum definitions from the client */
|
/* enum definitions from the client */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: It might be a good idea to make this file build-specific, but
|
|
||||||
* I'm pretty sure there were seldom any new packets added, and they're
|
|
||||||
* probably always going to be the non-essential things that we won't be
|
|
||||||
* implementing just yet anyway.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// floats
|
// floats
|
||||||
const float VALUE_BATTERY_EMPTY_PENALTY = 0.5f;
|
const float VALUE_BATTERY_EMPTY_PENALTY = 0.5f;
|
||||||
const float CN_EP_RANK_1 = 0.8f;
|
const float CN_EP_RANK_1 = 0.8f;
|
||||||
@ -16,6 +9,21 @@ const float CN_EP_RANK_3 = 0.5f;
|
|||||||
const float CN_EP_RANK_4 = 0.3f;
|
const float CN_EP_RANK_4 = 0.3f;
|
||||||
const float CN_EP_RANK_5 = 0.29f;
|
const float CN_EP_RANK_5 = 0.29f;
|
||||||
|
|
||||||
|
// methods of finding players for GM commands
|
||||||
|
enum eCN_GM_TargetSearchBy {
|
||||||
|
eCN_GM_TargetSearchBy__PC_ID, // player id
|
||||||
|
eCN_GM_TargetSearchBy__PC_Name, // firstname, lastname
|
||||||
|
eCN_GM_TargetSearchBy__PC_UID // account id
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eCN_GM_TeleportType {
|
||||||
|
eCN_GM_TeleportMapType__XYZ,
|
||||||
|
eCN_GM_TeleportMapType__MapXYZ,
|
||||||
|
eCN_GM_TeleportMapType__MyLocation,
|
||||||
|
eCN_GM_TeleportMapType__SomeoneLocation,
|
||||||
|
eCN_GM_TeleportMapType__Unstick
|
||||||
|
};
|
||||||
|
|
||||||
// NPC classes
|
// NPC classes
|
||||||
enum NPCClass {
|
enum NPCClass {
|
||||||
NPC_BASE = 0,
|
NPC_BASE = 0,
|
||||||
|
@ -172,6 +172,18 @@ void GroupManager::chatGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
std::string fullChat = ChatManager::sanitizeText(U16toU8(chat->szFreeChat));
|
std::string fullChat = ChatManager::sanitizeText(U16toU8(chat->szFreeChat));
|
||||||
|
|
||||||
|
if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX
|
||||||
|
ChatManager::runCmd(fullChat, sock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__MUTE_FREECHAT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string logLine = "[GroupChat] " + PlayerManager::getPlayerName(plr, true) + ": " + fullChat;
|
||||||
|
std::cout << logLine << std::endl;
|
||||||
|
ChatManager::dump.push_back(logLine);
|
||||||
|
|
||||||
// send to client
|
// send to client
|
||||||
INITSTRUCT(sP_FE2CL_REP_SEND_ALL_GROUP_FREECHAT_MESSAGE_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_SEND_ALL_GROUP_FREECHAT_MESSAGE_SUCC, resp);
|
||||||
|
|
||||||
@ -194,6 +206,10 @@ void GroupManager::menuChatGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
std::string fullChat = ChatManager::sanitizeText(U16toU8(chat->szFreeChat));
|
std::string fullChat = ChatManager::sanitizeText(U16toU8(chat->szFreeChat));
|
||||||
|
std::string logLine = "[GroupMenuChat] " + PlayerManager::getPlayerName(plr, true) + ": " + fullChat;
|
||||||
|
|
||||||
|
std::cout << logLine << std::endl;
|
||||||
|
ChatManager::dump.push_back(logLine);
|
||||||
|
|
||||||
// send to client
|
// send to client
|
||||||
INITSTRUCT(sP_FE2CL_REP_SEND_ALL_GROUP_MENUCHAT_MESSAGE_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_SEND_ALL_GROUP_MENUCHAT_MESSAGE_SUCC, resp);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "NanoManager.hpp"
|
#include "NanoManager.hpp"
|
||||||
#include "NPCManager.hpp"
|
#include "NPCManager.hpp"
|
||||||
#include "Player.hpp"
|
#include "Player.hpp"
|
||||||
|
#include "ChatManager.hpp"
|
||||||
|
|
||||||
#include <string.h> // for memset()
|
#include <string.h> // for memset()
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -808,30 +809,34 @@ void ItemManager::itemTradeChatHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT* pacdat = (sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT*)data->buf;
|
sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT* pacdat = (sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT*)data->buf;
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT, resp);
|
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT, resp);
|
||||||
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
resp.iID_Request = pacdat->iID_Request;
|
resp.iID_Request = pacdat->iID_Request;
|
||||||
resp.iID_From = pacdat->iID_From;
|
resp.iID_From = pacdat->iID_From;
|
||||||
resp.iID_To = pacdat->iID_To;
|
resp.iID_To = pacdat->iID_To;
|
||||||
|
|
||||||
memcpy(resp.szFreeChat, pacdat->szFreeChat, sizeof(pacdat->szFreeChat));
|
std::string fullChat = ChatManager::sanitizeText(U16toU8(pacdat->szFreeChat));
|
||||||
|
U8toU16(fullChat, resp.szFreeChat, sizeof(resp.szFreeChat));
|
||||||
resp.iEmoteCode = pacdat->iEmoteCode;
|
|
||||||
|
|
||||||
int iID_Check;
|
int iID_Check;
|
||||||
|
|
||||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||||
iID_Check = pacdat->iID_To;
|
iID_Check = pacdat->iID_To;
|
||||||
} else {
|
} else {
|
||||||
iID_Check = pacdat->iID_From;
|
iID_Check = pacdat->iID_From;
|
||||||
}
|
}
|
||||||
|
|
||||||
CNSocket* otherSock = sock;
|
CNSocket* otherSock = PlayerManager::getSockFromID(iID_Check);;
|
||||||
|
if (otherSock == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto pair : PlayerManager::players) {
|
Player *otherPlr = PlayerManager::getPlayer(otherSock);
|
||||||
if (pair.second->iID == iID_Check) {
|
|
||||||
otherSock = pair.first;
|
std::string logLine = "[TradeChat] " + PlayerManager::getPlayerName(plr) + " (to " + PlayerManager::getPlayerName(otherPlr) + "): " + fullChat;
|
||||||
}
|
|
||||||
}
|
std::cout << logLine << std::endl;
|
||||||
|
ChatManager::dump.push_back(logLine);
|
||||||
|
|
||||||
|
resp.iEmoteCode = pacdat->iEmoteCode;
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT));
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT));
|
||||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT));
|
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT));
|
||||||
|
@ -37,16 +37,21 @@ void PlayerManager::init() {
|
|||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_MOVETRANSPORTATION, moveSliderPlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_MOVETRANSPORTATION, moveSliderPlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SLOPE, moveSlopePlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SLOPE, moveSlopePlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GOTO, gotoPlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GOTO, gotoPlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SET_VALUE, setSpecialPlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SET_VALUE, setValuePlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REP_LIVE_CHECK, heartbeatPlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REP_LIVE_CHECK, heartbeatPlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_REGEN, revivePlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_REGEN, revivePlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EXIT, exitGame);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EXIT, exitGame);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH, setSpecialSwitchPlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH, setSpecialSwitchPlayer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH, setGMSpecialSwitchPlayer);
|
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH, setGMSpecialSwitchPlayer);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF, setGMSpecialOnOff);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_ON, enterPlayerVehicle);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_ON, enterPlayerVehicle);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_OFF, exitPlayerVehicle);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_OFF, exitPlayerVehicle);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_CHANGE_MENTOR, changePlayerGuide);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_CHANGE_MENTOR, changePlayerGuide);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_FIRST_USE_FLAG_SET, setFirstUseFlag);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_FIRST_USE_FLAG_SET, setFirstUseFlag);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_LOCATION, locatePlayer);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_KICK_PLAYER, kickPlayer);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_TO_PC, warpToPlayer);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_TARGET_PC_TELEPORT, teleportPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::addPlayer(CNSocket* key, Player plr) {
|
void PlayerManager::addPlayer(CNSocket* key, Player plr) {
|
||||||
@ -664,6 +669,10 @@ void PlayerManager::gotoPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_GOTO))
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_GOTO))
|
||||||
return; // ignore the malformed packet
|
return; // ignore the malformed packet
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
if (plr->accountLevel > 50)
|
||||||
|
return;
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_GOTO* gotoData = (sP_CL2FE_REQ_PC_GOTO*)data->buf;
|
sP_CL2FE_REQ_PC_GOTO* gotoData = (sP_CL2FE_REQ_PC_GOTO*)data->buf;
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, response);
|
INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, response);
|
||||||
|
|
||||||
@ -677,12 +686,15 @@ void PlayerManager::gotoPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
sendPlayerTo(sock, gotoData->iToX, gotoData->iToY, gotoData->iToZ, INSTANCE_OVERWORLD);
|
sendPlayerTo(sock, gotoData->iToX, gotoData->iToY, gotoData->iToZ, INSTANCE_OVERWORLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::setSpecialPlayer(CNSocket* sock, CNPacketData* data) {
|
void PlayerManager::setValuePlayer(CNSocket* sock, CNPacketData* data) {
|
||||||
if (data->size != sizeof(sP_CL2FE_GM_REQ_PC_SET_VALUE))
|
if (data->size != sizeof(sP_CL2FE_GM_REQ_PC_SET_VALUE))
|
||||||
return; // ignore the malformed packet
|
return; // ignore the malformed packet
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
if (plr->accountLevel > 50)
|
||||||
|
return;
|
||||||
|
|
||||||
sP_CL2FE_GM_REQ_PC_SET_VALUE* setData = (sP_CL2FE_GM_REQ_PC_SET_VALUE*)data->buf;
|
sP_CL2FE_GM_REQ_PC_SET_VALUE* setData = (sP_CL2FE_GM_REQ_PC_SET_VALUE*)data->buf;
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_GM_REP_PC_SET_VALUE, response);
|
INITSTRUCT(sP_FE2CL_GM_REP_PC_SET_VALUE, response);
|
||||||
|
|
||||||
@ -897,6 +909,29 @@ void PlayerManager::setGMSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data)
|
|||||||
setSpecialState(sock, data);
|
setSpecialState(sock, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerManager::setSpecialState(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH))
|
||||||
|
return; // ignore the malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH* setData = (sP_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH*)data->buf;
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
|
// HACK: work around the invisible weapon bug
|
||||||
|
if (setData->iSpecialStateFlag == CN_SPECIAL_STATE_FLAG__FULL_UI)
|
||||||
|
ItemManager::updateEquips(sock, plr);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_PC_SPECIAL_STATE_CHANGE, response);
|
||||||
|
|
||||||
|
plr->iSpecialState ^= setData->iSpecialStateFlag;
|
||||||
|
|
||||||
|
response.iPC_ID = setData->iPC_ID;
|
||||||
|
response.iReqSpecialStateFlag = setData->iSpecialStateFlag;
|
||||||
|
response.iSpecialState = plr->iSpecialState;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC, sizeof(sP_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC));
|
||||||
|
sendToViewable(sock, (void*)&response, P_FE2CL_PC_SPECIAL_STATE_CHANGE, sizeof(sP_FE2CL_PC_SPECIAL_STATE_CHANGE));
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerManager::changePlayerGuide(CNSocket *sock, CNPacketData *data) {
|
void PlayerManager::changePlayerGuide(CNSocket *sock, CNPacketData *data) {
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_CHANGE_MENTOR))
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_CHANGE_MENTOR))
|
||||||
return;
|
return;
|
||||||
@ -945,6 +980,186 @@ void PlayerManager::setFirstUseFlag(CNSocket* sock, CNPacketData* data) {
|
|||||||
plr->iFirstUseFlag[1] |= (1ULL << (flag->iFlagCode - 65));
|
plr->iFirstUseFlag[1] |= (1ULL << (flag->iFlagCode - 65));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerManager::setGMSpecialOnOff(CNSocket *sock, CNPacketData *data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF))
|
||||||
|
return; // sanity check
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
|
// access check
|
||||||
|
if (plr->accountLevel > 30)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF *req = (sP_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF*)data->buf;
|
||||||
|
|
||||||
|
CNSocket *otherSock = getSockFromAny(req->eTargetSearchBy, req->iTargetPC_ID, req->iTargetPC_UID,
|
||||||
|
U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName));
|
||||||
|
if (otherSock == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "player to teleport not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player *otherPlr = getPlayer(otherSock);
|
||||||
|
if (req->iONOFF)
|
||||||
|
otherPlr->iSpecialState |= req->iSpecialStateFlag;
|
||||||
|
else
|
||||||
|
otherPlr->iSpecialState &= ~req->iSpecialStateFlag;
|
||||||
|
|
||||||
|
// this is only used for muting players, so no need to update the client since that logic is server-side
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerManager::locatePlayer(CNSocket *sock, CNPacketData *data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_GM_REQ_PC_LOCATION))
|
||||||
|
return; // sanity check
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
|
// access check
|
||||||
|
if (plr->accountLevel > 30)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2FE_GM_REQ_PC_LOCATION *req = (sP_CL2FE_GM_REQ_PC_LOCATION*)data->buf;
|
||||||
|
|
||||||
|
CNSocket *otherSock = getSockFromAny(req->eTargetSearchBy, req->iTargetPC_ID, req->iTargetPC_UID,
|
||||||
|
U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName));
|
||||||
|
if (otherSock == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "player not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_GM_REP_PC_LOCATION, resp);
|
||||||
|
Player *otherPlr = getPlayer(otherSock);
|
||||||
|
|
||||||
|
resp.iTargetPC_UID = otherPlr->accountId;
|
||||||
|
resp.iTargetPC_ID = otherPlr->iID;
|
||||||
|
resp.iShardID = 0; // sharding is unsupported
|
||||||
|
resp.iMapType = !!PLAYERID(otherPlr->instanceID); // private instance or not
|
||||||
|
resp.iMapID = PLAYERID(otherPlr->instanceID);
|
||||||
|
resp.iMapNum = MAPNUM(otherPlr->instanceID);
|
||||||
|
resp.iX = otherPlr->x;
|
||||||
|
resp.iY = otherPlr->y;
|
||||||
|
resp.iZ = otherPlr->z;
|
||||||
|
|
||||||
|
memcpy(resp.szTargetPC_FirstName, otherPlr->PCStyle.szFirstName, sizeof(resp.szTargetPC_FirstName));
|
||||||
|
memcpy(resp.szTargetPC_LastName, otherPlr->PCStyle.szLastName, sizeof(resp.szTargetPC_LastName));
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_GM_REP_PC_LOCATION, sizeof(sP_FE2CL_GM_REP_PC_LOCATION));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerManager::kickPlayer(CNSocket *sock, CNPacketData *data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_GM_REQ_KICK_PLAYER))
|
||||||
|
return; // sanity check
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
|
// access check
|
||||||
|
if (plr->accountLevel > 30)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2FE_GM_REQ_KICK_PLAYER *req = (sP_CL2FE_GM_REQ_KICK_PLAYER*)data->buf;
|
||||||
|
|
||||||
|
CNSocket *otherSock = getSockFromAny(req->eTargetSearchBy, req->iTargetPC_ID, req->iTargetPC_UID,
|
||||||
|
U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName));
|
||||||
|
if (otherSock == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "player not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player *otherPlr = getPlayer(otherSock);
|
||||||
|
|
||||||
|
if (otherPlr->accountLevel > plr->accountLevel) {
|
||||||
|
ChatManager::sendServerMessage(sock, "player has higher access level");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_EXIT_SUCC, response);
|
||||||
|
|
||||||
|
response.iID = otherPlr->iID;
|
||||||
|
response.iExitCode = 3; // "a GM has terminated your connection"
|
||||||
|
|
||||||
|
// send to target player
|
||||||
|
otherSock->sendPacket((void*)&response, P_FE2CL_REP_PC_EXIT_SUCC, sizeof(sP_FE2CL_REP_PC_EXIT_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerManager::warpToPlayer(CNSocket *sock, CNPacketData *data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_WARP_TO_PC))
|
||||||
|
return; // sanity check
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
|
// access check
|
||||||
|
if (plr->accountLevel > 30)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_WARP_TO_PC *req = (sP_CL2FE_REQ_PC_WARP_TO_PC*)data->buf;
|
||||||
|
|
||||||
|
Player *otherPlr = getPlayerFromID(req->iPC_ID);
|
||||||
|
if (otherPlr == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "player not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPlayerTo(sock, otherPlr->x, otherPlr->y, otherPlr->z, otherPlr->instanceID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GM teleport command
|
||||||
|
void PlayerManager::teleportPlayer(CNSocket *sock, CNPacketData *data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_GM_REQ_TARGET_PC_TELEPORT))
|
||||||
|
return; // sanity check
|
||||||
|
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
|
// access check
|
||||||
|
if (plr->accountLevel > 30)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2FE_GM_REQ_TARGET_PC_TELEPORT *req = (sP_CL2FE_GM_REQ_TARGET_PC_TELEPORT*)data->buf;
|
||||||
|
|
||||||
|
// player to teleport
|
||||||
|
CNSocket *targetSock = getSockFromAny(req->eTargetPCSearchBy, req->iTargetPC_ID, req->iTargetPC_UID,
|
||||||
|
U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName));
|
||||||
|
if (targetSock == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "player to teleport not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNSocket *goalSock = nullptr;
|
||||||
|
Player *goalPlr = nullptr;
|
||||||
|
Player *targetPlr = nullptr;
|
||||||
|
uint64_t instance = plr->instanceID;
|
||||||
|
const int unstickRange = 400;
|
||||||
|
|
||||||
|
switch (req->eTeleportType) {
|
||||||
|
case eCN_GM_TeleportMapType__MyLocation:
|
||||||
|
sendPlayerTo(targetSock, plr->x, plr->y, plr->z);
|
||||||
|
break;
|
||||||
|
case eCN_GM_TeleportMapType__MapXYZ:
|
||||||
|
instance = req->iToMap;
|
||||||
|
// fallthrough
|
||||||
|
case eCN_GM_TeleportMapType__XYZ:
|
||||||
|
sendPlayerTo(targetSock, req->iToX, req->iToY, req->iToZ, instance);
|
||||||
|
break;
|
||||||
|
case eCN_GM_TeleportMapType__SomeoneLocation:
|
||||||
|
// player to teleport to
|
||||||
|
goalSock = getSockFromAny(req->eGoalPCSearchBy, req->iGoalPC_ID, req->iGoalPC_UID,
|
||||||
|
U16toU8(req->szGoalPC_FirstName), U16toU8(req->szGoalPC_LastName));
|
||||||
|
if (goalSock == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "teleportation target player not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
goalPlr = getPlayer(goalSock);
|
||||||
|
|
||||||
|
sendPlayerTo(targetSock, goalPlr->x, goalPlr->y, goalPlr->z, goalPlr->instanceID);
|
||||||
|
break;
|
||||||
|
case eCN_GM_TeleportMapType__Unstick:
|
||||||
|
targetPlr = getPlayer(targetSock);
|
||||||
|
|
||||||
|
sendPlayerTo(targetSock, targetPlr->x - unstickRange/2 + rand() % unstickRange,
|
||||||
|
targetPlr->y - unstickRange/2 + rand() % unstickRange, targetPlr->z + 80);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma region Helper methods
|
#pragma region Helper methods
|
||||||
Player *PlayerManager::getPlayer(CNSocket* key) {
|
Player *PlayerManager::getPlayer(CNSocket* key) {
|
||||||
if (players.find(key) != players.end())
|
if (players.find(key) != players.end())
|
||||||
@ -1014,32 +1229,9 @@ void PlayerManager::exitDuplicate(int accountId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::setSpecialState(CNSocket* sock, CNPacketData* data) {
|
// TODO: just call getPlayer() after getSockFromID()?
|
||||||
if (data->size != sizeof(sP_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH))
|
|
||||||
return; // ignore the malformed packet
|
|
||||||
|
|
||||||
Player *plr = getPlayer(sock);
|
|
||||||
|
|
||||||
sP_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH* setData = (sP_CL2FE_GM_REQ_PC_SPECIAL_STATE_SWITCH*)data->buf;
|
|
||||||
|
|
||||||
// HACK: work around the invisible weapon bug
|
|
||||||
if (setData->iSpecialStateFlag == CN_SPECIAL_STATE_FLAG__FULL_UI)
|
|
||||||
ItemManager::updateEquips(sock, plr);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_PC_SPECIAL_STATE_CHANGE, response);
|
|
||||||
|
|
||||||
plr->iSpecialState ^= setData->iSpecialStateFlag;
|
|
||||||
|
|
||||||
response.iPC_ID = setData->iPC_ID;
|
|
||||||
response.iReqSpecialStateFlag = setData->iSpecialStateFlag;
|
|
||||||
response.iSpecialState = plr->iSpecialState;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC, sizeof(sP_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC));
|
|
||||||
sendToViewable(sock, (void*)&response, P_FE2CL_PC_SPECIAL_STATE_CHANGE, sizeof(sP_FE2CL_PC_SPECIAL_STATE_CHANGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
Player *PlayerManager::getPlayerFromID(int32_t iID) {
|
Player *PlayerManager::getPlayerFromID(int32_t iID) {
|
||||||
for (auto& pair : PlayerManager::players)
|
for (auto& pair : players)
|
||||||
if (pair.second->iID == iID)
|
if (pair.second->iID == iID)
|
||||||
return pair.second;
|
return pair.second;
|
||||||
|
|
||||||
@ -1047,10 +1239,39 @@ Player *PlayerManager::getPlayerFromID(int32_t iID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CNSocket *PlayerManager::getSockFromID(int32_t iID) {
|
CNSocket *PlayerManager::getSockFromID(int32_t iID) {
|
||||||
for (auto& pair : PlayerManager::players)
|
for (auto& pair : players)
|
||||||
if (pair.second->iID == iID)
|
if (pair.second->iID == iID)
|
||||||
return pair.first;
|
return pair.first;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CNSocket *PlayerManager::getSockFromName(std::string firstname, std::string lastname) {
|
||||||
|
for (auto& pair : players)
|
||||||
|
if (U16toU8(pair.second->PCStyle.szFirstName) == firstname
|
||||||
|
&& U16toU8(pair.second->PCStyle.szLastName) == lastname)
|
||||||
|
return pair.first;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNSocket *PlayerManager::getSockFromAny(int by, int id, int uid, std::string firstname, std::string lastname) {
|
||||||
|
switch (by) {
|
||||||
|
case eCN_GM_TargetSearchBy__PC_ID:
|
||||||
|
assert(id != 0);
|
||||||
|
return getSockFromID(id);
|
||||||
|
case eCN_GM_TargetSearchBy__PC_UID: // account id; not player id
|
||||||
|
assert(uid != 0);
|
||||||
|
for (auto& pair : players)
|
||||||
|
if (pair.second->accountId == uid)
|
||||||
|
return pair.first;
|
||||||
|
case eCN_GM_TargetSearchBy__PC_Name:
|
||||||
|
assert(firstname != "" && lastname != ""); // XXX: remove this if we start messing around with edited names?
|
||||||
|
return getSockFromName(firstname, lastname);
|
||||||
|
}
|
||||||
|
|
||||||
|
// not found
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -38,14 +38,19 @@ namespace PlayerManager {
|
|||||||
void moveSliderPlayer(CNSocket* sock, CNPacketData* data);
|
void moveSliderPlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void moveSlopePlayer(CNSocket* sock, CNPacketData* data);
|
void moveSlopePlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void gotoPlayer(CNSocket* sock, CNPacketData* data);
|
void gotoPlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void setSpecialPlayer(CNSocket* sock, CNPacketData* data);
|
void setValuePlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void heartbeatPlayer(CNSocket* sock, CNPacketData* data);
|
void heartbeatPlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void revivePlayer(CNSocket* sock, CNPacketData* data);
|
void revivePlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void exitGame(CNSocket* sock, CNPacketData* data);
|
void exitGame(CNSocket* sock, CNPacketData* data);
|
||||||
|
|
||||||
void setSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data);
|
void setSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data);
|
||||||
void setGMSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data);
|
void setGMSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data);
|
||||||
|
void setGMSpecialOnOff(CNSocket* sock, CNPacketData *data);
|
||||||
void changePlayerGuide(CNSocket *sock, CNPacketData *data);
|
void changePlayerGuide(CNSocket *sock, CNPacketData *data);
|
||||||
|
void locatePlayer(CNSocket *sock, CNPacketData *data);
|
||||||
|
void kickPlayer(CNSocket *sock, CNPacketData *data);
|
||||||
|
void warpToPlayer(CNSocket *sock, CNPacketData *data);
|
||||||
|
void teleportPlayer(CNSocket *sock, CNPacketData *data);
|
||||||
|
|
||||||
void enterPlayerVehicle(CNSocket* sock, CNPacketData* data);
|
void enterPlayerVehicle(CNSocket* sock, CNPacketData* data);
|
||||||
void exitPlayerVehicle(CNSocket* sock, CNPacketData* data);
|
void exitPlayerVehicle(CNSocket* sock, CNPacketData* data);
|
||||||
@ -61,6 +66,8 @@ namespace PlayerManager {
|
|||||||
void setSpecialState(CNSocket* sock, CNPacketData* data);
|
void setSpecialState(CNSocket* sock, CNPacketData* data);
|
||||||
Player *getPlayerFromID(int32_t iID);
|
Player *getPlayerFromID(int32_t iID);
|
||||||
CNSocket *getSockFromID(int32_t iID);
|
CNSocket *getSockFromID(int32_t iID);
|
||||||
|
CNSocket *getSockFromName(std::string firstname, std::string lastname);
|
||||||
|
CNSocket *getSockFromAny(int by, int id, int uid, std::string firstname, std::string lastname);
|
||||||
|
|
||||||
void sendNanoBookSubset(CNSocket *sock);
|
void sendNanoBookSubset(CNSocket *sock);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user