Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Paul Coene
2015-01-26 14:30:21 -05:00
578 changed files with 28955 additions and 30355 deletions
+216 -272
View File
@@ -15,25 +15,23 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/global_define.h"
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// for windows compile
#ifdef _WINDOWS
#define abs64 _abs64
#else
#ifndef _WINDOWS
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "../common/unix.h"
#define abs64 abs
#endif
extern volatile bool RunLoops;
#include "../common/eqemu_logsys.h"
#include "../common/features.h"
#include "../common/spdat.h"
#include "../common/guilds.h"
@@ -47,7 +45,7 @@ extern volatile bool RunLoops;
#include "petitions.h"
#include "command.h"
#include "string_ids.h"
#include "client_logs.h"
#include "guild_mgr.h"
#include "quest_parser_collection.h"
#include "queryserv.h"
@@ -76,8 +74,8 @@ Client::Client(EQStreamInterface* ieqs)
0, // npctypeid
0, // size
0.7, // runspeed
xyz_heading::Origin(),
0, // light
glm::vec4(),
0, // light - verified for client innate_light value
0xFF, // texture
0xFF, // helmtexture
0, // ac
@@ -246,7 +244,7 @@ Client::Client(EQStreamInterface* ieqs)
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
AttemptedMessages = 0;
TotalKarma = 0;
ClientVersion = EQClientUnknown;
m_ClientVersion = ClientVersion::Unknown;
ClientVersionBit = 0;
AggroCount = 0;
RestRegenHP = 0;
@@ -304,6 +302,9 @@ Client::Client(EQStreamInterface* ieqs)
SavedRaidRestTimer = 0;
interrogateinv_flag = false;
active_light = innate_light;
spell_light = equip_light = NOT_USED;
}
Client::~Client() {
@@ -328,7 +329,7 @@ Client::~Client() {
ToggleBuyerMode(false);
if(conn_state != ClientConnectFinished) {
LogFile->write(EQEmuLog::Debug, "Client '%s' was destroyed before reaching the connected state:", GetName());
Log.Out(Logs::General, Logs::None, "Client '%s' was destroyed before reaching the connected state:", GetName());
ReportConnectingState();
}
@@ -337,11 +338,6 @@ Client::~Client() {
m_tradeskill_object = nullptr;
}
#ifdef CLIENT_LOGS
client_logs.unsubscribeAll(this);
#endif
ChangeSQLLog(nullptr);
if(IsDueling() && GetDuelTarget() != 0) {
Entity* entity = entity_list.GetID(GetDuelTarget());
if(entity != nullptr && entity->IsClient()) {
@@ -374,9 +370,9 @@ Client::~Client() {
{
m_pp.zone_id = m_pp.binds[0].zoneId;
m_pp.zoneInstance = m_pp.binds[0].instance_id;
m_Position.m_X = m_pp.binds[0].x;
m_Position.m_Y = m_pp.binds[0].y;
m_Position.m_Z = m_pp.binds[0].z;
m_Position.x = m_pp.binds[0].x;
m_Position.y = m_pp.binds[0].y;
m_Position.z = m_pp.binds[0].z;
}
// we save right now, because the client might be zoning and the world
@@ -426,31 +422,31 @@ void Client::SendLogoutPackets() {
void Client::ReportConnectingState() {
switch(conn_state) {
case NoPacketsReceived: //havent gotten anything
LogFile->write(EQEmuLog::Debug, "Client has not sent us an initial zone entry packet.");
Log.Out(Logs::General, Logs::None, "Client has not sent us an initial zone entry packet.");
break;
case ReceivedZoneEntry: //got the first packet, loading up PP
LogFile->write(EQEmuLog::Debug, "Client sent initial zone packet, but we never got their player info from the database.");
Log.Out(Logs::General, Logs::None, "Client sent initial zone packet, but we never got their player info from the database.");
break;
case PlayerProfileLoaded: //our DB work is done, sending it
LogFile->write(EQEmuLog::Debug, "We were sending the player profile, tributes, tasks, spawns, time and weather, but never finished.");
Log.Out(Logs::General, Logs::None, "We were sending the player profile, tributes, tasks, spawns, time and weather, but never finished.");
break;
case ZoneInfoSent: //includes PP, tributes, tasks, spawns, time and weather
LogFile->write(EQEmuLog::Debug, "We successfully sent player info and spawns, waiting for client to request new zone.");
Log.Out(Logs::General, Logs::None, "We successfully sent player info and spawns, waiting for client to request new zone.");
break;
case NewZoneRequested: //received and sent new zone request
LogFile->write(EQEmuLog::Debug, "We received client's new zone request, waiting for client spawn request.");
Log.Out(Logs::General, Logs::None, "We received client's new zone request, waiting for client spawn request.");
break;
case ClientSpawnRequested: //client sent ReqClientSpawn
LogFile->write(EQEmuLog::Debug, "We received the client spawn request, and were sending objects, doors, zone points and some other stuff, but never finished.");
Log.Out(Logs::General, Logs::None, "We received the client spawn request, and were sending objects, doors, zone points and some other stuff, but never finished.");
break;
case ZoneContentsSent: //objects, doors, zone points
LogFile->write(EQEmuLog::Debug, "The rest of the zone contents were successfully sent, waiting for client ready notification.");
Log.Out(Logs::General, Logs::None, "The rest of the zone contents were successfully sent, waiting for client ready notification.");
break;
case ClientReadyReceived: //client told us its ready, send them a bunch of crap like guild MOTD, etc
LogFile->write(EQEmuLog::Debug, "We received client ready notification, but never finished Client::CompleteConnect");
Log.Out(Logs::General, Logs::None, "We received client ready notification, but never finished Client::CompleteConnect");
break;
case ClientConnectFinished: //client finally moved to finished state, were done here
LogFile->write(EQEmuLog::Debug, "Client is successfully connected.");
Log.Out(Logs::General, Logs::None, "Client is successfully connected.");
break;
};
}
@@ -500,11 +496,11 @@ bool Client::Save(uint8 iCommitNow) {
return false;
/* Wrote current basics to PP for saves */
m_pp.x = m_Position.m_X;
m_pp.y = m_Position.m_Y;
m_pp.z = m_Position.m_Z;
m_pp.x = m_Position.x;
m_pp.y = m_Position.y;
m_pp.z = m_Position.z;
m_pp.guildrank = guildrank;
m_pp.heading = m_Position.m_Heading;
m_pp.heading = m_Position.w;
/* Mana and HP */
if (GetHP() <= 0) {
@@ -521,8 +517,8 @@ bool Client::Save(uint8 iCommitNow) {
database.SaveCharacterCurrency(CharacterID(), &m_pp);
/* Save Current Bind Points */
auto regularBindPosition = xyz_heading(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f);
auto homeBindPosition = xyz_heading(m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0.0f);
auto regularBindPosition = glm::vec4(m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0.0f);
auto homeBindPosition = glm::vec4(m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0.0f);
database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[0].zoneId, m_pp.binds[0].instance_id, regularBindPosition, 0); /* Regular bind */
database.SaveCharacterBindPoint(CharacterID(), m_pp.binds[4].zoneId, m_pp.binds[4].instance_id, homeBindPosition, 1); /* Home Bind */
@@ -640,9 +636,7 @@ bool Client::SendAllPackets() {
if(eqs)
eqs->FastQueuePacket((EQApplicationPacket **)&cp->app, cp->ack_req);
iterator.RemoveCurrent();
#if EQDEBUG >= 6
LogFile->write(EQEmuLog::Normal, "Transmitting a packet");
#endif
Log.Out(Logs::Moderate, Logs::Client_Server_Packet, "Transmitting a packet");
}
return true;
}
@@ -690,10 +684,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
char message[4096];
strn0cpy(message, orig_message, sizeof(message));
#if EQDEBUG >= 11
LogFile->write(EQEmuLog::Debug,"Client::ChannelMessageReceived() Channel:%i message:'%s'", chan_num, message);
#endif
Log.Out(Logs::Detail, Logs::Zone_Server, "Client::ChannelMessageReceived() Channel:%i message:'%s'", chan_num, message);
if (targetname == nullptr) {
targetname = (!GetTarget()) ? "" : GetTarget()->GetName();
@@ -994,7 +985,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
CheckEmoteHail(GetTarget(), message);
if(ComparativeDistanceNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
NPC *tar = GetTarget()->CastToNPC();
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
@@ -1006,7 +997,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
}
else {
if (ComparativeDistanceNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
if (DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
parse->EventNPC(EVENT_AGGRO_SAY, GetTarget()->CastToNPC(), this, message, language);
}
}
@@ -1440,7 +1431,7 @@ void Client::UpdateWho(uint8 remove) {
else if (m_pp.anon >= 2)
scl->anon = 2;
scl->ClientVersion = GetClientVersion();
scl->ClientVersion = static_cast<unsigned int>(GetClientVersion());
scl->tellsoff = tellsoff;
scl->guild_id = guild_id;
scl->LFG = LFG;
@@ -1501,9 +1492,7 @@ void Client::UpdateAdmin(bool iFromDB) {
if(m_pp.gm)
{
#if EQDEBUG >= 5
printf("%s is a GM\n", GetName());
#endif
Log.Out(Logs::Moderate, Logs::Zone_Server, "%s - %s is a GM", __FUNCTION__ , GetName());
// no need for this, having it set in pp you already start as gm
// and it's also set in your spawn packet so other people see it too
// SendAppearancePacket(AT_GM, 1, false);
@@ -1698,12 +1687,11 @@ void Client::SendManaUpdatePacket() {
if (!Connected() || IsCasting())
return;
if (GetClientVersion() >= EQClientSoD) {
if (GetClientVersion() >= ClientVersion::SoD) {
SendManaUpdate();
SendEnduranceUpdate();
}
//std::cout << "Sending mana update: " << (cur_mana - last_reported_mana) << std::endl;
if (last_reported_mana != cur_mana || last_reported_endur != cur_end) {
@@ -1734,7 +1722,7 @@ void Client::SendManaUpdatePacket() {
for(int i = 0; i < MAX_GROUP_MEMBERS; ++i)
if(g->members[i] && g->members[i]->IsClient() && (g->members[i] != this) && (g->members[i]->CastToClient()->GetClientVersion() >= EQClientSoD))
if(g->members[i] && g->members[i]->IsClient() && (g->members[i] != this) && (g->members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD))
{
g->members[i]->CastToClient()->QueuePacket(outapp);
g->members[i]->CastToClient()->QueuePacket(outapp2);
@@ -1810,6 +1798,9 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
ns->spawn.runspeed = (gmspeed == 0) ? runspeed : 3.125f;
ns->spawn.showhelm = m_pp.showhelm ? 1 : 0;
UpdateEquipLightValue();
UpdateActiveLightValue();
ns->spawn.light = active_light;
}
bool Client::GMHideMe(Client* client) {
@@ -1908,13 +1899,13 @@ void Client::ReadBook(BookRequest_Struct *book) {
if (booktxt2[0] != '\0') {
#if EQDEBUG >= 6
LogFile->write(EQEmuLog::Normal,"Client::ReadBook() textfile:%s Text:%s", txtfile, booktxt2.c_str());
Log.Out(Logs::General, Logs::Normal, "Client::ReadBook() textfile:%s Text:%s", txtfile, booktxt2.c_str());
#endif
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ReadBook, length + sizeof(BookText_Struct));
BookText_Struct *out = (BookText_Struct *) outapp->pBuffer;
out->window = book->window;
if(GetClientVersion() >= EQClientSoF)
if(GetClientVersion() >= ClientVersion::SoF)
{
const ItemInst *inst = m_inv[book->invslot];
if(inst)
@@ -1978,7 +1969,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
copperpp -= copper;
if(copperpp <= 0)
{
copper = abs64(copperpp);
copper = std::abs(copperpp);
m_pp.copper = 0;
}
else
@@ -1992,7 +1983,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
silver -= copper;
if(silver <= 0)
{
copper = abs64(silver);
copper = std::abs(silver);
m_pp.silver = 0;
}
else
@@ -2009,7 +2000,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
if(gold <= 0)
{
copper = abs64(gold);
copper = std::abs(gold);
m_pp.gold = 0;
}
else
@@ -2102,7 +2093,7 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){
SaveCurrency();
LogFile->write(EQEmuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
}
void Client::EVENT_ITEM_ScriptStopReturn(){
@@ -2142,7 +2133,7 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat
SaveCurrency();
#if (EQDEBUG>=5)
LogFile->write(EQEmuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
#endif
}
@@ -2232,13 +2223,13 @@ bool Client::CheckIncreaseSkill(SkillUseTypes skillid, Mob *against_who, int cha
if(zone->random.Real(0, 99) < Chance)
{
SetSkill(skillid, GetRawSkill(skillid) + 1);
_log(SKILLS__GAIN, "Skill %d at value %d successfully gain with %.4f%%chance (mod %d)", skillid, skillval, Chance, chancemodi);
Log.Out(Logs::Detail, Logs::Skills, "Skill %d at value %d successfully gain with %d%%chance (mod %d)", skillid, skillval, Chance, chancemodi);
return true;
} else {
_log(SKILLS__GAIN, "Skill %d at value %d failed to gain with %.4f%%chance (mod %d)", skillid, skillval, Chance, chancemodi);
Log.Out(Logs::Detail, Logs::Skills, "Skill %d at value %d failed to gain with %d%%chance (mod %d)", skillid, skillval, Chance, chancemodi);
}
} else {
_log(SKILLS__GAIN, "Skill %d at value %d cannot increase due to maxmum %d", skillid, skillval, maxskill);
Log.Out(Logs::Detail, Logs::Skills, "Skill %d at value %d cannot increase due to maxmum %d", skillid, skillval, maxskill);
}
return false;
}
@@ -2259,10 +2250,10 @@ void Client::CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill) {
if(zone->random.Real(0,100) < Chance) { // if they make the roll
IncreaseLanguageSkill(langid); // increase the language skill by 1
_log(SKILLS__GAIN, "Language %d at value %d successfully gain with %.4f%%chance", langid, LangSkill, Chance);
Log.Out(Logs::Detail, Logs::Skills, "Language %d at value %d successfully gain with %.4f%%chance", langid, LangSkill, Chance);
}
else
_log(SKILLS__GAIN, "Language %d at value %d failed to gain with %.4f%%chance", langid, LangSkill, Chance);
Log.Out(Logs::Detail, Logs::Skills, "Language %d at value %d failed to gain with %.4f%%chance", langid, LangSkill, Chance);
}
}
@@ -2361,7 +2352,7 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(SkillUseTypes skillid, uint16
Save();
LogFile->write(EQEmuLog::Normal, "Reset %s's caster specialization skills to 1. "
Log.Out(Logs::General, Logs::Normal, "Reset %s's caster specialization skills to 1. "
"Too many specializations skills were above 50.", GetCleanName());
}
@@ -2540,7 +2531,7 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){
}
else {
if (!GetFeigned() && (ComparativeDistance(bindmob->GetPosition(), m_Position) <= 400)) {
if (!GetFeigned() && (DistanceSquared(bindmob->GetPosition(), m_Position) <= 400)) {
// send bindmob bind done
if(!bindmob->IsAIControlled() && bindmob != this ) {
@@ -3179,7 +3170,7 @@ void Client::Insight(uint32 t_id)
Message(0,"This ability can only be used on NPCs.");
return;
}
if (Distance(static_cast<xyz_location>(m_Position), static_cast<xyz_location>(who->GetPosition())) > 200)
if (Distance(static_cast<glm::vec3>(m_Position), static_cast<glm::vec3>(who->GetPosition())) > 200)
{
Message(0,"You must get closer to your target!");
return;
@@ -3498,37 +3489,6 @@ void Client::Insight(uint32 t_id)
Message(0,"Your target is a level %i %s. It appears %s and %s for its level. It seems %s",who->GetLevel(),GetEQClassName(who->GetClass(),1),dmg,hitpoints,resists);
}
void Client::ChangeSQLLog(const char *file) {
if(SQL_log != nullptr) {
fclose(SQL_log);
SQL_log = nullptr;
}
if(file != nullptr) {
if(strstr(file, "..") != nullptr) {
Message(13, ".. is forbibben in SQL log file names.");
return;
}
char buf[512];
snprintf(buf, 511, "%s%s", SQL_LOG_PATH, file);
buf[511] = '\0';
SQL_log = fopen(buf, "a");
if(SQL_log == nullptr) {
Message(13, "Unable to open SQL log file: %s\n", strerror(errno));
}
}
}
void Client::LogSQL(const char *fmt, ...) {
if(SQL_log == nullptr)
return;
va_list argptr;
va_start(argptr, fmt);
vfprintf(SQL_log, fmt, argptr );
fputc('\n', SQL_log);
va_end(argptr);
}
void Client::GetGroupAAs(GroupLeadershipAA_Struct *into) const {
memcpy(into, &m_pp.leader_abilities.group, sizeof(GroupLeadershipAA_Struct));
}
@@ -3839,37 +3799,35 @@ void Client::SendWindow(uint32 PopupID, uint32 NegativeID, uint32 Buttons, const
void Client::KeyRingLoad()
{
std::string query = StringFormat("SELECT item_id FROM keyring "
"WHERE char_id = '%i' ORDER BY item_id", character_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
std::cerr << "Error in Client::KeyRingLoad query '" << query << "' " << results.ErrorMessage() << std::endl;
"WHERE char_id = '%i' ORDER BY item_id", character_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return;
}
}
for (auto row = results.begin(); row != results.end(); ++row)
keyring.push_back(atoi(row[0]));
for (auto row = results.begin(); row != results.end(); ++row)
keyring.push_back(atoi(row[0]));
}
void Client::KeyRingAdd(uint32 item_id)
{
if(0==item_id)
return;
return;
bool found = KeyRingCheck(item_id);
if (found)
return;
return;
std::string query = StringFormat("INSERT INTO keyring(char_id, item_id) VALUES(%i, %i)", character_id, item_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
std::cerr << "Error in Doors::HandleClick query '" << query << "' " << results.ErrorMessage() << std::endl;
return;
}
std::string query = StringFormat("INSERT INTO keyring(char_id, item_id) VALUES(%i, %i)", character_id, item_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return;
}
Message(4,"Added to keyring.");
Message(4,"Added to keyring.");
keyring.push_back(item_id);
keyring.push_back(item_id);
}
bool Client::KeyRingCheck(uint32 item_id)
@@ -3901,15 +3859,14 @@ void Client::KeyRingList()
bool Client::IsDiscovered(uint32 itemid) {
std::string query = StringFormat("SELECT count(*) FROM discovered_items WHERE item_id = '%lu'", itemid);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
std::cerr << "Error in IsDiscovered query '" << query << "' " << results.ErrorMessage() << std::endl;
return false;
}
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return false;
}
auto row = results.begin();
if (!atoi(row[0]))
return false;
if (!atoi(row[0]))
return false;
return true;
}
@@ -3917,9 +3874,9 @@ bool Client::IsDiscovered(uint32 itemid) {
void Client::DiscoverItem(uint32 itemid) {
std::string query = StringFormat("INSERT INTO discovered_items "
"SET item_id = %lu, char_name = '%s', "
"discovered_date = UNIX_TIMESTAMP(), account_status = %i",
itemid, GetName(), Admin());
"SET item_id = %lu, char_name = '%s', "
"discovered_date = UNIX_TIMESTAMP(), account_status = %i",
itemid, GetName(), Admin());
auto results = database.QueryDatabase(query);
parse->EventPlayer(EVENT_DISCOVER_ITEM, this, "", itemid);
@@ -4065,7 +4022,7 @@ bool Client::GroupFollow(Client* inviter) {
group->UpdateGroupAAs();
//Invite the inviter into the group first.....dont ask
if (inviter->GetClientVersion() < EQClientSoD)
if (inviter->GetClientVersion() < ClientVersion::SoD)
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
GroupJoin_Struct* outgj = (GroupJoin_Struct*)outapp->pBuffer;
@@ -4111,13 +4068,13 @@ bool Client::GroupFollow(Client* inviter) {
return false;
}
if (GetClientVersion() >= EQClientSoD)
if (GetClientVersion() >= ClientVersion::SoD)
{
SendGroupJoinAcknowledge();
}
// Temporary hack for SoD, as things seem to work quite differently
if (inviter->IsClient() && inviter->GetClientVersion() >= EQClientSoD)
if (inviter->IsClient() && inviter->GetClientVersion() >= ClientVersion::SoD)
{
database.RefreshGroupFromDB(inviter);
}
@@ -4351,7 +4308,7 @@ void Client::IncrementAggroCount() {
if (AggroCount == 1)
SavedRaidRestTimer = rest_timer.GetRemainingTime();
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RestState, 1);
char *Buffer = (char *)outapp->pBuffer;
@@ -4396,7 +4353,7 @@ void Client::DecrementAggroCount() {
rest_timer.Start(time_until_rest);
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RestState, 5);
char *Buffer = (char *)outapp->pBuffer;
@@ -4548,14 +4505,14 @@ void Client::HandleLDoNOpen(NPC *target)
{
if(target->GetClass() != LDON_TREASURE)
{
LogFile->write(EQEmuLog::Debug, "%s tried to open %s but %s was not a treasure chest.",
Log.Out(Logs::General, Logs::None, "%s tried to open %s but %s was not a treasure chest.",
GetName(), target->GetName(), target->GetName());
return;
}
if(ComparativeDistanceNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
if(DistanceSquaredNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse))
{
LogFile->write(EQEmuLog::Debug, "%s tried to open %s but %s was out of range",
Log.Out(Logs::General, Logs::None, "%s tried to open %s but %s was out of range",
GetName(), target->GetName(), target->GetName());
Message(13, "Treasure chest out of range.");
return;
@@ -4806,11 +4763,11 @@ void Client::SummonAndRezzAllCorpses()
Message(clientMessageYellow, "All your corpses have been summoned to your feet and have received a 100% resurrection.");
}
void Client::SummonAllCorpses(const xyz_heading& position)
void Client::SummonAllCorpses(const glm::vec4& position)
{
auto summonLocation = position;
if(position.isOrigin() && position.m_Heading == 0.0f)
summonLocation = GetPosition();
auto summonLocation = position;
if(IsOrigin(position) && position.w == 0.0f)
summonLocation = GetPosition();
ServerPacket *Pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct));
@@ -5285,50 +5242,49 @@ void Client::SendRewards()
{
std::vector<ClientReward> rewards;
std::string query = StringFormat("SELECT reward_id, amount "
"FROM account_rewards "
"WHERE account_id = %i "
"ORDER BY reward_id", AccountID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error in Client::SendRewards(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
"FROM account_rewards "
"WHERE account_id = %i "
"ORDER BY reward_id", AccountID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return;
}
}
for (auto row = results.begin(); row != results.end(); ++row) {
ClientReward cr;
cr.id = atoi(row[0]);
cr.amount = atoi(row[1]);
rewards.push_back(cr);
}
for (auto row = results.begin(); row != results.end(); ++row) {
ClientReward cr;
cr.id = atoi(row[0]);
cr.amount = atoi(row[1]);
rewards.push_back(cr);
}
if(rewards.size() == 0)
return;
return;
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(InternalVeteranReward) * rewards.size()));
uchar *data = vetapp->pBuffer;
for(int i = 0; i < rewards.size(); ++i) {
InternalVeteranReward *ivr = (InternalVeteranReward*)data;
ivr->claim_id = rewards[i].id;
ivr->number_available = rewards[i].amount;
auto iter = zone->VeteranRewards.begin();
for (;iter != zone->VeteranRewards.end(); ++iter)
if((*iter).claim_id == rewards[i].id)
break;
uchar *data = vetapp->pBuffer;
for(int i = 0; i < rewards.size(); ++i) {
InternalVeteranReward *ivr = (InternalVeteranReward*)data;
ivr->claim_id = rewards[i].id;
ivr->number_available = rewards[i].amount;
auto iter = zone->VeteranRewards.begin();
for (;iter != zone->VeteranRewards.end(); ++iter)
if((*iter).claim_id == rewards[i].id)
break;
if(iter != zone->VeteranRewards.end()) {
InternalVeteranReward ivro = (*iter);
ivr->claim_count = ivro.claim_count;
for(int x = 0; x < ivro.claim_count; ++x) {
ivr->items[x].item_id = ivro.items[x].item_id;
ivr->items[x].charges = ivro.items[x].charges;
strcpy(ivr->items[x].item_name, ivro.items[x].item_name);
}
}
if(iter != zone->VeteranRewards.end()) {
InternalVeteranReward ivro = (*iter);
ivr->claim_count = ivro.claim_count;
for(int x = 0; x < ivro.claim_count; ++x) {
ivr->items[x].item_id = ivro.items[x].item_id;
ivr->items[x].charges = ivro.items[x].charges;
strcpy(ivr->items[x].item_name, ivro.items[x].item_name);
}
}
data += sizeof(InternalVeteranReward);
}
data += sizeof(InternalVeteranReward);
}
FastQueuePacket(&vetapp);
FastQueuePacket(&vetapp);
}
bool Client::TryReward(uint32 claim_id) {
@@ -5354,20 +5310,19 @@ bool Client::TryReward(uint32 claim_id) {
char errbuf[MYSQL_ERRMSG_SIZE];
std::string query = StringFormat("SELECT amount FROM account_rewards "
"WHERE account_id = %i AND reward_id = %i",
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
"WHERE account_id = %i AND reward_id = %i",
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return false;
}
}
if (results.RowCount() == 0)
return false;
if (results.RowCount() == 0)
return false;
auto row = results.begin();
auto row = results.begin();
uint32 amt = atoi(row[0]);
uint32 amt = atoi(row[0]);
if(amt == 0)
return false;
@@ -5380,50 +5335,46 @@ bool Client::TryReward(uint32 claim_id) {
return false;
if(amt == 1) {
query = StringFormat("DELETE FROM account_rewards "
"WHERE account_id = %i AND reward_id = %i",
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
query = StringFormat("DELETE FROM account_rewards "
"WHERE account_id = %i AND reward_id = %i",
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
}
else {
query = StringFormat("UPDATE account_rewards SET amount = (amount-1) "
"WHERE account_id = %i AND reward_id = %i",
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
query = StringFormat("UPDATE account_rewards SET amount = (amount-1) "
"WHERE account_id = %i AND reward_id = %i",
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
}
InternalVeteranReward ivr = (*iter);
ItemInst *claim = database.CreateItem(ivr.items[0].item_id, ivr.items[0].charges);
if(!claim) {
Save();
return true;
Save();
return true;
}
bool lore_conflict = CheckLoreConflict(claim->GetItem());
bool lore_conflict = CheckLoreConflict(claim->GetItem());
for(int y = 1; y < 8; y++)
if(ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) {
ItemInst *item_temp = database.CreateItem(ivr.items[y].item_id, ivr.items[y].charges);
if(item_temp) {
if(CheckLoreConflict(item_temp->GetItem())) {
lore_conflict = true;
DuplicateLoreMessage(ivr.items[y].item_id);
}
claim->PutItem(y-1, *item_temp);
}
}
for(int y = 1; y < 8; y++)
if(ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) {
ItemInst *item_temp = database.CreateItem(ivr.items[y].item_id, ivr.items[y].charges);
if(item_temp) {
if(CheckLoreConflict(item_temp->GetItem())) {
lore_conflict = true;
DuplicateLoreMessage(ivr.items[y].item_id);
}
claim->PutItem(y-1, *item_temp);
}
}
if(lore_conflict) {
safe_delete(claim);
return true;
}
if(lore_conflict) {
safe_delete(claim);
return true;
}
PutItemInInventory(free_slot, *claim);
SendItemPacket(free_slot, claim, ItemPacketTrade);
PutItemInInventory(free_slot, *claim);
SendItemPacket(free_slot, claim, ItemPacketTrade);
Save();
return true;
@@ -6187,7 +6138,7 @@ void Client::DragCorpses()
Mob *corpse = entity_list.GetMob(It->second);
if (corpse && corpse->IsPlayerCorpse() &&
(ComparativeDistanceNoZ(m_Position, corpse->GetPosition()) <= RuleR(Character, DragCorpseDistance)))
(DistanceSquaredNoZ(m_Position, corpse->GetPosition()) <= RuleR(Character, DragCorpseDistance)))
continue;
if (!corpse || !corpse->IsPlayerCorpse() ||
@@ -6207,7 +6158,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
PetRecord record;
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
{
LogFile->write(EQEmuLog::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id);
Log.Out(Logs::General, Logs::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id);
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
return;
}
@@ -6221,7 +6172,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
const NPCType *npc_type = database.GetNPCType(pet.npc_id);
if(npc_type == nullptr) {
LogFile->write(EQEmuLog::Error, "Unknown npc type for doppelganger spell id: %d", spell_id);
Log.Out(Logs::General, Logs::Error, "Unknown npc type for doppelganger spell id: %d", spell_id);
Message(0,"Unable to find pet!");
return;
}
@@ -6274,11 +6225,11 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
if(summon_count > MAX_SWARM_PETS)
summon_count = MAX_SWARM_PETS;
static const xy_location swarmPetLocations[MAX_SWARM_PETS] = {
{5, 5}, {-5, 5}, {5, -5}, {-5, -5},
{10, 10}, {-10, 10}, {10, -10}, {-10, -10},
{8, 8}, {-8, 8}, {8, -8}, {-8, -8}
};
static const glm::vec2 swarmPetLocations[MAX_SWARM_PETS] = {
glm::vec2(5, 5), glm::vec2(-5, 5), glm::vec2(5, -5), glm::vec2(-5, -5),
glm::vec2(10, 10), glm::vec2(-10, 10), glm::vec2(10, -10), glm::vec2(-10, -10),
glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8)
};
while(summon_count > 0) {
NPCType *npc_dup = nullptr;
@@ -6290,7 +6241,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
NPC* npca = new NPC(
(npc_dup!=nullptr)?npc_dup:npc_type, //make sure we give the NPC the correct data pointer
0,
GetPosition()+swarmPetLocations[summon_count],
GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f),
FlyMode3);
if(!npca->GetSwarmInfo()){
@@ -6805,7 +6756,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
if(use_window) {
if(final_stats.size() < 4096)
{
uint32 Buttons = (client->GetClientVersion() < EQClientSoD) ? 0 : 1;
uint32 Buttons = (client->GetClientVersion() < ClientVersion::SoD) ? 0 : 1;
client->SendWindow(0, POPUPID_UPDATE_SHOWSTATSWINDOW, Buttons, "Cancel", "Update", 0, 1, this, "", "%s", final_stats.c_str());
goto Extra_Info;
}
@@ -6841,7 +6792,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
}
void Client::SendAltCurrencies() {
if(GetClientVersion() >= EQClientSoF) {
if(GetClientVersion() >= ClientVersion::SoF) {
uint32 count = zone->AlternateCurrencies.size();
if(count == 0) {
return;
@@ -7324,15 +7275,14 @@ void Client::SendMercPersonalInfo()
stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size();
if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES)
{
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: SendMercPersonalInfo Cancelled: (%i) (%i) (%i)", stancecount, mercCount, mercTypeCount);
Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo canceled: (%i) (%i) (%i)", stancecount, mercCount, mercTypeCount);
SendMercMerchantResponsePacket(0);
return;
}
if(mercData)
{
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= ClientVersion::RoF)
{
if (mercCount > 0)
{
@@ -7419,15 +7369,13 @@ void Client::SendMercPersonalInfo()
return;
}
}
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: SendMercPersonalInfo Send Successful");
Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo Send Successful");
SendMercMerchantResponsePacket(0);
}
else
{
if (MERC_DEBUG > 0)
Message(7, "Mercenary Debug: SendMercPersonalInfo Send Failed Due to no MercData for %i", GetMercInfo().MercTemplateID);
Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo Send Failed Due to no MercData for %i", GetMercInfo().MercTemplateID);
}
}
@@ -7801,26 +7749,24 @@ void Client::LoadAccountFlags()
accountflags.clear();
std::string query = StringFormat("SELECT p_flag, p_value "
"FROM account_flags WHERE p_accid = '%d'",
account_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
std::cerr << "Error in LoadAccountFlags query '" << query << "' " << results.ErrorMessage() << std::endl;
return;
}
"FROM account_flags WHERE p_accid = '%d'",
account_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return;
}
for (auto row = results.begin(); row != results.end(); ++row)
accountflags[row[0]] = row[1];
for (auto row = results.begin(); row != results.end(); ++row)
accountflags[row[0]] = row[1];
}
void Client::SetAccountFlag(std::string flag, std::string val) {
std::string query = StringFormat("REPLACE INTO account_flags (p_accid, p_flag, p_value) "
"VALUES( '%d', '%s', '%s')",
account_id, flag.c_str(), val.c_str());
auto results = database.QueryDatabase(query);
std::string query = StringFormat("REPLACE INTO account_flags (p_accid, p_flag, p_value) "
"VALUES( '%d', '%s', '%s')",
account_id, flag.c_str(), val.c_str());
auto results = database.QueryDatabase(query);
if(!results.Success()) {
std::cerr << "Error in SetAccountFlags query '" << query << "' " << results.ErrorMessage() << std::endl;
return;
}
@@ -8158,7 +8104,7 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
{
if(!item) { return; }
uint32 cons_mod = 180;
uint32 cons_mod = 180;
int32 metabolism_bonus = spellbonuses.Metabolism + itembonuses.Metabolism + aabonuses.Metabolism;
@@ -8169,36 +8115,36 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
if(type == ItemTypeFood)
{
int hchange = item->CastTime * cons_mod;
hchange = mod_food_value(item, hchange);
int hchange = item->CastTime * cons_mod;
hchange = mod_food_value(item, hchange);
if(hchange < 0) { return; }
if(hchange < 0) { return; }
m_pp.hunger_level += hchange;
DeleteItemInInventory(slot, 1, false);
m_pp.hunger_level += hchange;
DeleteItemInInventory(slot, 1, false);
if(!auto_consume) //no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name);
if(!auto_consume) //no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name);
#if EQDEBUG >= 5
LogFile->write(EQEmuLog::Debug, "Eating from slot:%i", (int)slot);
Log.Out(Logs::General, Logs::None, "Eating from slot:%i", (int)slot);
#endif
}
else
{
int tchange = item->CastTime * cons_mod;
tchange = mod_drink_value(item, tchange);
int tchange = item->CastTime * cons_mod;
tchange = mod_drink_value(item, tchange);
if(tchange < 0) { return; }
if(tchange < 0) { return; }
m_pp.thirst_level += tchange;
DeleteItemInInventory(slot, 1, false);
m_pp.thirst_level += tchange;
DeleteItemInInventory(slot, 1, false);
if(!auto_consume) //no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name);
if(!auto_consume) //no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name);
#if EQDEBUG >= 5
LogFile->write(EQEmuLog::Debug, "Drinking from slot:%i", (int)slot);
Log.Out(Logs::General, Logs::None, "Drinking from slot:%i", (int)slot);
#endif
}
}
@@ -8236,15 +8182,15 @@ void Client::PlayMP3(const char* fname)
void Client::ExpeditionSay(const char *str, int ExpID) {
std::string query = StringFormat("SELECT `player_name` FROM `cust_inst_players` "
"WHERE `inst_id` = %i", ExpID);
auto results = database.QueryDatabase(query);
"WHERE `inst_id` = %i", ExpID);
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
if(results.RowCount() == 0) {
this->Message(14, "You say to the expedition, '%s'", str);
return;
}
this->Message(14, "You say to the expedition, '%s'", str);
return;
}
for(auto row = results.begin(); row != results.end(); ++row) {
const char* charName = row[0];
@@ -8321,12 +8267,10 @@ std::string Client::TextLink::GenerateLink()
if ((m_Link.length() == 0) || (m_Link.length() > 250)) {
m_Error = true;
m_Link = "<LINKER ERROR>";
_log(CHANNELS__ERROR, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})",
Log.Out(Logs::General, Logs::Error, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})",
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
#if EQDEBUG >= 5
_log(CHANNELS__ERROR, ">> LinkBody: %s", m_LinkBody.c_str());
_log(CHANNELS__ERROR, ">> LinkText: %s", m_LinkText.c_str());
#endif
Log.Out(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str());
Log.Out(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str());
}
return m_Link;
@@ -8354,8 +8298,8 @@ void Client::TextLink::generate_body()
RoF2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X" (56)
RoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (55)
SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50)
6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45)
SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50)
6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45)
*/
memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct));