From 47da895544a857211fb3584c569bb422f0badfef Mon Sep 17 00:00:00 2001 From: Gent Date: Fri, 2 Oct 2020 22:05:20 -0400 Subject: [PATCH 1/2] Add basic MSS gruntwork commands --- src/ChatManager.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++++ src/TableData.cpp | 2 + src/TableData.hpp | 4 ++ 3 files changed, 116 insertions(+) diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index 6e98c2d..60e26c1 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -2,6 +2,7 @@ #include "CNStructs.hpp" #include "ChatManager.hpp" #include "PlayerManager.hpp" +#include "TableData.hpp" #include #include @@ -50,6 +51,114 @@ void accessCommand(std::string full, std::vector& args, CNSocket* s ChatManager::sendServerMessage(sock, "Your access level is " + std::to_string(PlayerManager::getPlayer(sock)->accountLevel)); } +void mssCommand(std::string full, std::vector& args, CNSocket* sock) { + if (args.size() < 2) { + ChatManager::sendServerMessage(sock, "[MSS] Too few arguments"); + ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); + return; + } + + // Validate route number + char* routeNumC; + int routeNum = std::strtol(args[1].c_str(), &routeNumC, 10); + if (*routeNumC) { + // not an integer + ChatManager::sendServerMessage(sock, "[MSS] Invalid route number '" + args[1] + "'"); + return; + } + + if (args.size() < 3) { + ChatManager::sendServerMessage(sock, "[MSS] Too few arguments"); + ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); + return; + } + + // get the route (if it doesn't exist yet, this will also make it) + std::stack* route = &TableData::RunningSkywayRoutes[routeNum]; + + // mss add + if (args[2] == "add") { + // make sure height token exists + if (args.size() < 4) { + ChatManager::sendServerMessage(sock, "[MSS] Point height must be specified"); + ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss add "); + return; + } + // validate height token + char* heightC; + int height = std::strtol(args[3].c_str(), &heightC, 10); + if (*heightC) { + ChatManager::sendServerMessage(sock, "[MSS] Invalid height " + args[3]); + return; + } + + Player* plr = PlayerManager::getPlayer(sock); + route->push({ plr->x, plr->y, height }); // add point to stack + ChatManager::sendServerMessage(sock, "[MSS] Added point (" + std::to_string(plr->x) + ", " + std::to_string(plr->y) + ", " + std::to_string(height) + ") to route " + std::to_string(routeNum)); + return; + } + + // mss remove + if (args[2] == "remove") { + if (route->empty()) { + ChatManager::sendServerMessage(sock, "[MSS] Route " + std::to_string(routeNum) + " is empty"); + return; + } + + WarpLocation pulled = route->top(); + route->pop(); // remove point at top of stack + ChatManager::sendServerMessage(sock, "[MSS] Removed point (" + std::to_string(pulled.x) + ", " + std::to_string(pulled.y) + ", " + std::to_string(pulled.z) + ") from route " + std::to_string(routeNum)); + return; + } + + // mss goto + if (args[2] == "goto") { + if (route->empty()) { + ChatManager::sendServerMessage(sock, "[MSS] Route " + std::to_string(routeNum) + " is empty"); + return; + } + + WarpLocation pulled = route->top(); + // simulate goto + INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, pkt); + Player* plr = PlayerManager::getPlayer(sock); + PlayerManager::updatePlayerPosition(sock, pulled.x, pulled.y, pulled.z); + pkt.iX = pulled.x; + pkt.iY = pulled.y; + pkt.iZ = pulled.z; + sock->sendPacket((void*)&pkt, P_FE2CL_REP_PC_GOTO_SUCC, sizeof(sP_FE2CL_REP_PC_GOTO_SUCC)); + return; + } + + // mss clear + if (args[2] == "clear") { + // clear the stack + while (!route->empty()) { + route->pop(); + } + ChatManager::sendServerMessage(sock, "[MSS] Cleared route " + std::to_string(routeNum)); + return; + } + + // mss reload + if (args[2] == "reload") { + ChatManager::sendServerMessage(sock, "[MSS] reload on " + std::to_string(routeNum)); + // TODO: inject route and reload + return; + } + + // mss export + if (args[2] == "export") { + ChatManager::sendServerMessage(sock, "[MSS] export on " + std::to_string(routeNum)); + // TODO: dump route to tdata + return; + } + + // mss ???? + ChatManager::sendServerMessage(sock, "[MSS] Unknown command '" + args[2] + "'"); + +} + void ChatManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_FREECHAT_MESSAGE, chatHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler); @@ -58,6 +167,7 @@ void ChatManager::init() { registerCommand("test", 1, testCommand); registerCommand("access", 100, accessCommand); // TODO: add help command + registerCommand("mss", 100, mssCommand); } void ChatManager::registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr) { diff --git a/src/TableData.cpp b/src/TableData.cpp index d84e71d..288b1bc 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -12,6 +12,8 @@ #include +std::map> TableData::RunningSkywayRoutes; + void TableData::init() { int32_t nextId = 0; diff --git a/src/TableData.hpp b/src/TableData.hpp index 697339c..482072e 100644 --- a/src/TableData.hpp +++ b/src/TableData.hpp @@ -1,9 +1,13 @@ #pragma once #include +#include #include "contrib/JSON.hpp" +#include "NPCManager.hpp" namespace TableData { + extern std::map> RunningSkywayRoutes; + void init(); void cleanup(); From a9837d6c1b538753ae95fc0e0788fb09fd8811d7 Mon Sep 17 00:00:00 2001 From: Gent Date: Sat, 3 Oct 2020 11:21:36 -0400 Subject: [PATCH 2/2] Finish MSS commands + convert stack to vector --- src/ChatManager.cpp | 51 ++++++++++++++++++++++++------------------- src/PlayerManager.cpp | 32 ++++++++++++++++++--------- src/PlayerManager.hpp | 3 +++ src/TableData.cpp | 2 +- src/TableData.hpp | 3 +-- 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index 60e26c1..8b6686b 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -2,6 +2,7 @@ #include "CNStructs.hpp" #include "ChatManager.hpp" #include "PlayerManager.hpp" +#include "TransportManager.hpp" #include "TableData.hpp" #include @@ -54,7 +55,7 @@ void accessCommand(std::string full, std::vector& args, CNSocket* s void mssCommand(std::string full, std::vector& args, CNSocket* sock) { if (args.size() < 2) { ChatManager::sendServerMessage(sock, "[MSS] Too few arguments"); - ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); + ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); return; } @@ -69,12 +70,12 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock if (args.size() < 3) { ChatManager::sendServerMessage(sock, "[MSS] Too few arguments"); - ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); + ChatManager::sendServerMessage(sock, "[MSS] Usage: /mss <>"); return; } // get the route (if it doesn't exist yet, this will also make it) - std::stack* route = &TableData::RunningSkywayRoutes[routeNum]; + std::vector* route = &TableData::RunningSkywayRoutes[routeNum]; // mss add if (args[2] == "add") { @@ -93,7 +94,7 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock } Player* plr = PlayerManager::getPlayer(sock); - route->push({ plr->x, plr->y, height }); // add point to stack + route->push_back({ plr->x, plr->y, height }); // add point ChatManager::sendServerMessage(sock, "[MSS] Added point (" + std::to_string(plr->x) + ", " + std::to_string(plr->y) + ", " + std::to_string(height) + ") to route " + std::to_string(routeNum)); return; } @@ -105,8 +106,8 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock return; } - WarpLocation pulled = route->top(); - route->pop(); // remove point at top of stack + WarpLocation pulled = route->back(); + route->pop_back(); // remove point at top of stack ChatManager::sendServerMessage(sock, "[MSS] Removed point (" + std::to_string(pulled.x) + ", " + std::to_string(pulled.y) + ", " + std::to_string(pulled.z) + ") from route " + std::to_string(routeNum)); return; } @@ -118,32 +119,38 @@ void mssCommand(std::string full, std::vector& args, CNSocket* sock return; } - WarpLocation pulled = route->top(); - // simulate goto - INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, pkt); - Player* plr = PlayerManager::getPlayer(sock); - PlayerManager::updatePlayerPosition(sock, pulled.x, pulled.y, pulled.z); - pkt.iX = pulled.x; - pkt.iY = pulled.y; - pkt.iZ = pulled.z; - sock->sendPacket((void*)&pkt, P_FE2CL_REP_PC_GOTO_SUCC, sizeof(sP_FE2CL_REP_PC_GOTO_SUCC)); + WarpLocation pulled = route->back(); + PlayerManager::sendPlayerTo(sock, pulled.x, pulled.y, pulled.z); return; } // mss clear if (args[2] == "clear") { - // clear the stack - while (!route->empty()) { - route->pop(); - } + route->clear(); ChatManager::sendServerMessage(sock, "[MSS] Cleared route " + std::to_string(routeNum)); return; } // mss reload - if (args[2] == "reload") { - ChatManager::sendServerMessage(sock, "[MSS] reload on " + std::to_string(routeNum)); - // TODO: inject route and reload + if (args[2] == "test") { + if (route->empty()) { + ChatManager::sendServerMessage(sock, "[MSS] Route " + std::to_string(routeNum) + " is empty"); + return; + } + + // IMPROMPTU LERP + int speed = 1500; // TODO: make this adjustable + std::queue path; + WarpLocation last = route->front(); // start pos + PlayerManager::sendPlayerTo(sock, last.x, last.y, last.z); // send the player to the start of the path + for (int i = 1; i < route->size(); i++) { + WarpLocation coords = route->at(i); + TransportManager::lerp(&path, last, coords, speed); + path.push(coords); // add keyframe to the queue + last = coords; // update start pos + } + + TransportManager::SkywayQueues[sock] = path; return; } diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 5a170b9..0081796 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -212,6 +212,27 @@ void PlayerManager::updatePlayerChunk(CNSocket* sock, int X, int Y) { view.currentChunks = allChunks; } +void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, int I) { + getPlayer(sock)->instanceID = I; + sendPlayerTo(sock, X, Y, Z); +} + +void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) { + + PlayerManager::updatePlayerPosition(sock, X, Y, Z); + INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, pkt); + pkt.iX = X; + pkt.iY = Y; + pkt.iZ = Z; + + // force player & NPC reload + PlayerView& plrv = players[sock]; + PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock); + plrv.currentChunks.clear(); + plrv.chunkPos = std::make_tuple(0, 0, plrv.plr->instanceID); + sock->sendPacket((void*)&pkt, P_FE2CL_REP_PC_GOTO_SUCC, sizeof(sP_FE2CL_REP_PC_GOTO_SUCC)); +} + void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_ENTER)) return; // ignore the malformed packet @@ -638,16 +659,7 @@ void PlayerManager::gotoPlayer(CNSocket* sock, CNPacketData* data) { std::cout << "\tZ: " << gotoData->iToZ << std::endl; ) - response.iX = plrv.plr->x = gotoData->iToX; - response.iY = plrv.plr->y = gotoData->iToY; - response.iZ = plrv.plr->z = gotoData->iToZ; - - // force player & NPC reload - PlayerManager::removePlayerFromChunks(plrv.currentChunks, sock); - plrv.currentChunks.clear(); - plrv.chunkPos = std::make_tuple(0, 0, plrv.plr->instanceID); - - sock->sendPacket((void*)&response, P_FE2CL_REP_PC_GOTO_SUCC, sizeof(sP_FE2CL_REP_PC_GOTO_SUCC)); + sendPlayerTo(sock, gotoData->iToX, gotoData->iToY, gotoData->iToZ); } void PlayerManager::setSpecialPlayer(CNSocket* sock, CNPacketData* data) { diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index d551fbe..d331f18 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -34,6 +34,9 @@ namespace PlayerManager { void updatePlayerPosition(CNSocket* sock, int X, int Y, int Z, int angle); void updatePlayerChunk(CNSocket* sock, int X, int Y); + void sendPlayerTo(CNSocket* sock, int X, int Y, int Z, int I); + void sendPlayerTo(CNSocket* sock, int X, int Y, int Z); + void sendToViewable(CNSocket* sock, void* buf, uint32_t type, size_t size); void enterPlayer(CNSocket* sock, CNPacketData* data); diff --git a/src/TableData.cpp b/src/TableData.cpp index 288b1bc..17fe358 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -12,7 +12,7 @@ #include -std::map> TableData::RunningSkywayRoutes; +std::map> TableData::RunningSkywayRoutes; void TableData::init() { int32_t nextId = 0; diff --git a/src/TableData.hpp b/src/TableData.hpp index 482072e..adba0ae 100644 --- a/src/TableData.hpp +++ b/src/TableData.hpp @@ -1,12 +1,11 @@ #pragma once #include -#include #include "contrib/JSON.hpp" #include "NPCManager.hpp" namespace TableData { - extern std::map> RunningSkywayRoutes; + extern std::map> RunningSkywayRoutes; void init(); void cleanup();