Add NPC barking, seeing saved characters

This commit is contained in:
Eperty123 2020-08-29 13:14:21 +02:00
parent 50431024c9
commit b239fb9331
5 changed files with 713 additions and 685 deletions

View File

@ -71,7 +71,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
// now send the characters :) // now send the characters :)
/*if (charCount > 0) { if (charCount > 0) {
std::list<Player> characters = Database::getCharacters(loginSessions[sock].userID); std::list<Player> characters = Database::getCharacters(loginSessions[sock].userID);
std::list<Player>::iterator it; std::list<Player>::iterator it;
@ -135,64 +135,66 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO)); sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
for (int i = 0; i < charCount; i++) {
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
charInfo.iSlot = (int8_t)i + 1;
charInfo.iLevel = (int16_t)36;
charInfo.sPC_Style.iPC_UID = rand(); // unique identifier for the character
charInfo.sPC_Style.iNameCheck = 1;
charInfo.sPC_Style.iGender = (i%2)+1; // can be 1(boy) or 2(girl)
charInfo.sPC_Style.iFaceStyle = 1;
charInfo.sPC_Style.iHairStyle = 1;
charInfo.sPC_Style.iHairColor = (rand()%19) + 1; // 1 - 19
charInfo.sPC_Style.iSkinColor = (rand()%13) + 1; // 1 - 13
charInfo.sPC_Style.iEyeColor = (rand()%6) + 1; // 1 - 6
charInfo.sPC_Style.iHeight = (rand()%6); // 0 -5
charInfo.sPC_Style.iBody = (rand()%4); // 0 - 3
charInfo.sPC_Style.iClass = 0;
charInfo.sPC_Style2.iAppearanceFlag = 1;
charInfo.sPC_Style2.iPayzoneFlag = 1;
charInfo.sPC_Style2.iTutorialFlag = 1;
// past's town hall
charInfo.iX = settings::SPAWN_X;
charInfo.iY = settings::SPAWN_Y;
charInfo.iZ = settings::SPAWN_Z;
U8toU16(std::string("Player"), charInfo.sPC_Style.szFirstName);
U8toU16(std::to_string(i + 1), charInfo.sPC_Style.szLastName);
int64_t UID = charInfo.sPC_Style.iPC_UID;
loginSessions[sock].characters[UID] = Player();
loginSessions[sock].characters[UID].level = charInfo.iLevel;
loginSessions[sock].characters[UID].money = 9001;
loginSessions[sock].characters[UID].slot = charInfo.iSlot;
loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
loginSessions[sock].characters[UID].x = charInfo.iX;
loginSessions[sock].characters[UID].y = charInfo.iY;
loginSessions[sock].characters[UID].z = charInfo.iZ;
loginSessions[sock].characters[UID].PCStyle = charInfo.sPC_Style;
loginSessions[sock].characters[UID].PCStyle2 = charInfo.sPC_Style2;
loginSessions[sock].characters[UID].isTrading = false;
loginSessions[sock].characters[UID].isTradeConfirm = false;
loginSessions[sock].characters[UID].IsGM = settings::GM;
for (int i = 0; i < AEQUIP_COUNT; i++) {
// setup equips
charInfo.aEquip[i].iID = 0;
charInfo.aEquip[i].iType = i;
charInfo.aEquip[i].iOpt = 0;
loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
} }
for (int i = 0; i < AINVEN_COUNT; i++) {
// setup inventories
loginSessions[sock].characters[UID].Inven[i].iID = 0;
loginSessions[sock].characters[UID].Inven[i].iType = 0;
loginSessions[sock].characters[UID].Inven[i].iOpt = 0;
} }
}*/ //for (int i = 0; i < charCount; i++) {
// sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
// charInfo.iSlot = (int8_t)i + 1;
// charInfo.iLevel = (int16_t)36;
// charInfo.sPC_Style.iPC_UID = rand(); // unique identifier for the character
// charInfo.sPC_Style.iNameCheck = 1;
// charInfo.sPC_Style.iGender = (i%2)+1; // can be 1(boy) or 2(girl)
// charInfo.sPC_Style.iFaceStyle = 1;
// charInfo.sPC_Style.iHairStyle = 1;
// charInfo.sPC_Style.iHairColor = (rand()%19) + 1; // 1 - 19
// charInfo.sPC_Style.iSkinColor = (rand()%13) + 1; // 1 - 13
// charInfo.sPC_Style.iEyeColor = (rand()%6) + 1; // 1 - 6
// charInfo.sPC_Style.iHeight = (rand()%6); // 0 -5
// charInfo.sPC_Style.iBody = (rand()%4); // 0 - 3
// charInfo.sPC_Style.iClass = 0;
// charInfo.sPC_Style2.iAppearanceFlag = 1;
// charInfo.sPC_Style2.iPayzoneFlag = 1;
// charInfo.sPC_Style2.iTutorialFlag = 1;
// // past's town hall
// charInfo.iX = settings::SPAWN_X;
// charInfo.iY = settings::SPAWN_Y;
// charInfo.iZ = settings::SPAWN_Z;
// U8toU16(std::string("Player"), charInfo.sPC_Style.szFirstName);
// U8toU16(std::to_string(i + 1), charInfo.sPC_Style.szLastName);
// int64_t UID = charInfo.sPC_Style.iPC_UID;
// loginSessions[sock].characters[UID] = Player();
// loginSessions[sock].characters[UID].level = charInfo.iLevel;
// loginSessions[sock].characters[UID].money = 9001;
// loginSessions[sock].characters[UID].slot = charInfo.iSlot;
// loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
// loginSessions[sock].characters[UID].x = charInfo.iX;
// loginSessions[sock].characters[UID].y = charInfo.iY;
// loginSessions[sock].characters[UID].z = charInfo.iZ;
// loginSessions[sock].characters[UID].PCStyle = charInfo.sPC_Style;
// loginSessions[sock].characters[UID].PCStyle2 = charInfo.sPC_Style2;
// loginSessions[sock].characters[UID].isTrading = false;
// loginSessions[sock].characters[UID].isTradeConfirm = false;
// loginSessions[sock].characters[UID].IsGM = settings::GM;
// for (int i = 0; i < AEQUIP_COUNT; i++) {
// // setup equips
// charInfo.aEquip[i].iID = 0;
// charInfo.aEquip[i].iType = i;
// charInfo.aEquip[i].iOpt = 0;
// loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
// }
//
// for (int i = 0; i < AINVEN_COUNT; i++) {
// // setup inventories
// loginSessions[sock].characters[UID].Inven[i].iID = 0;
// loginSessions[sock].characters[UID].Inven[i].iType = 0;
// loginSessions[sock].characters[UID].Inven[i].iOpt = 0;
// }
//}
} }
//Failure //Failure
else { else {
@ -354,7 +356,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_SUCC, resp); INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_SUCC, resp);
resp.iSlotNum = operationResult; resp.iSlotNum = operationResult;
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC)); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC));
} else { }
else {
// failure // failure
// client doesnt't care about this packet and softlocks // client doesnt't care about this packet and softlocks
INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_FAIL, resp); INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_FAIL, resp);

