net7/branches/linux-port/SaveManager.cpp
2014-05-11 16:54:16 -04:00

795 lines
26 KiB
C++

// SaveManager.cpp
// This class runs a thread which handles all the players' changes
// It keeps a connection to the SQL DB open
// Eventually this could become a separate process and run on another server PC.
#include "Net7.h"
#include "SaveManager.h"
#include "PacketMethods.h"
enum experience_type { XP_COMBAT, XP_EXPLORE, XP_TRADE };
SaveManager::SaveManager()
{
m_SaveBuffer = new CircularBuffer(0x20000, 2048);
m_SaveQueue = new MessageQueue(m_SaveBuffer);
#ifdef WIN32
UINT uiThreadId = 0;
m_SaveThreadHandle = (HANDLE)_beginthreadex(NULL, 0, StartSaveThread, this, CREATE_SUSPENDED, &uiThreadId);
#else
pthread_create(&m_SaveThreadHandle , NULL, &StartSaveThread, (void *) this);
#endif
}
SaveManager::~SaveManager()
{
// TODO: ensure thread is halted and shuts down ok, having saved everyone's status
}
void SaveManager::RunSaveThread()
{
int length;
EnbSaveHeader *header;
unsigned char msg[SAVE_MESSAGE_MAX_LENGTH]; //message will be under 256 or the 'AddMessage' method will not process it
//open the database connection
m_SQL_Conn.connect("net7_user", g_MySQL_Host, g_MySQL_User, g_MySQL_Pass);
m_SaveThreadRunning = true;
while (!g_ServerShutdown)
{
#ifdef WIN32
while (m_SaveQueue->CheckQueue(msg, &length, SAVE_MESSAGE_MAX_LENGTH)) //check if there are any messages in the queue, if there are write them into the 'msg' buffer
{
//process this message
//format is opcode/length/message
header = (EnbSaveHeader*)msg;
unsigned char *data = (msg + sizeof(EnbSaveHeader));
//process opcode accordingly
HandleSaveCode(header->save_code, header->player_id, header->size, data);
}
SuspendThread(m_SaveThreadHandle);
Sleep(2);
#else
m_SaveQueue->BlockingCheckQueue(msg, &length, SAVE_MESSAGE_MAX_LENGTH); //Wait for any messages in the queue, if there are write them into the 'msg' buffer
header = (EnbSaveHeader*)msg;
unsigned char *data = (msg + sizeof(EnbSaveHeader));
//process opcode accordingly
HandleSaveCode(header->save_code, header->player_id, header->size, data);
#endif
}
}
void SaveManager::AddSaveMessage(short save_code, long player_id, short length, unsigned char *data)
{
if (!m_SaveThreadRunning)
{
LogMessage("ERROR!: Save thread not running!!\n");
return;
}
unsigned char pData[SAVE_MESSAGE_MAX_LENGTH];
if (length + 4 > SAVE_MESSAGE_MAX_LENGTH)
{
LogMessage("Recv message overflow: length = %d\n", length);
return;
}
*((short*) &pData[0]) = length;
*((short*) &pData[2]) = save_code;
*((long* ) &pData[4]) = player_id;
if (data)
{
memcpy(pData + sizeof(short)*2 + sizeof(long), data, length);
}
m_SaveQueue->Add(pData, length+sizeof(EnbSaveHeader), player_id);
#ifdef WIN32
//Only necessary on win32 because we are using a blocking queue on linux.
//TODO: Modify the windows code to also use the blocking queue instead.
ResumeThread(m_SaveThreadHandle);
#endif
}
void SaveManager::HandleSaveCode(short save_code, long player_id, short bytes, unsigned char *data)
{
switch (save_code)
{
case SAVE_CODE_ADVANCE_LEVEL:
HandleAdvanceLevel(player_id, bytes, data);
break;
case SAVE_CODE_ADVANCE_SKILL:
HandleAdvanceSkill(player_id, bytes, data);
break;
case SAVE_CODE_CHANGE_INVENTORY:
HandleChangeInventory(player_id, bytes, data);
break;
case SAVE_CODE_CHANGE_EQUIPMENT:
HandleChangeEquipment(player_id, bytes, data);
break;
case SAVE_CODE_AWARD_XP:
HandleAwardXP(player_id, bytes, data);
break;
case SAVE_CODE_CREDIT_LEVEL:
HandleCreditChange(player_id, bytes, data);
break;
case SAVE_CODE_STORE_POSITION:
HandleStorePosition(player_id, bytes, data);
break;
case SAVE_CODE_ADVANCE_MISSION:
HandleAdvanceMission(player_id, bytes, data);
break;
case SAVE_CODE_CHARACTER_PROGRESS_WIPE:
HandleWipeCharacter(player_id);
break;
case SAVE_CODE_FULL_CHARACTER_WIPE:
HandleFullWipeCharacter(player_id);
break;
case SAVE_CODE_MISSION_FLAGS:
HandleAdvanceMissionFlags(player_id, bytes, data);
break;
case SAVE_CODE_CHANGE_AMMO:
HandleChangeAmmo(player_id, bytes, data);
break;
case SAVE_CODE_HULL_UPGRADE:
HandleHullUpgrade(player_id, bytes, data);
break;
case SAVE_CODE_HULL_LEVEL_CHANGE:
HandleHullLevelChange(player_id, bytes, data);
break;
case SAVE_CODE_MISSION_COMPLETE:
HandleMissionComplete(player_id, bytes, data);
break;
case SAVE_CODE_DISCOVER_NAV:
HandleDiscoverNav(player_id, bytes, data);
break;
case SAVE_CODE_EXPLORE_NAV:
HandleExploreNav(player_id, bytes, data);
break;
case SAVE_CODE_SET_SKILLPOINTS:
HandleSetSkillPoints(player_id, bytes, data);
break;
case SAVE_CODE_SET_STARBASE:
HandleSetRegisteredStarbase(player_id, bytes, data);
break;
case SAVE_CODE_SET_ENERGY_LEVELS:
HandleSaveEnergyLevels(player_id, bytes, data);
break;
default:
LogMessage( "Bad save code : %d for player %x\n", save_code, (player_id&0x00FFFFFF) );
break;
}
}
void SaveManager::HandleAdvanceLevel(long player_id, short bytes, unsigned char *data)
{
//player just levelled up.
sql_query_c account_query (&m_SQL_Conn);
u8 xp_type = *((u8 *) &data[0]);
long new_level = *((long *) &data[1]);
switch (xp_type)
{
case XP_COMBAT:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_info SET combat = '%ld' WHERE avatar_id = '%ld'", new_level, player_id);
break;
case XP_EXPLORE:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_info SET explore = '%ld' WHERE avatar_id = '%ld'", new_level, player_id);
break;
case XP_TRADE:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_info SET trade = '%ld' WHERE avatar_id = '%ld'", new_level, player_id);
break;
}
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleAdvanceSkill(long player_id, short bytes, unsigned char *data)
{
//player has just increased a skill
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
short skill_id = *((short *) &data[0]);
short new_level= *((short *) &data[2]);
//does this skill exist in the DB? //TODO:: create this entry when the skill is awarded, then just run 'UPDATE' queries on it.
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_skill_levels WHERE avatar_id = '%ld' AND skill_id = '%d'", player_id, skill_id);
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
sprintf(m_QueryStr, "UPDATE net7_user.avatar_skill_levels SET skill_level = '%d' WHERE avatar_id = '%ld' AND skill_id = '%d'", new_level, player_id, skill_id);
account_query.run_query(m_QueryStr);
}
else
{
//we need to create a new entry
sql_query SkillBuilder;
SkillBuilder.Clear();
SkillBuilder.SetTable("avatar_skill_levels");
SkillBuilder.AddData("avatar_id", player_id);
SkillBuilder.AddData("skill_id", skill_id);
SkillBuilder.AddData("skill_level", new_level);
if (!account_query.run_query(SkillBuilder.CreateQuery()))
{
LogMessage("Could not save Skill Info for id %d\n", player_id );
}
}
}
void SaveManager::HandleChangeInventory(long player_id, short bytes, unsigned char *data)
{
//player has just had an inventory change of some sort
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
u8 inventory_slot = *((u8 *) &data[0]);
u8 inventory_type = *((u8 *) &data[1]);
short stack_level = *((short *) &data[2]);
short trade_stack = *((short *) &data[4]);
float quality = *((float *) &data[6]);
long item_id = *((long *) &data[10]);
unsigned long cost = *((unsigned long *) &data[14]);
switch (inventory_type)
{
case PLAYER_INVENTORY:
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_inventory_items WHERE avatar_id = '%ld' AND inventory_slot = '%d'", player_id, inventory_slot);
break;
case PLAYER_VAULT:
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_vault_items WHERE avatar_id = '%ld' AND inventory_slot = '%d'", player_id, inventory_slot);
break;
}
//does this item exist in the DB?
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
//yes, just update the item
switch (inventory_type)
{
case PLAYER_INVENTORY:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_inventory_items SET item_id = '%ld', stack_level = '%d', trade_stack = '%d', quality = '%f', cost = '%ld' WHERE avatar_id = '%ld' AND inventory_slot = '%d'",
item_id, stack_level, trade_stack, quality, cost, player_id, inventory_slot);
break;
case PLAYER_VAULT:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_vault_items SET item_id = '%ld', stack_level = '%d', trade_stack = '%d', quality = '%f', cost = '%ld' WHERE avatar_id = '%ld' AND inventory_slot = '%d'",
item_id, stack_level, trade_stack, quality, cost, player_id, inventory_slot); break;
}
account_query.run_query(m_QueryStr);
}
else
{
//we need to create a new entry for this item, that's ok
sql_query ItemBuilder;
ItemBuilder.Clear();
switch (inventory_type)
{
case PLAYER_INVENTORY:
ItemBuilder.SetTable("avatar_inventory_items");
break;
case PLAYER_VAULT:
ItemBuilder.SetTable("avatar_vault_items");
break;
}
ItemBuilder.AddData("avatar_id", player_id);
ItemBuilder.AddData("item_id", item_id);
ItemBuilder.AddData("stack_level", stack_level);
ItemBuilder.AddData("trade_stack", trade_stack);
ItemBuilder.AddData("quality", quality);
ItemBuilder.AddData("inventory_slot", inventory_slot);
ItemBuilder.AddData("cost", cost);
if (!account_query.run_query(ItemBuilder.CreateQuery()))
{
LogMessage("Could not save Inventory Info for id %d [item id %d]\n", player_id, item_id );
}
}
}
void SaveManager::HandleChangeEquipment(long player_id, short bytes, unsigned char *data)
{
//player has just had an equipment change
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
u8 equipment_slot = *((u8 *) &data[0]);
float quality = *((float *) &data[1]);
long item_id = *((long *) &data[5]);
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_equipment WHERE avatar_id = '%ld' AND equipment_slot = '%d'", player_id, equipment_slot);
//does this item exist in the DB?
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
//yes, just update the equipment slot
sprintf(m_QueryStr, "UPDATE net7_user.avatar_equipment SET item_id = '%ld', quality = '%f' WHERE avatar_id = '%ld' AND equipment_slot = '%d'",
item_id, quality, player_id, equipment_slot);
account_query.run_query(m_QueryStr);
}
else
{
//we need to create a new entry for this item, that's ok
sql_query EquipBuilder;
EquipBuilder.Clear();
EquipBuilder.SetTable("avatar_equipment");
EquipBuilder.AddData("avatar_id", player_id);
EquipBuilder.AddData("item_id", item_id);
EquipBuilder.AddData("quality", quality);
EquipBuilder.AddData("equipment_slot", equipment_slot);
if (!account_query.run_query(EquipBuilder.CreateQuery()))
{
LogMessage("Could not save Equip Info for id %d\n", player_id );
}
}
}
void SaveManager::HandleChangeAmmo(long player_id, short bytes, unsigned char *data)
{
//player has just had an ammo change
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
u8 equipment_slot = *((u8 *) &data[0]);
short ammo_stack = *((short *) &data[1]);
float quality = *((float *) &data[3]);
long item_id = *((long *) &data[7]);
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_ammo WHERE avatar_id = '%ld' AND equipment_slot = '%d'", player_id, equipment_slot);
//does this item exist in the DB?
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
//yes, just update the equipment slot
sprintf(m_QueryStr, "UPDATE net7_user.avatar_ammo SET item_id = '%ld', quality = '%f', ammo_stack = '%d' WHERE avatar_id = '%ld' AND equipment_slot = '%d'",
item_id, quality, ammo_stack, player_id, equipment_slot);
account_query.run_query(m_QueryStr);
}
else
{
//we need to create a new entry for this item, that's ok
sql_query EquipBuilder;
EquipBuilder.Clear();
EquipBuilder.SetTable("avatar_ammo");
EquipBuilder.AddData("avatar_id", player_id);
EquipBuilder.AddData("item_id", item_id);
EquipBuilder.AddData("quality", quality);
EquipBuilder.AddData("equipment_slot", equipment_slot);
EquipBuilder.AddData("ammo_stack", ammo_stack);
if (!account_query.run_query(EquipBuilder.CreateQuery()))
{
LogMessage("Could not save Ammo Info for id %d\n", player_id );
}
}
}
void SaveManager::HandleAwardXP(long player_id, short bytes, unsigned char *data)
{
//player just received XP, bar is now at a new level
sql_query_c account_query (&m_SQL_Conn);
u8 xp_type = *((u8 *) &data[0]);
float new_level = *((float *) &data[1]);
switch (xp_type)
{
case XP_COMBAT:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET combat_bar_level = '%f' WHERE avatar_id = '%ld'", new_level, player_id);
break;
case XP_EXPLORE:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET explore_bar_level = '%f' WHERE avatar_id = '%ld'", new_level, player_id);
break;
case XP_TRADE:
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET trade_bar_level = '%f' WHERE avatar_id = '%ld'", new_level, player_id);
break;
}
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleCreditChange(long player_id, short bytes, unsigned char *data)
{
//player just received XP, bar is now at a new level
sql_query_c account_query (&m_SQL_Conn);
u64 credits = *((u64 *) &data[0]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET credits = '%I64d' WHERE avatar_id = '%ld'", credits, player_id);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleStorePosition(long player_id, short bytes, unsigned char *data)
{
//get the position stored
//get position out of data
float position[3];
float orientation[4];
long sector_id;
position[0] = *((float *) &data[0]);
position[1] = *((float *) &data[4]);
position[2] = *((float *) &data[8]);
orientation[0] = *((float *) &data[12]);
orientation[1] = *((float *) &data[16]);
orientation[2] = *((float *) &data[20]);
orientation[3] = *((float *) &data[24]);
sector_id = *((long *) &data[28]);
//now store data into DB
sql_query_c account_query (&m_SQL_Conn);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_position SET posx = '%.2f', posy = '%.2f', posz = '%.2f', ori_w = '%f', ori_x = '%f', ori_y = '%f', ori_z = '%f', sector_id = '%ld' WHERE avatar_id = '%ld'",
position[0], position[1], position[2], orientation[0], orientation[1], orientation[2], orientation[3], sector_id, player_id);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleAdvanceMission(long player_id, short bytes, unsigned char *data)
{
//player has just either been awarded a mission or has advanced in one
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
u8 mission_slot = *((u8 *) &data[0]);
long mission_id = *((long *) &data[1]);
short mission_stage = *((short *) &data[5]);
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_mission_progress WHERE avatar_id = '%ld' AND mission_slot = '%d'", player_id, mission_slot);
//does this item exist in the DB?
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
//yes, just update this mission and blank the mission flags
sprintf(m_QueryStr, "UPDATE net7_user.avatar_mission_progress SET stage_num = '%d', mission_flags = '0' WHERE avatar_id = '%ld' AND mission_slot = '%d'",
mission_stage, player_id, mission_slot);
account_query.run_query(m_QueryStr);
}
else
{
//we need to create a new entry for this mission
sql_query MissionBuilder;
MissionBuilder.Clear();
MissionBuilder.SetTable("avatar_mission_progress");
MissionBuilder.AddData("avatar_id", player_id);
MissionBuilder.AddData("mission_id", mission_id);
MissionBuilder.AddData("mission_slot", mission_slot);
MissionBuilder.AddData("mission_flags", 0);
MissionBuilder.AddData("stage_num", mission_stage);
if (!account_query.run_query(MissionBuilder.CreateQuery()))
{
LogMessage("Could not save Mission Info for id %d\n", player_id );
}
}
}
void SaveManager::HandleAdvanceMissionFlags(long player_id, short bytes, unsigned char *data)
{
//player has just had mission flags changed. This is only relevant if the mission exists in the DB
//so just do a simple DB commit.
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
u8 mission_slot = *((u8 *) &data[0]);
long mission_flags = *((long *) &data[1]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_mission_progress SET mission_flags = '%ld' WHERE avatar_id = '%ld' AND mission_slot = '%d'",
mission_flags, player_id, mission_slot);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleHullUpgrade(long player_id, short bytes, unsigned char *data)
{
//player has just had an hull upgrade change (or this is a new player)
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
u8 player_rank_name = *((u8 *) &data[0]);
u8 hull_upgrade_level = *((u8 *) &data[1]);
float max_hull_points = *((float *) &data[2]);
u8 cargo_space = *((u8 *) &data[6]);
u8 weapon_slots = *((u8 *) &data[7]);
u8 device_slots = *((u8 *) &data[8]);
u8 warp_power_level = *((u8 *) &data[9]);
u8 engine_thrust_type = *((u8 *) &data[10]);
sprintf(m_QueryStr, "SELECT * FROM net7_user.avatar_level_info WHERE avatar_id = '%ld'", player_id);
//does this item exist in the DB?
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
//yes, just update the level info row
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET player_rank_name = '%d', hull_upgrade_level = '%d', max_hull_points = '%.2f', cargo_space = '%d', weapon_slots = '%d', device_slots = '%d' WHERE avatar_id = '%ld'",
player_rank_name, hull_upgrade_level, max_hull_points, cargo_space, weapon_slots, device_slots, player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET engine_thrust_type = '%d', warp_power_level = '%d' WHERE avatar_id = '%ld'",
engine_thrust_type, warp_power_level, player_id);
account_query.run_query(m_QueryStr);
}
else
{
//we need to create a new entry for this player, that's ok
sql_query LevelBuilder;
LevelBuilder.Clear();
LevelBuilder.SetTable("avatar_level_info");
LevelBuilder.AddData("avatar_id", player_id);
LevelBuilder.AddData("player_rank_name", player_rank_name);
LevelBuilder.AddData("hull_upgrade_level", hull_upgrade_level);
LevelBuilder.AddData("max_hull_points", max_hull_points);
LevelBuilder.AddData("cargo_space", cargo_space);
LevelBuilder.AddData("weapon_slots", weapon_slots);
LevelBuilder.AddData("device_slots", device_slots);
LevelBuilder.AddData("combat_bar_level", 0.0f);
LevelBuilder.AddData("explore_bar_level", 0.0f);
LevelBuilder.AddData("trade_bar_level", 0.0f);
LevelBuilder.AddData("warp_power_level", warp_power_level);
LevelBuilder.AddData("engine_thrust_type", engine_thrust_type);
LevelBuilder.AddData("hull_points", max_hull_points);
LevelBuilder.AddData("credits", 0);
LevelBuilder.AddData("skill_points", 0); //skill
if (!account_query.run_query(LevelBuilder.CreateQuery()))
{
LogMessage("Could not save Avatar level Info for id %d\n", player_id );
}
}
}
void SaveManager::HandleHullLevelChange(long player_id, short bytes, unsigned char *data)
{
//player has just had an hull level change
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
float hull_points = *((float *) &data[0]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET hull_points = '%.2f' WHERE avatar_id = '%ld'",
hull_points, player_id);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleMissionComplete(long player_id, short bytes, unsigned char *data)
{
//player has just completed a mission
sql_query_c account_query (&m_SQL_Conn);
sql_result_c result;
long mission_id = *((long *) &data[0]);
u8 mission_flags = *((u8 *) &data[4]);
//first remove mission progress
sprintf(m_QueryStr, "DELETE FROM net7_user.avatar_mission_progress WHERE avatar_id = '%ld' AND mission_id = '%ld'",
player_id, mission_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "SELECT * FROM net7_user.missions_completed WHERE avatar_id = '%ld' AND mission_id = '%ld'", player_id, mission_id);
//does this item exist in the DB?
account_query.execute(m_QueryStr);
account_query.store(&result);
if (result.n_rows() != 0)
{
//yes, just update the info row
sprintf(m_QueryStr, "UPDATE net7_user.missions_completed SET mission_completion_flags = '%d' WHERE avatar_id = '%ld' AND mission_id = '%ld'",
mission_flags, player_id, mission_id);
account_query.run_query(m_QueryStr);
}
else
{
sql_query MissionBuilder;
MissionBuilder.Clear();
MissionBuilder.SetTable("missions_completed");
MissionBuilder.AddData("avatar_id", player_id);
MissionBuilder.AddData("mission_id", mission_id);
MissionBuilder.AddData("mission_completion_flags", mission_flags);
account_query.run_query(MissionBuilder.CreateQuery());
}
}
//this method leaves the base character design, name and ship but resets them back to a starting condition.
void SaveManager::HandleWipeCharacter(long player_id)
{
//ok remove all records of inventory, equipment, ammo, skills, levels & rank info
sql_query_c account_query (&m_SQL_Conn);
//remove position info
sprintf(m_QueryStr, "DELETE FROM `avatar_position` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_level_info` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_ammo` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_inventory_items` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_vault_items` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_equipment` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_mission_progress` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_info SET combat = '0', explore = '0', trade = '0' WHERE avatar_id = '%ld'", player_id);
account_query.run_query(m_QueryStr);
}
//this method removes all trace of the avatar in the database, must be used when the avatar is deleted via the client avatar character selector.
void SaveManager::HandleFullWipeCharacter(long player_id)
{
sql_query_c account_query (&m_SQL_Conn);
//remove position info
sprintf(m_QueryStr, "DELETE FROM `avatar_position` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_level_info` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_ammo` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_inventory_items` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_vault_items` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_equipment` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `avatar_mission_progress` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
sprintf(m_QueryStr, "DELETE FROM `missions_completed` WHERE `avatar_id` = '%ld'", player_id);
account_query.run_query(m_QueryStr);
}
#ifdef WIN32
UINT WINAPI SaveManager::StartSaveThread(LPVOID Param)
{
SaveManager* p_this = reinterpret_cast<SaveManager*>( Param );
p_this->RunSaveThread();
return 1;
}
#else
void* SaveManager::StartSaveThread(void* Param)
{
SaveManager* p_this = reinterpret_cast<SaveManager*>( Param );
p_this->RunSaveThread();
return NULL;
}
#endif
void SaveManager::HandleDiscoverNav(long player_id, short bytes, unsigned char *data)
{
//player has just discovered a nav, make a record
sql_query_c account_query (&m_SQL_Conn);
long object_uid = *((long *) &data[0]);
sql_query ExploreBuilder;
ExploreBuilder.Clear();
ExploreBuilder.SetTable("avatar_exploration");
ExploreBuilder.AddData("avatar_id", player_id);
ExploreBuilder.AddData("object_id", object_uid);
ExploreBuilder.AddData("explore_flags", DISCOVER_NAV);
account_query.run_query(ExploreBuilder.CreateQuery());
}
void SaveManager::HandleExploreNav(long player_id, short bytes, unsigned char *data)
{
//player has just explored a nav, update the record
sql_query_c account_query (&m_SQL_Conn);
long object_uid = *((long *) &data[0]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_exploration SET explore_flags = '%d' WHERE avatar_id = '%ld' AND object_id = '%ld'",
EXPLORE_NAV, player_id, object_uid);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleSetSkillPoints(long player_id, short bytes, unsigned char *data)
{
//set skill points
sql_query_c account_query (&m_SQL_Conn);
long skill_points = *((long *) &data[0]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET skill_points = '%ld' WHERE avatar_id = '%ld'",
skill_points, player_id);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleSetRegisteredStarbase(long player_id, short bytes, unsigned char *data)
{
//set skill points
sql_query_c account_query (&m_SQL_Conn);
long registered_starbase = *((long *) &data[0]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET registered_starbase = '%ld' WHERE avatar_id = '%ld'",
registered_starbase, player_id);
account_query.run_query(m_QueryStr);
}
void SaveManager::HandleSaveEnergyLevels(long player_id, short bytes, unsigned char *data)
{
//set skill points
sql_query_c account_query (&m_SQL_Conn);
float energy = *((float *) &data[0]);
float shield = *((float *) &data[4]);
sprintf(m_QueryStr, "UPDATE net7_user.avatar_level_info SET reactor_level = '%f', shield_level = '%f' WHERE avatar_id = '%ld'",
energy, shield, player_id);
account_query.run_query(m_QueryStr);
}