From 574f0cab098e42881499b292df2967ed2279e04d Mon Sep 17 00:00:00 2001 From: CPunch Date: Wed, 17 Mar 2021 23:41:47 -0500 Subject: [PATCH] Added a wrapper for U16toU8, called AUTOU16TOU8 - U16toU8 now requires a max arument to be passed --- src/Buddies.cpp | 2 +- src/BuiltinCommands.cpp | 10 +++++----- src/Chat.cpp | 16 ++++++++-------- src/Email.cpp | 8 ++++---- src/PlayerManager.cpp | 8 ++++---- src/core/CNStructs.hpp | 6 +++++- src/db/login.cpp | 8 ++++---- src/main.cpp | 3 ++- src/servers/CNLoginServer.cpp | 20 ++++++++++---------- 9 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/Buddies.cpp b/src/Buddies.cpp index e51ed98..53cdcc3 100644 --- a/src/Buddies.cpp +++ b/src/Buddies.cpp @@ -137,7 +137,7 @@ static void reqBuddyByName(CNSocket* sock, CNPacketData* data) { INITSTRUCT(sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC, resp); - CNSocket* otherSock = PlayerManager::getSockFromName(U16toU8(pkt->szFirstName), U16toU8(pkt->szLastName)); + CNSocket* otherSock = PlayerManager::getSockFromName(AUTOU16TOU8(pkt->szFirstName), AUTOU16TOU8(pkt->szLastName)); if (otherSock == nullptr) return; // no player found diff --git a/src/BuiltinCommands.cpp b/src/BuiltinCommands.cpp index 0dbd04e..f5a403a 100644 --- a/src/BuiltinCommands.cpp +++ b/src/BuiltinCommands.cpp @@ -131,7 +131,7 @@ static void setGMSpecialOnOff(CNSocket *sock, CNPacketData *data) { sP_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF *req = (sP_CL2FE_GM_REQ_TARGET_PC_SPECIAL_STATE_ONOFF*)data->buf; CNSocket *otherSock = PlayerManager::getSockFromAny(req->eTargetSearchBy, req->iTargetPC_ID, req->iTargetPC_UID, - U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName)); + AUTOU16TOU8(req->szTargetPC_FirstName), AUTOU16TOU8(req->szTargetPC_LastName)); if (otherSock == nullptr) { Chat::sendServerMessage(sock, "player to teleport not found"); return; @@ -159,7 +159,7 @@ static void locatePlayer(CNSocket *sock, CNPacketData *data) { sP_CL2FE_GM_REQ_PC_LOCATION *req = (sP_CL2FE_GM_REQ_PC_LOCATION*)data->buf; CNSocket *otherSock = PlayerManager::getSockFromAny(req->eTargetSearchBy, req->iTargetPC_ID, req->iTargetPC_UID, - U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName)); + AUTOU16TOU8(req->szTargetPC_FirstName), AUTOU16TOU8(req->szTargetPC_LastName)); if (otherSock == nullptr) { Chat::sendServerMessage(sock, "player not found"); return; @@ -197,7 +197,7 @@ static void kickPlayer(CNSocket *sock, CNPacketData *data) { sP_CL2FE_GM_REQ_KICK_PLAYER *req = (sP_CL2FE_GM_REQ_KICK_PLAYER*)data->buf; CNSocket *otherSock = PlayerManager::getSockFromAny(req->eTargetSearchBy, req->iTargetPC_ID, req->iTargetPC_UID, - U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName)); + AUTOU16TOU8(req->szTargetPC_FirstName), AUTOU16TOU8(req->szTargetPC_LastName)); if (otherSock == nullptr) { Chat::sendServerMessage(sock, "player not found"); return; @@ -258,7 +258,7 @@ static void teleportPlayer(CNSocket *sock, CNPacketData *data) { // player to teleport CNSocket *targetSock = PlayerManager::getSockFromAny(req->eTargetPCSearchBy, req->iTargetPC_ID, req->iTargetPC_UID, - U16toU8(req->szTargetPC_FirstName), U16toU8(req->szTargetPC_LastName)); + AUTOU16TOU8(req->szTargetPC_FirstName), AUTOU16TOU8(req->szTargetPC_LastName)); if (targetSock == nullptr) { Chat::sendServerMessage(sock, "player to teleport not found"); return; @@ -283,7 +283,7 @@ static void teleportPlayer(CNSocket *sock, CNPacketData *data) { case eCN_GM_TeleportMapType__SomeoneLocation: // player to teleport to goalSock = PlayerManager::getSockFromAny(req->eGoalPCSearchBy, req->iGoalPC_ID, req->iGoalPC_UID, - U16toU8(req->szGoalPC_FirstName), U16toU8(req->szGoalPC_LastName)); + AUTOU16TOU8(req->szGoalPC_FirstName), AUTOU16TOU8(req->szGoalPC_LastName)); if (goalSock == nullptr) { Chat::sendServerMessage(sock, "teleportation target player not found"); return; diff --git a/src/Chat.cpp b/src/Chat.cpp index 7ff305c..dc63f33 100644 --- a/src/Chat.cpp +++ b/src/Chat.cpp @@ -16,7 +16,7 @@ static void chatHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE* chat = (sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE*)data->buf; Player* plr = PlayerManager::getPlayer(sock); - std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(chat->szFreeChat)); if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX CustomCommands::runCmd(fullChat, sock); return; @@ -50,7 +50,7 @@ static void menuChatHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_SEND_MENUCHAT_MESSAGE* chat = (sP_CL2FE_REQ_SEND_MENUCHAT_MESSAGE*)data->buf; Player *plr = PlayerManager::getPlayer(sock); - std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(chat->szFreeChat)); std::string logLine = "[MenuChat] " + PlayerManager::getPlayerName(plr, true) + ": " + fullChat; std::cout << logLine << std::endl; @@ -131,7 +131,7 @@ static void announcementHandler(CNSocket* sock, CNPacketData* data) { break; } - std::string logLine = "[Bcast " + std::to_string(announcement->iAreaType) + "] " + PlayerManager::getPlayerName(plr, false) + ": " + U16toU8(msg.szAnnounceMsg); + std::string logLine = "[Bcast " + std::to_string(announcement->iAreaType) + "] " + PlayerManager::getPlayerName(plr, false) + ": " + AUTOU16TOU8(msg.szAnnounceMsg); std::cout << logLine << std::endl; dump.push_back("**" + logLine + "**"); } @@ -157,7 +157,7 @@ static void buddyChatHandler(CNSocket* sock, CNPacketData* data) { resp.iToPCUID = pkt->iBuddyPCUID; resp.iEmoteCode = pkt->iEmoteCode; - std::string fullChat = sanitizeText(U16toU8(pkt->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(pkt->szFreeChat)); if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX CustomCommands::runCmd(fullChat, sock); @@ -198,7 +198,7 @@ static void buddyMenuChatHandler(CNSocket* sock, CNPacketData* data) { resp.iToPCUID = pkt->iBuddyPCUID; resp.iEmoteCode = pkt->iEmoteCode; - std::string fullChat = sanitizeText(U16toU8(pkt->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(pkt->szFreeChat)); std::string logLine = "[BuddyMenuChat] " + PlayerManager::getPlayerName(plr) + " (to " + PlayerManager::getPlayerName(otherPlr) + "): " + fullChat; std::cout << logLine << std::endl; @@ -231,7 +231,7 @@ static void tradeChatHandler(CNSocket* sock, CNPacketData* data) { resp.iID_Request = pacdat->iID_Request; resp.iID_From = pacdat->iID_From; resp.iID_To = pacdat->iID_To; - std::string fullChat = sanitizeText(U16toU8(pacdat->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(pacdat->szFreeChat)); U8toU16(fullChat, resp.szFreeChat, sizeof(resp.szFreeChat)); std::string logLine = "[TradeChat] " + PlayerManager::getPlayerName(plr) + " (to " + PlayerManager::getPlayerName(otherPlr) + "): " + fullChat; @@ -255,7 +255,7 @@ static void groupChatHandler(CNSocket* sock, CNPacketData* data) { if (otherPlr == nullptr) return; - std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(chat->szFreeChat)); if (fullChat.length() > 1 && fullChat[0] == CMD_PREFIX) { // PREFIX CustomCommands::runCmd(fullChat, sock); @@ -290,7 +290,7 @@ static void groupMenuChatHandler(CNSocket* sock, CNPacketData* data) { if (otherPlr == nullptr) return; - std::string fullChat = sanitizeText(U16toU8(chat->szFreeChat)); + std::string fullChat = sanitizeText(AUTOU16TOU8(chat->szFreeChat)); std::string logLine = "[GroupMenuChat] " + PlayerManager::getPlayerName(plr, true) + ": " + fullChat; std::cout << logLine << std::endl; diff --git a/src/Email.cpp b/src/Email.cpp index 23242df..7413f65 100644 --- a/src/Email.cpp +++ b/src/Email.cpp @@ -289,10 +289,10 @@ static void emailSend(CNSocket* sock, CNPacketData* data) { 0, // ReadFlag (unread) (pkt->iCash > 0 || attachments.size() > 0) ? 1 : 0, // ItemFlag plr->iID, // SenderID - U16toU8(plr->PCStyle.szFirstName), // SenderFirstName - U16toU8(plr->PCStyle.szLastName), // SenderLastName - Chat::sanitizeText(U16toU8(pkt->szSubject)), // SubjectLine - Chat::sanitizeText(U16toU8(pkt->szContent), true), // MsgBody + AUTOU16TOU8(plr->PCStyle.szFirstName), // SenderFirstName + AUTOU16TOU8(plr->PCStyle.szLastName), // SenderLastName + Chat::sanitizeText(AUTOU16TOU8(pkt->szSubject)), // SubjectLine + Chat::sanitizeText(AUTOU16TOU8(pkt->szContent), true), // MsgBody pkt->iCash, // Taros (uint64_t)getTimestamp(), // SendTime 0 // DeleteTime (unimplemented) diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index fa14825..b06e2a1 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -209,7 +209,7 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) { DEBUGLOG( std::cout << "P_CL2FE_REQ_PC_ENTER:" << std::endl; - std::cout << "\tID: " << U16toU8(enter->szID) << std::endl; + std::cout << "\tID: " << AUTOU16TOU8(enter->szID) << std::endl; std::cout << "\tSerial: " << enter->iEnterSerialKey << std::endl; std::cout << "\tTemp: " << enter->iTempValue << std::endl; std::cout << "\tPC_UID: " << plr.PCStyle.iPC_UID << std::endl; @@ -607,7 +607,7 @@ std::string PlayerManager::getPlayerName(Player *plr, bool id) { if (id && plr->accountLevel <= 30) ret += "(GM) "; - ret += U16toU8(plr->PCStyle.szFirstName) + " " + U16toU8(plr->PCStyle.szLastName); + ret += AUTOU16TOU8(plr->PCStyle.szFirstName) + " " + AUTOU16TOU8(plr->PCStyle.szLastName); if (id) ret += " [" + std::to_string(plr->iID) + "]"; @@ -662,8 +662,8 @@ CNSocket *PlayerManager::getSockFromID(int32_t iID) { 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) + if (AUTOU16TOU8(pair.second->PCStyle.szFirstName) == firstname + && AUTOU16TOU8(pair.second->PCStyle.szLastName) == lastname) return pair.first; return nullptr; diff --git a/src/core/CNStructs.hpp b/src/core/CNStructs.hpp index 890f826..c9a30d1 100644 --- a/src/core/CNStructs.hpp +++ b/src/core/CNStructs.hpp @@ -32,12 +32,16 @@ #define MAPNUM(x) ((x) & 0xffffffff) #define PLAYERID(x) ((x) >> 32) +// wrapper for U16toU8 +#define ARRLEN(x) (sizeof(x)/sizeof(*x)) +#define AUTOU16TOU8(x) U16toU8(x, ARRLEN(x)) + // typedef for chunk position tuple typedef std::tuple ChunkPos; // TODO: rewrite U16toU8 & U8toU16 to not use codecvt -std::string U16toU8(char16_t* src); +std::string U16toU8(char16_t* src, size_t max); size_t U8toU16(std::string src, char16_t* des, size_t max); // returns number of char16_t that was written at des time_t getTime(); time_t getTimestamp(); diff --git a/src/db/login.cpp b/src/db/login.cpp index d946a21..db44133 100644 --- a/src/db/login.cpp +++ b/src/db/login.cpp @@ -161,8 +161,8 @@ int Database::createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); )"; sqlite3_stmt* stmt; - std::string firstName = U16toU8(save->szFirstName); - std::string lastName = U16toU8(save->szLastName); + std::string firstName = AUTOU16TOU8(save->szFirstName); + std::string lastName = AUTOU16TOU8(save->szLastName); sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, AccountID); @@ -519,8 +519,8 @@ bool Database::changeName(sP_CL2LS_REQ_CHANGE_CHAR_NAME* save, int accountId) { sqlite3_stmt* stmt; sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); - std::string firstName = U16toU8(save->szFirstName); - std::string lastName = U16toU8(save->szLastName); + std::string firstName = AUTOU16TOU8(save->szFirstName); + std::string lastName = AUTOU16TOU8(save->szLastName); sqlite3_bind_text(stmt, 1, firstName.c_str(), -1, NULL); sqlite3_bind_text(stmt, 2, lastName.c_str(), -1, NULL); diff --git a/src/main.cpp b/src/main.cpp index fdbd73f..a108dc9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -148,7 +148,8 @@ int main() { // helper functions -std::string U16toU8(char16_t* src) { +std::string U16toU8(char16_t* src, size_t max) { + src[max-1] = '\0'; // force a NULL terminatorstd::string U16toU8(char16_t* src) { try { std::wstring_convert,char16_t> convert; return convert.to_bytes(src); diff --git a/src/servers/CNLoginServer.cpp b/src/servers/CNLoginServer.cpp index 9ffbedd..edfe7de 100644 --- a/src/servers/CNLoginServer.cpp +++ b/src/servers/CNLoginServer.cpp @@ -107,8 +107,8 @@ void CNLoginServer::login(CNSocket* sock, CNPacketData* data) { * The std::string -> char* -> std::string maneuver should remove any * trailing garbage after the null terminator. */ - userLogin = std::string(U16toU8(login->szID).c_str()); - userPassword = std::string(U16toU8(login->szPassword).c_str()); + userLogin = std::string(AUTOU16TOU8(login->szID).c_str()); + userPassword = std::string(AUTOU16TOU8(login->szPassword).c_str()); } // the client inserts a "\n" in the password if you press enter key in the middle of the password @@ -288,9 +288,9 @@ void CNLoginServer::nameSave(CNSocket* sock, CNPacketData* data) { INITSTRUCT(sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC, resp); int errorCode = 0; - if (!CNLoginServer::isCharacterNameGood(U16toU8(save->szFirstName), U16toU8(save->szLastName))) { + if (!CNLoginServer::isCharacterNameGood(AUTOU16TOU8(save->szFirstName), AUTOU16TOU8(save->szLastName))) { errorCode = 4; - } else if (!Database::isNameFree(U16toU8(save->szFirstName), U16toU8(save->szLastName))) { + } else if (!Database::isNameFree(AUTOU16TOU8(save->szFirstName), AUTOU16TOU8(save->szLastName))) { errorCode = 1; } @@ -330,7 +330,7 @@ void CNLoginServer::nameSave(CNSocket* sock, CNPacketData* data) { DEBUGLOG( std::cout << "Login Server: new character created" << std::endl; std::cout << "\tSlot: " << (int)save->iSlotNum << std::endl; - std::cout << "\tName: " << U16toU8(save->szFirstName) << " " << U16toU8(save->szLastName) << std::endl; + std::cout << "\tName: " << AUTOU16TOU8(save->szFirstName) << " " << AUTOU16TOU8(save->szLastName) << std::endl; ) } @@ -406,7 +406,7 @@ void CNLoginServer::characterCreate(CNSocket* sock, CNPacketData* data) { std::cout << "Login Server: Character creation completed" << std::endl; std::cout << "\tPC_UID: " << character->PCStyle.iPC_UID << std::endl; std::cout << "\tNameCheck: " << (int)character->PCStyle.iNameCheck << std::endl; - std::cout << "\tName: " << U16toU8(character->PCStyle.szFirstName) << " " << U16toU8(character->PCStyle.szLastName) << std::endl; + std::cout << "\tName: " << AUTOU16TOU8(character->PCStyle.szFirstName) << " " << AUTOU16TOU8(character->PCStyle.szLastName) << std::endl; std::cout << "\tGender: " << (int)character->PCStyle.iGender << std::endl; std::cout << "\tFace: " << (int)character->PCStyle.iFaceStyle << std::endl; std::cout << "\tHair: " << (int)character->PCStyle.iHairStyle << std::endl; @@ -513,10 +513,10 @@ void CNLoginServer::changeName(CNSocket* sock, CNPacketData* data) { sP_CL2LS_REQ_CHANGE_CHAR_NAME* save = (sP_CL2LS_REQ_CHANGE_CHAR_NAME*)data->buf; int errorCode = 0; - if (!CNLoginServer::isCharacterNameGood(U16toU8(save->szFirstName), U16toU8(save->szLastName))) { + if (!CNLoginServer::isCharacterNameGood(AUTOU16TOU8(save->szFirstName), AUTOU16TOU8(save->szLastName))) { errorCode = 4; } - else if (!Database::isNameFree(U16toU8(save->szFirstName), U16toU8(save->szLastName))) { + else if (!Database::isNameFree(AUTOU16TOU8(save->szFirstName), AUTOU16TOU8(save->szLastName))) { errorCode = 1; } @@ -547,7 +547,7 @@ void CNLoginServer::changeName(CNSocket* sock, CNPacketData* data) { DEBUGLOG( std::cout << "Login Server: Name check success for character [" << save->iPCUID << "]" << std::endl; - std::cout << "\tNew name: " << U16toU8(save->szFirstName) << " " << U16toU8(save->szLastName) << std::endl; + std::cout << "\tNew name: " << AUTOU16TOU8(save->szFirstName) << " " << AUTOU16TOU8(save->szLastName) << std::endl; ) } @@ -559,7 +559,7 @@ void CNLoginServer::duplicateExit(CNSocket* sock, CNPacketData* data) { sP_CL2LS_REQ_PC_EXIT_DUPLICATE* exit = (sP_CL2LS_REQ_PC_EXIT_DUPLICATE*)data->buf; Database::Account account = {}; - Database::findAccount(&account, U16toU8(exit->szID)); + Database::findAccount(&account, AUTOU16TOU8(exit->szID)); // sanity check if (account.AccountID == 0) {