View File

@ -24,7 +24,8 @@ void Database::open() {
// if exists, assign it // if exists, assign it
db = sqlite3pp::database("data.db"); db = sqlite3pp::database("data.db");
DEBUGLOG(std::cout << "Database in operation" << std::endl; ) DEBUGLOG(std::cout << "Database in operation" << std::endl; )
} else { }
else {
// if doesn't, create all the tables // if doesn't, create all the tables
DEBUGLOG(std::cout << "Creating new database" << std::endl;) DEBUGLOG(std::cout << "Creating new database" << std::endl;)
db = sqlite3pp::database("data.db"); db = sqlite3pp::database("data.db");
@ -285,7 +286,7 @@ std::list<Player> Database::getCharacters(int userID) {
std::string Database::CharacterToJson(sP_CL2LS_REQ_SAVE_CHAR_NAME* save) { std::string Database::CharacterToJson(sP_CL2LS_REQ_SAVE_CHAR_NAME* save) {
nlohmann::json json = { nlohmann::json json = {
{"Level",1}, {"Level",36},
//to check //to check
{"HP",1000}, {"HP",1000},
{"NameCheck", 1}, {"NameCheck", 1},
@ -317,9 +318,9 @@ std::string Database::CharacterToJson(sP_CL2LS_REQ_SAVE_CHAR_NAME* save) {
std::string Database::PlayerToJson(Player player) { std::string Database::PlayerToJson(Player player) {
nlohmann::json json = { nlohmann::json json = {
{"Level",1}, {"Level",player.level},
//to check //to check
{"HP",1000}, {"HP",player.HP},
{"NameCheck", 1}, {"NameCheck", 1},
{"FirstName",U16toU8(player.PCStyle.szFirstName)}, {"FirstName",U16toU8(player.PCStyle.szFirstName)},
{"LastName",U16toU8(player.PCStyle.szLastName)}, {"LastName",U16toU8(player.PCStyle.szLastName)},
@ -392,7 +393,7 @@ Player Database::JsonToPlayer(std::string input, int PC_UID) {
std::string Database::CharacterToJson(sP_CL2LS_REQ_CHAR_CREATE* character) { std::string Database::CharacterToJson(sP_CL2LS_REQ_CHAR_CREATE* character) {
nlohmann::json json = { nlohmann::json json = {
{"Level",1}, {"Level",36},
//to check //to check
{"HP",1000}, {"HP",1000},
{"NameCheck", 1}, {"NameCheck", 1},

View File

@ -28,10 +28,11 @@ void NPCManager::init() {
NPCs[tmp.appearanceData.iNPC_ID] = tmp; NPCs[tmp.appearanceData.iNPC_ID] = tmp;
if (npc.value()["id"] == 641 || npc.value()["id"] == 642) if (npc.value()["id"] == 641 || npc.value()["id"] == 642)
RespawnPoints.push_back({npc.value()["x"], npc.value()["y"], ((int)npc.value()["z"]) + RESURRECT_HEIGHT}); RespawnPoints.push_back({ npc.value()["x"], npc.value()["y"], ((int)npc.value()["z"]) + RESURRECT_HEIGHT });
} }
} catch (const std::exception& err) { }
catch (const std::exception& err) {
std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl; std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
} }
@ -51,7 +52,8 @@ void NPCManager::init() {
} }
std::cout << "[INFO] populated " << NPCs.size() << " NPCs" << std::endl; std::cout << "[INFO] populated " << NPCs.size() << " NPCs" << std::endl;
} catch (const std::exception& err) { }
catch (const std::exception& err) {
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl; std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
} }
@ -63,19 +65,21 @@ void NPCManager::init() {
infile >> warpData; infile >> warpData;
for (nlohmann::json::iterator warp = warpData.begin(); warp != warpData.end(); warp++) { for (nlohmann::json::iterator warp = warpData.begin(); warp != warpData.end(); warp++) {
WarpLocation warpLoc = {warp.value()["m_iToX"], warp.value()["m_iToY"], warp.value()["m_iToZ"]}; WarpLocation warpLoc = { warp.value()["m_iToX"], warp.value()["m_iToY"], warp.value()["m_iToZ"] };
int warpID = atoi(warp.key().c_str()); int warpID = atoi(warp.key().c_str());
Warps[warpID] = warpLoc; Warps[warpID] = warpLoc;
} }
std::cout << "[INFO] populated " << Warps.size() << " Warps" << std::endl; std::cout << "[INFO] populated " << Warps.size() << " Warps" << std::endl;
} catch (const std::exception& err) { }
catch (const std::exception& err) {
std::cerr << "[WARN] Malformed warps.json file! Reason:" << err.what() << std::endl; std::cerr << "[WARN] Malformed warps.json file! Reason:" << err.what() << std::endl;
} }
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler);
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler);
REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler);
} }
void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) { void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
@ -88,7 +92,8 @@ void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
if (diffX < settings::NPCDISTANCE && diffY < settings::NPCDISTANCE) { if (diffX < settings::NPCDISTANCE && diffY < settings::NPCDISTANCE) {
yesView.push_back(pair.first); yesView.push_back(pair.first);
} else { }
else {
noView.push_back(pair.first); noView.push_back(pair.first);
} }
} }
@ -106,7 +111,8 @@ void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
// remove from view // remove from view
view.viewableNPCs.erase(i++); view.viewableNPCs.erase(i++);
} else { }
else {
i++; i++;
} }
} }
@ -127,6 +133,45 @@ void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
PlayerManager::players[sock].viewableNPCs = view.viewableNPCs; PlayerManager::players[sock].viewableNPCs = view.viewableNPCs;
} }
void NPCManager::npcBarkHandler(CNSocket* sock, CNPacketData* data) {
sP_CL2FE_REQ_BARKER* bark = (sP_CL2FE_REQ_BARKER*)data->buf;
PlayerView& plr = PlayerManager::players[sock];
INITSTRUCT(sP_FE2CL_REP_BARKER, resp);
resp.iMissionStringID = bark->iMissionTaskID;
resp.iNPC_ID = bark->iNPC_ID;
// Send bark to other players.
for (CNSocket* otherSock : plr.viewable) {
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_BARKER, sizeof(sP_FE2CL_REP_BARKER));
}
// Then ourself.
sock->sendPacket((void*)&resp, P_FE2CL_REP_BARKER, sizeof(sP_FE2CL_REP_BARKER));
}
void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2FE_REQ_NPC_SUMMON))
return; // malformed packet
sP_CL2FE_REQ_NPC_SUMMON* req = (sP_CL2FE_REQ_NPC_SUMMON*)data->buf;
INITSTRUCT(sP_FE2CL_NPC_ENTER, resp);
Player* plr = PlayerManager::getPlayer(sock);
// permission & sanity check
if (!plr->IsGM || req->iNPCType >= 3314)
return;
resp.NPCAppearanceData.iNPC_ID = rand(); // cpunch-style
resp.NPCAppearanceData.iNPCType = req->iNPCType;
resp.NPCAppearanceData.iHP = 1000; // TODO: placeholder
resp.NPCAppearanceData.iX = plr->x;
resp.NPCAppearanceData.iY = plr->y;
resp.NPCAppearanceData.iZ = plr->z;
sock->sendPacket((void*)&resp, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER));
}
void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) { void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2FE_REQ_PC_WARP_USE_NPC)) if (data->size != sizeof(sP_CL2FE_REQ_PC_WARP_USE_NPC))
return; // malformed packet return; // malformed packet
@ -149,27 +194,4 @@ void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
plrv.viewableNPCs.clear(); plrv.viewableNPCs.clear();
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC)); sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC));
}
void NPCManager::npcSummonHandler(CNSocket *sock, CNPacketData *data) {
if (data->size != sizeof(sP_CL2FE_REQ_NPC_SUMMON))
return; // malformed packet
sP_CL2FE_REQ_NPC_SUMMON* req = (sP_CL2FE_REQ_NPC_SUMMON*)data->buf;
INITSTRUCT(sP_FE2CL_NPC_ENTER, resp);
Player *plr = PlayerManager::getPlayer(sock);
// permission & sanity check
if (!plr->IsGM || req->iNPCType >= 3314)
return;
resp.NPCAppearanceData.iNPC_ID = rand(); // cpunch-style
resp.NPCAppearanceData.iNPCType = req->iNPCType;
resp.NPCAppearanceData.iHP = 1000; // TODO: placeholder
resp.NPCAppearanceData.iX = plr->x;
resp.NPCAppearanceData.iY = plr->y;
resp.NPCAppearanceData.iZ = plr->z;
sock->sendPacket((void*)&resp, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER));
} }

