mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
[refactor] Separate internal and external DB functions
This commit is contained in:
parent
ec67cc6527
commit
df1ac82300
331
src/Database.cpp
331
src/Database.cpp
@ -22,47 +22,63 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::mutex dbCrit;
|
using namespace Database;
|
||||||
sqlite3* db;
|
|
||||||
|
|
||||||
void Database::open() {
|
static std::mutex dbCrit;
|
||||||
int rc = sqlite3_open(settings::DBPATH.c_str(), &db);
|
static sqlite3* db;
|
||||||
if (rc != SQLITE_OK) {
|
|
||||||
std::cout << "[FATAL] Cannot open database: " << sqlite3_errmsg(db) << std::endl;
|
static void createMetaTable() {
|
||||||
|
std::lock_guard<std::mutex> lock(dbCrit); // XXX
|
||||||
|
|
||||||
|
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
||||||
|
|
||||||
|
const char* sql = R"(
|
||||||
|
CREATE TABLE Meta(
|
||||||
|
Key TEXT NOT NULL UNIQUE,
|
||||||
|
Value INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
)";
|
||||||
|
sqlite3_stmt* stmt;
|
||||||
|
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||||
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
|
std::cout << "[FATAL] Failed to create meta table: " << sqlite3_errmsg(db) << std::endl;
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
sql = R"(
|
||||||
|
INSERT INTO Meta (Key, Value)
|
||||||
|
VALUES (?, ?);
|
||||||
|
)";
|
||||||
|
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||||
|
sqlite3_bind_text(stmt, 1, "ProtocolVersion", -1, NULL);
|
||||||
|
sqlite3_bind_int(stmt, 2, PROTOCOL_VERSION);
|
||||||
|
|
||||||
|
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||||
|
std::cout << "[FATAL] Failed to create meta table: " << sqlite3_errmsg(db) << std::endl;
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// foreign keys in sqlite are off by default; enable them
|
sqlite3_reset(stmt);
|
||||||
sqlite3_exec(db, "PRAGMA foreign_keys=ON;", NULL, NULL, NULL);
|
sqlite3_bind_text(stmt, 1, "DatabaseVersion", -1, NULL);
|
||||||
|
sqlite3_bind_int(stmt, 2, DATABASE_VERSION);
|
||||||
// just in case a DB operation collides with an external manual modification
|
int rc = sqlite3_step(stmt);
|
||||||
sqlite3_busy_timeout(db, 2000);
|
sqlite3_finalize(stmt);
|
||||||
|
if (rc != SQLITE_DONE) {
|
||||||
checkMetaTable();
|
std::cout << "[FATAL] Failed to create meta table: " << sqlite3_errmsg(db) << std::endl;
|
||||||
createTables();
|
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
||||||
|
exit(1);
|
||||||
std::cout << "[INFO] Database in operation ";
|
|
||||||
int accounts = getTableSize("Accounts");
|
|
||||||
int players = getTableSize("Players");
|
|
||||||
std::string message = "";
|
|
||||||
if (accounts > 0) {
|
|
||||||
message += ": Found " + std::to_string(accounts) + " Account";
|
|
||||||
if (accounts > 1)
|
|
||||||
message += "s";
|
|
||||||
}
|
}
|
||||||
if (players > 0) {
|
|
||||||
message += " and " + std::to_string(players) + " Player Character";
|
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
|
||||||
if (players > 1)
|
std::cout << "[INFO] Created new meta table" << std::endl;
|
||||||
message += "s";
|
|
||||||
}
|
|
||||||
std::cout << message << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::close() {
|
static void checkMetaTable() {
|
||||||
sqlite3_close(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::checkMetaTable() {
|
|
||||||
// first check if meta table exists
|
// first check if meta table exists
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='Meta';
|
SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='Meta';
|
||||||
@ -170,58 +186,7 @@ void Database::checkMetaTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::createMetaTable() {
|
static void createTables() {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
|
||||||
|
|
||||||
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
|
|
||||||
|
|
||||||
const char* sql = R"(
|
|
||||||
CREATE TABLE Meta(
|
|
||||||
Key TEXT NOT NULL UNIQUE,
|
|
||||||
Value INTEGER NOT NULL
|
|
||||||
);
|
|
||||||
)";
|
|
||||||
sqlite3_stmt* stmt;
|
|
||||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
||||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
|
||||||
std::cout << "[FATAL] Failed to create meta table: " << sqlite3_errmsg(db) << std::endl;
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
sql = R"(
|
|
||||||
INSERT INTO Meta (Key, Value)
|
|
||||||
VALUES (?, ?);
|
|
||||||
)";
|
|
||||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
||||||
sqlite3_bind_text(stmt, 1, "ProtocolVersion", -1, NULL);
|
|
||||||
sqlite3_bind_int(stmt, 2, PROTOCOL_VERSION);
|
|
||||||
|
|
||||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
|
||||||
std::cout << "[FATAL] Failed to create meta table: " << sqlite3_errmsg(db) << std::endl;
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_reset(stmt);
|
|
||||||
sqlite3_bind_text(stmt, 1, "DatabaseVersion", -1, NULL);
|
|
||||||
sqlite3_bind_int(stmt, 2, DATABASE_VERSION);
|
|
||||||
int rc = sqlite3_step(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
if (rc != SQLITE_DONE) {
|
|
||||||
std::cout << "[FATAL] Failed to create meta table: " << sqlite3_errmsg(db) << std::endl;
|
|
||||||
sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, NULL, NULL);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
|
|
||||||
std::cout << "[INFO] Created new meta table" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::createTables() {
|
|
||||||
std::ifstream file("sql/tables.sql");
|
std::ifstream file("sql/tables.sql");
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
std::cout << "[FATAL] Failed to open database scheme" << std::endl;
|
std::cout << "[FATAL] Failed to open database scheme" << std::endl;
|
||||||
@ -241,8 +206,8 @@ void Database::createTables() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getTableSize(std::string tableName) {
|
static int getTableSize(std::string tableName) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit); // XXX
|
||||||
|
|
||||||
const char* sql = "SELECT COUNT(*) FROM ?";
|
const char* sql = "SELECT COUNT(*) FROM ?";
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt* stmt;
|
||||||
@ -254,6 +219,44 @@ int Database::getTableSize(std::string tableName) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::open() {
|
||||||
|
// XXX: move locks here
|
||||||
|
int rc = sqlite3_open(settings::DBPATH.c_str(), &db);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
std::cout << "[FATAL] Cannot open database: " << sqlite3_errmsg(db) << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// foreign keys in sqlite are off by default; enable them
|
||||||
|
sqlite3_exec(db, "PRAGMA foreign_keys=ON;", NULL, NULL, NULL);
|
||||||
|
|
||||||
|
// just in case a DB operation collides with an external manual modification
|
||||||
|
sqlite3_busy_timeout(db, 2000);
|
||||||
|
|
||||||
|
checkMetaTable();
|
||||||
|
createTables();
|
||||||
|
|
||||||
|
std::cout << "[INFO] Database in operation ";
|
||||||
|
int accounts = getTableSize("Accounts");
|
||||||
|
int players = getTableSize("Players");
|
||||||
|
std::string message = "";
|
||||||
|
if (accounts > 0) {
|
||||||
|
message += ": Found " + std::to_string(accounts) + " Account";
|
||||||
|
if (accounts > 1)
|
||||||
|
message += "s";
|
||||||
|
}
|
||||||
|
if (players > 0) {
|
||||||
|
message += " and " + std::to_string(players) + " Player Character";
|
||||||
|
if (players > 1)
|
||||||
|
message += "s";
|
||||||
|
}
|
||||||
|
std::cout << message << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::close() {
|
||||||
|
sqlite3_close(db);
|
||||||
|
}
|
||||||
|
|
||||||
void Database::findAccount(Account* account, std::string login) {
|
void Database::findAccount(Account* account, std::string login) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
@ -304,8 +307,37 @@ int Database::addAccount(std::string login, std::string password) {
|
|||||||
return sqlite3_last_insert_rowid(db);
|
return sqlite3_last_insert_rowid(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: internal function; does not lock dbCrit
|
static int getAccountIDFromPlayerID(int playerId, int *accountLevel=nullptr) {
|
||||||
bool Database::banAccount(int accountId, int days, std::string& reason) {
|
const char *sql = R"(
|
||||||
|
SELECT Players.AccountID, AccountLevel
|
||||||
|
FROM Players
|
||||||
|
JOIN Accounts ON Players.AccountID = Accounts.AccountID
|
||||||
|
WHERE PlayerID = ?;
|
||||||
|
)";
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
|
// get AccountID from PlayerID
|
||||||
|
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||||
|
sqlite3_bind_int(stmt, 1, playerId);
|
||||||
|
|
||||||
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||||
|
std::cout << "[WARN] Database: failed to get AccountID from PlayerID: " << sqlite3_errmsg(db) << std::endl;
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int accountId = sqlite3_column_int(stmt, 0);
|
||||||
|
|
||||||
|
// optional secondary return value, for checking GM status
|
||||||
|
if (accountLevel != nullptr)
|
||||||
|
*accountLevel = sqlite3_column_int(stmt, 1);
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool banAccount(int accountId, int days, std::string& reason) {
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
UPDATE Accounts SET
|
UPDATE Accounts SET
|
||||||
BannedSince = (strftime('%s', 'now')),
|
BannedSince = (strftime('%s', 'now')),
|
||||||
@ -331,8 +363,7 @@ bool Database::banAccount(int accountId, int days, std::string& reason) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: internal function; does not lock dbCrit
|
static bool unbanAccount(int accountId) {
|
||||||
bool Database::unbanAccount(int accountId) {
|
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
UPDATE Accounts SET
|
UPDATE Accounts SET
|
||||||
BannedSince = 0,
|
BannedSince = 0,
|
||||||
@ -391,36 +422,6 @@ bool Database::unbanPlayer(int playerId) {
|
|||||||
return unbanAccount(accountId);
|
return unbanAccount(accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getAccountIDFromPlayerID(int playerId, int *accountLevel) {
|
|
||||||
const char *sql = R"(
|
|
||||||
SELECT Players.AccountID, AccountLevel
|
|
||||||
FROM Players
|
|
||||||
JOIN Accounts ON Players.AccountID = Accounts.AccountID
|
|
||||||
WHERE PlayerID = ?;
|
|
||||||
)";
|
|
||||||
sqlite3_stmt *stmt;
|
|
||||||
|
|
||||||
// get AccountID from PlayerID
|
|
||||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
||||||
sqlite3_bind_int(stmt, 1, playerId);
|
|
||||||
|
|
||||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
|
||||||
std::cout << "[WARN] Database: failed to get AccountID from PlayerID: " << sqlite3_errmsg(db) << std::endl;
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int accountId = sqlite3_column_int(stmt, 0);
|
|
||||||
|
|
||||||
// optional secondary return value, for checking GM status
|
|
||||||
if (accountLevel != nullptr)
|
|
||||||
*accountLevel = sqlite3_column_int(stmt, 1);
|
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
return accountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::updateSelected(int accountId, int slot) {
|
void Database::updateSelected(int accountId, int slot) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
@ -904,6 +905,40 @@ bool Database::changeName(sP_CL2LS_REQ_CHANGE_CHAR_NAME* save, int accountId) {
|
|||||||
return rc == SQLITE_DONE;
|
return rc == SQLITE_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeExpiredVehicles(Player* player) {
|
||||||
|
int32_t currentTime = getTimestamp();
|
||||||
|
|
||||||
|
// if there are expired vehicles in bank just remove them silently
|
||||||
|
for (int i = 0; i < ABANK_COUNT; i++) {
|
||||||
|
if (player->Bank[i].iType == 10 && player->Bank[i].iTimeLimit < currentTime && player->Bank[i].iTimeLimit != 0) {
|
||||||
|
memset(&player->Bank[i], 0, sizeof(sItemBase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we want to leave only 1 expired vehicle on player to delete it with the client packet
|
||||||
|
std::vector<sItemBase*> toRemove;
|
||||||
|
|
||||||
|
// equipped vehicle
|
||||||
|
if (player->Equip[8].iOpt > 0 && player->Equip[8].iTimeLimit < currentTime && player->Equip[8].iTimeLimit != 0) {
|
||||||
|
toRemove.push_back(&player->Equip[8]);
|
||||||
|
player->toRemoveVehicle.eIL = 0;
|
||||||
|
player->toRemoveVehicle.iSlotNum = 8;
|
||||||
|
}
|
||||||
|
// inventory
|
||||||
|
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||||
|
if (player->Inven[i].iType == 10 && player->Inven[i].iTimeLimit < currentTime && player->Inven[i].iTimeLimit != 0) {
|
||||||
|
toRemove.push_back(&player->Inven[i]);
|
||||||
|
player->toRemoveVehicle.eIL = 1;
|
||||||
|
player->toRemoveVehicle.iSlotNum = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete all but one vehicles, leave last one for ceremonial deletion
|
||||||
|
for (int i = 0; i < (int)toRemove.size()-1; i++) {
|
||||||
|
memset(toRemove[i], 0, sizeof(sItemBase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Database::getPlayer(Player* plr, int id) {
|
void Database::getPlayer(Player* plr, int id) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
@ -1028,7 +1063,7 @@ void Database::getPlayer(Player* plr, int id) {
|
|||||||
|
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
Database::removeExpiredVehicles(plr);
|
removeExpiredVehicles(plr);
|
||||||
|
|
||||||
// get quest inventory
|
// get quest inventory
|
||||||
sql = R"(
|
sql = R"(
|
||||||
@ -1404,40 +1439,6 @@ void Database::updatePlayer(Player *player) {
|
|||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::removeExpiredVehicles(Player* player) {
|
|
||||||
int32_t currentTime = getTimestamp();
|
|
||||||
|
|
||||||
// if there are expired vehicles in bank just remove them silently
|
|
||||||
for (int i = 0; i < ABANK_COUNT; i++) {
|
|
||||||
if (player->Bank[i].iType == 10 && player->Bank[i].iTimeLimit < currentTime && player->Bank[i].iTimeLimit != 0) {
|
|
||||||
memset(&player->Bank[i], 0, sizeof(sItemBase));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we want to leave only 1 expired vehicle on player to delete it with the client packet
|
|
||||||
std::vector<sItemBase*> toRemove;
|
|
||||||
|
|
||||||
// equipped vehicle
|
|
||||||
if (player->Equip[8].iOpt > 0 && player->Equip[8].iTimeLimit < currentTime && player->Equip[8].iTimeLimit != 0) {
|
|
||||||
toRemove.push_back(&player->Equip[8]);
|
|
||||||
player->toRemoveVehicle.eIL = 0;
|
|
||||||
player->toRemoveVehicle.iSlotNum = 8;
|
|
||||||
}
|
|
||||||
// inventory
|
|
||||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
|
||||||
if (player->Inven[i].iType == 10 && player->Inven[i].iTimeLimit < currentTime && player->Inven[i].iTimeLimit != 0) {
|
|
||||||
toRemove.push_back(&player->Inven[i]);
|
|
||||||
player->toRemoveVehicle.eIL = 1;
|
|
||||||
player->toRemoveVehicle.iSlotNum = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete all but one vehicles, leave last one for ceremonial deletion
|
|
||||||
for (int i = 0; i < (int)toRemove.size()-1; i++) {
|
|
||||||
memset(toRemove[i], 0, sizeof(sItemBase));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// buddies
|
// buddies
|
||||||
// returns num of buddies + blocked players
|
// returns num of buddies + blocked players
|
||||||
int Database::getNumBuddies(Player* player) {
|
int Database::getNumBuddies(Player* player) {
|
||||||
@ -1559,10 +1560,10 @@ int Database::getUnreadEmailCount(int playerID) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Database::EmailData> Database::getEmails(int playerID, int page) {
|
std::vector<EmailData> Database::getEmails(int playerID, int page) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
std::vector<Database::EmailData> emails;
|
std::vector<EmailData> emails;
|
||||||
|
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
SELECT
|
SELECT
|
||||||
@ -1581,7 +1582,7 @@ std::vector<Database::EmailData> Database::getEmails(int playerID, int page) {
|
|||||||
int offset = 5 * page - 5;
|
int offset = 5 * page - 5;
|
||||||
sqlite3_bind_int(stmt, 2, offset);
|
sqlite3_bind_int(stmt, 2, offset);
|
||||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
Database::EmailData toAdd;
|
EmailData toAdd;
|
||||||
toAdd.PlayerId = playerID;
|
toAdd.PlayerId = playerID;
|
||||||
toAdd.MsgIndex = sqlite3_column_int(stmt, 0);
|
toAdd.MsgIndex = sqlite3_column_int(stmt, 0);
|
||||||
toAdd.ItemFlag = sqlite3_column_int(stmt, 1);
|
toAdd.ItemFlag = sqlite3_column_int(stmt, 1);
|
||||||
@ -1602,7 +1603,7 @@ std::vector<Database::EmailData> Database::getEmails(int playerID, int page) {
|
|||||||
return emails;
|
return emails;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::EmailData Database::getEmail(int playerID, int index) {
|
EmailData Database::getEmail(int playerID, int index) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
@ -1618,7 +1619,7 @@ Database::EmailData Database::getEmail(int playerID, int index) {
|
|||||||
sqlite3_bind_int(stmt, 1, playerID);
|
sqlite3_bind_int(stmt, 1, playerID);
|
||||||
sqlite3_bind_int(stmt, 2, index);
|
sqlite3_bind_int(stmt, 2, index);
|
||||||
|
|
||||||
Database::EmailData result;
|
EmailData result;
|
||||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||||
std::cout << "[WARN] Database: Email not found!" << std::endl;
|
std::cout << "[WARN] Database: Email not found!" << std::endl;
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
@ -1873,7 +1874,7 @@ bool Database::sendEmail(EmailData* data, std::vector<sItemBase> attachments) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::RaceRanking Database::getTopRaceRanking(int epID, int playerID) {
|
RaceRanking Database::getTopRaceRanking(int epID, int playerID) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
std::string sql(R"(
|
std::string sql(R"(
|
||||||
SELECT
|
SELECT
|
||||||
@ -1897,7 +1898,7 @@ Database::RaceRanking Database::getTopRaceRanking(int epID, int playerID) {
|
|||||||
if(playerID > -1)
|
if(playerID > -1)
|
||||||
sqlite3_bind_int(stmt, 2, playerID);
|
sqlite3_bind_int(stmt, 2, playerID);
|
||||||
|
|
||||||
Database::RaceRanking ranking = {};
|
RaceRanking ranking = {};
|
||||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||||
// this race hasn't been run before, so return a blank ranking
|
// this race hasn't been run before, so return a blank ranking
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
@ -1917,7 +1918,7 @@ Database::RaceRanking Database::getTopRaceRanking(int epID, int playerID) {
|
|||||||
return ranking;
|
return ranking;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::postRaceRanking(Database::RaceRanking ranking) {
|
void Database::postRaceRanking(RaceRanking ranking) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
|
@ -15,6 +15,7 @@ namespace Database {
|
|||||||
time_t BannedUntil;
|
time_t BannedUntil;
|
||||||
std::string BanReason;
|
std::string BanReason;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EmailData {
|
struct EmailData {
|
||||||
int PlayerId;
|
int PlayerId;
|
||||||
int MsgIndex;
|
int MsgIndex;
|
||||||
@ -29,6 +30,7 @@ namespace Database {
|
|||||||
uint64_t SendTime;
|
uint64_t SendTime;
|
||||||
uint64_t DeleteTime;
|
uint64_t DeleteTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaceRanking {
|
struct RaceRanking {
|
||||||
int EPID;
|
int EPID;
|
||||||
int PlayerID;
|
int PlayerID;
|
||||||
@ -40,20 +42,15 @@ namespace Database {
|
|||||||
|
|
||||||
void open();
|
void open();
|
||||||
void close();
|
void close();
|
||||||
void checkMetaTable();
|
|
||||||
void createMetaTable();
|
|
||||||
void createTables();
|
|
||||||
int getTableSize(std::string tableName);
|
|
||||||
|
|
||||||
void findAccount(Account* account, std::string login);
|
void findAccount(Account* account, std::string login);
|
||||||
/// returns ID, 0 if something failed
|
// returns ID, 0 if something failed
|
||||||
int addAccount(std::string login, std::string password);
|
int addAccount(std::string login, std::string password);
|
||||||
bool banAccount(int accountId, int days, std::string& reason);
|
|
||||||
bool unbanAccount(int accountId);
|
// interface for the /ban command
|
||||||
bool banPlayer(int playerId, std::string& reason);
|
bool banPlayer(int playerId, std::string& reason);
|
||||||
bool unbanPlayer(int playerId);
|
bool unbanPlayer(int playerId);
|
||||||
|
|
||||||
int getAccountIDFromPlayerID(int playerId, int *accountLevel=nullptr);
|
|
||||||
void updateSelected(int accountId, int playerId);
|
void updateSelected(int accountId, int playerId);
|
||||||
|
|
||||||
bool validateCharacter(int characterID, int userID);
|
bool validateCharacter(int characterID, int userID);
|
||||||
@ -68,6 +65,7 @@ namespace Database {
|
|||||||
/// returns slot number if query succeeded
|
/// returns slot number if query succeeded
|
||||||
int deleteCharacter(int characterID, int userID);
|
int deleteCharacter(int characterID, int userID);
|
||||||
void getCharInfo(std::vector <sP_LS2CL_REP_CHAR_INFO>* result, int userID);
|
void getCharInfo(std::vector <sP_LS2CL_REP_CHAR_INFO>* result, int userID);
|
||||||
|
|
||||||
/// accepting/declining custom name
|
/// accepting/declining custom name
|
||||||
enum class CustomName {
|
enum class CustomName {
|
||||||
APPROVE = 1,
|
APPROVE = 1,
|
||||||
@ -80,7 +78,6 @@ namespace Database {
|
|||||||
// getting players
|
// getting players
|
||||||
void getPlayer(Player* plr, int id);
|
void getPlayer(Player* plr, int id);
|
||||||
void updatePlayer(Player *player);
|
void updatePlayer(Player *player);
|
||||||
void removeExpiredVehicles(Player* player);
|
|
||||||
|
|
||||||
// buddies
|
// buddies
|
||||||
int getNumBuddies(Player* player);
|
int getNumBuddies(Player* player);
|
||||||
|
Loading…
Reference in New Issue
Block a user