diff --git a/config.ini b/config.ini index 7779905..2d3471b 100644 --- a/config.ini +++ b/config.ini @@ -14,6 +14,9 @@ port=8001 randomcharacters=true # will all custom names be approved instantly? acceptallcustomnames=true +# how often should everything be flushed to the database? +# the default is 4 minutes +dbsaveinterval=240 # Shard Server configuration [shard] diff --git a/src/CNLoginServer.cpp b/src/CNLoginServer.cpp index 2c78559..d61d561 100644 --- a/src/CNLoginServer.cpp +++ b/src/CNLoginServer.cpp @@ -30,9 +30,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { std::string userPassword((char*)login->szCookie_authid); /* - * Sometimes the client sends garbage cookie data. - * Validate it as normal credentials instead of using a length check before falling back. - */ + * Sometimes the client sends garbage cookie data. + * Validate it as normal credentials instead of using a length check before falling back. + */ if (!CNLoginServer::isLoginDataGood(userLogin, userPassword)) { /* * The std::string -> char* -> std::string maneuver should remove any @@ -48,7 +48,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { //checking regex if (!CNLoginServer::isLoginDataGood(userLogin, userPassword)) { - errorCode = (int)LOGINERRORID::login_error; + errorCode = (int)LoginError::LOGIN_ERROR; } else { @@ -68,7 +68,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { if (CNLoginServer::isAccountInUse(findUser->AccountID) || PlayerManager::isAccountInUse(findUser->AccountID)) { - errorCode = (int)LOGINERRORID::id_already_in_use; + errorCode = (int)LoginError::ID_ALREADY_IN_USE; } //if not, login success else @@ -81,7 +81,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { } else { - errorCode = (int)LOGINERRORID::id_and_password_do_not_match; + errorCode = (int)LoginError::ID_AND_PASSWORD_DO_NOT_MATCH; } } @@ -169,9 +169,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { if (!CNLoginServer::isCharacterNameGood(U16toU8(nameCheck->szFirstName), U16toU8(nameCheck->szLastName))) { success = false; errorcode = 4; - } - //check if name isn't already occupied - else if (!Database::isNameFree(nameCheck)){ + } else if (!Database::isNameFree(nameCheck)){ //check if name isn't already occupied success = false; errorcode = 1; } @@ -180,16 +178,15 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC, resp); DEBUGLOG( - std::cout << "P_CL2LS_REQ_CHECK_CHAR_NAME:" << std::endl; - std::cout << "\tFirstName: " << U16toU8(nameCheck->szFirstName) << " LastName: " << U16toU8(nameCheck->szLastName) << std::endl; + std::cout << "P_CL2LS_REQ_CHECK_CHAR_NAME:" << std::endl; + std::cout << "\tFirstName: " << U16toU8(nameCheck->szFirstName) << " LastName: " << U16toU8(nameCheck->szLastName) << std::endl; ) memcpy(resp.szFirstName, nameCheck->szFirstName, sizeof(char16_t) * 9); memcpy(resp.szLastName, nameCheck->szLastName, sizeof(char16_t) * 17); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC)); - } - else { + } else { INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL, resp); resp.iErrorCode = errorcode; sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_FAIL, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL)); @@ -390,8 +387,8 @@ bool CNLoginServer::isAccountInUse(int accountId) { } return false; } -bool CNLoginServer::exitDuplicate(int accountId) -{ + +bool CNLoginServer::exitDuplicate(int accountId) { std::map::iterator it; for (it = CNLoginServer::loginSessions.begin(); it != CNLoginServer::loginSessions.end(); it++) { @@ -407,18 +404,18 @@ bool CNLoginServer::exitDuplicate(int accountId) } return false; } -bool CNLoginServer::isLoginDataGood(std::string login, std::string password) -{ + +bool CNLoginServer::isLoginDataGood(std::string login, std::string password) { std::regex loginRegex("[a-zA-Z0-9_-]{4,32}"); std::regex passwordRegex("[a-zA-Z0-9!@#$%^&*()_+]{8,32}"); return (std::regex_match(login, loginRegex) && std::regex_match(password, passwordRegex)); } -bool CNLoginServer::isPasswordCorrect(std::string actualPassword, std::string tryPassword) -{ + +bool CNLoginServer::isPasswordCorrect(std::string actualPassword, std::string tryPassword) { return BCrypt::validatePassword(tryPassword, actualPassword); } -bool CNLoginServer::isCharacterNameGood(std::string Firstname, std::string Lastname) -{ + +bool CNLoginServer::isCharacterNameGood(std::string Firstname, std::string Lastname) { std::regex firstnamecheck("[a-zA-Z0-9]+(?: [a-zA-Z0-9]+)*$"); std::regex lastnamecheck("[a-zA-Z0-9]+(?: [a-zA-Z0-9]+)*$"); return (std::regex_match(Firstname, firstnamecheck) && std::regex_match(Lastname, lastnamecheck)); diff --git a/src/CNLoginServer.hpp b/src/CNLoginServer.hpp index 6ca38c9..eea7f59 100644 --- a/src/CNLoginServer.hpp +++ b/src/CNLoginServer.hpp @@ -12,16 +12,16 @@ struct CNLoginData { int userID; int slot; }; -enum class LOGINERRORID { - database_error = 0, - id_doesnt_exist = 1, - id_and_password_do_not_match = 2, - id_already_in_use = 3, - login_error = 4, - client_version_outdated = 6, - you_are_not_an_authorized_beta_tester = 7, - authentication_connection_error = 8, - updated_euala_required = 9 +enum class LoginError { + DATABASE_ERROR = 0, + ID_DOESNT_EXIST = 1, + ID_AND_PASSWORD_DO_NOT_MATCH = 2, + ID_ALREADY_IN_USE = 3, + LOGIN_ERROR = 4, + CLIENT_VERSION_OUTDATED = 6, + YOU_ARE_NOT_AN_AUTHORIZED_BETA_TESTER = 7, + AUTHENTICATION_CONNECTION_ERROR = 8, + UPDATED_EUALA_REQUIRED = 9 }; // WARNING: THERE CAN ONLY BE ONE OF THESE SERVERS AT A TIME!!!!!! TODO: change loginSessions & packet handlers to be non-static diff --git a/src/CNShardServer.cpp b/src/CNShardServer.cpp index 134ea36..af568b7 100644 --- a/src/CNShardServer.cpp +++ b/src/CNShardServer.cpp @@ -33,7 +33,7 @@ void CNShardServer::handlePacket(CNSocket* sock, CNPacketData* data) { void CNShardServer::keepAliveTimer(CNServer* serv, uint64_t currTime) { auto cachedPlayers = PlayerManager::players; - for (auto pair : cachedPlayers) { + for (auto& pair : cachedPlayers) { if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > 60000) { // if the client hadn't responded in 60 seconds, its a dead connection so throw it out pair.first->kill(); continue; @@ -47,9 +47,10 @@ void CNShardServer::keepAliveTimer(CNServer* serv, uint64_t currTime) { void CNShardServer::periodicSaveTimer(CNServer* serv, uint64_t currTime) { auto cachedPlayers = PlayerManager::players; - for (auto pair : cachedPlayers) { - Database::updatePlayer(*pair.second.plr); - } + + for (auto& pair : cachedPlayers) { + Database::updatePlayer(pair.second.plr); + } } void CNShardServer::newConnection(CNSocket* cns) { @@ -61,8 +62,8 @@ void CNShardServer::killConnection(CNSocket* cns) { if (PlayerManager::players.find(cns) == PlayerManager::players.end()) return; - //save player to DB - Database::updatePlayer(*PlayerManager::players[cns].plr); + // save player to DB + Database::updatePlayer(PlayerManager::players[cns].plr); // remove from CNSharedData int64_t key = PlayerManager::getPlayer(cns)->SerialKey; diff --git a/src/Database.cpp b/src/Database.cpp index 7b207bc..5b8472f 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -113,7 +113,6 @@ std::unique_ptr Database::findAccount(std::string login) bool Database::isNameFree(sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck) { - //TODO: add colate nocase std::string First = U16toU8(nameCheck->szFirstName); std::string Last = U16toU8(nameCheck->szLastName); return @@ -125,45 +124,49 @@ bool Database::isNameFree(sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck) int Database::createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID) { - if (db.count(where(c(&DbPlayer::AccountID) == AccountID))<4) { - DbPlayer create = {}; - //save packet data - create.FirstName = U16toU8(save->szFirstName); - create.LastName = U16toU8(save->szLastName); - create.slot = save->iSlotNum; - create.AccountID = AccountID; - //set flags - create.AppearanceFlag = 0; - create.TutorialFlag = 0; - create.PayZoneFlag = 0; - //set namecheck based on setting - if (settings::APPROVEALLNAMES || save->iFNCode) - create.NameCheck = 1; - else - create.NameCheck = 0; - //create default body character - create.Body = 0; - create.Class = 0; - create.EyeColor = 1; - create.FaceStyle = 1; - create.Gender = 1; - create.HP = 1000; - create.HairColor = 1; - create.HairStyle = 1; - create.Height = 0; - create.Level = 1; - create.SkinColor = 1; - create.isGM = false; - create.x_coordinates = settings::SPAWN_X; - create.y_coordinates = settings::SPAWN_Y; - create.z_coordinates = settings::SPAWN_Z; - create.angle = settings::SPAWN_ANGLE; - create.QuestFlag = std::vector(); - return db.insert(create); - } - else { + // fail if the player already has 4 or more characters + if (db.count(where(c(&DbPlayer::AccountID) == AccountID)) >= 4) return -1; - } + + DbPlayer create = {}; + + //save packet data + create.FirstName = U16toU8(save->szFirstName); + create.LastName = U16toU8(save->szLastName); + create.slot = save->iSlotNum; + create.AccountID = AccountID; + + //set flags + create.AppearanceFlag = 0; + create.TutorialFlag = 0; + create.PayZoneFlag = 0; + + //set namecheck based on setting + if (settings::APPROVEALLNAMES || save->iFNCode) + create.NameCheck = 1; + else + create.NameCheck = 0; + + //create default body character + create.Body = 0; + create.Class = 0; + create.EyeColor = 1; + create.FaceStyle = 1; + create.Gender = 1; + create.HP = 1000; + create.HairColor = 1; + create.HairStyle = 1; + create.Height = 0; + create.Level = 1; + create.SkinColor = 1; + create.isGM = false; + create.x_coordinates = settings::SPAWN_X; + create.y_coordinates = settings::SPAWN_Y; + create.z_coordinates = settings::SPAWN_Z; + create.angle = settings::SPAWN_ANGLE; + create.QuestFlag = std::vector(); + + return db.insert(create); } void Database::finishCharacter(sP_CL2LS_REQ_CHAR_CREATE* character) @@ -231,7 +234,7 @@ void Database::finishTutorial(int PlayerID) MissionManager::saveMission(&finish, 0); MissionManager::saveMission(&finish, 1); - db.update(playerToDb(finish)); + db.update(playerToDb(&finish)); } int Database::deleteCharacter(int characterID, int userID) @@ -262,7 +265,8 @@ std::vector Database::getCharacters(int UserID) return result; } -void Database::evaluateCustomName(int characterID, CUSTOMNAME decision) { +// XXX: This is never called? +void Database::evaluateCustomName(int characterID, CustomName decision) { DbPlayer player = getDbPlayerById(characterID); player.NameCheck = (int)decision; db.update(player); @@ -279,48 +283,48 @@ void Database::changeName(sP_CL2LS_REQ_CHANGE_CHAR_NAME* save) { db.update(Player); } -Database::DbPlayer Database::playerToDb(Player player) +Database::DbPlayer Database::playerToDb(Player *player) { DbPlayer result = {}; // fixes some weird memory errors, this zeros out the members (not the padding inbetween though) - result.PlayerID = player.iID; - result.AccountID = player.accountId; - result.AppearanceFlag = player.PCStyle2.iAppearanceFlag; - result.Body = player.PCStyle.iBody; - result.Class = player.PCStyle.iClass; - result.EyeColor = player.PCStyle.iEyeColor; - result.FaceStyle = player.PCStyle.iFaceStyle; - result.FirstName = U16toU8( player.PCStyle.szFirstName); - result.FusionMatter = player.fusionmatter; - result.Gender = player.PCStyle.iGender; - result.HairColor = player.PCStyle.iHairColor; - result.HairStyle = player.PCStyle.iHairStyle; - result.Height = player.PCStyle.iHeight; - result.HP = player.HP; - result.isGM = player.IsGM; - result.LastName = U16toU8(player.PCStyle.szLastName); - result.Level = player.level; - result.NameCheck = player.PCStyle.iNameCheck; - result.PayZoneFlag = player.PCStyle2.iPayzoneFlag; - result.PlayerID = player.PCStyle.iPC_UID; - result.SkinColor = player.PCStyle.iSkinColor; - result.slot = player.slot; - result.Taros = player.money; - result.TutorialFlag = player.PCStyle2.iTutorialFlag; - result.x_coordinates = player.x; - result.y_coordinates = player.y; - result.z_coordinates = player.z; - result.angle = player.angle; - result.Nano1 = player.equippedNanos[0]; - result.Nano2 = player.equippedNanos[1]; - result.Nano3 = player.equippedNanos[2]; + result.PlayerID = player->iID; + result.AccountID = player->accountId; + result.AppearanceFlag = player->PCStyle2.iAppearanceFlag; + result.Body = player->PCStyle.iBody; + result.Class = player->PCStyle.iClass; + result.EyeColor = player->PCStyle.iEyeColor; + result.FaceStyle = player->PCStyle.iFaceStyle; + result.FirstName = U16toU8( player->PCStyle.szFirstName); + result.FusionMatter = player->fusionmatter; + result.Gender = player->PCStyle.iGender; + result.HairColor = player->PCStyle.iHairColor; + result.HairStyle = player->PCStyle.iHairStyle; + result.Height = player->PCStyle.iHeight; + result.HP = player->HP; + result.isGM = player->IsGM; + result.LastName = U16toU8(player->PCStyle.szLastName); + result.Level = player->level; + result.NameCheck = player->PCStyle.iNameCheck; + result.PayZoneFlag = player->PCStyle2.iPayzoneFlag; + result.PlayerID = player->PCStyle.iPC_UID; + result.SkinColor = player->PCStyle.iSkinColor; + result.slot = player->slot; + result.Taros = player->money; + result.TutorialFlag = player->PCStyle2.iTutorialFlag; + result.x_coordinates = player->x; + result.y_coordinates = player->y; + result.z_coordinates = player->z; + result.angle = player->angle; + result.Nano1 = player->equippedNanos[0]; + result.Nano2 = player->equippedNanos[1]; + result.Nano3 = player->equippedNanos[2]; //quests result.QuestFlag = std::vector(); //parsing long array to char vector for (int i=0; i<16; i++) { - int64_t temp = player.aQuestFlag[i]; + int64_t temp = player->aQuestFlag[i]; for (int j = 0; j < 8; j++) { int64_t check2 = (temp >> (8 * (7 - j))); char toadd = check2; @@ -408,26 +412,26 @@ Player Database::getPlayer(int id) { #pragma region ShardServer -void Database::updatePlayer(Player player) { +void Database::updatePlayer(Player *player) { DbPlayer toUpdate = playerToDb(player); db.update(toUpdate); updateInventory(player); updateNanos(player); } -void Database::updateInventory(Player player){ +void Database::updateInventory(Player *player){ //start transaction db.begin_transaction(); //remove all db.remove_all( - where(c(&Inventory::playerId) == player.iID) + where(c(&Inventory::playerId) == player->iID) ); //insert equip for (int i = 0; i < AEQUIP_COUNT; i++) { - if (player.Equip[i].iID != 0) { - sItemBase* next = &player.Equip[i]; + if (player->Equip[i].iID != 0) { + sItemBase* next = &player->Equip[i]; Inventory toAdd = {}; - toAdd.playerId = player.iID; + toAdd.playerId = player->iID; toAdd.slot = i; toAdd.id = next->iID; toAdd.Opt = next->iOpt; @@ -438,10 +442,10 @@ void Database::updateInventory(Player player){ } //insert inventory for (int i = 0; i < AINVEN_COUNT; i++) { - if (player.Inven[i].iID != 0) { - sItemBase* next = &player.Inven[i]; + if (player->Inven[i].iID != 0) { + sItemBase* next = &player->Inven[i]; Inventory toAdd = {}; - toAdd.playerId = player.iID; + toAdd.playerId = player->iID; toAdd.slot = i + AEQUIP_COUNT; toAdd.id = next->iID; toAdd.Opt = next->iOpt; @@ -452,10 +456,10 @@ void Database::updateInventory(Player player){ } //insert bank for (int i = 0; i < ABANK_COUNT; i++) { - if (player.Bank[i].iID != 0) { - sItemBase* next = &player.Bank[i]; + if (player->Bank[i].iID != 0) { + sItemBase* next = &player->Bank[i]; Inventory toAdd = {}; - toAdd.playerId = player.iID; + toAdd.playerId = player->iID; toAdd.slot = i + AEQUIP_COUNT + AINVEN_COUNT; toAdd.id = next->iID; toAdd.Opt = next->iOpt; @@ -466,21 +470,21 @@ void Database::updateInventory(Player player){ } db.commit(); } -void Database::updateNanos(Player player) { +void Database::updateNanos(Player *player) { //start transaction db.begin_transaction(); //remove all db.remove_all( - where(c(&Nano::playerId) == player.iID) + where(c(&Nano::playerId) == player->iID) ); //insert for (int i=1; i < SIZEOF_NANO_BANK_SLOT; i++) { - if ((player.Nanos[i]).iID == 0) + if ((player->Nanos[i]).iID == 0) continue; Nano toAdd = {}; - sNano* next = &player.Nanos[i]; - toAdd.playerId = player.iID; + sNano* next = &player->Nanos[i]; + toAdd.playerId = player->iID; toAdd.iID = next->iID; toAdd.iSkillID = next->iSkillID; toAdd.iStamina = next->iStamina; diff --git a/src/Database.hpp b/src/Database.hpp index 1b517c5..68c604e 100644 --- a/src/Database.hpp +++ b/src/Database.hpp @@ -86,24 +86,24 @@ namespace Database { int deleteCharacter(int characterID, int userID); std::vector getCharacters(int userID); //accepting/declining custom name - enum class CUSTOMNAME { - approve = 1, - disapprove = 2 + enum class CustomName { + APPROVE = 1, + DISAPPROVE = 2 }; - void evaluateCustomName(int characterID, CUSTOMNAME decision); + void evaluateCustomName(int characterID, CustomName decision); void changeName(sP_CL2LS_REQ_CHANGE_CHAR_NAME* save); //parsing DbPlayer - DbPlayer playerToDb(Player player); + DbPlayer playerToDb(Player *player); Player DbToPlayer(DbPlayer player); //getting players DbPlayer getDbPlayerById(int id); Player getPlayer(int id); - void updatePlayer(Player player); - void updateInventory(Player player); - void updateNanos(Player player); + void updatePlayer(Player *player); + void updateInventory(Player *player); + void updateNanos(Player *player); void getInventory(Player* player); void getNanos(Player* player); diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index f1fe611..70f813b 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -55,28 +55,28 @@ void ItemManager::itemMoveHandler(CNSocket* sock, CNPacketData* data) { //get the fromItem sItemBase *fromItem; - switch (itemmove->eFrom) { - case (int)slot::equip: + switch ((SlotType)itemmove->eFrom) { + case SlotType::EQUIP: fromItem = &plr.plr->Equip[itemmove->iFromSlotNum]; break; - case (int)slot::inventory: + case SlotType::INVENTORY: fromItem = &plr.plr->Inven[itemmove->iFromSlotNum]; break; - case (int)slot::bank: + case SlotType::BANK: fromItem = &plr.plr->Bank[itemmove->iFromSlotNum]; break; } //get the toItem sItemBase* toItem; - switch (itemmove->eTo) { - case (int)slot::equip: + switch ((SlotType)itemmove->eTo) { + case SlotType::EQUIP: toItem = &plr.plr->Equip[itemmove->iToSlotNum]; break; - case (int)slot::inventory: + case SlotType::INVENTORY: toItem = &plr.plr->Inven[itemmove->iToSlotNum]; break; - case (int)slot::bank: + case SlotType::BANK: toItem = &plr.plr->Bank[itemmove->iToSlotNum]; break; } @@ -91,11 +91,11 @@ void ItemManager::itemMoveHandler(CNSocket* sock, CNPacketData* data) { *fromItem = temp; //send equip change to viewable players - if (itemmove->eFrom == (int)slot::equip || itemmove->eTo == (int)slot::equip) { + if (itemmove->eFrom == (int)SlotType::EQUIP || itemmove->eTo == (int)SlotType::EQUIP) { INITSTRUCT(sP_FE2CL_PC_EQUIP_CHANGE, equipChange); equipChange.iPC_ID = plr.plr->iID; - if (itemmove->eFrom == (int)slot::equip) { + if (itemmove->eFrom == (int)SlotType::EQUIP) { equipChange.iEquipSlotNum = itemmove->iFromSlotNum; equipChange.EquipSlotItem = resp.ToSlotItem; } @@ -202,9 +202,10 @@ void ItemManager::itemTradeOfferHandler(CNSocket* sock, CNPacketData* data) { CNSocket* otherSock = sock; - for (auto pair : PlayerManager::players) { + for (auto& pair : PlayerManager::players) { if (pair.second.plr->iID == iID_Check) { otherSock = pair.first; + break; } } @@ -247,9 +248,10 @@ void ItemManager::itemTradeOfferAcceptHandler(CNSocket* sock, CNPacketData* data CNSocket* otherSock = sock; - for (auto pair : PlayerManager::players) { + for (auto& pair : PlayerManager::players) { if (pair.second.plr->iID == iID_Check) { otherSock = pair.first; + break; } } @@ -281,21 +283,8 @@ void ItemManager::itemTradeOfferAcceptHandler(CNSocket* sock, CNPacketData* data plr.plr->isTradeConfirm = false; plr2.plr->isTradeConfirm = false; - for (int i = 0; i < 5; i++) { - plr.plr->Trade[i].iID = 0; - plr.plr->Trade[i].iType = 0; - plr.plr->Trade[i].iOpt = 0; - plr.plr->Trade[i].iInvenNum = 0; - plr.plr->Trade[i].iSlotNum = 0; - } - - for (int i = 0; i < 5; i++) { - plr2.plr->Trade[i].iID = 0; - plr2.plr->Trade[i].iType = 0; - plr2.plr->Trade[i].iOpt = 0; - plr2.plr->Trade[i].iInvenNum = 0; - plr2.plr->Trade[i].iSlotNum = 0; - } + memset(&plr.plr->Trade, 0, sizeof(plr.plr->Trade)); + memset(&plr2.plr->Trade, 0, sizeof(plr2.plr->Trade)); otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_SUCC)); } @@ -321,9 +310,10 @@ void ItemManager::itemTradeOfferRefusalHandler(CNSocket* sock, CNPacketData* dat CNSocket* otherSock = sock; - for (auto pair : PlayerManager::players) { + for (auto& pair : PlayerManager::players) { if (pair.second.plr->iID == iID_Check) { otherSock = pair.first; + break; } } @@ -346,9 +336,10 @@ void ItemManager::itemTradeConfirmHandler(CNSocket* sock, CNPacketData* data) { CNSocket* otherSock = sock; - for (auto pair : PlayerManager::players) { + for (auto& pair : PlayerManager::players) { if (pair.second.plr->iID == iID_Check) { otherSock = pair.first; + break; } } diff --git a/src/ItemManager.hpp b/src/ItemManager.hpp index a0c9685..3f4103b 100644 --- a/src/ItemManager.hpp +++ b/src/ItemManager.hpp @@ -4,10 +4,10 @@ #include "Player.hpp" namespace ItemManager { - enum class slot { - equip = 0, - inventory = 1, - bank = 3 + enum class SlotType { + EQUIP = 0, + INVENTORY = 1, + BANK = 3 }; void init(); diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index ed39106..8af6a97 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -334,6 +334,6 @@ void MissionManager::mobKilled(CNSocket *sock, int mobid) { void MissionManager::saveMission(Player* player, int missionId) { //Missions are stored in int_64t array int row = missionId / 64; - int collumn = missionId % 64; - player->aQuestFlag[row] |= (1LL << collumn); + int column = missionId % 64; + player->aQuestFlag[row] |= (1ULL << column); } diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index 236b62b..d48ed5d 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -152,6 +152,7 @@ void NanoManager::addNano(CNSocket* sock, int16_t nanoId, int16_t slot) { // Update player plr->Nanos[nanoId] = resp.Nano; plr->level = level; + plr->HP = 1000 * plr->level; sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_NANO_CREATE_SUCC, sizeof(sP_FE2CL_REP_PC_NANO_CREATE_SUCC)); @@ -183,16 +184,17 @@ void NanoManager::summonNano(CNSocket *sock, int slot) { int nanoId = slot == -1 ? -1 : plr->equippedNanos[slot]; - if (nanoId > 36 || nanoId < 0) + if (nanoId > 36 || nanoId < -1) return; // sanity check - sNano nano = plr->Nanos[nanoId]; - // Send to other players INITSTRUCT(sP_FE2CL_NANO_ACTIVE, pkt1); pkt1.iPC_ID = plr->iID; - pkt1.Nano = nano; + if (nanoId == -1) + memset(&pkt1.Nano, 0, sizeof(pkt1.Nano)); + else + pkt1.Nano = plr->Nanos[nanoId]; for (CNSocket* s : PlayerManager::players[sock].viewable) s->sendPacket((void*)&pkt1, P_FE2CL_NANO_ACTIVE, sizeof(sP_FE2CL_NANO_ACTIVE)); diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index f6416c2..05867c9 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -200,7 +200,7 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { std::cout << "\tSerial: " << enter->iEnterSerialKey << std::endl; std::cout << "\tTemp: " << enter->iTempValue << std::endl; std::cout << "\tPC_UID: " << plr.PCStyle.iPC_UID << std::endl; - ) + ) response.iID = plr.iID; response.uiSvrTime = getTime(); @@ -233,7 +233,6 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { for (int i = 0; i < 3; i++) { response.PCLoadData2CL.aNanoSlots[i] = plr.equippedNanos[i]; } - response.PCLoadData2CL.aQuestFlag[0] = -1; //missions for (int i = 0; i < 16; i++) { diff --git a/src/TransportManager.cpp b/src/TransportManager.cpp index a183bac..f93f616 100644 --- a/src/TransportManager.cpp +++ b/src/TransportManager.cpp @@ -34,7 +34,7 @@ void TransportManager::transportRegisterLocationHandler(CNSocket* sock, CNPacket } // update registration bitfield using bit shifting + bitwise or - plr->iWarpLocationFlag |= (1 << (transport->iLocationID - 1)); + plr->iWarpLocationFlag |= (1UL << (transport->iLocationID - 1)); } else if (transport->eTT == 2) { // Monkey Skyway System if (transport->iLocationID < 1 || transport->iLocationID > 127) { // sanity check std::cout << "[WARN] Skyway location ID " << transport->iLocationID << " is out of bounds" << std::endl; @@ -52,7 +52,7 @@ void TransportManager::transportRegisterLocationHandler(CNSocket* sock, CNPacket * assuming the two bitfields are just stuck together to make a longer one... do a similar operation, but on the respective integer * this approach seems to work with initial testing, but we have yet to see a monkey ID greater than 63. */ - plr->aSkywayLocationFlag[transport->iLocationID > 63 ? 1 : 0] |= (1 << (transport->iLocationID > 63 ? transport->iLocationID - 65 : transport->iLocationID - 1)); + plr->aSkywayLocationFlag[transport->iLocationID > 63 ? 1 : 0] |= (1ULL << (transport->iLocationID > 63 ? transport->iLocationID - 65 : transport->iLocationID - 1)); } else { std::cout << "[WARN] Unknown mode of transport; eTT = " << transport->eTT << std::endl; INITSTRUCT(sP_FE2CL_REP_PC_REGIST_TRANSPORTATION_LOCATION_FAIL, failResp); diff --git a/src/settings.cpp b/src/settings.cpp index 1309207..6da8989 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -19,9 +19,9 @@ int settings::SPAWN_X = 632032; int settings::SPAWN_Y = 187177; int settings::SPAWN_Z = -5500; int settings::SPAWN_ANGLE = 130; -std::string settings::NPCJSON = "data/NPCs.json"; -std::string settings::XDTJSON = "data/xdt.json"; -std::string settings::MOBJSON = "data/mobs.json"; +std::string settings::NPCJSON = "tdata/NPCs.json"; +std::string settings::XDTJSON = "tdata/xdt.json"; +std::string settings::MOBJSON = "tdata/mobs.json"; std::string settings::MOTDSTRING = "Welcome to OpenFusion!"; bool settings::GM = false; @@ -42,7 +42,7 @@ void settings::init() { LOGINPORT = reader.GetInteger("login", "port", LOGINPORT); SHARDPORT = reader.GetInteger("shard", "port", SHARDPORT); SHARDSERVERIP = reader.Get("shard", "ip", "127.0.0.1"); - DBSAVEINTERVAL = reader.GetInteger("shard", "dbsaveinterval", DBSAVEINTERVAL); + DBSAVEINTERVAL = reader.GetInteger("login", "dbsaveinterval", DBSAVEINTERVAL); PLAYERDISTANCE = reader.GetInteger("shard", "playerdistance", PLAYERDISTANCE); NPCDISTANCE = reader.GetInteger("shard", "npcdistance", NPCDISTANCE); SPAWN_X = reader.GetInteger("shard", "spawnx", SPAWN_X);