View File

@ -20,7 +20,9 @@ namespace NPCManager {
extern std::vector<WarpLocation> RespawnPoints; extern std::vector<WarpLocation> RespawnPoints;
void init(); void init();
void updatePlayerNPCS(CNSocket* sock, PlayerView& plr); void npcBarkHandler(CNSocket* sock, CNPacketData* data);
void npcWarpHandler(CNSocket* sock, CNPacketData* data);
void npcSummonHandler(CNSocket* sock, CNPacketData* data); void npcSummonHandler(CNSocket* sock, CNPacketData* data);
void npcWarpHandler(CNSocket* sock, CNPacketData* data);
void updatePlayerNPCS(CNSocket* sock, PlayerView& plr);
} }

View File

@ -63,7 +63,7 @@ void PlayerManager::removePlayer(CNSocket* key) {
otherSock->sendPacket((void*)&exitPacket, P_FE2CL_PC_EXIT, sizeof(sP_FE2CL_PC_EXIT)); otherSock->sendPacket((void*)&exitPacket, P_FE2CL_PC_EXIT, sizeof(sP_FE2CL_PC_EXIT));
} }
std::cout << U16toU8(cachedView.plr->PCStyle.szFirstName) << U16toU8(cachedView.plr->PCStyle.szLastName) << " has left!" << std::endl; std::cout << U16toU8(cachedView.plr->PCStyle.szFirstName) << " " << U16toU8(cachedView.plr->PCStyle.szLastName) << " has left!" << std::endl;
std::cout << players.size() << " players" << std::endl; std::cout << players.size() << " players" << std::endl;
delete cachedView.plr; delete cachedView.plr;