mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 05:20: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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for convenience
|
Player plr = {};
|
||||||
Player& plr = lm->plr;
|
Database::getPlayer(&plr, lm->playerId);
|
||||||
|
|
||||||
plr.groupCnt = 1;
|
|
||||||
plr.iIDGroup = plr.groupIDs[0] = plr.iID;
|
|
||||||
|
|
||||||
// check if account is already in use
|
// check if account is already in use
|
||||||
if (isAccountInUse(plr.accountId)) {
|
if (isAccountInUse(plr.accountId)) {
|
||||||
// kick the other player
|
// kick the other player
|
||||||
exitDuplicate(plr.accountId);
|
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.iID = plr.iID;
|
||||||
response.uiSvrTime = getTime();
|
response.uiSvrTime = getTime();
|
||||||
response.PCLoadData2CL.iUserLevel = plr.accountLevel;
|
response.PCLoadData2CL.iUserLevel = plr.accountLevel;
|
||||||
@ -345,7 +349,7 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (pair.second->notify)
|
if (pair.second->notify)
|
||||||
Chat::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(&plr) + " has joined.");
|
Chat::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(&plr) + " has joined.");
|
||||||
|
|
||||||
// deallocate lm (and therefore the plr object)
|
// deallocate lm
|
||||||
delete lm;
|
delete lm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
struct LoginMetadata {
|
struct LoginMetadata {
|
||||||
uint64_t FEKey;
|
uint64_t FEKey;
|
||||||
Player plr;
|
int32_t playerId;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@ namespace Database {
|
|||||||
bool banPlayer(int playerId, std::string& reason);
|
bool banPlayer(int playerId, std::string& reason);
|
||||||
bool unbanPlayer(int playerId);
|
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 validateCharacter(int characterID, int userID);
|
||||||
bool isNameFree(std::string firstName, std::string lastName);
|
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;
|
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) {
|
bool Database::validateCharacter(int characterID, int userID) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
|
@ -471,11 +471,7 @@ void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
|
|||||||
LoginMetadata *lm = new LoginMetadata();
|
LoginMetadata *lm = new LoginMetadata();
|
||||||
lm->FEKey = sock->getFEKey();
|
lm->FEKey = sock->getFEKey();
|
||||||
lm->timestamp = getTime();
|
lm->timestamp = getTime();
|
||||||
|
lm->playerId = selection->iPC_UID;
|
||||||
Database::getPlayer(&lm->plr, selection->iPC_UID);
|
|
||||||
// this should never happen but for extra safety
|
|
||||||
if (lm->plr.iID == 0)
|
|
||||||
return invalidCharacter(sock);
|
|
||||||
|
|
||||||
resp.iEnterSerialKey = Rand::cryptoRand();
|
resp.iEnterSerialKey = Rand::cryptoRand();
|
||||||
|
|
||||||
@ -485,7 +481,7 @@ void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
|
|||||||
sock->sendPacket(resp, P_LS2CL_REP_SHARD_SELECT_SUCC);
|
sock->sendPacket(resp, P_LS2CL_REP_SHARD_SELECT_SUCC);
|
||||||
|
|
||||||
// update current slot in DB
|
// 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) {
|
void CNLoginServer::finishTutorial(CNSocket* sock, CNPacketData* data) {
|
||||||
|
Loading…
Reference in New Issue
Block a user