mirror of
https://github.com/therealKyp/Earth-and-Beyond-server
synced 2026-08-13 22:23:03 -04:00
1225 lines
47 KiB
C++
1225 lines
47 KiB
C++
// AccountManager.cpp
|
|
//
|
|
|
|
//To make things easier, the top of this file will be SQL methods
|
|
//and the bottom of the file will be flatfile methods
|
|
|
|
//TODO: Use column indexes instead of names for SQL
|
|
|
|
#include "AccountManager.h"
|
|
#include "ServerManager.h"
|
|
#include "StringManager.h"
|
|
#include "StaticData.h"
|
|
#include <time.h>
|
|
#include "mysql/mysqlplus.h"
|
|
#include "SaveManager.h"
|
|
|
|
#ifdef USE_MYSQL_ACCOUNT_DATA
|
|
sql_connection_c m_SQL_Conn;
|
|
#endif
|
|
|
|
AccountManager::AccountManager()
|
|
{
|
|
SetupTickets();
|
|
#ifdef USE_MYSQL_ACCOUNT_DATA
|
|
m_SQL_Conn.connect("net7_user", g_MySQL_Host, g_MySQL_User, g_MySQL_Pass);
|
|
#else
|
|
m_NumAccounts = 0;
|
|
LoadAccounts();
|
|
#endif
|
|
}
|
|
|
|
AccountManager::~AccountManager()
|
|
{
|
|
#ifdef USE_MYSQL_ACCOUNT_DATA
|
|
m_SQL_Conn.disconnect();
|
|
#endif
|
|
|
|
AccountTicket * ticket;
|
|
while (m_Tickets)
|
|
{
|
|
ticket = m_Tickets->next;
|
|
delete m_Tickets;
|
|
m_Tickets = ticket;
|
|
}
|
|
}
|
|
|
|
void AccountManager::SetupTickets()
|
|
{
|
|
//Allocate 5 structures for storing tickets
|
|
//This is dirty, but the easiest way to do it since they are linked lists
|
|
m_Tickets = new AccountTicket();
|
|
memset(m_Tickets, 0, sizeof(AccountTicket));
|
|
|
|
m_Tickets->next = new AccountTicket();
|
|
memset(m_Tickets->next, 0, sizeof(AccountTicket));
|
|
|
|
m_Tickets->next->next = new AccountTicket();
|
|
memset(m_Tickets->next->next, 0, sizeof(AccountTicket));
|
|
|
|
m_Tickets->next->next->next = new AccountTicket();
|
|
memset(m_Tickets->next->next->next, 0, sizeof(AccountTicket));
|
|
|
|
m_Tickets->next->next->next->next = new AccountTicket();
|
|
memset(m_Tickets->next->next->next->next, 0, sizeof(AccountTicket));
|
|
}
|
|
|
|
#ifdef USE_MYSQL_ACCOUNT_DATA
|
|
|
|
void AccountManager::UpdateTime(long account_id)
|
|
{
|
|
char queryString[256];
|
|
sql_query_c TimeUpdate(&m_SQL_Conn);
|
|
|
|
char timestr[32];
|
|
time_t rawtime;
|
|
time(&rawtime);
|
|
strftime(timestr, sizeof(timestr), "%d/%m/%y %H:%M:%S", localtime(&rawtime));
|
|
|
|
sprintf(queryString, "UPDATE `accounts` SET `last_login` = '%s' WHERE `id` = '%ld'", timestr, account_id);
|
|
TimeUpdate.run_query(queryString);
|
|
}
|
|
|
|
long AccountManager::GetAccountStatus(char *username)
|
|
{
|
|
char query_str[256];
|
|
sql_query_c account_query (&m_SQL_Conn);
|
|
sql_result_c account_result;
|
|
sql_row_c account_row;
|
|
|
|
sprintf(query_str, "SELECT `status` FROM `accounts` WHERE `username` = '%s'", username);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
return -2;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
return account_row[0];
|
|
}
|
|
|
|
long AccountManager::GetAccountID(char *username)
|
|
{
|
|
char query_str[256];
|
|
sql_query_c account_query(&m_SQL_Conn);
|
|
sql_result_c account_result;
|
|
sql_row_c account_row;
|
|
|
|
sprintf(query_str, "SELECT `id` FROM `accounts` WHERE `username` = '%s'", username);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
return account_row[0];
|
|
}
|
|
|
|
//Validates the username/password set, returns the account if valid
|
|
long AccountManager::ValidateAccount(char *username, char *password)
|
|
{
|
|
char query_str[256];
|
|
sql_query_c account_query(&m_SQL_Conn);
|
|
sql_result_c account_result;
|
|
sql_row_c account_row;
|
|
|
|
sprintf(query_str, "SELECT `id` FROM `accounts` WHERE `username` = '%s' AND `password` = '%s'", username, password);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
return account_row[0];
|
|
}
|
|
|
|
bool AccountManager::AddUser(char *username, char *password, char *access)
|
|
{
|
|
LogMessage("Adding new user `%s`\n", username);
|
|
|
|
sql_query_c account_query(&m_SQL_Conn);
|
|
sql_query account_buider;
|
|
|
|
account_buider.SetTable("accounts");
|
|
account_buider.AddData("username", username);
|
|
account_buider.AddData("password", password);
|
|
account_buider.AddData("status", access);
|
|
account_buider.AddData("last_login", "never");
|
|
|
|
if (!account_query.run_query(account_buider.CreateQuery()))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AccountManager::SetAccountStatus(char *username, long status)
|
|
{
|
|
LogMessage("Changing access to (%d) for `%s`\n", status, username);
|
|
|
|
char query_str[256];
|
|
sql_query_c account_query(&m_SQL_Conn);
|
|
|
|
sprintf(query_str, "UPDATE `accounts` SET `status`='%ld' WHERE `username`='%s'", status, username);
|
|
if (!account_query.run_query(query_str))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AccountManager::ChangePassword(char *username, char *password)
|
|
{
|
|
LogMessage("Changing password on %s\n", username);
|
|
|
|
char query_str[256];
|
|
sql_query_c account_query(&m_SQL_Conn);
|
|
|
|
sprintf(query_str, "UPDATE `accounts` SET `password`='%s' WHERE `username`='%s'", password, username);
|
|
if (!account_query.run_query(query_str))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AccountManager::IsUsernameUnique(char *name)
|
|
{
|
|
char query_str[256];
|
|
sql_query_c account_query (&m_SQL_Conn);
|
|
|
|
sprintf(query_str, "SELECT * FROM `avatar_data` WHERE `first_name` = '%s'", name);
|
|
if (account_query.run_query(query_str) && account_query.n_rows() > 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void AccountManager::DeleteCharacter(long avatar_id)
|
|
{
|
|
char query_str[256];
|
|
sql_query_c account_query (&m_SQL_Conn);
|
|
|
|
//Delete this character from the tables
|
|
sprintf(query_str, "DELETE FROM `ship_info` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
account_query.run_query(query_str);
|
|
|
|
sprintf(query_str, "DELETE FROM `ship_data` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
account_query.run_query(query_str);
|
|
|
|
sprintf(query_str, "DELETE FROM `avatar_data` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
account_query.run_query(query_str);
|
|
|
|
sprintf(query_str, "DELETE FROM `avatar_info` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
account_query.run_query(query_str);
|
|
|
|
g_SaveMgr->AddSaveMessage(SAVE_CODE_FULL_CHARACTER_WIPE, avatar_id, 0, 0);
|
|
|
|
//Now delete the Aux file
|
|
sprintf(query_str, "%sCharInfo-%ld.chr", SERVER_USER_PATH, avatar_id);
|
|
|
|
LogMessage("Deleting %s\n", query_str);
|
|
DeleteFile(query_str);
|
|
}
|
|
|
|
bool AccountManager::SaveDatabase(CharacterDatabase * database, long avatar_id)
|
|
{
|
|
char query_str[256];
|
|
sql_query_c account_query (&m_SQL_Conn);
|
|
|
|
//We need to completely remove the character we are saving (in this order due to foreign keys)
|
|
|
|
sprintf(query_str, "DELETE FROM `ship_info` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
if (!account_query.run_query(query_str)) return false;
|
|
|
|
sprintf(query_str, "DELETE FROM `ship_data` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
if (!account_query.run_query(query_str)) return false;
|
|
|
|
sprintf(query_str, "DELETE FROM `avatar_data` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
if (!account_query.run_query(query_str)) return false;
|
|
|
|
sprintf(query_str, "DELETE FROM `avatar_info` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
if (!account_query.run_query(query_str)) return false;
|
|
|
|
sql_query account_builder;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////// Save AvatarInfo ////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
account_builder.Clear();
|
|
account_builder.SetTable("avatar_info");
|
|
|
|
account_builder.AddData("avatar_id", avatar_id);
|
|
account_builder.AddData("account_id", ntohl(database->info.account_id_lsb));
|
|
account_builder.AddData("slot", ntohl(database->info.avatar_slot));
|
|
account_builder.AddData("sector", ntohl(database->info.sector_id));
|
|
account_builder.AddData("galaxy", ntohl(database->info.galaxy_id));
|
|
account_builder.AddData("count", ntohl(database->info.count));
|
|
account_builder.AddData("admin", ntohl(database->info.admin_level));
|
|
account_builder.AddData("combat", ntohl(database->info.combat_level));
|
|
account_builder.AddData("explore", ntohl(database->info.explore_level));
|
|
account_builder.AddData("trade", ntohl(database->info.trade_level));
|
|
|
|
if (!account_query.run_query(account_builder.CreateQuery()))
|
|
{
|
|
LogMessage("Could not save AvatarInfo for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////// Save AvatarData ////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
account_builder.Clear();
|
|
account_builder.SetTable("avatar_data");
|
|
|
|
account_builder.AddData("avatar_id", avatar_id);
|
|
account_builder.AddData("first_name", database->avatar.avatar_first_name);
|
|
account_builder.AddData("last_name", database->avatar.avatar_last_name);
|
|
account_builder.AddData("type", database->avatar.avatar_type);
|
|
account_builder.AddData("version", database->avatar.avatar_version);
|
|
account_builder.AddData("race", database->avatar.race);
|
|
account_builder.AddData("prof", database->avatar.profession);
|
|
account_builder.AddData("gender", database->avatar.gender);
|
|
account_builder.AddData("mood", database->avatar.mood_type);
|
|
account_builder.AddData("personality", database->avatar.personality);
|
|
account_builder.AddData("nlp", database->avatar.nlp);
|
|
account_builder.AddData("body", database->avatar.body_type);
|
|
account_builder.AddData("pants", database->avatar.pants_type);
|
|
account_builder.AddData("head", database->avatar.head_type);
|
|
account_builder.AddData("hair", database->avatar.hair_num);
|
|
account_builder.AddData("ear", database->avatar.ear_num);
|
|
account_builder.AddData("goggle", database->avatar.goggle_num);
|
|
account_builder.AddData("beard", database->avatar.beard_num);
|
|
account_builder.AddData("weapon_hip", database->avatar.weapon_hip_num);
|
|
account_builder.AddData("weapon_unique", database->avatar.weapon_unique_num);
|
|
account_builder.AddData("weapon_back", database->avatar.weapon_back_num);
|
|
account_builder.AddData("head_texture", database->avatar.head_texture_num);
|
|
account_builder.AddData("tattoo_texture", database->avatar.tattoo_texture_num);
|
|
account_builder.AddData("tattoo_X", database->avatar.tattoo_offset[0]);
|
|
account_builder.AddData("tattoo_Y", database->avatar.tattoo_offset[1]);
|
|
account_builder.AddData("tattoo_Z", database->avatar.tattoo_offset[2]);
|
|
account_builder.AddData("hair_H", database->avatar.hair_color[0]);
|
|
account_builder.AddData("hair_S", database->avatar.hair_color[1]);
|
|
account_builder.AddData("hair_V", database->avatar.hair_color[2]);
|
|
account_builder.AddData("beard_H", database->avatar.beard_color[0]);
|
|
account_builder.AddData("beard_S", database->avatar.beard_color[1]);
|
|
account_builder.AddData("beard_V", database->avatar.beard_color[2]);
|
|
account_builder.AddData("eye_H", database->avatar.eye_color[0]);
|
|
account_builder.AddData("eye_S", database->avatar.eye_color[1]);
|
|
account_builder.AddData("eye_V", database->avatar.eye_color[2]);
|
|
account_builder.AddData("skin_H", database->avatar.skin_color[0]);
|
|
account_builder.AddData("skin_S", database->avatar.skin_color[1]);
|
|
account_builder.AddData("skin_V", database->avatar.skin_color[2]);
|
|
account_builder.AddData("shirt_p_H", database->avatar.shirt_primary_color[0]);
|
|
account_builder.AddData("shirt_p_S", database->avatar.shirt_primary_color[1]);
|
|
account_builder.AddData("shirt_p_V", database->avatar.shirt_primary_color[2]);
|
|
account_builder.AddData("shirt_s_H", database->avatar.shirt_secondary_color[0]);
|
|
account_builder.AddData("shirt_s_S", database->avatar.shirt_secondary_color[1]);
|
|
account_builder.AddData("shirt_s_V", database->avatar.shirt_secondary_color[2]);
|
|
account_builder.AddData("pants_p_H", database->avatar.pants_primary_color[0]);
|
|
account_builder.AddData("pants_p_S", database->avatar.pants_primary_color[1]);
|
|
account_builder.AddData("pants_p_V", database->avatar.pants_primary_color[2]);
|
|
account_builder.AddData("pants_s_H", database->avatar.pants_secondary_color[0]);
|
|
account_builder.AddData("pants_s_S", database->avatar.pants_secondary_color[1]);
|
|
account_builder.AddData("pants_s_V", database->avatar.pants_secondary_color[2]);
|
|
account_builder.AddData("shirt_p_metal", database->avatar.shirt_primary_metal);
|
|
account_builder.AddData("shirt_s_metal", database->avatar.shirt_secondary_metal);
|
|
account_builder.AddData("pants_p_metal", database->avatar.pants_primary_metal);
|
|
account_builder.AddData("pants_s_metal", database->avatar.pants_secondary_metal);
|
|
account_builder.AddData("height_weight_0", database->avatar.height_weight_1[0]);
|
|
account_builder.AddData("height_weight_1", database->avatar.height_weight_1[1]);
|
|
account_builder.AddData("height_weight_2", database->avatar.height_weight_1[2]);
|
|
account_builder.AddData("height_weight_3", database->avatar.height_weight_1[3]);
|
|
account_builder.AddData("height_weight_4", database->avatar.height_weight_1[4]);
|
|
|
|
if (!account_query.run_query(account_builder.CreateQuery()))
|
|
{
|
|
LogMessage("Could not save AvatarData for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////// Save ShipData /////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
account_builder.Clear();
|
|
account_builder.SetTable("ship_data");
|
|
|
|
account_builder.AddData("avatar_id", avatar_id);
|
|
account_builder.AddData("race", database->ship_data.race);
|
|
account_builder.AddData("prof", database->ship_data.profession);
|
|
account_builder.AddData("hull", database->ship_data.hull);
|
|
account_builder.AddData("wing", database->ship_data.wing);
|
|
account_builder.AddData("decal", database->ship_data.decal);
|
|
account_builder.AddData("name", database->ship_data.ship_name);
|
|
account_builder.AddData("name_H", database->ship_data.ship_name_color[0]);
|
|
account_builder.AddData("name_S", database->ship_data.ship_name_color[1]);
|
|
account_builder.AddData("name_V", database->ship_data.ship_name_color[2]);
|
|
account_builder.AddData("hull_p_H", database->ship_data.HullPrimaryColor.HSV[0]);
|
|
account_builder.AddData("hull_p_S", database->ship_data.HullPrimaryColor.HSV[1]);
|
|
account_builder.AddData("hull_p_V", database->ship_data.HullPrimaryColor.HSV[2]);
|
|
account_builder.AddData("hull_p_flat", database->ship_data.HullPrimaryColor.flat);
|
|
account_builder.AddData("hull_p_metal", database->ship_data.HullPrimaryColor.metal);
|
|
account_builder.AddData("hull_s_H", database->ship_data.HullSecondaryColor.HSV[0]);
|
|
account_builder.AddData("hull_s_S", database->ship_data.HullSecondaryColor.HSV[1]);
|
|
account_builder.AddData("hull_s_V", database->ship_data.HullSecondaryColor.HSV[2]);
|
|
account_builder.AddData("hull_s_flat", database->ship_data.HullSecondaryColor.flat);
|
|
account_builder.AddData("hull_s_metal", database->ship_data.HullSecondaryColor.metal);
|
|
account_builder.AddData("prof_p_H", database->ship_data.ProfessionPrimaryColor.HSV[0]);
|
|
account_builder.AddData("prof_p_S", database->ship_data.ProfessionPrimaryColor.HSV[1]);
|
|
account_builder.AddData("prof_p_V", database->ship_data.ProfessionPrimaryColor.HSV[2]);
|
|
account_builder.AddData("prof_p_flat", database->ship_data.ProfessionPrimaryColor.flat);
|
|
account_builder.AddData("prof_p_metal", database->ship_data.ProfessionPrimaryColor.metal);
|
|
account_builder.AddData("prof_s_H", database->ship_data.ProfessionSecondaryColor.HSV[0]);
|
|
account_builder.AddData("prof_s_S", database->ship_data.ProfessionSecondaryColor.HSV[1]);
|
|
account_builder.AddData("prof_s_V", database->ship_data.ProfessionSecondaryColor.HSV[2]);
|
|
account_builder.AddData("prof_s_flat", database->ship_data.ProfessionSecondaryColor.flat);
|
|
account_builder.AddData("prof_s_metal", database->ship_data.ProfessionSecondaryColor.metal);
|
|
account_builder.AddData("wing_p_H", database->ship_data.WingPrimaryColor.HSV[0]);
|
|
account_builder.AddData("wing_p_S", database->ship_data.WingPrimaryColor.HSV[1]);
|
|
account_builder.AddData("wing_p_V", database->ship_data.WingPrimaryColor.HSV[2]);
|
|
account_builder.AddData("wing_p_flat", database->ship_data.WingPrimaryColor.flat);
|
|
account_builder.AddData("wing_p_metal", database->ship_data.WingPrimaryColor.metal);
|
|
account_builder.AddData("wing_s_H", database->ship_data.WingSecondaryColor.HSV[0]);
|
|
account_builder.AddData("wing_s_S", database->ship_data.WingSecondaryColor.HSV[1]);
|
|
account_builder.AddData("wing_s_V", database->ship_data.WingSecondaryColor.HSV[2]);
|
|
account_builder.AddData("wing_s_flat", database->ship_data.WingSecondaryColor.flat);
|
|
account_builder.AddData("wing_s_metal", database->ship_data.WingSecondaryColor.metal);
|
|
account_builder.AddData("engine_p_H", database->ship_data.EnginePrimaryColor.HSV[0]);
|
|
account_builder.AddData("engine_p_S", database->ship_data.EnginePrimaryColor.HSV[1]);
|
|
account_builder.AddData("engine_p_V", database->ship_data.EnginePrimaryColor.HSV[2]);
|
|
account_builder.AddData("engine_p_flat", database->ship_data.EnginePrimaryColor.flat);
|
|
account_builder.AddData("engine_p_metal", database->ship_data.EnginePrimaryColor.metal);
|
|
account_builder.AddData("engine_s_H", database->ship_data.EngineSecondaryColor.HSV[0]);
|
|
account_builder.AddData("engine_s_S", database->ship_data.EngineSecondaryColor.HSV[1]);
|
|
account_builder.AddData("engine_s_V", database->ship_data.EngineSecondaryColor.HSV[2]);
|
|
account_builder.AddData("engine_s_flat", database->ship_data.EngineSecondaryColor.flat);
|
|
account_builder.AddData("engine_s_metal", database->ship_data.EngineSecondaryColor.metal);
|
|
|
|
if (!account_query.run_query(account_builder.CreateQuery()))
|
|
{
|
|
LogMessage("Could not save ShipData for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////// Save ShipInfo /////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
account_builder.Clear();
|
|
account_builder.SetTable("ship_info");
|
|
|
|
account_builder.AddData("avatar_id", avatar_id);
|
|
account_builder.AddData("hull", database->ship_info.hull);
|
|
account_builder.AddData("prof", database->ship_info.profession);
|
|
account_builder.AddData("engine", database->ship_info.engine);
|
|
account_builder.AddData("wing", database->ship_info.wing);
|
|
account_builder.AddData("pos_0", database->ship_info.Position[0]);
|
|
account_builder.AddData("pos_1", database->ship_info.Position[1]);
|
|
account_builder.AddData("pos_2", database->ship_info.Position[2]);
|
|
account_builder.AddData("ori_0", database->ship_info.Orientation[0]);
|
|
account_builder.AddData("ori_1", database->ship_info.Orientation[1]);
|
|
account_builder.AddData("ori_2", database->ship_info.Orientation[2]);
|
|
account_builder.AddData("ori_3", database->ship_info.Orientation[3]);
|
|
|
|
if (!account_query.run_query(account_builder.CreateQuery()))
|
|
{
|
|
LogMessage("Could not save ShipData for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//Read the avatar database for the player given an avatarID
|
|
bool AccountManager::ReadDatabase(CharacterDatabase *database, long avatar_id)
|
|
{
|
|
memset(database, 0, sizeof(CharacterDatabase));
|
|
|
|
char query_str[256];
|
|
sql_query_c account_query (&m_SQL_Conn);
|
|
sql_result_c account_result;
|
|
sql_row_c account_row;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////// Read in AvatarInfo ///////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
sprintf(query_str, "SELECT * FROM `avatar_info` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
//LogMessage("Could not load AvatarInfo for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
//This is the same order as the structure
|
|
database->info.avatar_id_msb = 0;
|
|
database->info.avatar_id_lsb = ntohl(avatar_id);
|
|
database->info.account_id_msb = 0;
|
|
database->info.account_id_lsb = ntohl(account_row["account_id"]);
|
|
database->info.avatar_slot = ntohl(account_row["slot"]); //Also (avatar_id - 1) / 5
|
|
database->info.sector_id = ntohl(account_row["sector"]);
|
|
database->info.galaxy_id = ntohl(account_row["galaxy"]);
|
|
database->info.count = ntohl(account_row["count"]);
|
|
database->info.admin_level = ntohl(account_row["admin"]);
|
|
database->info.gm_flag = ntohl(1);
|
|
database->info.combat_level = ntohl(account_row["combat"]);
|
|
database->info.explore_level = ntohl(account_row["explore"]);
|
|
database->info.trade_level = ntohl(account_row["trade"]);
|
|
|
|
sprintf(database->info.location, "%s", g_ServerMgr->GetSectorName(account_row["sector"]));
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////// Read in AvatarData ///////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
sprintf(query_str, "SELECT * FROM `avatar_data` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
//LogMessage("Could not load AvatarData for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
strcpy(database->avatar.avatar_first_name, account_row["first_name"]);
|
|
strcpy(database->avatar.avatar_last_name, account_row["last_name"]);
|
|
database->avatar.avatar_type = account_row["type"];
|
|
database->avatar.avatar_version = account_row["version"];
|
|
database->avatar.race = account_row["race"];
|
|
database->avatar.profession = account_row["prof"];
|
|
database->avatar.gender = account_row["gender"];
|
|
database->avatar.mood_type = account_row["mood"];
|
|
database->avatar.personality = account_row["personality"];
|
|
database->avatar.nlp = account_row["nlp"];
|
|
database->avatar.body_type = account_row["body"];
|
|
database->avatar.pants_type = account_row["pants"];
|
|
database->avatar.head_type = account_row["head"];
|
|
database->avatar.hair_num = account_row["hair"];
|
|
database->avatar.ear_num = account_row["ear"];
|
|
database->avatar.goggle_num = account_row["goggle"];
|
|
database->avatar.beard_num = account_row["beard"];
|
|
database->avatar.weapon_hip_num = account_row["weapon_hip"];
|
|
database->avatar.weapon_unique_num = account_row["weapon_unique"];
|
|
database->avatar.weapon_back_num = account_row["weapon_back"];
|
|
database->avatar.head_texture_num = account_row["head_texture"];
|
|
database->avatar.tattoo_texture_num = account_row["tattoo_texture"];
|
|
database->avatar.tattoo_offset[0] = account_row["tattoo_X"];
|
|
database->avatar.tattoo_offset[1] = account_row["tattoo_Y"];
|
|
database->avatar.tattoo_offset[2] = account_row["tattoo_Z"];
|
|
database->avatar.hair_color[0] = account_row["hair_H"];
|
|
database->avatar.hair_color[1] = account_row["hair_S"];
|
|
database->avatar.hair_color[2] = account_row["hair_V"];
|
|
database->avatar.beard_color[0] = account_row["beard_H"];
|
|
database->avatar.beard_color[1] = account_row["beard_S"];
|
|
database->avatar.beard_color[2] = account_row["beard_V"];
|
|
database->avatar.eye_color[0] = account_row["eye_H"];
|
|
database->avatar.eye_color[1] = account_row["eye_S"];
|
|
database->avatar.eye_color[2] = account_row["eye_V"];
|
|
database->avatar.skin_color[0] = account_row["skin_H"];
|
|
database->avatar.skin_color[1] = account_row["skin_S"];
|
|
database->avatar.skin_color[2] = account_row["skin_V"];
|
|
database->avatar.shirt_primary_color[0] = account_row["shirt_p_H"];
|
|
database->avatar.shirt_primary_color[1] = account_row["shirt_p_S"];
|
|
database->avatar.shirt_primary_color[2] = account_row["shirt_p_V"];
|
|
database->avatar.shirt_secondary_color[0] = account_row["shirt_s_H"];
|
|
database->avatar.shirt_secondary_color[1] = account_row["shirt_s_S"];
|
|
database->avatar.shirt_secondary_color[2] = account_row["shirt_s_V"];
|
|
database->avatar.pants_primary_color[0] = account_row["pants_p_H"];
|
|
database->avatar.pants_primary_color[1] = account_row["pants_p_S"];
|
|
database->avatar.pants_primary_color[2] = account_row["pants_p_V"];
|
|
database->avatar.pants_secondary_color[0] = account_row["pants_s_H"];
|
|
database->avatar.pants_secondary_color[1] = account_row["pants_s_S"];
|
|
database->avatar.pants_secondary_color[2] = account_row["pants_s_V"];
|
|
database->avatar.shirt_primary_metal = account_row["shirt_p_metal"];
|
|
database->avatar.shirt_secondary_metal = account_row["shirt_s_metal"];
|
|
database->avatar.pants_primary_metal = account_row["pants_p_metal"];
|
|
database->avatar.pants_secondary_metal = account_row["pants_s_metal"];
|
|
database->avatar.height_weight_1[0] = account_row["height_weight_0"];
|
|
database->avatar.height_weight_1[1] = account_row["height_weight_1"];
|
|
database->avatar.height_weight_1[2] = account_row["height_weight_2"];
|
|
database->avatar.height_weight_1[3] = account_row["height_weight_3"];
|
|
database->avatar.height_weight_1[4] = account_row["height_weight_4"];
|
|
|
|
//These two have always been the same when testing
|
|
database->avatar.height_weight_2[0] = database->avatar.height_weight_1[0];
|
|
database->avatar.height_weight_2[1] = database->avatar.height_weight_1[1];
|
|
database->avatar.height_weight_2[2] = database->avatar.height_weight_1[2];
|
|
database->avatar.height_weight_2[3] = database->avatar.height_weight_1[3];
|
|
database->avatar.height_weight_2[4] = database->avatar.height_weight_1[4];
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////// Read in ShipData ///////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
sprintf(query_str, "SELECT * FROM `ship_data` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
//LogMessage("Could not load ShipInfo for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
database->ship_data.race = account_row["race"];
|
|
database->ship_data.profession = account_row["prof"];
|
|
database->ship_data.hull = account_row["hull"];
|
|
database->ship_data.wing = account_row["wing"];
|
|
database->ship_data.decal = account_row["decal"];
|
|
strcpy(database->ship_data.ship_name, account_row["name"]);
|
|
database->ship_data.ship_name_color[0] = account_row["name_H"];
|
|
database->ship_data.ship_name_color[1] = account_row["name_S"];
|
|
database->ship_data.ship_name_color[2] = account_row["name_V"];
|
|
database->ship_data.HullPrimaryColor.HSV[0] = account_row["hull_p_H"];
|
|
database->ship_data.HullPrimaryColor.HSV[1] = account_row["hull_p_S"];
|
|
database->ship_data.HullPrimaryColor.HSV[2] = account_row["hull_p_V"];
|
|
database->ship_data.HullPrimaryColor.flat = account_row["hull_p_flat"];
|
|
database->ship_data.HullPrimaryColor.metal = account_row["hull_p_metal"];
|
|
database->ship_data.HullSecondaryColor.HSV[0] = account_row["hull_s_H"];
|
|
database->ship_data.HullSecondaryColor.HSV[1] = account_row["hull_s_S"];
|
|
database->ship_data.HullSecondaryColor.HSV[2] = account_row["hull_s_V"];
|
|
database->ship_data.HullSecondaryColor.flat = account_row["hull_s_flat"];
|
|
database->ship_data.HullSecondaryColor.metal = account_row["hull_s_metal"];
|
|
database->ship_data.ProfessionPrimaryColor.HSV[0] = account_row["prof_p_H"];
|
|
database->ship_data.ProfessionPrimaryColor.HSV[1] = account_row["prof_p_S"];
|
|
database->ship_data.ProfessionPrimaryColor.HSV[2] = account_row["prof_p_V"];
|
|
database->ship_data.ProfessionPrimaryColor.flat = account_row["prof_p_flat"];
|
|
database->ship_data.ProfessionPrimaryColor.metal = account_row["prof_p_metal"];
|
|
database->ship_data.ProfessionSecondaryColor.HSV[0] = account_row["prof_s_H"];
|
|
database->ship_data.ProfessionSecondaryColor.HSV[1] = account_row["prof_s_S"];
|
|
database->ship_data.ProfessionSecondaryColor.HSV[2] = account_row["prof_s_V"];
|
|
database->ship_data.ProfessionSecondaryColor.flat = account_row["prof_s_flat"];
|
|
database->ship_data.ProfessionSecondaryColor.metal = account_row["prof_s_metal"];
|
|
database->ship_data.WingPrimaryColor.HSV[0] = account_row["wing_p_H"];
|
|
database->ship_data.WingPrimaryColor.HSV[1] = account_row["wing_p_S"];
|
|
database->ship_data.WingPrimaryColor.HSV[2] = account_row["wing_p_V"];
|
|
database->ship_data.WingPrimaryColor.flat = account_row["wing_p_flat"];
|
|
database->ship_data.WingPrimaryColor.metal = account_row["wing_p_metal"];
|
|
database->ship_data.WingSecondaryColor.HSV[0] = account_row["wing_s_H"];
|
|
database->ship_data.WingSecondaryColor.HSV[1] = account_row["wing_s_S"];
|
|
database->ship_data.WingSecondaryColor.HSV[2] = account_row["wing_s_V"];
|
|
database->ship_data.WingSecondaryColor.flat = account_row["wing_s_flat"];
|
|
database->ship_data.WingSecondaryColor.metal = account_row["wing_s_metal"];
|
|
database->ship_data.EnginePrimaryColor.HSV[0] = account_row["engine_p_H"];
|
|
database->ship_data.EnginePrimaryColor.HSV[1] = account_row["engine_p_S"];
|
|
database->ship_data.EnginePrimaryColor.HSV[2] = account_row["engine_p_V"];
|
|
database->ship_data.EnginePrimaryColor.flat = account_row["engine_p_flat"];
|
|
database->ship_data.EnginePrimaryColor.metal = account_row["engine_p_metal"];
|
|
database->ship_data.EngineSecondaryColor.HSV[0] = account_row["engine_s_H"];
|
|
database->ship_data.EngineSecondaryColor.HSV[1] = account_row["engine_s_S"];
|
|
database->ship_data.EngineSecondaryColor.HSV[2] = account_row["engine_s_V"];
|
|
database->ship_data.EngineSecondaryColor.flat = account_row["engine_s_flat"];
|
|
database->ship_data.EngineSecondaryColor.metal = account_row["engine_s_metal"];
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////// Read in ShipInfo ///////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//Load in the mounts and location of the player
|
|
//assume that the data is intact
|
|
sprintf(query_str, "SELECT * FROM `ship_info` WHERE `avatar_id` = '%ld'", avatar_id);
|
|
|
|
if (!account_query.run_query(query_str) || account_query.n_rows() == 0)
|
|
{
|
|
//LogMessage("Could not load ShipInfo for id %d\n", avatar_id);
|
|
return false;
|
|
}
|
|
|
|
account_query.store(&account_result);
|
|
account_result.fetch_row(&account_row);
|
|
|
|
database->ship_info.hull = account_row["hull"];
|
|
database->ship_info.profession = account_row["prof"];
|
|
database->ship_info.engine = account_row["engine"];
|
|
database->ship_info.wing = account_row["wing"];
|
|
|
|
database->ship_info.Position[0] = account_row["pos_0"];
|
|
database->ship_info.Position[1] = account_row["pos_1"];
|
|
database->ship_info.Position[2] = account_row["pos_2"];
|
|
database->ship_info.Orientation[0] = account_row["ori_0"];
|
|
database->ship_info.Orientation[1] = account_row["ori_1"];
|
|
database->ship_info.Orientation[2] = account_row["ori_2"];
|
|
database->ship_info.Orientation[3] = account_row["ori_3"];
|
|
|
|
return true;
|
|
}
|
|
|
|
#else
|
|
|
|
void AccountManager::LoadAccounts()
|
|
{
|
|
if (m_NumAccounts != 0)
|
|
{
|
|
LogMessage("Flat file accounts already loaded. Restart server to import changes\n");
|
|
return;
|
|
}
|
|
|
|
m_Mutex.Lock();
|
|
|
|
char buffer[256];
|
|
char filename[MAX_PATH];
|
|
sprintf(filename, "%saccounts.txt", SERVER_DATABASE_PATH);
|
|
FILE *f = fopen(filename, "r");
|
|
if (f)
|
|
{
|
|
while (!feof(f))
|
|
{
|
|
if (fgets(buffer, sizeof(buffer), f))
|
|
{
|
|
// ignore records starting with a semicolon
|
|
if (buffer[0] != ';')
|
|
{
|
|
char *username = buffer;
|
|
char *password = strstr(buffer, ",");
|
|
if (password)
|
|
{
|
|
*password++ = 0;
|
|
char *status = strstr(password, ",");
|
|
if (status)
|
|
{
|
|
*status++ = 0;
|
|
m_Accounts[m_NumAccounts].ID = m_NumAccounts;
|
|
m_Accounts[m_NumAccounts].UserName = g_StringMgr->GetStr(username);
|
|
m_Accounts[m_NumAccounts].Password = g_StringMgr->GetStr(password);
|
|
m_Accounts[m_NumAccounts].Ticket = g_StringMgr->NullStr();
|
|
m_Accounts[m_NumAccounts].Status = atoi(status);
|
|
m_Accounts[m_NumAccounts].InUse = false;
|
|
m_NumAccounts++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
|
|
m_Mutex.Unlock();
|
|
|
|
printf("Loaded %d accounts from file\n", m_NumAccounts);
|
|
}
|
|
|
|
AccountManager::_User * AccountManager::GetUserFromID(long account_id)
|
|
{
|
|
for (int i=0; i<m_NumAccounts; i++)
|
|
{
|
|
if (m_Accounts[i].ID == account_id)
|
|
{
|
|
return &m_Accounts[i];
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
AccountManager::_User * AccountManager::GetUserFromUsername(char *username)
|
|
{
|
|
for (int i=0; i<m_NumAccounts; i++)
|
|
{
|
|
if (_strcmpi(m_Accounts[i].UserName, username) == 0)
|
|
{
|
|
return &m_Accounts[i];
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int AccountManager::NumAccounts()
|
|
{
|
|
return m_NumAccounts;
|
|
}
|
|
|
|
long AccountManager::GetAccountID(int index)
|
|
{
|
|
return index < m_NumAccounts ? m_Accounts[index].ID : -1;
|
|
}
|
|
|
|
//Create the path to a charachter's database given an accountID, buffer must be long enough (MAX_PATH)
|
|
bool AccountManager::CreateCharacterDatabasePath(char *buffer, long avatar_id)
|
|
{
|
|
_User * u = GetUserFromID((avatar_id - 1) / 5);
|
|
if (!u)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
sprintf(buffer, "%sUser_%s_Slot_%d.dat", SERVER_USER_PATH, u->UserName, avatar_id);
|
|
return true;
|
|
}
|
|
|
|
long AccountManager::GetAccountStatus(char *username)
|
|
{
|
|
_User * u = GetUserFromUsername(username);
|
|
return u ? u->Status : -2;
|
|
}
|
|
|
|
long AccountManager::GetAccountID(char *username)
|
|
{
|
|
_User * u = GetUserFromUsername(username);
|
|
return u ? u->ID : -1;
|
|
}
|
|
|
|
//Validates the username/password set, returns the account if valid
|
|
long AccountManager::ValidateAccount(char *username, char *password)
|
|
{
|
|
for (int i=0; i<m_NumAccounts; i++)
|
|
{
|
|
if (strcmp(m_Accounts[i].UserName, username) == 0)
|
|
{
|
|
if (m_Accounts[i].InUse)
|
|
{
|
|
LogMessage("ValidateUserAccount: Account `%s` already in use!\n", username);
|
|
return -1;
|
|
}
|
|
else if (strcmp(m_Accounts[i].Password, password) != 0)
|
|
{
|
|
LogMessage("ValidateUserAccount: Invalid password: `%s` for user: `%s`\n", password, username);
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return m_Accounts[i].ID;
|
|
}
|
|
}
|
|
}
|
|
|
|
LogMessage("ValidateUserAccount: Could not find user: `%s`\n", username);
|
|
return -1;
|
|
}
|
|
|
|
bool AccountManager::AddUser(char *username, char *password, char *access)
|
|
{
|
|
LogMessage("Cannot add users when using flat file for accounts!\n");
|
|
return false;
|
|
}
|
|
|
|
bool AccountManager::SetAccountStatus(char *username, long status)
|
|
{
|
|
LogMessage("Cannot set access level when using flat file for accounts!\n");
|
|
return false;
|
|
}
|
|
|
|
bool AccountManager::ChangePassword(char *username, char *password)
|
|
{
|
|
LogMessage("Cannot change password when using flat file for accounts!\n");
|
|
return false;
|
|
}
|
|
|
|
bool AccountManager::IsUsernameUnique(char *name)
|
|
{
|
|
CharacterDatabase database;
|
|
int account_count = g_AccountMgr->NumAccounts();
|
|
long account_id, avatar_id;
|
|
|
|
for (int i=0; i<account_count; i++)
|
|
{
|
|
account_id = g_AccountMgr->GetAccountID(i);
|
|
|
|
for (long j=0; j<5; j++)
|
|
{
|
|
avatar_id = account_id * 5 + j;
|
|
|
|
if (ReadDatabase(&database, avatar_id))
|
|
{
|
|
if (_strcmpi(database.avatar.avatar_first_name, name) == 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void AccountManager::DeleteCharacter(long avatar_id)
|
|
{
|
|
char filename[MAX_PATH];
|
|
if (!CreateCharacterDatabasePath(filename, avatar_id))
|
|
{
|
|
return;
|
|
}
|
|
|
|
LogDebug("Deleting %s\n", filename);
|
|
DeleteFile(filename);
|
|
|
|
sprintf(filename, "%sCharInfo-%d.chr", SERVER_USER_PATH, avatar_id);
|
|
|
|
LogDebug("Deleting %s\n", filename);
|
|
DeleteFile(filename);
|
|
}
|
|
|
|
bool AccountManager::SaveDatabase(CharacterDatabase * database, long avatar_id)
|
|
{
|
|
char filename[MAX_PATH];
|
|
if (!CreateCharacterDatabasePath(filename, avatar_id))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Write the flat file database
|
|
FILE *f = fopen(filename, "wb");
|
|
if (f)
|
|
{
|
|
fwrite(database, 1, sizeof(CharacterDatabase), f);
|
|
fclose(f);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//Read the avatar database for the player given an avatarID
|
|
bool AccountManager::ReadDatabase(CharacterDatabase *database, long avatar_id)
|
|
{
|
|
char filename[MAX_PATH];
|
|
if (!CreateCharacterDatabasePath(filename, avatar_id))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Read the database from the character file
|
|
FILE *f = fopen(filename, "rb");
|
|
if (f)
|
|
{
|
|
if (fread(database, 1, sizeof(CharacterDatabase), f) == sizeof(CharacterDatabase))
|
|
{
|
|
fclose(f);
|
|
return true;
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
//Returns the avatar ID (base 1) for a player's character, or -1 on error
|
|
long AccountManager::GetAvatarID(char *username, int slot)
|
|
{
|
|
if (slot >= 0 && slot <= 4)
|
|
{
|
|
long account_id = GetAccountID(username);
|
|
return account_id == -1 ? -1 : AVATAR_ID(account_id,slot);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
char * AccountManager::IssueTicket(char *username, char *password)
|
|
{
|
|
//Check if the account is already in use!
|
|
if (g_PlayerMgr->CheckAccountInUse(username))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
long account = ValidateAccount(username, password);
|
|
|
|
//If ValidateAccount returned -1, this username/password set is invalid
|
|
if (account == -1)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//If using SQL, update the last login time
|
|
#ifdef USE_MYSQL_ACCOUNT_DATA
|
|
UpdateTime(account);
|
|
#endif
|
|
|
|
return BuildTicket(username);
|
|
}
|
|
|
|
char * AccountManager::BuildTicket(char *username)
|
|
{
|
|
unsigned long cur_time = GetNet7TickCount();
|
|
|
|
m_Mutex.Lock();
|
|
|
|
AccountTicket * last = 0;
|
|
AccountTicket * time_slot = 0;
|
|
|
|
for (time_slot = m_Tickets; time_slot; time_slot=time_slot->next)
|
|
{
|
|
last = time_slot;
|
|
|
|
//If this ticket expired, use this slot
|
|
if (time_slot->expire_time < cur_time)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//If the slot is empty use it
|
|
if (!time_slot->username)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//If we did not find an empty slot
|
|
if (!time_slot)
|
|
{
|
|
last->next = new AccountTicket();
|
|
memset(last->next, 0, sizeof(AccountTicket));
|
|
time_slot = last->next;
|
|
}
|
|
|
|
//Seed the randomizer
|
|
srand((unsigned int)time(NULL));
|
|
|
|
//Fill the slot
|
|
sprintf(time_slot->ticket, "%s-%d", username, rand());
|
|
time_slot->username = g_StringMgr->GetStr(username);
|
|
time_slot->expire_time = cur_time + TICKET_EXPIRE_TIME;
|
|
|
|
m_Mutex.Unlock();
|
|
|
|
return time_slot->ticket;
|
|
}
|
|
|
|
//This returns a string from the string manager
|
|
char * AccountManager::GetUsernameFromTicket(char *ticket)
|
|
{
|
|
unsigned long cur_time = GetNet7TickCount();
|
|
|
|
m_Mutex.Lock();
|
|
|
|
for (AccountTicket * time_slot = m_Tickets; time_slot; time_slot=time_slot->next)
|
|
{
|
|
//We need to first compare the ticket, then see if it expired
|
|
if (strcmp(time_slot->ticket, ticket) == 0)
|
|
{
|
|
if (time_slot->expire_time > cur_time)
|
|
{
|
|
//Ticket is valid, expire it
|
|
time_slot->expire_time = cur_time;
|
|
|
|
m_Mutex.Unlock();
|
|
return time_slot->username;
|
|
}
|
|
else
|
|
{
|
|
//The ticket expired, free this slot
|
|
time_slot->expire_time = 0;
|
|
time_slot->ticket[0] = 0;
|
|
time_slot->username = 0;
|
|
|
|
m_Mutex.Unlock();
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//The ticket was not found
|
|
m_Mutex.Unlock();
|
|
return 0;
|
|
}
|
|
|
|
//Returns -1 if successful, and an error otherwise
|
|
long AccountManager::CreateCharacter(GlobalCreateCharacter * create)
|
|
{
|
|
//The new character needs to be checked for errors before it is allowed to be added
|
|
char * name = create->avatar.avatar_first_name;
|
|
int name_len = strlen(create->avatar.avatar_first_name);
|
|
|
|
//Name must be atleast 3 characters long
|
|
if (name_len < 3)
|
|
{
|
|
return G_ERROR_TOO_SHORT;
|
|
}
|
|
|
|
//Name cannot have more than 3 repeating characters
|
|
//Name must also have atleast one vowel
|
|
char chr, last = 0, count = 0;
|
|
bool has_vowel = false;
|
|
|
|
for(int i=0; i<name_len; i++)
|
|
{
|
|
chr = name[i];
|
|
|
|
//Check for vowel in the same loop
|
|
if (!has_vowel)
|
|
{
|
|
if (name[i] == 'a' || name[i] == 'e' || name[i] == 'i' || name[i] == 'o' || name[i] == 'u' || name[i] == 'y')
|
|
{
|
|
has_vowel = true;
|
|
}
|
|
}
|
|
|
|
if (isupper(chr))
|
|
{
|
|
chr = tolower(chr);
|
|
}
|
|
|
|
if (last == chr)
|
|
{
|
|
count++;
|
|
|
|
//When count is 2, there were 3 repeating characters
|
|
if (count == 2)
|
|
{
|
|
return G_ERROR_REPEATING_CHAR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
count = 0;
|
|
}
|
|
|
|
last = chr;
|
|
}
|
|
|
|
//If no vowel was found above, send error
|
|
if (!has_vowel)
|
|
{
|
|
return G_ERROR_ONE_VOWEL;
|
|
}
|
|
|
|
//Check to see if character name or ship name is not forbidden
|
|
char ForName[MAX_PATH];
|
|
sprintf(ForName, "%sforbidden.txt", SERVER_DATABASE_PATH);
|
|
|
|
FILE *f = fopen(ForName, "r");
|
|
if (f)
|
|
{
|
|
char buffer[128];
|
|
char * restricted_name;
|
|
|
|
while (!feof(f))
|
|
{
|
|
if (fgets(buffer, sizeof(buffer), f))
|
|
{
|
|
if ((restricted_name = strtok(buffer, "\n")))
|
|
{
|
|
//Check character name
|
|
#ifdef msvc
|
|
if (!_strcmpi(restricted_name, create->avatar.avatar_first_name))
|
|
#else
|
|
if (!stricmp(restricted_name, create->avatar.avatar_first_name))
|
|
#endif
|
|
{
|
|
fclose(f);
|
|
return G_ERROR_RESTRICTED_LIST;
|
|
}
|
|
|
|
//Check ship name
|
|
#ifdef msvc
|
|
if (!_strcmpi(restricted_name, create->ship_data.ship_name))
|
|
#else
|
|
if (!stricmp(restricted_name, create->ship_data.ship_name))
|
|
#endif
|
|
{
|
|
fclose(f);
|
|
return G_ERROR_RESTRICTED_SHIP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
//Lastly, check to see if that name was used
|
|
if (!IsUsernameUnique(name))
|
|
{
|
|
return G_ERROR_NICKNAME_USED;
|
|
}
|
|
|
|
//Now the character has been validated and needs to be created
|
|
CharacterDatabase database;
|
|
memset(&database, 0, sizeof(CharacterDatabase));
|
|
|
|
long start_sector = StartSector[create->avatar.race * 3 + create->avatar.profession];
|
|
long avatar_id = GetAvatarID(create->account_username, htonl(create->character_slot));
|
|
|
|
if (avatar_id == -1)
|
|
{
|
|
//Something went wrong
|
|
return G_ERROR_NET7_INTERNAL;
|
|
}
|
|
|
|
//Set data to AvatarInfo
|
|
database.info.avatar_id_lsb = ntohl(avatar_id);
|
|
database.info.account_id_lsb = ntohl(ACCOUNT_ID(avatar_id));
|
|
database.info.avatar_slot = create->character_slot;
|
|
database.info.sector_id = ntohl(start_sector);
|
|
database.info.galaxy_id = create->galaxy_id;
|
|
database.info.count = ntohl(5);
|
|
database.info.admin_level = ntohl(GetAccountStatus(create->account_username));
|
|
database.info.gm_flag = ntohl(1);
|
|
|
|
//Copy in the sector location (even if its null)
|
|
sprintf(database.info.location, "%s", g_ServerMgr->GetSectorName(start_sector));
|
|
|
|
//Copy in their avatar and ship
|
|
database.avatar = create->avatar;
|
|
database.ship_data = create->ship_data;
|
|
|
|
//Now setup the ship base assets
|
|
database.ship_info.hull = BaseHullAsset[create->ship_data.race * 3 + create->ship_data.hull];
|
|
database.ship_info.profession = BaseProfAsset[create->ship_data.race * 3 + create->ship_data.profession];
|
|
database.ship_info.wing = BaseWingAsset[create->ship_data.race * 3 + create->ship_data.wing];
|
|
database.ship_info.engine = BaseEngineAsset[create->ship_data.race];
|
|
|
|
//Finally save this character in out database
|
|
SaveDatabase(&database, avatar_id);
|
|
|
|
return -1;
|
|
}
|
|
|
|
void AccountManager::BuildAvatarList(GlobalAvatarList * list, long account_id)
|
|
{
|
|
const char *LOCAL_IP = "127.0.0.1"; //local loopback
|
|
CharacterDatabase database;
|
|
memset(list, 0, sizeof(GlobalAvatarList));
|
|
|
|
//Insert the five characters into the avatar list
|
|
for (int i=0; i<5; i++)
|
|
{
|
|
if (ReadDatabase(&database, AVATAR_ID(account_id, i)))
|
|
{
|
|
sprintf(database.info.location, "%s",
|
|
g_ServerMgr->GetSectorName(ntohl(database.info.sector_id)));
|
|
|
|
list->avatar[i].data = database.avatar;
|
|
list->avatar[i].info = database.info;
|
|
}
|
|
}
|
|
|
|
list->num_galaxies = ntohl(1);
|
|
strcpy(list->galaxy[0].Name, g_Galaxy_Name);
|
|
list->galaxy[0].GalaxyID = 1;
|
|
list->galaxy[0].IP_Address = ntohl(inet_addr(LOCAL_IP));//ntohl(g_ServerMgr->m_IpAddress);
|
|
list->galaxy[0].port = ntohs(MASTER_SERVER_PORT);
|
|
list->galaxy[0].NumPlayers = g_ServerMgr->m_GlobMemMgr->GetPlayerCount();
|
|
list->galaxy[0].MaxPlayers = MAX_ONLINE_PLAYERS;
|
|
list->galaxy[0].unknown2 = 1;
|
|
}
|
|
|