diff --git a/src/CNStructs.hpp b/src/CNStructs.hpp index dfa9ded..d65fedf 100644 --- a/src/CNStructs.hpp +++ b/src/CNStructs.hpp @@ -28,6 +28,10 @@ #define INITSTRUCT(T, x) T x; \ memset(&x, 0, sizeof(T)); +// macros to extract fields from instanceIDs +#define MAPNUM(x) ((x) & 0xffffffff) +#define PLAYERID(x) ((x) >> 32) + // TODO: rewrite U16toU8 & U8toU16 to not use codecvt std::string U16toU8(char16_t* src); diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index 01a53bb..ea45f32 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -43,7 +43,7 @@ bool runCmd(std::string full, CNSocket* sock) { } void helpCommand(std::string full, std::vector& args, CNSocket* sock) { - ChatManager::sendServerMessage(sock, "Commands available to you"); + ChatManager::sendServerMessage(sock, "Commands available to you:"); Player *plr = PlayerManager::getPlayer(sock); for (auto& cmd : ChatManager::commands) { @@ -52,14 +52,6 @@ void helpCommand(std::string full, std::vector& args, CNSocket* soc } } -void testCommand(std::string full, std::vector& args, CNSocket* sock) { - ChatManager::sendServerMessage(sock, "Test command is working! Here are your passed args:"); - - for (std::string arg : args) { - ChatManager::sendServerMessage(sock, arg); - } -} - void accessCommand(std::string full, std::vector& args, CNSocket* sock) { ChatManager::sendServerMessage(sock, "Your access level is " + std::to_string(PlayerManager::getPlayer(sock)->accountLevel)); } @@ -241,8 +233,8 @@ void summonWCommand(std::string full, std::vector& args, CNSocket* NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, plr->x, plr->y, plr->z); // if we're in a lair, we need to spawn the mob in both the private instance and the template - if ((plr->instanceID >> 32) != 0) { - npc = new Mob(plr->x, plr->y, plr->z + 200, plr->instanceID & 0xffffffff, type, NPCManager::NPCData[type], NPCManager::nextId++); + if (PLAYERID(plr->instanceID) != 0) { + npc = new Mob(plr->x, plr->y, plr->z + 200, MAPNUM(plr->instanceID), type, NPCManager::NPCData[type], NPCManager::nextId++); npc->appearanceData.iAngle = (plr->angle + 180) % 360; NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc; @@ -342,7 +334,7 @@ void instanceCommand(std::string full, std::vector& args, CNSocket* // no additional arguments: report current instance ID if (args.size() < 2) { ChatManager::sendServerMessage(sock, "[INST] Current instance ID: " + std::to_string(plr->instanceID)); - ChatManager::sendServerMessage(sock, "[INST] (Map " + std::to_string(plr->instanceID & 0xffffffff) + ", instance " + std::to_string(plr->instanceID >> 32) + ")"); + ChatManager::sendServerMessage(sock, "[INST] (Map " + std::to_string(MAPNUM(plr->instanceID)) + ", instance " + std::to_string(PLAYERID(plr->instanceID)) + ")"); return; } @@ -399,20 +391,19 @@ void ChatManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_MENUCHAT_MESSAGE, menuChatHandler); - registerCommand("help", 100, helpCommand, "lists all unlocked commands"); - registerCommand("test", 1, testCommand); - registerCommand("access", 100, accessCommand); - registerCommand("instance", 30, instanceCommand); - registerCommand("mss", 30, mssCommand); - registerCommand("npcr", 30, npcRotateCommand); - registerCommand("npci", 30, npcInstanceCommand); - registerCommand("summonW", 30, summonWCommand); - registerCommand("unsummonW", 30, unsummonWCommand); - registerCommand("toggleai", 30, toggleAiCommand); - registerCommand("flush", 30, flushCommand); - registerCommand("level", 50, levelCommand); - registerCommand("population", 100, populationCommand); - registerCommand("refresh", 100, refreshCommand); + registerCommand("help", 100, helpCommand, "list all unlocked server-side commands"); + registerCommand("access", 100, accessCommand, "print your access level"); + registerCommand("instance", 30, instanceCommand, "print or change your current instance"); + registerCommand("mss", 30, mssCommand, "edit Monkey Skyway routes"); + registerCommand("npcr", 30, npcRotateCommand, "rotate NPCs"); + registerCommand("npci", 30, npcInstanceCommand, "move NPCs across instances"); + registerCommand("summonW", 30, summonWCommand, "permanently summon NPCs"); + registerCommand("unsummonW", 30, unsummonWCommand, "delete permanently summoned NPCs"); + registerCommand("toggleai", 30, toggleAiCommand, "enable/disable mob AI"); + registerCommand("flush", 30, flushCommand, "save gruntwork to file"); + registerCommand("level", 50, levelCommand, "change your character's level"); + registerCommand("population", 100, populationCommand, "check how many players are online"); + registerCommand("refresh", 100, refreshCommand, "teleport yourself to your current location"); } void ChatManager::registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr, std::string help) { diff --git a/src/ChunkManager.cpp b/src/ChunkManager.cpp index 876a120..bc53470 100644 --- a/src/ChunkManager.cpp +++ b/src/ChunkManager.cpp @@ -202,7 +202,7 @@ bool ChunkManager::inPopulatedChunks(int posX, int posY, uint64_t instanceID) { void ChunkManager::createInstance(uint64_t instanceID) { - std::vector> templateChunks = ChunkManager::getChunksInMap(instanceID & 0xffffffff); // base instance chunks + std::vector> templateChunks = ChunkManager::getChunksInMap(MAPNUM(instanceID)); // base instance chunks if (ChunkManager::getChunksInMap(instanceID).size() == 0) { // only instantiate if the instance doesn't exist already std::cout << "Creating instance " << instanceID << std::endl; for (std::tuple &coords : templateChunks) { diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 508d028..0f9f6af 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -628,7 +628,7 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) { } // post-warp: check if the source instance has no more players in it and delete it if so - if ((fromInstance >> 32) == 0) + if (PLAYERID(fromInstance) == 0) return; // don't clean up overworld/IZ chunks std::vector> sourceChunkCoords = ChunkManager::getChunksInMap(fromInstance); diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index a579378..90365fe 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -233,8 +233,8 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, uint64_t I plr->instanceID = I; if (I != INSTANCE_OVERWORLD) { INITSTRUCT(sP_FE2CL_INSTANCE_MAP_INFO, pkt); - pkt.iEP_ID = (I >> 32) == 0; // iEP_ID has to be positive for the map to be enabled - pkt.iInstanceMapNum = (int32_t)(I & 0xffffffff); // lower 32 bits are mapnum + pkt.iEP_ID = PLAYERID(I) == 0; // iEP_ID has to be positive for the map to be enabled + pkt.iInstanceMapNum = (int32_t)MAPNUM(I); // lower 32 bits are mapnum sock->sendPacket((void*)&pkt, P_FE2CL_INSTANCE_MAP_INFO, sizeof(sP_FE2CL_INSTANCE_MAP_INFO)); sendPlayerTo(sock, X, Y, Z); } else { @@ -939,7 +939,7 @@ WarpLocation PlayerManager::getRespawnPoint(Player *plr) { for (auto targ : NPCManager::RespawnPoints) { curDist = sqrt(pow(plr->x - targ.x, 2) + pow(plr->y - targ.y, 2)); - if (curDist < bestDist && targ.instanceID == (plr->instanceID & 0xffffffff)) { // only mapNum needs to match + if (curDist < bestDist && targ.instanceID == MAPNUM(plr->instanceID)) { // only mapNum needs to match best = targ; bestDist = curDist; } diff --git a/src/TableData.cpp b/src/TableData.cpp index 05ef7e2..41bd55f 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -629,7 +629,7 @@ void TableData::flush() { mob["iX"] = m->spawnX; mob["iY"] = m->spawnY; mob["iZ"] = m->spawnZ; - mob["iMapNum"] = m->instanceID & 0xffffffff; + mob["iMapNum"] = MAPNUM(m->instanceID); // this is a bit imperfect, since this is a live angle, not a spawn angle so it'll change often, but eh mob["iAngle"] = m->appearanceData.iAngle; diff --git a/tdata b/tdata index 57323d6..b4a2ffd 160000 --- a/tdata +++ b/tdata @@ -1 +1 @@ -Subproject commit 57323d64af19d36d5855454bfec5fdc0a54be3dc +Subproject commit b4a2ffd37e8c966744be6730cb3507619f412718