mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2025-10-02 04:30:06 +00:00
[refactor] Split Database.cpp into db subdirectory
* Database.hpp is still the only external include file (moved to db/) * The header is still uppercase to match its namespace * db/internal.hpp is the shared header for the DB source files * Added -Isrc/ compile flag for src-relative include paths * Hoisted CHDR above CSRC in Makefile (it was bothering me) * make clean now removes all objects in the subdirectories as well
This commit is contained in:
536
src/db/login.cpp
Normal file
536
src/db/login.cpp
Normal file
@@ -0,0 +1,536 @@
|
||||
#include "db/internal.hpp"
|
||||
|
||||
#include "bcrypt/BCrypt.hpp"
|
||||
|
||||
void Database::findAccount(Account* account, std::string login) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
SELECT AccountID, Password, Selected, BannedUntil, BanReason
|
||||
FROM Accounts
|
||||
WHERE Login = ?
|
||||
LIMIT 1;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_text(stmt, 1, login.c_str(), -1, NULL);
|
||||
|
||||
int rc = sqlite3_step(stmt);
|
||||
if (rc == SQLITE_ROW) {
|
||||
account->AccountID = sqlite3_column_int(stmt, 0);
|
||||
account->Password = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));
|
||||
account->Selected = sqlite3_column_int(stmt, 2);
|
||||
account->BannedUntil = sqlite3_column_int64(stmt, 3);
|
||||
account->BanReason = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4));
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
int Database::addAccount(std::string login, std::string password) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
INSERT INTO Accounts (Login, Password, AccountLevel)
|
||||
VALUES (?, ?, ?);
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_text(stmt, 1, login.c_str(), -1, NULL);
|
||||
std::string hashedPassword = BCrypt::generateHash(password);
|
||||
sqlite3_bind_text(stmt, 2, hashedPassword.c_str(), -1, NULL);
|
||||
sqlite3_bind_int(stmt, 3, settings::ACCLEVEL);
|
||||
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
if (rc != SQLITE_DONE) {
|
||||
std::cout << "[WARN] Database: failed to add new account" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sqlite3_last_insert_rowid(db);
|
||||
}
|
||||
|
||||
void Database::updateSelected(int accountId, int slot) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
if (slot < 1 || slot > 4) {
|
||||
std::cout << "[WARN] Invalid slot number passed to updateSelected()! " << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
const char* sql = R"(
|
||||
UPDATE Accounts SET
|
||||
Selected = ?,
|
||||
LastLogin = (strftime('%s', 'now'))
|
||||
WHERE AccountID = ?;
|
||||
)";
|
||||
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, slot);
|
||||
sqlite3_bind_int(stmt, 2, accountId);
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (rc != SQLITE_DONE)
|
||||
std::cout << "[WARN] Database fail on updateSelected(): " << sqlite3_errmsg(db) << std::endl;
|
||||
}
|
||||
|
||||
bool Database::validateCharacter(int characterID, int userID) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
// query whatever
|
||||
const char* sql = R"(
|
||||
SELECT PlayerID
|
||||
FROM Players
|
||||
WHERE PlayerID = ? AND AccountID = ?
|
||||
LIMIT 1;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, characterID);
|
||||
sqlite3_bind_int(stmt, 2, userID);
|
||||
int rc = sqlite3_step(stmt);
|
||||
// if we got a row back, the character is valid
|
||||
bool result = (rc == SQLITE_ROW);
|
||||
sqlite3_finalize(stmt);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Database::isNameFree(std::string firstName, std::string lastName) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
SELECT COUNT(*)
|
||||
FROM Players
|
||||
WHERE FirstName = ? AND LastName = ?
|
||||
LIMIT 1;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_text(stmt, 1, firstName.c_str(), -1, NULL);
|
||||
sqlite3_bind_text(stmt, 2, lastName.c_str(), -1, NULL);
|
||||
int rc = sqlite3_step(stmt);
|
||||
|
||||
bool result = (rc == SQLITE_ROW && sqlite3_column_int(stmt, 0) == 0);
|
||||
sqlite3_finalize(stmt);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Database::isSlotFree(int accountId, int slotNum) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
if (slotNum < 1 || slotNum > 4) {
|
||||
std::cout << "[WARN] Invalid slot number passed to isSlotFree()! " << slotNum << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* sql = R"(
|
||||
SELECT COUNT(*)
|
||||
FROM Players
|
||||
WHERE AccountID = ? AND Slot = ?
|
||||
LIMIT 1;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, accountId);
|
||||
sqlite3_bind_int(stmt, 2, slotNum);
|
||||
int rc = sqlite3_step(stmt);
|
||||
|
||||
bool result = (rc == SQLITE_ROW && sqlite3_column_int(stmt, 0) == 0);
|
||||
sqlite3_finalize(stmt);
|
||||
return result;
|
||||
}
|
||||
|
||||
int Database::createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
||||
|
||||
const char* sql = R"(
|
||||
INSERT INTO Players
|
||||
(AccountID, Slot, FirstName, LastName,
|
||||
XCoordinate, YCoordinate, ZCoordinate, Angle,
|
||||
HP, NameCheck, Quests, SkywayLocationFlag, FirstUseFlag)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
std::string firstName = U16toU8(save->szFirstName);
|
||||
std::string lastName = U16toU8(save->szLastName);
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, AccountID);
|
||||
sqlite3_bind_int(stmt, 2, save->iSlotNum);
|
||||
sqlite3_bind_text(stmt, 3, firstName.c_str(), -1, NULL);
|
||||
sqlite3_bind_text(stmt, 4, lastName.c_str(), -1, NULL);
|
||||
sqlite3_bind_int(stmt, 5, settings::SPAWN_X);
|
||||
sqlite3_bind_int(stmt, 6, settings::SPAWN_Y);
|
||||
sqlite3_bind_int(stmt, 7, settings::SPAWN_Z);
|
||||
sqlite3_bind_int(stmt, 8, settings::SPAWN_ANGLE);
|
||||
sqlite3_bind_int(stmt, 9, PC_MAXHEALTH(1));
|
||||
|
||||
// if FNCode isn't 0, it's a wheel name
|
||||
int nameCheck = (settings::APPROVEALLNAMES || save->iFNCode) ? 1 : 0;
|
||||
sqlite3_bind_int(stmt, 10, nameCheck);
|
||||
|
||||
// blobs
|
||||
unsigned char blobBuffer[sizeof(Player::aQuestFlag)] = { 0 };
|
||||
sqlite3_bind_blob(stmt, 11, blobBuffer, sizeof(Player::aQuestFlag), NULL);
|
||||
sqlite3_bind_blob(stmt, 12, blobBuffer, sizeof(Player::aSkywayLocationFlag), NULL);
|
||||
sqlite3_bind_blob(stmt, 13, blobBuffer, sizeof(Player::iFirstUseFlag), NULL);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int playerId = sqlite3_last_insert_rowid(db);
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
sql = R"(
|
||||
INSERT INTO Appearances (PlayerID)
|
||||
VALUES (?);
|
||||
)";
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, playerId);
|
||||
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
if (rc != SQLITE_DONE) {
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
|
||||
return playerId;
|
||||
}
|
||||
|
||||
bool Database::finishCharacter(sP_CL2LS_REQ_CHAR_CREATE* character, int accountId) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
||||
|
||||
const char* sql = R"(
|
||||
UPDATE Players
|
||||
SET AppearanceFlag = 1
|
||||
WHERE PlayerID = ? AND AccountID = ? AND AppearanceFlag = 0;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, character->PCStyle.iPC_UID);
|
||||
sqlite3_bind_int(stmt, 2, accountId);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
sql = R"(
|
||||
UPDATE Appearances
|
||||
SET
|
||||
Body = ?,
|
||||
EyeColor = ?,
|
||||
FaceStyle = ?,
|
||||
Gender = ?,
|
||||
HairColor = ?,
|
||||
HairStyle = ?,
|
||||
Height = ?,
|
||||
SkinColor = ?
|
||||
WHERE PlayerID = ?;
|
||||
)";
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, character->PCStyle.iBody);
|
||||
sqlite3_bind_int(stmt, 2, character->PCStyle.iEyeColor);
|
||||
sqlite3_bind_int(stmt, 3, character->PCStyle.iFaceStyle);
|
||||
sqlite3_bind_int(stmt, 4, character->PCStyle.iGender);
|
||||
sqlite3_bind_int(stmt, 5, character->PCStyle.iHairColor);
|
||||
sqlite3_bind_int(stmt, 6, character->PCStyle.iHairStyle);
|
||||
sqlite3_bind_int(stmt, 7, character->PCStyle.iHeight);
|
||||
sqlite3_bind_int(stmt, 8, character->PCStyle.iSkinColor);
|
||||
sqlite3_bind_int(stmt, 9, character->PCStyle.iPC_UID);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
sql = R"(
|
||||
INSERT INTO Inventory (PlayerID, Slot, ID, Type, Opt)
|
||||
VALUES (?, ?, ?, ?, 1);
|
||||
)";
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||
|
||||
int items[3] = { character->sOn_Item.iEquipUBID, character->sOn_Item.iEquipLBID, character->sOn_Item.iEquipFootID };
|
||||
for (int i = 0; i < 3; i++) {
|
||||
sqlite3_bind_int(stmt, 1, character->PCStyle.iPC_UID);
|
||||
sqlite3_bind_int(stmt, 2, i+1);
|
||||
sqlite3_bind_int(stmt, 3, items[i]);
|
||||
sqlite3_bind_int(stmt, 4, i+1);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::finishTutorial(int playerID, int accountID) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
||||
|
||||
const char* sql = R"(
|
||||
UPDATE Players SET
|
||||
TutorialFlag = 1,
|
||||
Nano1 = ?,
|
||||
Quests = ?
|
||||
WHERE PlayerID = ? AND AccountID = ? AND TutorialFlag = 0;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
|
||||
unsigned char questBuffer[128] = { 0 };
|
||||
|
||||
#ifndef ACADEMY
|
||||
// save missions nr 1 & 2; equip Buttercup
|
||||
questBuffer[0] = 3;
|
||||
sqlite3_bind_int(stmt, 1, 1);
|
||||
#else
|
||||
// no, none of that
|
||||
sqlite3_bind_int(stmt, 1, 0);
|
||||
#endif
|
||||
|
||||
sqlite3_bind_blob(stmt, 2, questBuffer, sizeof(questBuffer), NULL);
|
||||
sqlite3_bind_int(stmt, 3, playerID);
|
||||
sqlite3_bind_int(stmt, 4, accountID);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
#ifndef ACADEMY
|
||||
// Lightning Gun
|
||||
sql = R"(
|
||||
INSERT INTO Inventory
|
||||
(PlayerID, Slot, ID, Type, Opt)
|
||||
VALUES (?, 0, 328, 0, 1);
|
||||
)";
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, playerID);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
// Nano Buttercup
|
||||
sql = R"(
|
||||
INSERT INTO Nanos
|
||||
(PlayerID, ID, Skill)
|
||||
VALUES (?, 1, 1);
|
||||
)";
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, playerID);
|
||||
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (rc != SQLITE_DONE) {
|
||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
int Database::deleteCharacter(int characterID, int userID) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
SELECT Slot
|
||||
FROM Players
|
||||
WHERE AccountID = ? AND PlayerID = ?
|
||||
LIMIT 1;
|
||||
)";
|
||||
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, userID);
|
||||
sqlite3_bind_int(stmt, 2, characterID);
|
||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
return 0;
|
||||
}
|
||||
int slot = sqlite3_column_int(stmt, 0);
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
sql = R"(
|
||||
DELETE FROM Players
|
||||
WHERE AccountID = ? AND PlayerID = ?;
|
||||
)";
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||
sqlite3_bind_int(stmt, 1, userID);
|
||||
sqlite3_bind_int(stmt, 2, characterID);
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (rc != SQLITE_DONE)
|
||||
return 0;
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
void Database::getCharInfo(std::vector <sP_LS2CL_REP_CHAR_INFO>* result, int userID) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
SELECT
|
||||
p.PlayerID, p.Slot, p.FirstName, p.LastName, p.Level, p.AppearanceFlag, p.TutorialFlag, p.PayZoneFlag,
|
||||
p.XCoordinate, p.YCoordinate, p.ZCoordinate, p.NameCheck,
|
||||
a.Body, a.EyeColor, a.FaceStyle, a.Gender, a.HairColor, a.HairStyle, a.Height, a.SkinColor
|
||||
FROM Players as p
|
||||
INNER JOIN Appearances as a ON p.PlayerID = a.PlayerID
|
||||
WHERE p.AccountID = ?;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, userID);
|
||||
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
sP_LS2CL_REP_CHAR_INFO toAdd = {};
|
||||
toAdd.sPC_Style.iPC_UID = sqlite3_column_int(stmt, 0);
|
||||
toAdd.iSlot = sqlite3_column_int(stmt, 1);
|
||||
|
||||
// parsing const unsigned char* to char16_t
|
||||
std::string placeHolder = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2)));
|
||||
U8toU16(placeHolder, toAdd.sPC_Style.szFirstName, sizeof(toAdd.sPC_Style.szFirstName));
|
||||
placeHolder = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)));
|
||||
U8toU16(placeHolder, toAdd.sPC_Style.szLastName, sizeof(toAdd.sPC_Style.szLastName));
|
||||
|
||||
toAdd.iLevel = sqlite3_column_int(stmt, 4);
|
||||
toAdd.sPC_Style2.iAppearanceFlag = sqlite3_column_int(stmt, 5);
|
||||
toAdd.sPC_Style2.iTutorialFlag = sqlite3_column_int(stmt, 6);
|
||||
toAdd.sPC_Style2.iPayzoneFlag = sqlite3_column_int(stmt, 7);
|
||||
toAdd.iX = sqlite3_column_int(stmt, 8);
|
||||
toAdd.iY = sqlite3_column_int(stmt, 9);
|
||||
toAdd.iZ = sqlite3_column_int(stmt, 10);
|
||||
toAdd.sPC_Style.iNameCheck = sqlite3_column_int(stmt, 11);
|
||||
toAdd.sPC_Style.iBody = sqlite3_column_int(stmt, 12);
|
||||
toAdd.sPC_Style.iEyeColor = sqlite3_column_int(stmt, 13);
|
||||
toAdd.sPC_Style.iFaceStyle = sqlite3_column_int(stmt, 14);
|
||||
toAdd.sPC_Style.iGender = sqlite3_column_int(stmt, 15);
|
||||
toAdd.sPC_Style.iHairColor = sqlite3_column_int(stmt, 16);
|
||||
toAdd.sPC_Style.iHairStyle = sqlite3_column_int(stmt, 17);
|
||||
toAdd.sPC_Style.iHeight = sqlite3_column_int(stmt, 18);
|
||||
toAdd.sPC_Style.iSkinColor = sqlite3_column_int(stmt, 19);
|
||||
|
||||
// request aEquip
|
||||
const char* sql2 = R"(
|
||||
SELECT Slot, Type, ID, Opt, TimeLimit
|
||||
FROM Inventory
|
||||
WHERE PlayerID = ? AND Slot < ?;
|
||||
)";
|
||||
sqlite3_stmt* stmt2;
|
||||
|
||||
sqlite3_prepare_v2(db, sql2, -1, &stmt2, NULL);
|
||||
sqlite3_bind_int(stmt2, 1, toAdd.sPC_Style.iPC_UID);
|
||||
sqlite3_bind_int(stmt2, 2, AEQUIP_COUNT);
|
||||
|
||||
while (sqlite3_step(stmt2) == SQLITE_ROW) {
|
||||
sItemBase* item = &toAdd.aEquip[sqlite3_column_int(stmt2, 0)];
|
||||
item->iType = sqlite3_column_int(stmt2, 1);
|
||||
item->iID = sqlite3_column_int(stmt2, 2);
|
||||
item->iOpt = sqlite3_column_int(stmt2, 3);
|
||||
item->iTimeLimit = sqlite3_column_int(stmt2, 4);
|
||||
}
|
||||
sqlite3_finalize(stmt2);
|
||||
|
||||
result->push_back(toAdd);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
// NOTE: This is currently never called.
|
||||
void Database::evaluateCustomName(int characterID, CustomName decision) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
UPDATE Players
|
||||
SET NameCheck = ?
|
||||
WHERE PlayerID = ?;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
sqlite3_bind_int(stmt, 1, int(decision));
|
||||
sqlite3_bind_int(stmt, 2, characterID);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE)
|
||||
std::cout << "[WARN] Database: Failed to update nameCheck: " << sqlite3_errmsg(db) << std::endl;
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
bool Database::changeName(sP_CL2LS_REQ_CHANGE_CHAR_NAME* save, int accountId) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
const char* sql = R"(
|
||||
UPDATE Players
|
||||
SET
|
||||
FirstName = ?,
|
||||
LastName = ?,
|
||||
NameCheck = ?
|
||||
WHERE PlayerID = ? AND AccountID = ?;
|
||||
)";
|
||||
sqlite3_stmt* stmt;
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
|
||||
std::string firstName = U16toU8(save->szFirstName);
|
||||
std::string lastName = U16toU8(save->szLastName);
|
||||
|
||||
sqlite3_bind_text(stmt, 1, firstName.c_str(), -1, NULL);
|
||||
sqlite3_bind_text(stmt, 2, lastName.c_str(), -1, NULL);
|
||||
// if FNCode isn't 0, it's a wheel name
|
||||
int nameCheck = (settings::APPROVEALLNAMES || save->iFNCode) ? 1 : 0;
|
||||
sqlite3_bind_int(stmt, 3, nameCheck);
|
||||
sqlite3_bind_int(stmt, 4, save->iPCUID);
|
||||
sqlite3_bind_int(stmt, 5, accountId);
|
||||
|
||||
int rc = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
return rc == SQLITE_DONE;
|
||||
}
|
Reference in New Issue
Block a user