mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-22 19:30:05 +00:00
On login, load Player from DB in shard thread, not in login thread
This avoids some needless data shuffling and fixes a rare desync.
This commit is contained in:
parent
d92b407349
commit
3f44f53f97
@ -224,18 +224,22 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// for convenience
|
||||
Player& plr = lm->plr;
|
||||
|
||||
plr.groupCnt = 1;
|
||||
plr.iIDGroup = plr.groupIDs[0] = plr.iID;
|
||||
Player plr = {};
|
||||
Database::getPlayer(&plr, lm->playerId);
|
||||
|
||||
// check if account is already in use
|
||||
if (isAccountInUse(plr.accountId)) {
|
||||
// kick the other player
|
||||
exitDuplicate(plr.accountId);
|
||||
|
||||
// re-read the player from disk, in case it was just flushed
|
||||
plr = {};
|
||||
Database::getPlayer(&plr, lm->playerId);
|
||||
}
|
||||
|
||||
plr.groupCnt = 1;
|
||||
plr.iIDGroup = plr.groupIDs[0] = plr.iID;
|
||||
|
||||
response.iID = plr.iID;
|
||||
response.uiSvrTime = getTime();
|
||||
response.PCLoadData2CL.iUserLevel = plr.accountLevel;
|
||||
@ -345,7 +349,7 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
if (pair.second->notify)
|
||||
Chat::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(&plr) + " has joined.");
|
||||
|
||||
// deallocate lm (and therefore the plr object)
|
||||
// deallocate lm
|
||||
delete lm;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
struct LoginMetadata {
|
||||
uint64_t FEKey;
|
||||
Player plr;
|
||||
int32_t playerId;
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
|
@ -52,7 +52,8 @@ namespace Database {
|
||||
bool banPlayer(int playerId, std::string& reason);
|
||||
bool unbanPlayer(int playerId);
|
||||
|
||||
void updateSelected(int accountId, int playerId);
|
||||
void updateSelected(int accountId, int slot);
|
||||
void updateSelectedByPlayerId(int accountId, int playerId);
|
||||
|
||||
bool validateCharacter(int characterID, int userID);
|
||||
bool isNameFree(std::string firstName, std::string lastName);
|
||||
|
@ -79,6 +79,29 @@ void Database::updateSelected(int accountId, int slot) {
|
||||
std::cout << "[WARN] Database fail on updateSelected(): " << sqlite3_errmsg(db) << std::endl;
|
||||
}
|
||||
|
||||
void Database::updateSelectedByPlayerId(int accountId, int32_t playerId) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
UPDATE Accounts SET
|
||||
Selected = p.Slot,
|
||||
LastLogin = (strftime('%s', 'now'))
|
||||
FROM (SELECT Slot From Players WHERE PlayerId = ?) AS p
|
||||
WHERE AccountID = ?;
|
||||
)";
|
||||
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, playerId);
|
||||
sqlite3_bind_int(stmt, 2, accountId);
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (rc != SQLITE_DONE)
|
||||
std::cout << "[WARN] Database fail on updateSelectedByPlayerId(): " << sqlite3_errmsg(db) << std::endl;
|
||||
}
|
||||
|
||||
bool Database::validateCharacter(int characterID, int userID) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
|
@ -471,11 +471,7 @@ void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
|
||||
LoginMetadata *lm = new LoginMetadata();
|
||||
lm->FEKey = sock->getFEKey();
|
||||
lm->timestamp = getTime();
|
||||
|
||||
Database::getPlayer(&lm->plr, selection->iPC_UID);
|
||||
// this should never happen but for extra safety
|
||||
if (lm->plr.iID == 0)
|
||||
return invalidCharacter(sock);
|
||||
lm->playerId = selection->iPC_UID;
|
||||
|
||||
resp.iEnterSerialKey = Rand::cryptoRand();
|
||||
|
||||
@ -485,7 +481,7 @@ void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
|
||||
sock->sendPacket(resp, P_LS2CL_REP_SHARD_SELECT_SUCC);
|
||||
|
||||
// update current slot in DB
|
||||
Database::updateSelected(loginSessions[sock].userID, lm->plr.slot);
|
||||
Database::updateSelectedByPlayerId(loginSessions[sock].userID, selection->iPC_UID);
|
||||
}
|
||||
|
||||
void CNLoginServer::finishTutorial(CNSocket* sock, CNPacketData* data) {
|
||||
|
Loading…
Reference in New Issue
Block a user