Hopefully completely merged from master in what is the biggest merge ever

This commit is contained in:
KimLS
2014-12-07 13:23:16 -08:00
513 changed files with 68160 additions and 63864 deletions
+30 -30
View File
@@ -1,68 +1,68 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(world_sources
Adventure.cpp
AdventureManager.cpp
adventure.cpp
adventure_manager.cpp
client.cpp
cliententry.cpp
clientlist.cpp
CMakeLists.txt
console.cpp
EQLConfig.cpp
EQW.cpp
EQWHTTPHandler.cpp
EQWParser.cpp
HTTPRequest.cpp
LauncherLink.cpp
LauncherList.cpp
eql_config.cpp
eqw.cpp
eqw_http_handler.cpp
eqw_parser.cpp
http_request.cpp
launcher_link.cpp
launcher_list.cpp
lfplist.cpp
LoginServer.cpp
LoginServerList.cpp
login_server.cpp
login_server_list.cpp
net.cpp
perl_EQLConfig.cpp
perl_EQW.cpp
perl_HTTPRequest.cpp
perl_eql_config.cpp
perl_eqw.cpp
perl_http_request.cpp
queryserv.cpp
remote_call.cpp
ucs.cpp
web_interface.cpp
wguild_mgr.cpp
world_logsys.cpp
WorldConfig.cpp
world_config.cpp
worlddb.cpp
zonelist.cpp
zoneserver.cpp
)
SET(world_headers
Adventure.h
AdventureManager.h
AdventureTemplate.h
adventure.h
adventure_manager.h
adventure_template.h
client.h
cliententry.h
clientlist.h
CMakeLists.txt
console.h
EQLConfig.h
EQW.h
EQWHTTPHandler.h
EQWParser.h
HTTPRequest.h
LauncherLink.h
LauncherList.h
eql_config.h
eqw.h
eqw_http_handler.h
eqw_parser.h
http_request.h
launcher_link.h
launcher_list.h
lfplist.h
LoginServer.h
LoginServerList.h
login_server.h
login_server_list.h
net.h
queryserv.h
remote_call.h
SoFCharCreateData.h
sof_char_create_data.h
ucs.h
web_interface.h
wguild_mgr.h
WorldConfig.h
world_config.h
worlddb.h
WorldTCPConnection.h
world_tcp_connection.h
zonelist.h
zoneserver.h
)
+35 -46
View File
@@ -2,10 +2,10 @@
#include "../common/servertalk.h"
#include "../common/extprofile.h"
#include "../common/rulesys.h"
#include "../common/MiscFunctions.h"
#include "../common/StringUtil.h"
#include "Adventure.h"
#include "AdventureManager.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "adventure.h"
#include "adventure_manager.h"
#include "worlddb.h"
#include "zonelist.h"
#include "clientlist.h"
@@ -54,10 +54,10 @@ void Adventure::AddPlayer(std::string character_name, bool add_client_to_instanc
{
if(!PlayerExists(character_name))
{
int client_id = database.GetCharacterID(character_name.c_str());
if(add_client_to_instance)
int32 character_id = database.GetCharacterID(character_name.c_str());
if(character_id && add_client_to_instance)
{
database.AddClientToInstance(instance_id, client_id);
database.AddClientToInstance(instance_id, character_id);
}
players.push_back(character_name);
}
@@ -70,8 +70,12 @@ void Adventure::RemovePlayer(std::string character_name)
{
if((*iter).compare(character_name) == 0)
{
database.RemoveClientFromInstance(instance_id, database.GetCharacterID(character_name.c_str()));
players.erase(iter);
int32 character_id = database.GetCharacterID(character_name.c_str());
if (character_id)
{
database.RemoveClientFromInstance(instance_id, character_id);
players.erase(iter);
}
return;
}
++iter;
@@ -358,6 +362,7 @@ void Adventure::Finished(AdventureWinStatus ws)
afe.points = 0;
}
adventure_manager.AddFinishedEvent(afe);
database.UpdateAdventureStatsEntry(database.GetCharacterID((*iter).c_str()), GetTemplate()->theme, (ws != AWS_Lose) ? true : false);
}
++iter;
@@ -374,49 +379,35 @@ void Adventure::MoveCorpsesToGraveyard()
std::list<uint32> dbid_list;
std::list<uint32> charid_list;
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()), errbuf, &result))
{
while((row = mysql_fetch_row(result)))
{
dbid_list.push_back(atoi(row[0]));
charid_list.push_back(atoi(row[1]));
}
mysql_free_result(result);
safe_delete_array(query);
}
else
{
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
safe_delete_array(query);
}
std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instanceid=%d", GetInstanceID());
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
std::list<uint32>::iterator iter = dbid_list.begin();
while(iter != dbid_list.end())
for(auto row = results.begin(); row != results.end(); ++row) {
dbid_list.push_back(atoi(row[0]));
charid_list.push_back(atoi(row[1]));
}
for (auto iter = dbid_list.begin(); iter != dbid_list.end(); ++iter)
{
float x = GetTemplate()->graveyard_x + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
float z = GetTemplate()->graveyard_z;
if(database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid=%d, instanceid=0, x=%f, y=%f, z=%f WHERE instanceid=%d",
GetTemplate()->graveyard_zone_id, x, y, z, GetInstanceID()), errbuf))
{
safe_delete_array(query);
}
else
{
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
safe_delete_array(query);
}
++iter;
query = StringFormat("UPDATE character_corpses "
"SET zoneid = %d, instanceid = 0, "
"x = %f, y = %f, z = %f WHERE instanceid = %d",
GetTemplate()->graveyard_zone_id,
x, y, z, GetInstanceID());
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
}
iter = dbid_list.begin();
std::list<uint32>::iterator c_iter = charid_list.begin();
while(iter != dbid_list.end())
auto c_iter = charid_list.begin();
for (auto iter = dbid_list.begin(); iter != dbid_list.end(); ++iter, ++c_iter)
{
ServerPacket* pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct));
ServerDepopAllPlayersCorpses_Struct *dpc = (ServerDepopAllPlayersCorpses_Struct*)pack->pBuffer;
@@ -433,8 +424,6 @@ void Adventure::MoveCorpsesToGraveyard()
zoneserver_list.SendPacket(spc->zone_id, 0, pack);
delete pack;
++iter;
++c_iter;
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
#include "../common/debug.h"
#include "../common/types.h"
#include "../common/timer.h"
#include "AdventureTemplate.h"
#include "adventure_template.h"
#include <list>
#include <string>
#include <stdlib.h>
@@ -1,10 +1,10 @@
#include "../common/debug.h"
#include "../common/MiscFunctions.h"
#include "../common/StringUtil.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/servertalk.h"
#include "../common/rulesys.h"
#include "Adventure.h"
#include "AdventureManager.h"
#include "adventure.h"
#include "adventure_manager.h"
#include "worlddb.h"
#include "zonelist.h"
#include "clientlist.h"
@@ -639,119 +639,90 @@ AdventureTemplate *AdventureManager::GetAdventureTemplate(int id)
bool AdventureManager::LoadAdventureTemplates()
{
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, zone, zone_version, "
std::string query = "SELECT id, zone, zone_version, "
"is_hard, min_level, max_level, type, type_data, type_count, assa_x, "
"assa_y, assa_z, assa_h, text, duration, zone_in_time, win_points, lose_points, "
"theme, zone_in_zone_id, zone_in_x, zone_in_y, zone_in_object_id, dest_x, dest_y,"
" dest_z, dest_h, graveyard_zone_id, graveyard_x, graveyard_y, graveyard_z, "
"graveyard_radius FROM adventure_template"), errbuf, &result))
{
while((row = mysql_fetch_row(result)))
{
uint8 x = 0;
AdventureTemplate *t = new AdventureTemplate;
t->id = atoi(row[x++]);
strcpy(t->zone, row[x++]);
t->zone_version = atoi(row[x++]);
t->is_hard = atoi(row[x++]);
t->min_level = atoi(row[x++]);
t->max_level = atoi(row[x++]);
t->type = atoi(row[x++]);
t->type_data = atoi(row[x++]);
t->type_count = atoi(row[x++]);
t->assa_x = atof(row[x++]);
t->assa_y = atof(row[x++]);
t->assa_z = atof(row[x++]);
t->assa_h = atof(row[x++]);
strn0cpy(t->text, row[x++], sizeof(t->text));
t->duration = atoi(row[x++]);
t->zone_in_time = atoi(row[x++]);
t->win_points = atoi(row[x++]);
t->lose_points = atoi(row[x++]);
t->theme = atoi(row[x++]);
t->zone_in_zone_id = atoi(row[x++]);
t->zone_in_x = atof(row[x++]);
t->zone_in_y = atof(row[x++]);
t->zone_in_object_id = atoi(row[x++]);
t->dest_x = atof(row[x++]);
t->dest_y = atof(row[x++]);
t->dest_z = atof(row[x++]);
t->dest_h = atof(row[x++]);
t->graveyard_zone_id = atoi(row[x++]);
t->graveyard_x = atof(row[x++]);
t->graveyard_y = atof(row[x++]);
t->graveyard_z = atof(row[x++]);
t->graveyard_radius = atof(row[x++]);
adventure_templates[t->id] = t;
}
mysql_free_result(result);
safe_delete_array(query);
return true;
}
else
{
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::LoadAdventures: %s (%s)", query, errbuf);
safe_delete_array(query);
"theme, zone_in_zone_id, zone_in_x, zone_in_y, zone_in_object_id, dest_x, dest_y, "
"dest_z, dest_h, graveyard_zone_id, graveyard_x, graveyard_y, graveyard_z, "
"graveyard_radius FROM adventure_template";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::LoadAdventures: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return false;
}
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
AdventureTemplate *aTemplate = new AdventureTemplate;
aTemplate->id = atoi(row[0]);
strcpy(aTemplate->zone, row[1]);
aTemplate->zone_version = atoi(row[2]);
aTemplate->is_hard = atoi(row[3]);
aTemplate->min_level = atoi(row[4]);
aTemplate->max_level = atoi(row[5]);
aTemplate->type = atoi(row[6]);
aTemplate->type_data = atoi(row[7]);
aTemplate->type_count = atoi(row[8]);
aTemplate->assa_x = atof(row[9]);
aTemplate->assa_y = atof(row[10]);
aTemplate->assa_z = atof(row[11]);
aTemplate->assa_h = atof(row[12]);
strn0cpy(aTemplate->text, row[13], sizeof(aTemplate->text));
aTemplate->duration = atoi(row[14]);
aTemplate->zone_in_time = atoi(row[15]);
aTemplate->win_points = atoi(row[16]);
aTemplate->lose_points = atoi(row[17]);
aTemplate->theme = atoi(row[18]);
aTemplate->zone_in_zone_id = atoi(row[19]);
aTemplate->zone_in_x = atof(row[20]);
aTemplate->zone_in_y = atof(row[21]);
aTemplate->zone_in_object_id = atoi(row[22]);
aTemplate->dest_x = atof(row[23]);
aTemplate->dest_y = atof(row[24]);
aTemplate->dest_z = atof(row[25]);
aTemplate->dest_h = atof(row[26]);
aTemplate->graveyard_zone_id = atoi(row[27]);
aTemplate->graveyard_x = atof(row[28]);
aTemplate->graveyard_y = atof(row[29]);
aTemplate->graveyard_z = atof(row[30]);
aTemplate->graveyard_radius = atof(row[31]);
adventure_templates[aTemplate->id] = aTemplate;
}
return true;
}
bool AdventureManager::LoadAdventureEntries()
{
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, template_id FROM adventure_template_entry"), errbuf, &result))
std::string query = "SELECT id, template_id FROM adventure_template_entry";
auto results = database.QueryDatabase(query);
if (!results.Success())
{
while((row = mysql_fetch_row(result)))
{
int id = atoi(row[0]);
int template_id = atoi(row[1]);
AdventureTemplate* tid = nullptr;
std::map<uint32, AdventureTemplate*>::iterator t_iter = adventure_templates.find(template_id);
if(t_iter == adventure_templates.end())
{
continue;
}
else
{
tid = adventure_templates[template_id];
}
std::list<AdventureTemplate*> temp;
std::map<uint32, std::list<AdventureTemplate*> >::iterator iter = adventure_entries.find(id);
if(iter == adventure_entries.end())
{
temp.push_back(tid);
adventure_entries[id] = temp;
}
else
{
temp = adventure_entries[id];
temp.push_back(tid);
adventure_entries[id] = temp;
}
}
mysql_free_result(result);
safe_delete_array(query);
return true;
}
else
{
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::LoadAdventureEntries: %s (%s)", query, errbuf);
safe_delete_array(query);
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::LoadAdventureEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return false;
}
return false;
for (auto row = results.begin(); row != results.end(); ++row)
{
int id = atoi(row[0]);
int template_id = atoi(row[1]);
AdventureTemplate* tid = nullptr;
auto t_iter = adventure_templates.find(template_id);
if(t_iter == adventure_templates.end())
continue;
tid = adventure_templates[template_id];
std::list<AdventureTemplate*> temp;
auto iter = adventure_entries.find(id);
if(iter != adventure_entries.end())
temp = adventure_entries[id];
temp.push_back(tid);
adventure_entries[id] = temp;
}
return true;
}
void AdventureManager::PlayerClickedDoor(const char *player, int zone_id, int door_id)
@@ -1096,79 +1067,69 @@ void AdventureManager::LoadLeaderboardInfo()
leaderboard_info_percentage_ruj.clear();
leaderboard_info_wins_tak.clear();
leaderboard_info_percentage_tak.clear();
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query,MakeAnyLenString(&query,"select ch.name, ch.id, adv_stats.* from adventure_stats "
"AS adv_stats ""left join character_ AS ch on adv_stats.player_id = ch.id;"), errbuf, &result))
{
while((row = mysql_fetch_row(result)))
{
if(row[0])
{
LeaderboardInfo lbi;
lbi.name = row[0];
lbi.wins = atoi(row[3]);
lbi.guk_wins = atoi(row[3]);
lbi.wins += atoi(row[4]);
lbi.mir_wins = atoi(row[4]);
lbi.wins += atoi(row[5]);
lbi.mmc_wins = atoi(row[5]);
lbi.wins += atoi(row[6]);
lbi.ruj_wins = atoi(row[6]);
lbi.wins += atoi(row[7]);
lbi.tak_wins = atoi(row[7]);
lbi.losses = atoi(row[8]);
lbi.guk_losses = atoi(row[8]);
lbi.losses += atoi(row[9]);
lbi.mir_losses = atoi(row[9]);
lbi.losses += atoi(row[10]);
lbi.mmc_losses = atoi(row[10]);
lbi.losses += atoi(row[11]);
lbi.ruj_losses = atoi(row[11]);
lbi.losses += atoi(row[12]);
lbi.tak_losses = atoi(row[12]);
leaderboard_info_wins.push_back(lbi);
leaderboard_info_percentage.push_back(lbi);
leaderboard_info_wins_guk.push_back(lbi);
leaderboard_info_percentage_guk.push_back(lbi);
leaderboard_info_wins_mir.push_back(lbi);
leaderboard_info_percentage_mir.push_back(lbi);
leaderboard_info_wins_mmc.push_back(lbi);
leaderboard_info_percentage_mmc.push_back(lbi);
leaderboard_info_wins_ruj.push_back(lbi);
leaderboard_info_percentage_ruj.push_back(lbi);
leaderboard_info_wins_tak.push_back(lbi);
leaderboard_info_percentage_tak.push_back(lbi);
leaderboard_sorted_wins = false;
leaderboard_sorted_percentage = false;
leaderboard_sorted_wins_guk = false;
leaderboard_sorted_percentage_guk = false;
leaderboard_sorted_wins_mir = false;
leaderboard_sorted_percentage_mir = false;
leaderboard_sorted_wins_mmc = false;
leaderboard_sorted_percentage_mmc = false;
leaderboard_sorted_wins_ruj = false;
leaderboard_sorted_percentage_ruj = false;
leaderboard_sorted_wins_tak = false;
leaderboard_sorted_percentage_tak = false;
}
}
mysql_free_result(result);
safe_delete_array(query);
std::string query = "SELECT ch.name, ch.id, adv_stats.* FROM adventure_stats "
"AS adv_stats LEFT JOIN `character_data` AS ch ON adv_stats.player_id = ch.id;";
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::GetLeaderboardInfo: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
else
{
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::GetLeaderboardInfo: %s (%s)", query, errbuf);
safe_delete_array(query);
return;
for (auto row = results.begin(); row != results.end(); ++row)
{
if(!row[0])
continue;
LeaderboardInfo lbi;
lbi.name = row[0];
lbi.wins = atoi(row[3]);
lbi.guk_wins = atoi(row[3]);
lbi.wins += atoi(row[4]);
lbi.mir_wins = atoi(row[4]);
lbi.wins += atoi(row[5]);
lbi.mmc_wins = atoi(row[5]);
lbi.wins += atoi(row[6]);
lbi.ruj_wins = atoi(row[6]);
lbi.wins += atoi(row[7]);
lbi.tak_wins = atoi(row[7]);
lbi.losses = atoi(row[8]);
lbi.guk_losses = atoi(row[8]);
lbi.losses += atoi(row[9]);
lbi.mir_losses = atoi(row[9]);
lbi.losses += atoi(row[10]);
lbi.mmc_losses = atoi(row[10]);
lbi.losses += atoi(row[11]);
lbi.ruj_losses = atoi(row[11]);
lbi.losses += atoi(row[12]);
lbi.tak_losses = atoi(row[12]);
leaderboard_info_wins.push_back(lbi);
leaderboard_info_percentage.push_back(lbi);
leaderboard_info_wins_guk.push_back(lbi);
leaderboard_info_percentage_guk.push_back(lbi);
leaderboard_info_wins_mir.push_back(lbi);
leaderboard_info_percentage_mir.push_back(lbi);
leaderboard_info_wins_mmc.push_back(lbi);
leaderboard_info_percentage_mmc.push_back(lbi);
leaderboard_info_wins_ruj.push_back(lbi);
leaderboard_info_percentage_ruj.push_back(lbi);
leaderboard_info_wins_tak.push_back(lbi);
leaderboard_info_percentage_tak.push_back(lbi);
leaderboard_sorted_wins = false;
leaderboard_sorted_percentage = false;
leaderboard_sorted_wins_guk = false;
leaderboard_sorted_percentage_guk = false;
leaderboard_sorted_wins_mir = false;
leaderboard_sorted_percentage_mir = false;
leaderboard_sorted_wins_mmc = false;
leaderboard_sorted_percentage_mmc = false;
leaderboard_sorted_wins_ruj = false;
leaderboard_sorted_percentage_ruj = false;
leaderboard_sorted_wins_tak = false;
leaderboard_sorted_percentage_tak = false;
}
return;
};
void AdventureManager::DoLeaderboardRequest(const char* player, uint8 type)
@@ -4,8 +4,8 @@
#include "../common/debug.h"
#include "../common/types.h"
#include "../common/timer.h"
#include "Adventure.h"
#include "AdventureTemplate.h"
#include "adventure.h"
#include "adventure_template.h"
#include <map>
#include <list>
+165 -223
View File
@@ -1,31 +1,31 @@
#include "../common/debug.h"
#include "../common/EQPacket.h"
#include "../common/EQStreamIntf.h"
#include "../common/eq_packet.h"
#include "../common/eq_stream_intf.h"
#include "../common/misc.h"
#include "../common/rulesys.h"
#include "../common/emu_opcodes.h"
#include "../common/eq_packet_structs.h"
#include "../common/packet_dump.h"
#include "../common/EQStreamIntf.h"
#include "../common/Item.h"
#include "../common/eq_stream_intf.h"
#include "../common/item.h"
#include "../common/races.h"
#include "../common/classes.h"
#include "../common/languages.h"
#include "../common/skills.h"
#include "../common/extprofile.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
#include "../common/clientversions.h"
#include "client.h"
#include "worlddb.h"
#include "WorldConfig.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "world_config.h"
#include "login_server.h"
#include "login_server_list.h"
#include "zoneserver.h"
#include "zonelist.h"
#include "clientlist.h"
#include "wguild_mgr.h"
#include "SoFCharCreateData.h"
#include "sof_char_create_data.h"
#include <iostream>
#include <iomanip>
@@ -64,8 +64,6 @@ extern ClientList client_list;
extern uint32 numclients;
extern volatile bool RunLoops;
Client::Client(EQStreamInterface* ieqs)
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
CLE_keepalive_timer(RuleI(World, ClientKeepaliveTimeoutMS)),
@@ -130,7 +128,7 @@ void Client::SendLogServer()
void Client::SendEnterWorld(std::string name)
{
char char_name[32]= { 0 };
char char_name[64] = { 0 };
if (pZoning && database.GetLiveChar(GetAccountID(), char_name)) {
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
eqs->Close();
@@ -174,7 +172,7 @@ void Client::SendCharInfo() {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendCharInfo, sizeof(CharacterSelect_Struct));
CharacterSelect_Struct* cs = (CharacterSelect_Struct*)outapp->pBuffer;
database.GetCharSelectInfo(GetAccountID(), cs);
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
QueuePacket(outapp);
safe_delete(outapp);
@@ -471,8 +469,8 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
return true;
}
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
{
if (GetAccountID() == 0) {
clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
return false;
@@ -482,7 +480,7 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
uchar race = app->pBuffer[64];
uchar clas = app->pBuffer[68];
clog(WORLD__CLIENT,"Name approval request. Name=%s, race=%s, class=%s",char_name,GetRaceName(race),GetEQClassName(clas));
clog(WORLD__CLIENT, "Name approval request. Name=%s, race=%s, class=%s", char_name, GetRaceName(race), GetEQClassName(clas));
EQApplicationPacket *outapp;
outapp = new EQApplicationPacket;
@@ -490,27 +488,27 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
outapp->pBuffer = new uchar[1];
outapp->size = 1;
bool valid;
if(!database.CheckNameFilter(char_name)) {
valid = false;
bool valid = false;
if(!database.CheckNameFilter(char_name)) {
valid = false;
}
else if(char_name[0] < 'A' && char_name[0] > 'Z') {
//name must begin with an upper-case letter.
valid = false;
/* Name must begin with an upper-case letter. */
else if (islower(char_name[0])) {
valid = false;
}
else if (database.ReserveName(GetAccountID(), char_name)) {
valid = true;
}
else if (database.ReserveName(GetAccountID(), char_name)) {
valid = true;
}
else {
valid = false;
else {
valid = false;
}
outapp->pBuffer[0] = valid? 1 : 0;
QueuePacket(outapp);
safe_delete(outapp);
if(!valid) {
if (!valid)
memset(char_name, 0, sizeof(char_name));
}
return true;
}
@@ -642,13 +640,11 @@ bool Client::HandleCharacterCreateRequestPacket(const EQApplicationPacket *app)
}
bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
if (GetAccountID() == 0)
{
if (GetAccountID() == 0) {
clog(WORLD__CLIENT_ERR,"Account ID not set; unable to create character.");
return false;
}
else if (app->size != sizeof(CharCreate_Struct))
{
else if (app->size != sizeof(CharCreate_Struct)) {
clog(WORLD__CLIENT_ERR,"Wrong size on OP_CharacterCreate. Got: %d, Expected: %d",app->size,sizeof(CharCreate_Struct));
DumpPacket(app);
// the previous behavior was essentially returning true here
@@ -657,8 +653,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
}
CharCreate_Struct *cc = (CharCreate_Struct*)app->pBuffer;
if(OPCharCreate(char_name, cc) == false)
{
if(OPCharCreate(char_name, cc) == false) {
database.DeleteCharacter(char_name);
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ApproveName, 1);
outapp->pBuffer[0] = 0;
@@ -675,8 +670,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
return true;
}
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
if (GetAccountID() == 0) {
clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
eqs->Close();
@@ -713,11 +707,10 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
return true;
}
if(!pZoning && ew->return_home && !ew->tutorial)
{
if(!pZoning && ew->return_home && !ew->tutorial) {
CharacterSelect_Struct* cs = new CharacterSelect_Struct;
memset(cs, 0, sizeof(CharacterSelect_Struct));
database.GetCharSelectInfo(GetAccountID(), cs);
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
bool home_enabled = false;
for(int x = 0; x < 10; ++x)
@@ -733,12 +726,10 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
}
safe_delete(cs);
if(home_enabled)
{
if(home_enabled) {
zoneID = database.MoveCharacterToBind(charid,4);
}
else
{
else {
clog(WORLD__CLIENT_ERR,"'%s' is trying to go home before they're able...",char_name);
database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
eqs->Close();
@@ -749,7 +740,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
if(!pZoning && (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial))) {
CharacterSelect_Struct* cs = new CharacterSelect_Struct;
memset(cs, 0, sizeof(CharacterSelect_Struct));
database.GetCharSelectInfo(GetAccountID(), cs);
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
bool tutorial_enabled = false;
for(int x = 0; x < 10; ++x)
@@ -807,16 +798,16 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
database.SetLoginFlags(charid, false, false, 1);
}
else{
uint32 groupid=database.GetGroupID(char_name);
if(groupid>0){
char* leader=0;
char leaderbuf[64]={0};
if((leader=database.GetGroupLeaderForLogin(char_name,leaderbuf)) && strlen(leader)>1){
uint32 groupid = database.GetGroupID(char_name);
if(groupid > 0){
char* leader = 0;
char leaderbuf[64] = {0};
if((leader = database.GetGroupLeaderForLogin(char_name, leaderbuf)) && strlen(leader)>1){
EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer;
gj->action=8;
strcpy(gj->yourname,char_name);
strcpy(gj->membername,leader);
strcpy(gj->yourname, char_name);
strcpy(gj->membername, leader);
QueuePacket(outapp3);
safe_delete(outapp3);
}
@@ -895,8 +886,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
bool Client::HandleDeleteCharacterPacket(const EQApplicationPacket *app) {
uint32 char_acct_id = database.GetAccountIDByChar((char*)app->pBuffer);
if(char_acct_id == GetAccountID())
{
if(char_acct_id == GetAccountID()) {
clog(WORLD__CLIENT,"Delete character: %s",app->pBuffer);
database.DeleteCharacter((char *)app->pBuffer);
SendCharInfo();
@@ -1355,57 +1345,41 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
time_t bday = time(nullptr);
char startzone[50]={0};
uint32 i;
struct in_addr in;
struct in_addr in;
int stats_sum = cc->STR + cc->STA + cc->AGI + cc->DEX +
cc->WIS + cc->INT + cc->CHA;
int stats_sum = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
in.s_addr = GetIP();
clog(WORLD__CLIENT,"Character creation request from %s LS#%d (%s:%d) : ", GetCLE()->LSName(), GetCLE()->LSID(), inet_ntoa(in), GetPort());
clog(WORLD__CLIENT,"Name: %s", name);
clog(WORLD__CLIENT,"Race: %d Class: %d Gender: %d Deity: %d Start zone: %d",
cc->race, cc->class_, cc->gender, cc->deity, cc->start_zone);
clog(WORLD__CLIENT,"STR STA AGI DEX WIS INT CHA Total");
clog(WORLD__CLIENT,"%3d %3d %3d %3d %3d %3d %3d %3d",
clog(WORLD__CLIENT, "Character creation request from %s LS#%d (%s:%d) : ", GetCLE()->LSName(), GetCLE()->LSID(), inet_ntoa(in), GetPort());
clog(WORLD__CLIENT, "Name: %s", name);
clog(WORLD__CLIENT, "Race: %d Class: %d Gender: %d Deity: %d Start zone: %d Tutorial: %s",
cc->race, cc->class_, cc->gender, cc->deity, cc->start_zone, cc->tutorial ? "true" : "false");
clog(WORLD__CLIENT, "STR STA AGI DEX WIS INT CHA Total");
clog(WORLD__CLIENT, "%3d %3d %3d %3d %3d %3d %3d %3d",
cc->STR, cc->STA, cc->AGI, cc->DEX, cc->WIS, cc->INT, cc->CHA,
stats_sum);
clog(WORLD__CLIENT,"Face: %d Eye colors: %d %d", cc->face, cc->eyecolor1, cc->eyecolor2);
clog(WORLD__CLIENT,"Hairstyle: %d Haircolor: %d", cc->hairstyle, cc->haircolor);
clog(WORLD__CLIENT,"Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
clog(WORLD__CLIENT, "Face: %d Eye colors: %d %d", cc->face, cc->eyecolor1, cc->eyecolor2);
clog(WORLD__CLIENT, "Hairstyle: %d Haircolor: %d", cc->hairstyle, cc->haircolor);
clog(WORLD__CLIENT, "Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
// validate the char creation struct
if(ClientVersionBit & BIT_SoFAndLater) {
if(!CheckCharCreateInfoSoF(cc))
{
/* Validate the char creation struct */
if (ClientVersionBit & BIT_SoFAndLater) {
if (!CheckCharCreateInfoSoF(cc)) {
clog(WORLD__CLIENT_ERR,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
} else {
if(!CheckCharCreateInfoTitanium(cc))
{
if (!CheckCharCreateInfoTitanium(cc)) {
clog(WORLD__CLIENT_ERR,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
}
// Convert incoming cc_s to the new PlayerProfile_Struct
/* Convert incoming cc_s to the new PlayerProfile_Struct */
memset(&pp, 0, sizeof(PlayerProfile_Struct)); // start building the profile
InitExtendedProfile(&ext);
strn0cpy(pp.name, name, 63);
// clean the capitalization of the name
#if 0 // on second thought, don't - this will just make the creation fail
// because the name won't match what was already reserved earlier
for (i = 0; pp.name[i] && i < 63; i++)
{
if(!isalpha(pp.name[i]))
return false;
pp.name[i] = tolower(pp.name[i]);
}
pp.name[0] = toupper(pp.name[0]);
#endif
pp.race = cc->race;
pp.class_ = cc->class_;
@@ -1433,149 +1407,128 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
pp.level = 1;
pp.points = 5;
pp.cur_hp = 1000; // 1k hp during dev only
//what was the point of this? zone dosent handle this:
//pp.expAA = 0xFFFFFFFF;
pp.hunger_level = 6000;
pp.thirst_level = 6000;
// FIXME: FV roleplay, database goodness...
// Racial Languages
SetRacialLanguages( &pp ); // bUsh
SetRaceStartingSkills( &pp ); // bUsh
SetClassStartingSkills( &pp ); // bUsh
/* Set Racial and Class specific language and skills */
SetRacialLanguages(&pp);
SetRaceStartingSkills(&pp);
SetClassStartingSkills(&pp);
SetClassLanguages(&pp);
pp.skills[SkillSenseHeading] = 200;
// Some one fucking fix this to use a field name. -Doodman
//pp.unknown3596[28] = 15; // @bp: This is to enable disc usage
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
for(i = 0; i < MAX_PP_SPELLBOOK; i++)
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++)
pp.spell_book[i] = 0xFFFFFFFF;
for(i = 0; i < MAX_PP_MEMSPELL; i++)
for(i = 0; i < MAX_PP_REF_MEMSPELL; i++)
pp.mem_spells[i] = 0xFFFFFFFF;
for(i = 0; i < BUFF_COUNT; i++)
pp.buffs[i].spellid = 0xFFFF;
//was memset(pp.unknown3704, 0xffffffff, 8);
//but I dont think thats what you really wanted to do...
//memset is byte based
//If server is PVP by default, make all character set to it.
/* If server is PVP by default, make all character set to it. */
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
//If it is an SoF Client and the SoF Start Zone rule is set, send new chars there
if((ClientVersionBit & BIT_SoFAndLater) && (RuleI(World, SoFStartZoneID) > 0)) {
clog(WORLD__CLIENT,"Found 'SoFStartZoneID' rule setting: %i", (RuleI(World, SoFStartZoneID)));
pp.zone_id = (RuleI(World, SoFStartZoneID));
if(pp.zone_id)
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
if (ClientVersionBit & BIT_SoFAndLater && RuleI(World, SoFStartZoneID) > 0) {
clog(WORLD__CLIENT,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID));
pp.zone_id = RuleI(World, SoFStartZoneID);
if (pp.zone_id)
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
else
clog(WORLD__CLIENT_ERR,"Error getting zone id for Zone ID %i", (RuleI(World, SoFStartZoneID)));
}
else
{
// if there's a startzone variable put them in there
if(database.GetVariable("startzone", startzone, 50))
{
clog(WORLD__CLIENT_ERR,"Error getting zone id for Zone ID %i", RuleI(World, SoFStartZoneID));
} else {
/* if there's a startzone variable put them in there */
if (database.GetVariable("startzone", startzone, 50)) {
clog(WORLD__CLIENT,"Found 'startzone' variable setting: %s", startzone);
pp.zone_id = database.GetZoneID(startzone);
if(pp.zone_id)
if (pp.zone_id)
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
else
clog(WORLD__CLIENT_ERR,"Error getting zone id for '%s'", startzone);
}
else // otherwise use normal starting zone logic
{
} else { /* otherwise use normal starting zone logic */
bool ValidStartZone = false;
if(ClientVersionBit & BIT_TitaniumAndEarlier)
if (ClientVersionBit & BIT_TitaniumAndEarlier)
ValidStartZone = database.GetStartZone(&pp, cc);
else
ValidStartZone = database.GetStartZoneSoF(&pp, cc);
if(!ValidStartZone)
if (!ValidStartZone)
return false;
}
}
if(!pp.zone_id)
{
/* just in case */
if (!pp.zone_id) {
pp.zone_id = 1; // qeynos
pp.x = pp.y = pp.z = -1;
}
if(!pp.binds[0].zoneId)
{
pp.binds[0].zoneId = pp.zone_id;
pp.binds[0].x = pp.x;
pp.binds[0].y = pp.y;
pp.binds[0].z = pp.z;
pp.binds[0].heading = pp.heading;
/* Set Home Binds */
pp.binds[4].zoneId = pp.zone_id;
pp.binds[4].x = pp.x;
pp.binds[4].y = pp.y;
pp.binds[4].z = pp.z;
pp.binds[4].heading = pp.heading;
/* Overrides if we have the tutorial flag set! */
if (cc->tutorial && RuleB(World, EnableTutorialButton)) {
pp.zone_id = RuleI(World, TutorialZoneID);
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
}
// set starting city location to the initial bind point
pp.binds[4] = pp.binds[0];
/* Will either be the same as home or tutorial */
pp.binds[0].zoneId = pp.zone_id;
pp.binds[0].x = pp.x;
pp.binds[0].y = pp.y;
pp.binds[0].z = pp.z;
pp.binds[0].heading = pp.heading;
clog(WORLD__CLIENT,"Current location: %s (%d) %0.2f, %0.2f, %0.2f, %0.2f",
database.GetZoneName(pp.zone_id), pp.zone_id, pp.x, pp.y, pp.z, pp.heading);
clog(WORLD__CLIENT,"Bind location: %s (%d) %0.2f, %0.2f, %0.2f",
database.GetZoneName(pp.binds[0].zoneId), pp.binds[0].zoneId, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z);
clog(WORLD__CLIENT,"Home location: %s (%d) %0.2f, %0.2f, %0.2f",
database.GetZoneName(pp.binds[4].zoneId), pp.binds[4].zoneId, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z);
clog(WORLD__CLIENT,"Current location: %s %0.2f, %0.2f, %0.2f, %0.2f",
database.GetZoneName(pp.zone_id), pp.x, pp.y, pp.z, pp.heading);
clog(WORLD__CLIENT,"Bind location: %s %0.2f, %0.2f, %0.2f",
database.GetZoneName(pp.binds[0].zoneId), pp.binds[0].x, pp.binds[0].y, pp.binds[0].z);
// Starting Items inventory
/* Starting Items inventory */
database.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
// now we give the pp and the inv we made to StoreCharacter
// to see if we can store it
if (!database.StoreCharacter(GetAccountID(), &pp, &inv, &ext))
{
if (!database.StoreCharacter(GetAccountID(), &pp, &inv)) {
clog(WORLD__CLIENT_ERR,"Character creation failed: %s", pp.name);
return false;
}
else
{
clog(WORLD__CLIENT,"Character creation successful: %s", pp.name);
return true;
}
clog(WORLD__CLIENT,"Character creation successful: %s", pp.name);
return true;
}
// returns true if the request is ok, false if there's an error
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
{
if(!cc) return false;
if (!cc)
return false;
_log(WORLD__CLIENT, "Validating char creation info...");
RaceClassCombos class_combo;
bool found = false;
int combos = character_create_race_class_combos.size();
for(int i = 0; i < combos; ++i) {
if(character_create_race_class_combos[i].Class == cc->class_ &&
character_create_race_class_combos[i].Race == cc->race &&
character_create_race_class_combos[i].Deity == cc->deity) {
if(RuleB(World, EnableTutorialButton) &&
(RuleI(World, TutorialZoneID) == cc->start_zone ||
(character_create_race_class_combos[i].Zone == cc->start_zone))) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
} else if(character_create_race_class_combos[i].Zone == cc->start_zone) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
}
for (int i = 0; i < combos; ++i) {
if (character_create_race_class_combos[i].Class == cc->class_ &&
character_create_race_class_combos[i].Race == cc->race &&
character_create_race_class_combos[i].Deity == cc->deity &&
character_create_race_class_combos[i].Zone == cc->start_zone) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
}
}
if(!found) {
if (!found) {
_log(WORLD__CLIENT_ERR, "Could not find class/race/deity/start_zone combination");
return false;
}
@@ -1584,15 +1537,15 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
uint32 allocs = character_create_allocations.size();
RaceClassAllocation allocation = {0};
found = false;
for(int i = 0; i < combos; ++i) {
if(character_create_allocations[i].Index == class_combo.AllocationIndex) {
for (int i = 0; i < allocs; ++i) {
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
allocation = character_create_allocations[i];
found = true;
break;
}
}
if(!found) {
if (!found) {
_log(WORLD__CLIENT_ERR, "Could not find starting stats for selected character combo, cannot verify stats");
return false;
}
@@ -1605,37 +1558,37 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
allocation.DefaultPointAllocation[5] +
allocation.DefaultPointAllocation[6];
if(cc->STR > allocation.BaseStats[0] + max_stats || cc->STR < allocation.BaseStats[0]) {
if (cc->STR > allocation.BaseStats[0] + max_stats || cc->STR < allocation.BaseStats[0]) {
_log(WORLD__CLIENT_ERR, "Strength out of range");
return false;
}
if(cc->DEX > allocation.BaseStats[1] + max_stats || cc->DEX < allocation.BaseStats[1]) {
if (cc->DEX > allocation.BaseStats[1] + max_stats || cc->DEX < allocation.BaseStats[1]) {
_log(WORLD__CLIENT_ERR, "Dexterity out of range");
return false;
}
if(cc->AGI > allocation.BaseStats[2] + max_stats || cc->AGI < allocation.BaseStats[2]) {
if (cc->AGI > allocation.BaseStats[2] + max_stats || cc->AGI < allocation.BaseStats[2]) {
_log(WORLD__CLIENT_ERR, "Agility out of range");
return false;
}
if(cc->STA > allocation.BaseStats[3] + max_stats || cc->STA < allocation.BaseStats[3]) {
if (cc->STA > allocation.BaseStats[3] + max_stats || cc->STA < allocation.BaseStats[3]) {
_log(WORLD__CLIENT_ERR, "Stamina out of range");
return false;
}
if(cc->INT > allocation.BaseStats[4] + max_stats || cc->INT < allocation.BaseStats[4]) {
if (cc->INT > allocation.BaseStats[4] + max_stats || cc->INT < allocation.BaseStats[4]) {
_log(WORLD__CLIENT_ERR, "Intelligence out of range");
return false;
}
if(cc->WIS > allocation.BaseStats[5] + max_stats || cc->WIS < allocation.BaseStats[5]) {
if (cc->WIS > allocation.BaseStats[5] + max_stats || cc->WIS < allocation.BaseStats[5]) {
_log(WORLD__CLIENT_ERR, "Wisdom out of range");
return false;
}
if(cc->CHA > allocation.BaseStats[6] + max_stats || cc->CHA < allocation.BaseStats[6]) {
if (cc->CHA > allocation.BaseStats[6] + max_stats || cc->CHA < allocation.BaseStats[6]) {
_log(WORLD__CLIENT_ERR, "Charisma out of range");
return false;
}
@@ -1648,7 +1601,7 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
current_stats += cc->INT - allocation.BaseStats[4];
current_stats += cc->WIS - allocation.BaseStats[5];
current_stats += cc->CHA - allocation.BaseStats[6];
if(current_stats > max_stats) {
if (current_stats > max_stats) {
_log(WORLD__CLIENT_ERR, "Current Stats > Maximum Stats");
return false;
}
@@ -1727,7 +1680,8 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
{ /*Berserker*/ false, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false}
};//Initial table by kathgar, editted by Wiz for accuracy, solar too
if(!cc) return false;
if (!cc)
return false;
_log(WORLD__CLIENT,"Validating char creation info...");
@@ -1741,19 +1695,16 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
// if out of range looking it up in the table would crash stuff
// so we return from these
if(classtemp >= PLAYER_CLASS_COUNT)
{
if (classtemp >= PLAYER_CLASS_COUNT) {
_log(WORLD__CLIENT_ERR," class is out of range");
return false;
}
if(racetemp >= _TABLE_RACES)
{
if (racetemp >= _TABLE_RACES) {
_log(WORLD__CLIENT_ERR," race is out of range");
return false;
}
if(!ClassRaceLookupTable[classtemp][racetemp]) //Lookup table better than a bunch of ifs?
{
if (!ClassRaceLookupTable[classtemp][racetemp]) { //Lookup table better than a bunch of ifs?
_log(WORLD__CLIENT_ERR," invalid race/class combination");
// we return from this one, since if it's an invalid combination our table
// doesn't have meaningful values for the stats
@@ -1781,44 +1732,36 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
// NOTE: these could just be else if, but i want to see all the stats
// that are messed up not just the first hit
if(bTOTAL + stat_points != cTOTAL)
{
if (bTOTAL + stat_points != cTOTAL) {
_log(WORLD__CLIENT_ERR," stat points total doesn't match expected value: expecting %d got %d", bTOTAL + stat_points, cTOTAL);
Charerrors++;
}
if(cc->STR > bSTR + stat_points || cc->STR < bSTR)
{
if (cc->STR > bSTR + stat_points || cc->STR < bSTR) {
_log(WORLD__CLIENT_ERR," stat STR is out of range");
Charerrors++;
}
if(cc->STA > bSTA + stat_points || cc->STA < bSTA)
{
if (cc->STA > bSTA + stat_points || cc->STA < bSTA) {
_log(WORLD__CLIENT_ERR," stat STA is out of range");
Charerrors++;
}
if(cc->AGI > bAGI + stat_points || cc->AGI < bAGI)
{
if (cc->AGI > bAGI + stat_points || cc->AGI < bAGI) {
_log(WORLD__CLIENT_ERR," stat AGI is out of range");
Charerrors++;
}
if(cc->DEX > bDEX + stat_points || cc->DEX < bDEX)
{
if (cc->DEX > bDEX + stat_points || cc->DEX < bDEX) {
_log(WORLD__CLIENT_ERR," stat DEX is out of range");
Charerrors++;
}
if(cc->WIS > bWIS + stat_points || cc->WIS < bWIS)
{
if (cc->WIS > bWIS + stat_points || cc->WIS < bWIS) {
_log(WORLD__CLIENT_ERR," stat WIS is out of range");
Charerrors++;
}
if(cc->INT > bINT + stat_points || cc->INT < bINT)
{
if (cc->INT > bINT + stat_points || cc->INT < bINT) {
_log(WORLD__CLIENT_ERR," stat INT is out of range");
Charerrors++;
}
if(cc->CHA > bCHA + stat_points || cc->CHA < bCHA)
{
if (cc->CHA > bCHA + stat_points || cc->CHA < bCHA) {
_log(WORLD__CLIENT_ERR," stat CHA is out of range");
Charerrors++;
}
@@ -1831,28 +1774,15 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
return Charerrors == 0;
}
void Client::SetClassStartingSkills( PlayerProfile_Struct *pp )
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
for(uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
if(pp->skills[i] == 0) {
if(i >= SkillSpecializeAbjure && i <= SkillSpecializeEvocation) {
for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
if (pp->skills[i] == 0) {
// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
i == SkillAlcoholTolerance || i == SkillBindWound)
continue;
}
if(i == SkillMakePoison ||
i == SkillTinkering ||
i == SkillResearch ||
i == SkillAlchemy ||
i == SkillBaking ||
i == SkillTailoring ||
i == SkillBlacksmithing ||
i == SkillFletching ||
i == SkillBrewing ||
i == SkillPottery ||
i == SkillJewelryMaking ||
i == SkillBegging) {
continue;
}
pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
}
@@ -2034,3 +1964,15 @@ void Client::SetRacialLanguages( PlayerProfile_Struct *pp )
}
}
void Client::SetClassLanguages(PlayerProfile_Struct *pp)
{
// we only need to handle one class, but custom server might want to do more
switch(pp->class_) {
case ROGUE:
pp->languages[LANG_THIEVES_CANT] = 100;
break;
default:
break;
}
}
+2 -1
View File
@@ -20,7 +20,7 @@
#include <string>
//#include "../common/EQStream.h"
//#include "../common/eq_stream.h"
#include "../common/linked_list.h"
#include "../common/timer.h"
//#include "zoneserver.h"
@@ -90,6 +90,7 @@ private:
void SetClassStartingSkills( PlayerProfile_Struct *pp );
void SetRaceStartingSkills( PlayerProfile_Struct *pp );
void SetRacialLanguages( PlayerProfile_Struct *pp );
void SetClassLanguages(PlayerProfile_Struct *pp);
ClientListEntry* cle;
Timer CLE_keepalive_timer;
+24 -4
View File
@@ -18,13 +18,13 @@
#include "../common/debug.h"
#include "cliententry.h"
#include "clientlist.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "login_server.h"
#include "login_server_list.h"
#include "worlddb.h"
#include "zoneserver.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "../common/guilds.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
extern uint32 numplayers;
extern LoginServerList loginserverlist;
@@ -93,6 +93,7 @@ ClientListEntry::~ClientListEntry() {
Camp(); // updates zoneserver's numplayers
client_list.RemoveCLEReferances(this);
}
tell_queue.clear();
}
void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) {
@@ -233,6 +234,7 @@ void ClientListEntry::ClearVars(bool iAll) {
pLFG = 0;
gm = 0;
pClientVersion = 0;
tell_queue.clear();
}
void ClientListEntry::Camp(ZoneServer* iZS) {
@@ -295,3 +297,21 @@ bool ClientListEntry::CheckAuth(uint32 id, const char* iKey, uint32 ip) {
return false;
}
void ClientListEntry::ProcessTellQueue()
{
if (!Server())
return;
ServerPacket *pack;
auto it = tell_queue.begin();
while (it != tell_queue.end()) {
pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen((*it)->message) + 1);
memcpy(pack->pBuffer, *it, pack->size);
pack->Deflate();
Server()->SendPacket(pack);
safe_delete(pack);
it = tell_queue.erase(it);
}
return;
}
+10
View File
@@ -5,6 +5,8 @@
#include "../common/md5.h"
//#include "../common/eq_packet_structs.h"
#include "../common/servertalk.h"
#include "../common/rulesys.h"
#include <vector>
#define CLE_Status_Never -1
@@ -80,6 +82,11 @@ public:
inline const char* GetLFGComments() const { return pLFGComments; }
inline uint8 GetClientVersion() { return pClientVersion; }
inline bool TellQueueFull() const { return tell_queue.size() >= RuleI(World, TellQueueSize); }
inline bool TellQueueEmpty() const { return tell_queue.empty(); }
inline void PushToTellQueue(ServerChannelMessage_Struct *scm) { tell_queue.push_back(scm); }
void ProcessTellQueue();
private:
void ClearVars(bool iAll = false);
@@ -120,6 +127,9 @@ private:
uint8 pLFGToLevel;
bool pLFGMatchFilter;
char pLFGComments[64];
// Tell Queue -- really a vector :D
std::vector<ServerChannelMessage_Struct *> tell_queue;
};
#endif /*CLIENTENTRY_H_*/
+1 -1
View File
@@ -22,7 +22,7 @@
#include "client.h"
#include "console.h"
#include "worlddb.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
#include "../common/guilds.h"
#include "../common/races.h"
#include "../common/classes.h"
+10 -7
View File
@@ -30,20 +30,20 @@
#include "../common/packet_dump.h"
#include "../common/seperator.h"
#include "../common/eq_packet_structs.h"
#include "../common/EQPacket.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "../common/eq_packet.h"
#include "login_server.h"
#include "login_server_list.h"
#include "../common/serverinfo.h"
#include "../common/md5.h"
#include "../common/opcodemgr.h"
#include "../common/rulesys.h"
#include "../common/ruletypes.h"
#include "../common/StringUtil.h"
#include "WorldConfig.h"
#include "../common/string_util.h"
#include "world_config.h"
#include "zoneserver.h"
#include "zonelist.h"
#include "clientlist.h"
#include "LauncherList.h"
#include "launcher_list.h"
#include "ucs.h"
#include "queryserv.h"
#include "web_interface.h"
@@ -115,7 +115,7 @@ bool Console::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
break;
}
case 7: {
SendMessage(1, "%s tells you, '%s'", scm->from, scm->message);
SendMessage(1, "[%s] tells you, '%s'", scm->from, scm->message);
ServerPacket* pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
memcpy(pack->pBuffer, scm, pack->size);
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*) pack->pBuffer;
@@ -855,6 +855,9 @@ void Console::ProcessCommand(const char* command) {
zoneserver_list.SendPacket(pack);
safe_delete(pack);
}
else if (strcasecmp(sep.arg[0], "") == 0){
/* Hit Enter with no command */
}
else {
SendMessage(1, "Command unknown.");
}
+3 -3
View File
@@ -38,9 +38,9 @@ enum {
#include "../common/linked_list.h"
#include "../common/timer.h"
#include "../common/queue.h"
#include "../common/EmuTCPConnection.h"
#include "WorldTCPConnection.h"
#include "../common/Mutex.h"
#include "../common/emu_tcp_connection.h"
#include "world_tcp_connection.h"
#include "../common/mutex.h"
struct ServerChannelMessage_Struct;
+66 -108
View File
@@ -16,11 +16,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "EQLConfig.h"
#include "eql_config.h"
#include "worlddb.h"
#include "LauncherLink.h"
#include "LauncherList.h"
#include "../common/StringUtil.h"
#include "launcher_link.h"
#include "launcher_list.h"
#include "../common/string_util.h"
#include <cstdlib>
#include <cstring>
@@ -33,66 +33,51 @@ EQLConfig::EQLConfig(const char *launcher_name)
}
void EQLConfig::LoadSettings() {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
LauncherZone tmp;
LauncherZone tmp;
char namebuf[128];
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
namebuf[127] = '\0';
if (database.RunQuery(query, MakeAnyLenString(&query,
"SELECT dynamics FROM launcher WHERE name='%s'",
namebuf)
, errbuf, &result))
{
while ((row = mysql_fetch_row(result))) {
m_dynamics = atoi(row[0]);
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", errbuf);
}
safe_delete_array(query);
std::string query = StringFormat("SELECT dynamics FROM launcher WHERE name = '%s'", namebuf);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", results.ErrorMessage().c_str());
else {
auto row = results.begin();
m_dynamics = atoi(row[0]);
}
query = StringFormat("SELECT zone, port FROM launcher_zones WHERE launcher = '%s'", namebuf);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", results.ErrorMessage().c_str());
return;
}
LauncherZone zs;
for (auto row = results.begin(); row != results.end(); ++row) {
zs.name = row[0];
zs.port = atoi(row[1]);
m_zones[zs.name] = zs;
}
if (database.RunQuery(query, MakeAnyLenString(&query,
"SELECT zone,port FROM launcher_zones WHERE launcher='%s'",
namebuf)
, errbuf, &result))
{
LauncherZone zs;
while ((row = mysql_fetch_row(result))) {
zs.name = row[0];
zs.port = atoi(row[1]);
m_zones[zs.name] = zs;
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "EQLConfig::LoadSettings: %s", errbuf);
}
safe_delete_array(query);
}
EQLConfig *EQLConfig::CreateLauncher(const char *name, uint8 dynamic_count) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char namebuf[128];
database.DoEscapeString(namebuf, name, strlen(name)&0x3F); //limit len to 64
namebuf[127] = '\0';
if (!database.RunQuery(query, MakeAnyLenString(&query,
"INSERT INTO launcher (name,dynamics) VALUES('%s', %d)",
namebuf, dynamic_count), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in CreateLauncher query: %s", errbuf);
safe_delete_array(query);
std::string query = StringFormat("INSERT INTO launcher (name, dynamics) VALUES('%s', %d)", namebuf, dynamic_count);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in CreateLauncher query: %s", results.ErrorMessage().c_str());
return nullptr;
}
safe_delete_array(query);
return(new EQLConfig(name));
return new EQLConfig(name);
}
void EQLConfig::GetZones(std::vector<LauncherZone> &result) {
@@ -126,30 +111,23 @@ void EQLConfig::DeleteLauncher() {
launcher_list.Remove(m_name.c_str());
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char namebuf[128];
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
namebuf[127] = '\0';
if (!database.RunQuery(query, MakeAnyLenString(&query,
"DELETE FROM launcher WHERE name='%s'",
namebuf), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 1 query: %s", errbuf);
safe_delete_array(query);
std::string query = StringFormat("DELETE FROM launcher WHERE name = '%s'", namebuf);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 1st query: %s", results.ErrorMessage().c_str());
return;
}
safe_delete_array(query);
if (!database.RunQuery(query, MakeAnyLenString(&query,
"DELETE FROM launcher_zones WHERE launcher='%s'",
namebuf), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 2 query: %s", errbuf);
safe_delete_array(query);
query = StringFormat("DELETE FROM launcher_zones WHERE launcher = '%s'", namebuf);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in DeleteLauncher 2nd query: %s", results.ErrorMessage().c_str());
return;
}
safe_delete_array(query);
}
bool EQLConfig::IsConnected() const {
@@ -181,12 +159,9 @@ void EQLConfig::StartZone(Const_char *zone_ref) {
bool EQLConfig::BootStaticZone(Const_char *short_name, uint16 port) {
//make sure the short name is valid.
if(database.GetZoneID(short_name) == 0)
return(false);
return false;
//database update
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char namebuf[128];
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
namebuf[127] = '\0';
@@ -194,14 +169,13 @@ bool EQLConfig::BootStaticZone(Const_char *short_name, uint16 port) {
database.DoEscapeString(zonebuf, short_name, strlen(short_name)&0xF); //limit len to 16
zonebuf[31] = '\0';
if (!database.RunQuery(query, MakeAnyLenString(&query,
"INSERT INTO launcher_zones (launcher,zone,port) VALUES('%s', '%s', %d)",
namebuf, zonebuf, port), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in BootStaticZone query: %s", errbuf);
safe_delete_array(query);
std::string query = StringFormat("INSERT INTO launcher_zones (launcher, zone, port) "
"VALUES('%s', '%s', %d)", namebuf, zonebuf, port);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in BootStaticZone query: %s", results.ErrorMessage().c_str());
return false;
}
safe_delete_array(query);
//update our internal state.
LauncherZone lz;
@@ -215,13 +189,13 @@ bool EQLConfig::BootStaticZone(Const_char *short_name, uint16 port) {
ll->BootZone(short_name, port);
}
return(true);
return true;
}
bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
//make sure the short name is valid.
if(database.GetZoneID(short_name) == 0)
return(false);
return false;
//check internal state
std::map<std::string, LauncherZone>::iterator res;
@@ -229,14 +203,9 @@ bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
if(res == m_zones.end()) {
//not found.
LogFile->write(EQEMuLog::Error, "Update for unknown zone %s", short_name);
return(false);
return false;
}
//database update
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char namebuf[128];
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
namebuf[127] = '\0';
@@ -244,15 +213,13 @@ bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
database.DoEscapeString(zonebuf, short_name, strlen(short_name)&0xF); //limit len to 16
zonebuf[31] = '\0';
if (!database.RunQuery(query, MakeAnyLenString(&query,
"UPDATE launcher_zones SET port=%d WHERE launcher='%s' AND zone='%s'",
port, namebuf, zonebuf), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in ChangeStaticZone query: %s", errbuf);
safe_delete_array(query);
std::string query = StringFormat("UPDATE launcher_zones SET port=%d WHERE "
"launcher = '%s' AND zone = '%s'",port, namebuf, zonebuf);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ChangeStaticZone query: %s", results.ErrorMessage().c_str());
return false;
}
safe_delete_array(query);
//update internal state
res->second.port = port;
@@ -263,7 +230,7 @@ bool EQLConfig::ChangeStaticZone(Const_char *short_name, uint16 port) {
ll->RestartZone(short_name);
}
return(true);
return true;
}
bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
@@ -273,13 +240,9 @@ bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
if(res == m_zones.end()) {
//not found.
LogFile->write(EQEMuLog::Error, "Update for unknown zone %s", short_name);
return(false);
return false;
}
//database update
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char namebuf[128];
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
namebuf[127] = '\0';
@@ -287,14 +250,13 @@ bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
database.DoEscapeString(zonebuf, short_name, strlen(short_name)&0xF); //limit len to 16
zonebuf[31] = '\0';
if (!database.RunQuery(query, MakeAnyLenString(&query,
"DELETE FROM launcher_zones WHERE launcher='%s' AND zone='%s'",
namebuf, zonebuf), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in DeleteStaticZone query: %s", errbuf);
safe_delete_array(query);
std::string query = StringFormat("DELETE FROM launcher_zones WHERE "
"launcher = '%s' AND zone = '%s'", namebuf, zonebuf);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in DeleteStaticZone query: %s", results.ErrorMessage().c_str());
return false;
}
safe_delete_array(query);
//internal update.
m_zones.erase(res);
@@ -309,21 +271,17 @@ bool EQLConfig::DeleteStaticZone(Const_char *short_name) {
}
bool EQLConfig::SetDynamicCount(int count) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char namebuf[128];
database.DoEscapeString(namebuf, m_name.c_str(), m_name.length()&0x3F); //limit len to 64
namebuf[127] = '\0';
if (!database.RunQuery(query, MakeAnyLenString(&query,
"UPDATE launcher SET dynamics=%d WHERE name='%s'",
count, namebuf), errbuf)) {
LogFile->write(EQEMuLog::Error, "Error in SetDynamicCount query: %s", errbuf);
safe_delete_array(query);
std::string query = StringFormat("UPDATE launcher SET dynamics=%d WHERE name='%s'", count, namebuf);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in SetDynamicCount query: %s", results.ErrorMessage().c_str());
return false;
}
safe_delete_array(query);
//update in-memory version.
m_dynamics = count;
@@ -334,7 +292,7 @@ bool EQLConfig::SetDynamicCount(int count) {
ll->BootDynamics(count);
}
return(false);
return false;
}
int EQLConfig::GetDynamicCount() const {
+45 -60
View File
@@ -19,23 +19,23 @@
#ifdef EMBPERL
#include "../common/debug.h"
#include "EQW.h"
#include "EQWParser.h"
#include "WorldConfig.h"
#include "eqw.h"
#include "eqw_parser.h"
#include "world_config.h"
#include "../common/races.h"
#include "../common/classes.h"
#include "../common/misc.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
#include "zoneserver.h"
#include "zonelist.h"
#include "clientlist.h"
#include "cliententry.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "login_server.h"
#include "login_server_list.h"
#include "worlddb.h"
#include "client.h"
#include "LauncherList.h"
#include "LauncherLink.h"
#include "launcher_list.h"
#include "launcher_link.h"
#include "wguild_mgr.h"
#ifdef seed
@@ -384,72 +384,57 @@ bool EQW::SetPublicNote(uint32 charid, const char *note) {
}
int EQW::CountBugs() {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query, MakeAnyLenString(&query, "SELECT count(*) FROM bugs where status = 0"), errbuf, &result)) {
safe_delete_array(query);
if((row = mysql_fetch_row(result))) {
int count = atoi(row[0]);
mysql_free_result(result);
return count;
}
mysql_free_result(result);
}
safe_delete_array(query);
return 0;
std::string query = "SELECT count(*) FROM bugs where status = 0";
auto results = database.QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
std::vector<std::string> EQW::ListBugs(uint32 offset) {
std::vector<std::string> res;
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM bugs WHERE status = 0 limit %d, 30", offset), errbuf, &result)) {
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
res.push_back(row[0]);
}
mysql_free_result(result);
}
safe_delete_array(query);
std::string query = StringFormat("SELECT id FROM bugs WHERE status = 0 limit %d, 30", offset);
auto results = database.QueryDatabase(query);
if (!results.Success())
return res;
for (auto row = results.begin();row != results.end(); ++row)
res.push_back(row[0]);
return res;
}
std::map<std::string,std::string> EQW::GetBugDetails(Const_char *id) {
std::map<std::string,std::string> res;
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query, MakeAnyLenString(&query, "select name, zone, x, y, z, target, bug from bugs where id = %s", id), errbuf, &result)) {
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
res["name"] = row[0];
res["zone"] = row[1];
res["x"] = row[2];
res["y"] = row[3];
res["z"] = row[4];
res["target"] = row[5];
res["bug"] = row[6];
res["id"] = id;
}
mysql_free_result(result);
}
safe_delete_array(query);
std::string query = StringFormat("SELECT name, zone, x, y, z, target, bug FROM bugs WHERE id = %s", id);
auto results = database.QueryDatabase(query);
if (!results.Success())
return res;
for(auto row = results.begin(); row != results.end(); ++row) {
res["name"] = row[0];
res["zone"] = row[1];
res["x"] = row[2];
res["y"] = row[3];
res["z"] = row[4];
res["target"] = row[5];
res["bug"] = row[6];
res["id"] = id;
}
return res;
}
void EQW::ResolveBug(const char *id) {
std::vector<std::string> res;
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
if(database.RunQuery(query, MakeAnyLenString(&query, "UPDATE bugs SET status=1 WHERE id=%s", id), errbuf)) {
safe_delete_array(query);
}
safe_delete_array(query);
std::string query = StringFormat("UPDATE bugs SET status=1 WHERE id=%s", id);
database.QueryDatabase(query);
}
void EQW::SendMessage(uint32 type, const char *msg) {
View File
@@ -16,11 +16,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "EQWHTTPHandler.h"
#include "eqw_http_handler.h"
#include "../common/SocketLib/Base64.h"
#include "EQWParser.h"
#include "EQW.h"
#include "HTTPRequest.h"
#include "eqw_parser.h"
#include "eqw.h"
#include "http_request.h"
#include "../common/logsys.h"
#include "worlddb.h"
#include "console.h"
@@ -18,8 +18,8 @@
#ifndef EQWHTTPHandler_H
#define EQWHTTPHandler_H
#include "../common/TCPServer.h"
#include "../common/TCPConnection.h"
#include "../common/tcp_server.h"
#include "../common/tcp_connection.h"
#include "../common/SocketLib/HttpdSocket.h"
#include "../common/SocketLib/Mime.h"
#include "../common/types.h"
+3 -3
View File
@@ -21,9 +21,9 @@
#ifdef EMBPERL
#include "../common/debug.h"
#include "EQWParser.h"
#include "EQW.h"
#include "../common/EQDB.h"
#include "eqw_parser.h"
#include "eqw.h"
#include "../common/eqdb.h"
#include "../common/logsys.h"
#include "worlddb.h"
@@ -16,9 +16,9 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "HTTPRequest.h"
#include "EQWHTTPHandler.h"
#include "../common/EQDB.h"
#include "http_request.h"
#include "eqw_http_handler.h"
#include "../common/eqdb.h"
#include "../common/SocketLib/HttpdForm.h"
#include <cstdlib>
@@ -17,17 +17,17 @@
*/
#include "../common/debug.h"
#include "LauncherLink.h"
#include "LauncherList.h"
#include "WorldConfig.h"
#include "launcher_link.h"
#include "launcher_list.h"
#include "world_config.h"
#include "../common/logsys.h"
#include "../common/md5.h"
#include "../common/packet_dump.h"
#include "../common/servertalk.h"
#include "../common/EmuTCPConnection.h"
#include "../common/StringUtil.h"
#include "../common/emu_tcp_connection.h"
#include "../common/string_util.h"
#include "worlddb.h"
#include "EQLConfig.h"
#include "eql_config.h"
#include <vector>
#include <string>
@@ -18,7 +18,7 @@
#ifndef LAUNCHERLINK_H_
#define LAUNCHERLINK_H_
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/timer.h"
#include <string>
#include <vector>
@@ -18,10 +18,10 @@
#include "../common/debug.h"
#include "LauncherList.h"
#include "LauncherLink.h"
#include "launcher_list.h"
#include "launcher_link.h"
#include "../common/logsys.h"
#include "EQLConfig.h"
#include "eql_config.h"
LauncherList::LauncherList()
: nextID(1)
+1 -1
View File
@@ -22,7 +22,7 @@
#include "zoneserver.h"
#include "zonelist.h"
#include "../common/logsys.h"
#include "../common/MiscFunctions.h"
#include "../common/misc_functions.h"
extern ClientList client_list;
extern ZSList zoneserver_list;
@@ -52,16 +52,16 @@
#define IGNORE_LS_FATAL_ERROR
#include "../common/servertalk.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "login_server.h"
#include "login_server_list.h"
#include "../common/eq_packet_structs.h"
#include "../common/packet_dump.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
#include "zoneserver.h"
#include "worlddb.h"
#include "zonelist.h"
#include "clientlist.h"
#include "WorldConfig.h"
#include "world_config.h"
extern ZSList zoneserver_list;
extern ClientList client_list;
+2 -2
View File
@@ -23,8 +23,8 @@
#include "../common/timer.h"
#include "../common/queue.h"
#include "../common/eq_packet_structs.h"
#include "../common/Mutex.h"
#include "../common/EmuTCPConnection.h"
#include "../common/mutex.h"
#include "../common/emu_tcp_connection.h"
class LoginServer{
public:
@@ -26,15 +26,15 @@
#define IGNORE_LS_FATAL_ERROR
#include "../common/servertalk.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "login_server.h"
#include "login_server_list.h"
#include "../common/eq_packet_structs.h"
#include "../common/packet_dump.h"
#include "zoneserver.h"
#include "worlddb.h"
#include "zonelist.h"
#include "clientlist.h"
#include "WorldConfig.h"
#include "world_config.h"
extern ZSList zoneserver_list;
extern LoginServerList loginserverlist;
@@ -6,8 +6,8 @@
#include "../common/timer.h"
#include "../common/queue.h"
#include "../common/eq_packet_structs.h"
#include "../common/Mutex.h"
#include "../common/EmuTCPConnection.h"
#include "../common/mutex.h"
#include "../common/emu_tcp_connection.h"
#ifdef _WINDOWS
void AutoInitLoginServer(void *tmp);
+31 -25
View File
@@ -27,22 +27,21 @@
#include "../common/debug.h"
#include "../common/queue.h"
#include "../common/timer.h"
#include "../common/EQStreamFactory.h"
#include "../common/EQPacket.h"
#include "client.h"
#include "worlddb.h"
#include "../common/eq_stream_factory.h"
#include "../common/eq_packet.h"
#include "../common/seperator.h"
#include "../common/version.h"
#include "../common/eqtime.h"
#include "../common/timeoutmgr.h"
#include "../common/EQEMuError.h"
#include "../common/eqemu_error.h"
#include "../common/opcodemgr.h"
#include "../common/guilds.h"
#include "../common/EQStreamIdent.h"
//#include "../common/patches/Client62.h"
#include "../common/eq_stream_ident.h"
#include "../common/rulesys.h"
#include "../common/platform.h"
#include "../common/crash.h"
#include "client.h"
#include "worlddb.h"
#ifdef _WINDOWS
#include <process.h>
#define snprintf _snprintf
@@ -68,22 +67,21 @@
#endif
#include "../common/emu_tcp_server.h"
#include "../common/patches/patches.h"
#include "zoneserver.h"
#include "console.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "EQWHTTPHandler.h"
#include "../common/dbasync.h"
#include "../common/EmuTCPServer.h"
#include "WorldConfig.h"
#include "../common/patches/patches.h"
#include "login_server.h"
#include "login_server_list.h"
#include "eqw_http_handler.h"
#include "world_config.h"
#include "zoneserver.h"
#include "zonelist.h"
#include "clientlist.h"
#include "LauncherList.h"
#include "launcher_list.h"
#include "wguild_mgr.h"
#include "lfplist.h"
#include "AdventureManager.h"
#include "adventure_manager.h"
#include "ucs.h"
#include "queryserv.h"
#include "web_interface.h"
@@ -102,7 +100,6 @@ QueryServConnection QSLink;
WebInterfaceConnection WILink;
LauncherList launcher_list;
AdventureManager adventure_manager;
DBAsync *dbasync = nullptr;
volatile bool RunLoops = true;
uint32 numclients = 0;
uint32 numzones = 0;
@@ -117,6 +114,15 @@ int main(int argc, char** argv) {
set_exception_handler();
register_remote_call_handlers();
/* Database Version Check */
uint32 Database_Version = CURRENT_BINARY_DATABASE_VERSION;
if (argc >= 2) {
if (strcasecmp(argv[1], "db_version") == 0) {
std::cout << "Binary Database Version: " << Database_Version << std::endl;
return 0;
}
}
// Load server configuration
_log(WORLD__INIT, "Loading server configuration..");
if (!WorldConfig::LoadConfig()) {
@@ -179,7 +185,6 @@ int main(int argc, char** argv) {
_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
return 1;
}
dbasync = new DBAsync(&database);
guild_mgr.SetDatabase(&database);
if (argc >= 2) {
@@ -226,9 +231,8 @@ int main(int argc, char** argv) {
else if (strcasecmp(argv[1], "flag") == 0) {
if (argc == 4) {
if (Seperator::IsNumber(argv[3])) {
if (atoi(argv[3]) >= 0 && atoi(argv[3]) <= 255) {
if (database.SetAccountStatus(argv[2], atoi(argv[3]))) {
if (database.SetAccountStatus(argv[2], atoi(argv[3]))){
std::cout << "Account flagged: Username='" << argv[2] << "', status=" << argv[3] << std::endl;
return 0;
}
@@ -280,6 +284,8 @@ int main(int argc, char** argv) {
_log(WORLD__INIT, "HTTP world service disabled.");
}
_log(WORLD__INIT, "Checking Database Conversions..");
database.CheckDatabaseConversions();
_log(WORLD__INIT, "Loading variables..");
database.LoadVariables();
_log(WORLD__INIT, "Loading zones..");
@@ -289,10 +295,13 @@ int main(int argc, char** argv) {
_log(WORLD__INIT, "Clearing raids..");
database.ClearRaid();
database.ClearRaidDetails();
database.ClearRaidLeader();
_log(WORLD__INIT, "Loading items..");
if (!database.LoadItems()) {
if (!database.LoadItems())
_log(WORLD__INIT_ERR, "Error: Could not load item data. But ignoring");
}
_log(WORLD__INIT, "Loading skill caps..");
if (!database.LoadSkillCaps())
_log(WORLD__INIT_ERR, "Error: Could not load skill cap data. But ignoring");
_log(WORLD__INIT, "Loading guilds..");
guild_mgr.LoadGuilds();
//rules:
@@ -330,9 +339,6 @@ int main(int argc, char** argv) {
_log(WORLD__INIT, "Reboot zone modes %s",holdzones ? "ON" : "OFF");
_log(WORLD__INIT, "Deleted %i stale player corpses from database", database.DeleteStalePlayerCorpses());
if (RuleB(World, DeleteStaleCorpeBackups) == true) {
_log(WORLD__INIT, "Deleted %i stale player backups from database", database.DeleteStalePlayerBackups());
}
_log(WORLD__INIT, "Loading adventures...");
if(!adventure_manager.LoadAdventureTemplates())
@@ -29,8 +29,8 @@ typedef const char Const_char;
#ifdef EMBPERL
#include "../common/debug.h"
#include "EQWParser.h"
#include "EQLConfig.h"
#include "eqw_parser.h"
#include "eql_config.h"
#ifdef seed
#undef seed
+2 -2
View File
@@ -29,8 +29,8 @@ typedef const char Const_char;
#ifdef EMBPERL
#include "../common/debug.h"
#include "EQWParser.h"
#include "EQW.h"
#include "eqw_parser.h"
#include "eqw.h"
#ifdef seed
#undef seed
@@ -29,8 +29,8 @@ typedef const char Const_char;
#ifdef EMBPERL
#include "../common/debug.h"
#include "EQWParser.h"
#include "HTTPRequest.h"
#include "eqw_parser.h"
#include "http_request.h"
#ifdef seed
#undef seed
+2 -2
View File
@@ -1,12 +1,12 @@
#include "../common/debug.h"
#include "queryserv.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "clientlist.h"
#include "zonelist.h"
#include "../common/logsys.h"
#include "../common/logtypes.h"
#include "../common/md5.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/packet_dump.h"
extern ClientList client_list;
+1 -1
View File
@@ -2,7 +2,7 @@
#define QueryServ_H
#include "../common/types.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/servertalk.h"
class QueryServConnection
+2 -2
View File
@@ -4,9 +4,9 @@
#include "../common/logsys.h"
#include "../common/logtypes.h"
#include "../common/md5.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/packet_dump.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "clientlist.h"
#include "zonelist.h"
#include "web_interface.h"
+2 -2
View File
@@ -1,10 +1,10 @@
#include "../common/debug.h"
#include "ucs.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "../common/logsys.h"
#include "../common/logtypes.h"
#include "../common/md5.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/packet_dump.h"
UCSConnection::UCSConnection()
+1 -1
View File
@@ -2,7 +2,7 @@
#define UCS_H
#include "../common/types.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/servertalk.h"
class UCSConnection
+2 -2
View File
@@ -1,6 +1,6 @@
#include "../common/debug.h"
#include "web_interface.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "clientlist.h"
#include "zonelist.h"
#include "zoneserver.h"
@@ -8,7 +8,7 @@
#include "../common/logsys.h"
#include "../common/logtypes.h"
#include "../common/md5.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/packet_dump.h"
extern ClientList client_list;
+1 -1
View File
@@ -2,7 +2,7 @@
#define WORLD_WEB_INTERFACE_H
#include "../common/types.h"
#include "../common/EmuTCPConnection.h"
#include "../common/emu_tcp_connection.h"
#include "../common/servertalk.h"
class WebInterfaceConnection
@@ -16,7 +16,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "WorldConfig.h"
#include "world_config.h"
WorldConfig *WorldConfig::_world_config = nullptr;
+1 -1
View File
@@ -18,7 +18,7 @@
#ifndef __WorldConfig_H
#define __WorldConfig_H
#include "../common/EQEmuConfig.h"
#include "../common/eqemu_config.h"
class WorldConfig : public EQEmuConfig {
public:
+1 -1
View File
@@ -1,7 +1,7 @@
#include "../common/debug.h"
#include "../common/logsys.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
#include "zoneserver.h"
#include "client.h"
+322 -403
View File
@@ -17,16 +17,15 @@
*/
#include "worlddb.h"
//#include "../common/Item.h"
#include "../common/StringUtil.h"
//#include "../common/item.h"
#include "../common/string_util.h"
#include "../common/eq_packet_structs.h"
#include "../common/Item.h"
#include "../common/dbasync.h"
#include "../common/item.h"
#include "../common/rulesys.h"
#include <iostream>
#include <cstdlib>
#include <vector>
#include "SoFCharCreateData.h"
#include "sof_char_create_data.h"
WorldDatabase database;
extern std::vector<RaceClassAllocation> character_create_allocations;
@@ -34,295 +33,255 @@ extern std::vector<RaceClassCombos> character_create_race_class_combos;
// solar: the current stuff is at the bottom of this function
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) {
Inventory *inv;
uint8 has_home = 0;
uint8 has_bind = 0;
/* Initialize Variables */
for (int i=0; i<10; i++) {
strcpy(cs->name[i], "<none>");
cs->zone[i] = 0;
cs->level[i] = 0;
cs->tutorial[i] = 0;
cs->tutorial[i] = 0;
cs->gohome[i] = 0;
}
int char_num = 0;
unsigned long* lengths;
/* Get Character Info */
std::string cquery = StringFormat(
"SELECT "
"`id`, " // 0
"name, " // 1
"gender, " // 2
"race, " // 3
"class, " // 4
"`level`, " // 5
"deity, " // 6
"last_login, " // 7
"time_played, " // 8
"hair_color, " // 9
"beard_color, " // 10
"eye_color_1, " // 11
"eye_color_2, " // 12
"hair_style, " // 13
"beard, " // 14
"face, " // 15
"drakkin_heritage, " // 16
"drakkin_tattoo, " // 17
"drakkin_details, " // 18
"zone_id " // 19
"FROM "
"character_data "
"WHERE `account_id` = %i ORDER BY `name` LIMIT 10 ", account_id);
auto results = database.QueryDatabase(cquery); int char_num = 0;
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerProfile_Struct pp;
memset(&pp, 0, sizeof(PlayerProfile_Struct));
// Populate character info
if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) {
safe_delete_array(query);
while ((row = mysql_fetch_row(result))) {
lengths = mysql_fetch_lengths(result);
////////////
//////////// This is the current one, the other are for converting
////////////
if ((lengths[1] == sizeof(PlayerProfile_Struct))) {
strcpy(cs->name[char_num], row[0]);
PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1];
uint8 clas = atoi(row[3]);
uint8 lvl = atoi(row[4]);
uint32 character_id = atoi(row[0]);
strcpy(cs->name[char_num], row[1]);
uint8 lvl = atoi(row[5]);
cs->level[char_num] = lvl;
cs->class_[char_num] = atoi(row[4]);
cs->race[char_num] = atoi(row[3]);
cs->gender[char_num] = atoi(row[2]);
cs->deity[char_num] = atoi(row[6]);
cs->zone[char_num] = atoi(row[19]);
cs->face[char_num] = atoi(row[15]);
cs->haircolor[char_num] = atoi(row[9]);
cs->beardcolor[char_num] = atoi(row[10]);
cs->eyecolor2[char_num] = atoi(row[12]);
cs->eyecolor1[char_num] = atoi(row[11]);
cs->hairstyle[char_num] = atoi(row[13]);
cs->beard[char_num] = atoi(row[14]);
cs->drakkin_heritage[char_num] = atoi(row[16]);
cs->drakkin_tattoo[char_num] = atoi(row[17]);
cs->drakkin_details[char_num] = atoi(row[18]);
// Character information
if(lvl == 0)
cs->level[char_num] = pp->level; //no level in DB, trust PP
else
cs->level[char_num] = lvl;
if(clas == 0)
cs->class_[char_num] = pp->class_; //no class in DB, trust PP
else
cs->class_[char_num] = clas;
cs->race[char_num] = pp->race;
cs->gender[char_num] = pp->gender;
cs->deity[char_num] = pp->deity;
cs->zone[char_num] = GetZoneID(row[2]);
cs->face[char_num] = pp->face;
cs->haircolor[char_num] = pp->haircolor;
cs->beardcolor[char_num] = pp->beardcolor;
cs->eyecolor2[char_num] = pp->eyecolor2;
cs->eyecolor1[char_num] = pp->eyecolor1;
cs->hairstyle[char_num] = pp->hairstyle;
cs->beard[char_num] = pp->beard;
cs->drakkin_heritage[char_num] = pp->drakkin_heritage;
cs->drakkin_tattoo[char_num] = pp->drakkin_tattoo;
cs->drakkin_details[char_num] = pp->drakkin_details;
if (RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
cs->tutorial[char_num] = 1;
if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
cs->tutorial[char_num] = 1;
if (RuleB(World, EnableReturnHomeButton)) {
int now = time(nullptr);
if ((now - atoi(row[7])) >= RuleI(World, MinOfflineTimeToReturnHome))
cs->gohome[char_num] = 1;
}
if(RuleB(World, EnableReturnHomeButton)) {
int now = time(nullptr);
if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome))
cs->gohome[char_num] = 1;
/* Set Bind Point Data for any character that may possibly be missing it for any reason */
cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %i LIMIT 2", character_id);
auto results_bind = database.QueryDatabase(cquery); has_home = 0; has_bind = 0;
for (auto row_b = results_bind.begin(); row_b != results_bind.end(); ++row_b) {
if (row_b[6] && atoi(row_b[6]) == 1){ has_home = 1; }
if (row_b[6] && atoi(row_b[6]) == 0){ has_bind = 1; }
}
if (has_home == 0 || has_bind == 0){
cquery = StringFormat("SELECT `zone_id`, `bind_id`, `x`, `y`, `z` FROM `start_zones` WHERE `player_class` = %i AND `player_deity` = %i AND `player_race` = %i",
cs->class_[char_num], cs->deity[char_num], cs->race[char_num]);
auto results_bind = database.QueryDatabase(cquery);
for (auto row_d = results_bind.begin(); row_d != results_bind.end(); ++row_d) {
/* If a bind_id is specified, make them start there */
if (atoi(row_d[1]) != 0) {
pp.binds[4].zoneId = (uint32)atoi(row_d[1]);
GetSafePoints(pp.binds[4].zoneId, 0, &pp.binds[4].x, &pp.binds[4].y, &pp.binds[4].z);
}
/* Otherwise, use the zone and coordinates given */
else {
pp.binds[4].zoneId = (uint32)atoi(row_d[0]);
float x = atof(row_d[2]);
float y = atof(row_d[3]);
float z = atof(row_d[4]);
if (x == 0 && y == 0 && z == 0){ GetSafePoints(pp.binds[4].zoneId, 0, &x, &y, &z); }
pp.binds[4].x = x; pp.binds[4].y = y; pp.binds[4].z = z;
// This part creates home city entries for characters created before the home bind point was tracked.
// Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
// probably be removed at some point, when most accounts are safely converted.
if(pp->binds[4].zoneId == 0) {
bool altered = false;
MYSQL_RES *result2;
MYSQL_ROW row2;
char startzone[50] = {0};
// check for start zone variable (I didn't even know any variables were still being used...)
if(database.GetVariable("startzone", startzone, 50)) {
uint32 zoneid = database.GetZoneID(startzone);
if(zoneid) {
pp->binds[4].zoneId = zoneid;
GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
altered = true;
}
}
else {
RunQuery(query,
MakeAnyLenString(&query,
"SELECT zone_id,bind_id,x,y,z FROM start_zones "
"WHERE player_class=%i AND player_deity=%i AND player_race=%i",
pp->class_,
pp->deity,
pp->race
),
errbuf,
&result2
);
safe_delete_array(query);
// if there is only one possible start city, set it
if(mysql_num_rows(result2) == 1) {
row2 = mysql_fetch_row(result2);
if(atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there
pp->binds[4].zoneId = (uint32)atoi(row2[1]);
GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
}
else { // otherwise, use the zone and coordinates given
pp->binds[4].zoneId = (uint32)atoi(row2[0]);
float x = atof(row2[2]);
float y = atof(row2[3]);
float z = atof(row2[4]);
if(x == 0 && y == 0 && z == 0)
GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);
pp->binds[4].x = x;
pp->binds[4].y = y;
pp->binds[4].z = z;
}
altered = true;
}
mysql_free_result(result2);
}
// update the player profile
if(altered) {
uint32 char_id = GetCharacterID(cs->name[char_num]);
RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2);
safe_delete_array(query);
if(result2) {
row2 = mysql_fetch_row(result2);
ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0];
SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5);
}
mysql_free_result(result2);
}
} // end of "set start zone" block
// Character's equipped items
// @merth: Haven't done bracer01/bracer02 yet.
// Also: this needs a second look after items are a little more solid
// NOTE: items don't have a color, players MAY have a tint, if the
// use_tint part is set. otherwise use the regular color
inv = new Inventory;
if(GetInventory(account_id, cs->name[char_num], inv))
{
for (uint8 material = 0; material <= 8; material++)
{
uint32 color;
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
if(item == 0)
continue;
cs->equip[char_num][material] = item->GetItem()->Material;
if(pp->item_tint[material].rgb.use_tint) // they have a tint (LoY dye)
color = pp->item_tint[material].color;
else // no tint, use regular item color
color = item->GetItem()->Color;
cs->cs_colors[char_num][material].color = color;
// the weapons are kept elsewhere
if ((material==MaterialPrimary) || (material==MaterialSecondary))
{
if(strlen(item->GetItem()->IDFile) > 2) {
uint32 idfile=atoi(&item->GetItem()->IDFile[2]);
if (material==MaterialPrimary)
cs->primary[char_num]=idfile;
else
cs->secondary[char_num]=idfile;
}
}
}
}
else
{
printf("Error loading inventory for %s\n", cs->name[char_num]);
}
safe_delete(inv);
if (++char_num > 10)
break;
}
else
{
std::cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << std::endl;
std::cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct) << std::endl;
//DeleteCharacter(row[0]);
pp.binds[0] = pp.binds[4];
/* If no home bind set, set it */
if (has_home == 0){
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 1);
auto results_bset = QueryDatabase(query);
}
/* If no regular bind set, set it */
if (has_bind == 0){
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
character_id, pp.binds[0].zoneId, 0, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z, pp.binds[0].heading, 0);
auto results_bset = QueryDatabase(query);
}
}
mysql_free_result(result);
}
else
{
std::cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << std::endl;
safe_delete_array(query);
return;
/* Bind End */
/*
Character's equipped items
@merth: Haven't done bracer01/bracer02 yet.
Also: this needs a second look after items are a little more solid
NOTE: items don't have a color, players MAY have a tint, if the
use_tint part is set. otherwise use the regular color
*/
/* Load Character Material Data for Char Select */
cquery = StringFormat("SELECT slot, red, green, blue, use_tint, color FROM `character_material` WHERE `id` = %u", character_id);
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
slot = atoi(row_b[0]);
pp.item_tint[slot].rgb.red = atoi(row_b[1]);
pp.item_tint[slot].rgb.green = atoi(row_b[2]);
pp.item_tint[slot].rgb.blue = atoi(row_b[3]);
pp.item_tint[slot].rgb.use_tint = atoi(row_b[4]);
}
/* Load Inventory */
inv = new Inventory;
if (GetInventory(account_id, cs->name[char_num], inv)) {
for (uint8 material = 0; material <= 8; material++) {
uint32 color = 0;
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
if (item == 0)
continue;
cs->equip[char_num][material] = item->GetItem()->Material;
if (pp.item_tint[material].rgb.use_tint){ color = pp.item_tint[material].color; }
else{ color = item->GetItem()->Color; }
cs->cs_colors[char_num][material].color = color;
/* Weapons are handled a bit differently */
if ((material == MaterialPrimary) || (material == MaterialSecondary)) {
if (strlen(item->GetItem()->IDFile) > 2) {
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
uint32 idfile;
if (item->GetOrnamentationAug(ornamentationAugtype)) {
idfile = atoi(&item->GetOrnamentationAug(ornamentationAugtype)->GetItem()->IDFile[2]);
}
else if (item->GetOrnamentationIcon() && item->GetOrnamentationIDFile()) {
idfile = item->GetOrnamentationIDFile();
}
else {
idfile = atoi(&item->GetItem()->IDFile[2]);
}
if (material == MaterialPrimary)
cs->primary[char_num] = idfile;
else
cs->secondary[char_num] = idfile;
}
}
}
}
else {
printf("Error loading inventory for %s\n", cs->name[char_num]);
}
safe_delete(inv);
if (++char_num > 10)
break;
}
return;
}
int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) {
// if an invalid bind point is specified, use the primary bind
/* if an invalid bind point is specified, use the primary bind */
if (bindnum > 4)
{
bindnum = 0;
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
uint32 affected_rows = 0;
PlayerProfile_Struct pp;
bool PPValid = false;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile from character_ where id='%i'", CharID), errbuf, &result)) {
row = mysql_fetch_row(result);
unsigned long* lengths = mysql_fetch_lengths(result);
if (lengths[0] == sizeof(PlayerProfile_Struct)) {
memcpy(&pp, row[0], sizeof(PlayerProfile_Struct));
PPValid = true;
}
mysql_free_result(result);
}
safe_delete_array(query);
if(!PPValid) return 0;
const char *BindZoneName = StaticGetZoneName(pp.binds[bindnum].zoneId);
if(!strcmp(BindZoneName, "UNKNWN")) return pp.zone_id;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET zonename = '%s',zoneid=%i,x=%f, y=%f, z=%f, instanceid=0 WHERE id='%i'",
BindZoneName, pp.binds[bindnum].zoneId, pp.binds[bindnum].x, pp.binds[bindnum].y, pp.binds[bindnum].z,
CharID), errbuf, 0,&affected_rows)) {
return pp.zone_id;
std::string query = StringFormat("SELECT zone_id, instance_id, x, y, z FROM character_bind WHERE id = %u AND is_home = %u LIMIT 1", CharID, bindnum == 4 ? 1 : 0);
auto results = database.QueryDatabase(query);
if(!results.Success() || results.RowCount() == 0) {
return 0;
}
safe_delete_array(query);
return pp.binds[bindnum].zoneId;
int zone_id, instance_id;
double x, y, z, heading;
for (auto row = results.begin(); row != results.end(); ++row) {
zone_id = atoi(row[0]);
instance_id = atoi(row[1]);
x = atof(row[2]);
y = atof(row[3]);
z = atof(row[4]);
heading = atof(row[5]);
}
query = StringFormat("UPDATE character_data SET zone_id = '%d', zone_instance = '%d', x = '%f', y = '%f', z = '%f', heading = '%f' WHERE id = %u",
zone_id, instance_id, x, y, z, heading, CharID);
results = database.QueryDatabase(query);
if(!results.Success()) {
return 0;
}
return zone_id;
}
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row = 0;
int rows;
if(!in_pp || !in_cc)
return false;
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0;
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,zone_id,bind_id FROM start_zones WHERE player_choice=%i AND player_class=%i "
"AND player_deity=%i AND player_race=%i",
in_cc->start_zone,
in_cc->class_,
in_cc->deity,
in_cc->race), errbuf, &result))
{
LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query, errbuf);
safe_delete_array(query);
std::string query = StringFormat("SELECT x, y, z, heading, zone_id, bind_id "
"FROM start_zones WHERE player_choice = % i "
"AND player_class = %i AND player_deity = %i "
"AND player_race = %i",
in_cc->start_zone, in_cc->class_, in_cc->deity,
in_cc->race);
auto results = QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
return false;
}
LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query);
safe_delete_array(query);
LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query.c_str());
if((rows = mysql_num_rows(result)) > 0)
row = mysql_fetch_row(result);
if(row)
{
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
in_pp->x = atof(row[0]);
in_pp->y = atof(row[1]);
in_pp->z = atof(row[2]);
in_pp->heading = atof(row[3]);
in_pp->zone_id = atoi(row[4]);
in_pp->binds[0].zoneId = atoi(row[5]);
}
else
{
printf("No start_zones entry in database, using defaults\n");
if (results.RowCount() == 0) {
printf("No start_zones entry in database, using defaults\n");
switch(in_cc->start_zone)
{
case 0:
@@ -333,83 +292,93 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
}
case 1:
{
in_pp->zone_id =2; // qeynos2
in_pp->zone_id = 2; // qeynos2
in_pp->binds[0].zoneId = 2; // qeynos2
break;
}
case 2:
{
in_pp->zone_id =29; // halas
in_pp->zone_id = 29; // halas
in_pp->binds[0].zoneId = 30; // everfrost
break;
}
case 3:
{
in_pp->zone_id =19; // rivervale
in_pp->zone_id = 19; // rivervale
in_pp->binds[0].zoneId = 20; // kithicor
break;
}
case 4:
{
in_pp->zone_id =9; // freportw
in_pp->zone_id = 9; // freportw
in_pp->binds[0].zoneId = 9; // freportw
break;
}
case 5:
{
in_pp->zone_id =40; // neriaka
in_pp->zone_id = 40; // neriaka
in_pp->binds[0].zoneId = 25; // nektulos
break;
}
case 6:
{
in_pp->zone_id =52; // gukta
in_pp->zone_id = 52; // gukta
in_pp->binds[0].zoneId = 46; // innothule
break;
}
case 7:
{
in_pp->zone_id =49; // oggok
in_pp->zone_id = 49; // oggok
in_pp->binds[0].zoneId = 47; // feerrott
break;
}
case 8:
{
in_pp->zone_id =60; // kaladima
in_pp->zone_id = 60; // kaladima
in_pp->binds[0].zoneId = 68; // butcher
break;
}
case 9:
{
in_pp->zone_id =54; // gfaydark
in_pp->zone_id = 54; // gfaydark
in_pp->binds[0].zoneId = 54; // gfaydark
break;
}
case 10:
{
in_pp->zone_id =61; // felwithea
in_pp->zone_id = 61; // felwithea
in_pp->binds[0].zoneId = 54; // gfaydark
break;
}
case 11:
{
in_pp->zone_id =55; // akanon
in_pp->zone_id = 55; // akanon
in_pp->binds[0].zoneId = 56; // steamfont
break;
}
case 12:
{
in_pp->zone_id =82; // cabwest
in_pp->zone_id = 82; // cabwest
in_pp->binds[0].zoneId = 78; // fieldofbone
break;
}
case 13:
{
in_pp->zone_id =155; // sharvahl
in_pp->zone_id = 155; // sharvahl
in_pp->binds[0].zoneId = 155; // sharvahl
break;
}
}
}
else {
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
auto row = results.begin();
in_pp->x = atof(row[0]);
in_pp->y = atof(row[1]);
in_pp->z = atof(row[2]);
in_pp->heading = atof(row[3]);
in_pp->zone_id = atoi(row[4]);
in_pp->binds[0].zoneId = atoi(row[5]);
}
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
@@ -417,14 +386,12 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
if(result)
mysql_free_result(result);
return true;
}
bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
{
// SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead.
//
// For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity.
@@ -432,49 +399,25 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
// For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely
// reason for no match being found.
//
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row = 0;
int rows;
if(!in_pp || !in_cc)
return false;
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0;
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,bind_id FROM start_zones WHERE zone_id=%i AND player_class=%i "
"AND player_deity=%i AND player_race=%i",
in_cc->start_zone,
in_cc->class_,
in_cc->deity,
in_cc->race), errbuf, &result))
{
LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query, errbuf);
safe_delete_array(query);
std::string query = StringFormat("SELECT x, y, z, heading, bind_id FROM start_zones WHERE zone_id = %i "
"AND player_class = %i AND player_deity = %i AND player_race = %i",
in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
auto results = QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
return false;
}
LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query);
safe_delete_array(query);
LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query.c_str());
if((rows = mysql_num_rows(result)) > 0)
row = mysql_fetch_row(result);
if(row)
{
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
in_pp->x = atof(row[0]);
in_pp->y = atof(row[1]);
in_pp->z = atof(row[2]);
in_pp->heading = atof(row[3]);
in_pp->zone_id = in_cc->start_zone;
in_pp->binds[0].zoneId = atoi(row[4]);
}
else
{
printf("No start_zones entry in database, using defaults\n");
if (results.RowCount() == 0) {
printf("No start_zones entry in database, using defaults\n");
if(in_cc->start_zone == RuleI(World, TutorialZoneID))
in_pp->zone_id = in_cc->start_zone;
@@ -484,7 +427,16 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
in_pp->z = in_pp->binds[0].z = 0.79;
in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach.
}
}
else {
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
auto row = results.begin();
in_pp->x = atof(row[0]);
in_pp->y = atof(row[1]);
in_pp->z = atof(row[2]);
in_pp->heading = atof(row[3]);
in_pp->zone_id = in_cc->start_zone;
in_pp->binds[0].zoneId = atoi(row[4]);
}
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
@@ -492,39 +444,27 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
if(result)
mysql_free_result(result);
return true;
}
void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
rl.clear();
if (RunQuery(query, MakeAnyLenString(&query,
"SELECT name FROM launcher" )
, errbuf, &result))
{
while ((row = mysql_fetch_row(result))) {
rl.push_back(row[0]);
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetLauncherList: %s", errbuf);
}
safe_delete_array(query);
const std::string query = "SELECT name FROM launcher";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetLauncherList: %s", results.ErrorMessage().c_str());
return;
}
for (auto row = results.begin(); row != results.end(); ++row)
rl.push_back(row[0]);
}
void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char MailKeyString[17];
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
@@ -532,75 +472,60 @@ void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
else
sprintf(MailKeyString, "%08X", MailKey);
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET mailkey = '%s' WHERE id='%i'",
MailKeyString, CharID), errbuf))
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, errbuf);
safe_delete_array(query);
std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
MailKeyString, CharID);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
}
bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
std::string query = StringFormat("SELECT level FROM character_data WHERE name = '%s'", name);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetCharacterLevel: %s", results.ErrorMessage().c_str());
return false;
}
if(RunQuery(query, MakeAnyLenString(&query, "SELECT level FROM character_ WHERE name='%s'", name), errbuf, &result))
{
if(row = mysql_fetch_row(result))
{
level = atoi(row[0]);
mysql_free_result(result);
safe_delete_array(query);
return true;
}
mysql_free_result(result);
}
else
{
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetCharacterLevel: %s", errbuf);
}
safe_delete_array(query);
return false;
if (results.RowCount() == 0)
return false;
auto row = results.begin();
level = atoi(row[0]);
return true;
}
bool WorldDatabase::LoadCharacterCreateAllocations() {
character_create_allocations.clear();
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(RunQuery(query, MakeAnyLenString(&query, "SELECT * FROM char_create_point_allocations order by id"), errbuf, &result)) {
safe_delete_array(query);
while(row = mysql_fetch_row(result)) {
RaceClassAllocation allocate;
int r = 0;
allocate.Index = atoi(row[r++]);
allocate.BaseStats[0] = atoi(row[r++]);
allocate.BaseStats[3] = atoi(row[r++]);
allocate.BaseStats[1] = atoi(row[r++]);
allocate.BaseStats[2] = atoi(row[r++]);
allocate.BaseStats[4] = atoi(row[r++]);
allocate.BaseStats[5] = atoi(row[r++]);
allocate.BaseStats[6] = atoi(row[r++]);
allocate.DefaultPointAllocation[0] = atoi(row[r++]);
allocate.DefaultPointAllocation[3] = atoi(row[r++]);
allocate.DefaultPointAllocation[1] = atoi(row[r++]);
allocate.DefaultPointAllocation[2] = atoi(row[r++]);
allocate.DefaultPointAllocation[4] = atoi(row[r++]);
allocate.DefaultPointAllocation[5] = atoi(row[r++]);
allocate.DefaultPointAllocation[6] = atoi(row[r++]);
character_create_allocations.push_back(allocate);
}
mysql_free_result(result);
} else {
safe_delete_array(query);
return false;
}
std::string query = "SELECT * FROM char_create_point_allocations ORDER BY id";
auto results = QueryDatabase(query);
if (!results.Success())
return false;
for (auto row = results.begin(); row != results.end(); ++row) {
RaceClassAllocation allocate;
allocate.Index = atoi(row[0]);
allocate.BaseStats[0] = atoi(row[1]);
allocate.BaseStats[3] = atoi(row[2]);
allocate.BaseStats[1] = atoi(row[3]);
allocate.BaseStats[2] = atoi(row[4]);
allocate.BaseStats[4] = atoi(row[5]);
allocate.BaseStats[5] = atoi(row[6]);
allocate.BaseStats[6] = atoi(row[7]);
allocate.DefaultPointAllocation[0] = atoi(row[8]);
allocate.DefaultPointAllocation[3] = atoi(row[9]);
allocate.DefaultPointAllocation[1] = atoi(row[10]);
allocate.DefaultPointAllocation[2] = atoi(row[11]);
allocate.DefaultPointAllocation[4] = atoi(row[12]);
allocate.DefaultPointAllocation[5] = atoi(row[13]);
allocate.DefaultPointAllocation[6] = atoi(row[14]);
character_create_allocations.push_back(allocate);
}
return true;
}
@@ -608,27 +533,21 @@ bool WorldDatabase::LoadCharacterCreateAllocations() {
bool WorldDatabase::LoadCharacterCreateCombos() {
character_create_race_class_combos.clear();
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(RunQuery(query, MakeAnyLenString(&query, "select * from char_create_combinations order by race, class, deity, start_zone"), errbuf, &result)) {
safe_delete_array(query);
while(row = mysql_fetch_row(result)) {
RaceClassCombos combo;
int r = 0;
combo.AllocationIndex = atoi(row[r++]);
combo.Race = atoi(row[r++]);
combo.Class = atoi(row[r++]);
combo.Deity = atoi(row[r++]);
combo.Zone = atoi(row[r++]);
combo.ExpansionRequired = atoi(row[r++]);
character_create_race_class_combos.push_back(combo);
}
mysql_free_result(result);
} else {
safe_delete_array(query);
return false;
std::string query = "SELECT * FROM char_create_combinations ORDER BY race, class, deity, start_zone";
auto results = QueryDatabase(query);
if (!results.Success())
return false;
for (auto row = results.begin(); row != results.end(); ++row) {
RaceClassCombos combo;
combo.AllocationIndex = atoi(row[0]);
combo.Race = atoi(row[1]);
combo.Class = atoi(row[2]);
combo.Deity = atoi(row[3]);
combo.Zone = atoi(row[4]);
combo.ExpansionRequired = atoi(row[5]);
character_create_race_class_combos.push_back(combo);
}
return true;
+2 -2
View File
@@ -19,7 +19,7 @@
#define WORLDDB_H_
#include "../common/shareddb.h"
#include "../common/ZoneNumbers.h"
#include "../common/zone_numbers.h"
struct PlayerProfile_Struct;
struct CharCreate_Struct;
@@ -31,7 +31,7 @@ public:
bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
bool GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*);
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*, uint32 ClientVersion);
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
void GetLauncherList(std::vector<std::string> &result);
+5 -5
View File
@@ -18,12 +18,12 @@
#include "../common/debug.h"
#include "zonelist.h"
#include "zoneserver.h"
#include "WorldTCPConnection.h"
#include "world_tcp_connection.h"
#include "worlddb.h"
#include "console.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "../common/servertalk.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
extern uint32 numzones;
extern bool holdzones;
@@ -87,7 +87,7 @@ void ZSList::Process() {
CatchSignal(2);
}
if(reminder && reminder->Check()){
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i seconds...",shutdowntimer->GetRemainingTime()/1000);
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i minutes...", ((shutdowntimer->GetRemainingTime()/1000) / 60));
}
LinkedListIterator<ZoneServer*> iterator(list);
@@ -718,7 +718,7 @@ void ZSList::GetZoneIDList(std::vector<uint32> &zones) {
void ZSList::WorldShutDown(uint32 time, uint32 interval)
{
if( time > 0 ) {
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i seconds, everyone log out before this time.",time);
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i minutes, everyone log out before this time.", (time / 60));
time *= 1000;
interval *= 1000;
+103 -110
View File
@@ -18,22 +18,22 @@
#include "../common/debug.h"
#include "zoneserver.h"
#include "clientlist.h"
#include "LoginServer.h"
#include "LoginServerList.h"
#include "login_server.h"
#include "login_server_list.h"
#include "zonelist.h"
#include "worlddb.h"
#include "console.h"
#include "client.h"
#include "../common/md5.h"
#include "WorldConfig.h"
#include "world_config.h"
#include "../common/guilds.h"
#include "../common/packet_dump.h"
#include "../common/misc.h"
#include "../common/StringUtil.h"
#include "../common/string_util.h"
#include "cliententry.h"
#include "wguild_mgr.h"
#include "lfplist.h"
#include "AdventureManager.h"
#include "adventure_manager.h"
#include "ucs.h"
#include "queryserv.h"
#include "web_interface.h"
@@ -411,6 +411,14 @@ bool ZoneServer::Process() {
break;
}
case ServerOP_RaidMOTD: {
if (pack->size < sizeof(ServerRaidMOTD_Struct))
break;
zoneserver_list.SendPacket(pack);
break;
}
case ServerOP_SpawnCondition: {
if(pack->size != sizeof(ServerSpawnCondition_Struct))
break;
@@ -428,6 +436,8 @@ bool ZoneServer::Process() {
break;
}
case ServerOP_ChannelMessage: {
if (pack->size < sizeof(ServerChannelMessage_Struct))
break;
ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer;
if(scm->chan_num == 20)
{
@@ -439,42 +449,48 @@ bool ZoneServer::Process() {
Console* con = 0;
con = console_list.FindByAccountName(&scm->deliverto[1]);
if (((!con) || (!con->SendChannelMessage(scm))) && (!scm->noreply))
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to);
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to);
break;
}
ClientListEntry* cle = client_list.FindCharacter(scm->deliverto);
if (cle == 0 || cle->Online() < CLE_Status_Zoning || (cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) {
if (!scm->noreply)
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to);
}
else if (cle->Online() == CLE_Status_Zoning) {
if (cle == 0 || cle->Online() < CLE_Status_Zoning ||
(cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) {
if (!scm->noreply) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
//MYSQL_ROW row; Trumpcard - commenting. Currently unused.
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
char *telldate=asctime(timeinfo);
if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT name from character_ where name='%s'",scm->deliverto), errbuf, &result)) {
safe_delete(query);
if (result!=0) {
if (database.RunQuery(query, MakeAnyLenString(&query, "INSERT INTO tellque (Date,Receiver,Sender,Message) values('%s','%s','%s','%s')",telldate,scm->deliverto,scm->from,scm->message), errbuf, &result))
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "Your message has been added to the %s's que.", scm->to);
else
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to);
safe_delete(query);
}
else
zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to);
mysql_free_result(result);
}
else
safe_delete(query);
ClientListEntry* sender = client_list.FindCharacter(scm->from);
if (!sender || !sender->Server())
break;
scm->noreply = true;
scm->queued = 3; // offline
strcpy(scm->deliverto, scm->from);
// ideally this would be trimming off the message too, oh well
sender->Server()->SendPacket(pack);
}
} else if (cle->Online() == CLE_Status_Zoning) {
if (!scm->noreply) {
ClientListEntry* sender = client_list.FindCharacter(scm->from);
if (cle->TellQueueFull()) {
if (!sender || !sender->Server())
break;
scm->noreply = true;
scm->queued = 2; // queue full
strcpy(scm->deliverto, scm->from);
sender->Server()->SendPacket(pack);
} else {
size_t struct_size = sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1;
ServerChannelMessage_Struct *temp = (ServerChannelMessage_Struct *) new uchar[struct_size];
memset(temp, 0, struct_size); // just in case, was seeing some corrupt messages, but it shouldn't happen
memcpy(temp, scm, struct_size);
temp->noreply = true;
cle->PushToTellQueue(temp); // deallocation is handled in processing or deconstructor
if (!sender || !sender->Server())
break;
scm->noreply = true;
scm->queued = 1; // queued
strcpy(scm->deliverto, scm->from);
sender->Server()->SendPacket(pack);
}
}
// zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to);
}
else if (cle->Server() == 0) {
if (!scm->noreply)
@@ -651,17 +667,17 @@ bool ZoneServer::Process() {
client->Clearance(wtz->response);
}
case ServerOP_ZoneToZoneRequest: {
//
// solar: ZoneChange is received by the zone the player is in, then the
// zone sends a ZTZ which ends up here. This code then find the target
// (ingress point) and boots it if needed, then sends the ZTZ to it.
// The ingress server will decide wether the player can enter, then will
// send back the ZTZ to here. This packet is passed back to the egress
// server, which will send a ZoneChange response back to the client
// which can be an error, or a success, in which case the client will
// disconnect, and their zone location will be saved when ~Client is
// called, so it will be available when they ask to zone.
//
//
// solar: ZoneChange is received by the zone the player is in, then the
// zone sends a ZTZ which ends up here. This code then find the target
// (ingress point) and boots it if needed, then sends the ZTZ to it.
// The ingress server will decide wether the player can enter, then will
// send back the ZTZ to here. This packet is passed back to the egress
// server, which will send a ZoneChange response back to the client
// which can be an error, or a success, in which case the client will
// disconnect, and their zone location will be saved when ~Client is
// called, so it will be available when they ask to zone.
//
if(pack->size != sizeof(ZoneToZone_Struct))
@@ -674,40 +690,31 @@ bool ZoneServer::Process() {
zlog(WORLD__ZONE,"ZoneToZone request for %s current zone %d req zone %d\n",
ztz->name, ztz->current_zone_id, ztz->requested_zone_id);
if(GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) // this is a request from the egress zone
{
/* This is a request from the egress zone */
if(GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) {
zlog(WORLD__ZONE,"Processing ZTZ for egress from zone for client %s\n", ztz->name);
if
(
ztz->admin < 80 &&
ztz->ignorerestrictions < 2 &&
zoneserver_list.IsZoneLocked(ztz->requested_zone_id)
)
{
if (ztz->admin < 80 && ztz->ignorerestrictions < 2 && zoneserver_list.IsZoneLocked(ztz->requested_zone_id)) {
ztz->response = 0;
SendPacket(pack);
break;
}
ZoneServer *ingress_server = nullptr;
if(ztz->requested_instance_id > 0)
{
if(ztz->requested_instance_id > 0) {
ingress_server = zoneserver_list.FindByInstanceID(ztz->requested_instance_id);
}
else
{
ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id);
else {
ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id);
}
if(ingress_server) // found a zone already running
{
/* Zone was already running*/
if(ingress_server) {
_log(WORLD__ZONE,"Found a zone already booted for %s\n", ztz->name);
ztz->response = 1;
}
else // need to boot one
{
/* Boot the Zone*/
else {
int server_id;
if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id, ztz->requested_instance_id))){
_log(WORLD__ZONE,"Successfully booted a zone for %s\n", ztz->name);
@@ -715,8 +722,7 @@ bool ZoneServer::Process() {
ztz->response = 1;
ingress_server = zoneserver_list.FindByID(server_id);
}
else
{
else {
_log(WORLD__ZONE_ERR,"FAILED to boot a zone for %s\n", ztz->name);
// bootup failed, send back error code 0
ztz->response = 0;
@@ -724,27 +730,24 @@ bool ZoneServer::Process() {
}
if(ztz->response!=0 && client)
client->LSZoneChange(ztz);
SendPacket(pack); // send back to egress server
if(ingress_server) // if we couldn't boot one, this is 0
{
ingress_server->SendPacket(pack); // inform target server
}
SendPacket(pack); // send back to egress server
if(ingress_server) {
ingress_server->SendPacket(pack); // inform target server
}
}
else // this is response from the ingress server, route it back to the egress server
{
/* Response from Ingress server, route back to egress */
else{
zlog(WORLD__ZONE,"Processing ZTZ for ingress to zone for client %s\n", ztz->name);
ZoneServer *egress_server = nullptr;
if(ztz->current_instance_id > 0)
{
if(ztz->current_instance_id > 0) {
egress_server = zoneserver_list.FindByInstanceID(ztz->current_instance_id);
}
else
{
else {
egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id);
}
if(egress_server)
{
if(egress_server) {
egress_server->SendPacket(pack);
}
}
@@ -782,21 +785,18 @@ bool ZoneServer::Process() {
delete whom;
break;
}
case ServerOP_RequestOnlineGuildMembers:
{
case ServerOP_RequestOnlineGuildMembers: {
ServerRequestOnlineGuildMembers_Struct *srogms = (ServerRequestOnlineGuildMembers_Struct*) pack->pBuffer;
zlog(GUILDS__IN_PACKETS, "ServerOP_RequestOnlineGuildMembers Recieved. FromID=%i GuildID=%i", srogms->FromID, srogms->GuildID);
client_list.SendOnlineGuildMembers(srogms->FromID, srogms->GuildID);
break;
}
case ServerOP_ClientVersionSummary:
{
case ServerOP_ClientVersionSummary: {
ServerRequestClientVersionSummary_Struct *srcvss = (ServerRequestClientVersionSummary_Struct*) pack->pBuffer;
client_list.SendClientVersionSummary(srcvss->Name);
break;
}
case ServerOP_ReloadRules:
{
case ServerOP_ReloadRules: {
zoneserver_list.SendPacket(pack);
RuleManager::Instance()->LoadRules(&database, "default");
break;
@@ -1267,39 +1267,20 @@ bool ZoneServer::Process() {
UCSLink.SendPacket(pack);
break;
}
case ServerOP_QSSendQuery:
case ServerOP_QueryServGeneric:
case ServerOP_Speech:
case ServerOP_QSPlayerLogTrades:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogHandins:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogNPCKills:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogDeletes:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogMoves:
case ServerOP_QSPlayerLogMerchantTransactions:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSMerchantLogTransactions:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_WIRemoteCallResponse:
case ServerOP_WIClientSession:
case ServerOP_WIRemoteCallToClient:
@@ -1308,7 +1289,9 @@ bool ZoneServer::Process() {
break;
}
case ServerOP_CZSignalClientByName:
case ServerOP_CZMessagePlayer:
case ServerOP_CZMessagePlayer:
case ServerOP_CZSignalNPC:
case ServerOP_CZSetEntityVariableByNPCTypeID:
case ServerOP_CZSignalClient:
case ServerOP_DepopAllPlayersCorpses:
case ServerOP_DepopPlayerCorpse:
@@ -1321,6 +1304,16 @@ bool ZoneServer::Process() {
zoneserver_list.SendPacket(pack);
break;
}
case ServerOP_RequestTellQueue:
{
ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer;
ClientListEntry *cle = client_list.FindCharacter(rtq->name);
if (!cle || cle->TellQueueEmpty())
break;
cle->ProcessTellQueue();
break;
}
default:
{
zlog(WORLD__ZONE_ERR,"Unknown ServerOPcode from zone 0x%04x, size %d",pack->opcode,pack->size);
+2 -2
View File
@@ -18,8 +18,8 @@
#ifndef ZONESERVER_H
#define ZONESERVER_H
#include "WorldTCPConnection.h"
#include "../common/EmuTCPConnection.h"
#include "world_tcp_connection.h"
#include "../common/emu_tcp_connection.h"
#include <string.h>
#include <string>