mirror of
				https://github.com/OpenFusionProject/OpenFusion.git
				synced 2025-10-31 00:30:15 +00:00 
			
		
		
		
	Assorted cleanups and fixes.
* Clean up spacing/indentation * Proper enum formatting * Fix nano dismissal (for real this time) * Do not copy Player struct when a pointer is right there * Stop looking after the trade partner has been found * Make sure we're shifting unsigned values (and 64-bit when they need to be) * Look for JSONs in tdata/ * Add a dbsaveinterval to the example config.ini, in the login category
This commit is contained in:
		| @@ -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] | ||||
|   | ||||
| @@ -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<CNSocket*, CNLoginData>::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)); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
							
								
								
									
										186
									
								
								src/Database.cpp
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								src/Database.cpp
									
									
									
									
									
								
							| @@ -113,7 +113,6 @@ std::unique_ptr<Database::Account> 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<DbPlayer>(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<char>(); | ||||
|         return db.insert(create); | ||||
|     } | ||||
|     else { | ||||
|     // fail if the player already has 4 or more characters | ||||
|     if (db.count<DbPlayer>(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<char>(); | ||||
|  | ||||
|     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 <Player> 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<char>(); | ||||
|     //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<Inventory>( | ||||
|         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<Nano>( | ||||
|         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; | ||||
|   | ||||
| @@ -86,24 +86,24 @@ namespace Database { | ||||
|     int deleteCharacter(int characterID, int userID); | ||||
|     std::vector <Player> 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); | ||||
|   | ||||
| @@ -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; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|   | ||||
| @@ -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();	 | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|   | ||||
| @@ -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++) { | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user