merge from upstream

This commit is contained in:
Arthur Ice
2014-08-28 15:49:16 -07:00
90 changed files with 12579 additions and 3526 deletions
+217 -125
View File
@@ -62,8 +62,9 @@ extern volatile bool RunLoops;
#include "client_logs.h"
#include "guild_mgr.h"
#include "quest_parser_collection.h"
#include "queryserv.h"
extern QueryServ* QServ;
extern EntityList entity_list;
extern Zone* zone;
extern volatile bool ZoneLoaded;
@@ -324,7 +325,7 @@ Client::Client(EQStreamInterface* ieqs)
initial_respawn_selection = 0;
alternate_currency_loaded = false;
EngagedRaidTarget = false;
SavedRaidRestTimer = 0;
}
@@ -629,6 +630,9 @@ bool Client::Save(uint8 iCommitNow) {
return false;
}
/* Mirror Character Data */
database.StoreCharacterLookup(this->CharacterID());
return true;
}
@@ -805,8 +809,8 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
}
if(RuleB(QueryServ, PlayerChatLogging)) {
/* Logs Player Chat */
if (RuleB(QueryServ, PlayerLogChat)) {
ServerPacket* pack = new ServerPacket(ServerOP_Speech, sizeof(Server_Speech_Struct) + strlen(message) + 1);
Server_Speech_Struct* sem = (Server_Speech_Struct*) pack->pBuffer;
@@ -841,7 +845,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
switch(chan_num)
{
case 0: { // GuildChat
case 0: { /* Guild Chat */
if (!IsInAGuild())
Message_StringID(MT_DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild.
else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK))
@@ -850,7 +854,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
Message(0, "Error: World server disconnected");
break;
}
case 2: { // GroupChat
case 2: { /* Group Chat */
Raid* raid = entity_list.GetRaidByClient(this);
if(raid) {
raid->RaidGroupSay((const char*) message, this);
@@ -863,14 +867,14 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
break;
}
case 15: { //raid say
case 15: { /* Raid Say */
Raid* raid = entity_list.GetRaidByClient(this);
if(raid){
raid->RaidSay((const char*) message, this);
}
break;
}
case 3: { // Shout
case 3: { /* Shout */
Mob *sender = this;
if (GetPet() && GetPet()->FindType(SE_VoiceGraft))
sender = GetPet();
@@ -878,7 +882,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
break;
}
case 4: { // Auction
case 4: { /* Auction */
if(RuleB(Chat, ServerWideAuction))
{
if(!global_channel_timer.Check())
@@ -917,7 +921,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
break;
}
case 5: { // OOC
case 5: { /* OOC */
if(RuleB(Chat, ServerWideOOC))
{
if(!global_channel_timer.Check())
@@ -964,15 +968,15 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
}
break;
}
case 6: // Broadcast
case 11: { // GMSay
case 6: /* Broadcast */
case 11: { /* GM Say */
if (!(admin >= 80))
Message(0, "Error: Only GMs can use this channel");
else if (!worldserver.SendChannelMessage(this, targetname, chan_num, 0, language, message))
Message(0, "Error: World server disconnected");
break;
}
case 7: { // Tell
case 7: { /* Tell */
if(!global_channel_timer.Check())
{
if(strlen(targetname) == 0)
@@ -1020,7 +1024,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
Message(0, "Error: World server disconnected");
break;
}
case 8: { // /say
case 8: { /* Say */
if(message[0] == COMMAND_CHAR) {
if(command_dispatch(this, message) == -2) {
if(parse->PlayerHasQuestSub(EVENT_COMMAND)) {
@@ -1029,7 +1033,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
Message(13, "Command '%s' not recognized.", message);
}
} else {
if(!RuleB(Chat, SuppressCommandErrors))
if(!RuleB(Chat, SuppressCommandErrors))
Message(13, "Command '%s' not recognized.", message);
}
}
@@ -4060,25 +4064,40 @@ 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;
}
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
auto row = results.begin();
return atoi(row[0]) != 0;
if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT count(*) FROM discovered_items WHERE item_id = '%lu'", itemid), errbuf, &result))
{
row = mysql_fetch_row(result);
if (atoi(row[0]))
{
mysql_free_result(result);
safe_delete_array(query);
return true;
}
}
else
{
std::cerr << "Error in IsDiscovered query '" << query << "' " << errbuf << std::endl;
}
mysql_free_result(result);
safe_delete_array(query);
return false;
}
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());
auto results = database.QueryDatabase(query);
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
if (database.RunQuery(query,MakeAnyLenString(&query, "INSERT INTO discovered_items SET item_id=%lu, char_name='%s', discovered_date=UNIX_TIMESTAMP(), account_status=%i", itemid, GetName(), Admin()), errbuf, &result))
{
mysql_free_result(result);
}
safe_delete_array(query);
parse->EventPlayer(EVENT_DISCOVER_ITEM, this, "", itemid);
}
@@ -4315,15 +4334,15 @@ void Client::IncrementAggroCount() {
if(!RuleI(Character, RestRegenPercent))
return;
// If we already had aggro before this method was called, the combat indicator should already be up for SoF clients,
// so we don't need to send it again.
//
if(AggroCount > 1)
return;
// Pause the rest timer
if (AggroCount == 1)
if (AggroCount == 1)
SavedRaidRestTimer = rest_timer.GetRemainingTime();
if(GetClientVersion() >= EQClientSoF) {
@@ -4368,9 +4387,9 @@ void Client::DecrementAggroCount() {
time_until_rest = RuleI(Character, RestRegenTimeToActivate) * 1000;
}
}
rest_timer.Start(time_until_rest);
if(GetClientVersion() >= EQClientSoF) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RestState, 5);
@@ -4475,7 +4494,7 @@ void Client::SendRespawnBinds()
int num_options = respawn_options.size();
uint32 PacketLength = 17 + (26 * num_options); //Header size + per-option invariant size
std::list<RespawnOption>::iterator itr;
RespawnOption* opt;
@@ -5261,22 +5280,32 @@ const bool Client::IsMQExemptedArea(uint32 zoneID, float x, float y, float z) co
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());
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT reward_id, amount FROM"
" account_rewards WHERE account_id=%i ORDER by reward_id", AccountID()),
errbuf,&result))
{
while((row = mysql_fetch_row(result)))
{
ClientReward cr;
cr.id = atoi(row[0]);
cr.amount = atoi(row[1]);
rewards.push_back(cr);
}
mysql_free_result(result);
safe_delete_array(query);
}
else
{
LogFile->write(EQEMuLog::Error, "Error in Client::SendRewards(): %s (%s)", query, errbuf);
safe_delete_array(query);
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);
}
if(rewards.size() > 0)
{
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(InternalVeteranReward) * rewards.size()));
@@ -5336,54 +5365,88 @@ bool Client::TryReward(uint32 claim_id)
}
if(free_slot == 0xFFFFFFFF)
return false;
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());
return false;
}
if (results.RowCount() == 0)
return false;
uint32 amt = 0;
auto row = results.begin();
amt = atoi(row[0]);
if(amt == 0)
return false;
auto iter = zone->VeteranRewards.begin();
for (; iter != zone->VeteranRewards.end(); ++iter)
if((*iter).claim_id == claim_id)
break;
if(iter == zone->VeteranRewards.end())
return false;
if(amt == 1)
{
query = StringFormat("DELETE FROM account_rewards "
"WHERE account_id=%i AND reward_id=%i",
AccountID(), claim_id);
results = database.QueryDatabase(query);
if(!results.ErrorMessage().c_str())
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return false;
}
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
uint32 amt = 0;
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT amount FROM"
" account_rewards WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id),
errbuf,&result))
{
row = mysql_fetch_row(result);
if(row)
{
amt = atoi(row[0]);
}
else
{
mysql_free_result(result);
safe_delete_array(query);
return false;
}
mysql_free_result(result);
safe_delete_array(query);
}
else
{
query = StringFormat("UPDATE account_rewards SET amount=(amount-1) "
"WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id);
results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query, errbuf);
safe_delete_array(query);
return false;
}
if(amt == 0)
{
return false;
}
std::list<InternalVeteranReward>::iterator iter = zone->VeteranRewards.begin();
while(iter != zone->VeteranRewards.end())
{
if((*iter).claim_id == claim_id)
{
break;
}
++iter;
}
if(iter == zone->VeteranRewards.end())
{
return false;
}
if(amt == 1)
{
if(!database.RunQuery(query,MakeAnyLenString(&query,"DELETE FROM"
" account_rewards WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id),
errbuf))
{
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query, errbuf);
safe_delete_array(query);
}
else
{
safe_delete_array(query);
}
}
else
{
if(!database.RunQuery(query,MakeAnyLenString(&query,"UPDATE account_rewards SET amount=(amount-1)"
" WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id),
errbuf))
{
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query, errbuf);
safe_delete_array(query);
}
else
{
safe_delete_array(query);
}
}
InternalVeteranReward ivr = (*iter);
@@ -6862,8 +6925,18 @@ void Client::SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount)
SendAlternateCurrencyValue(currency_id);
}
void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount)
void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method)
{
/* Added via Quest, rest of the logging methods may be done inline due to information available in that area of the code */
if (method == 1){
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
std::string event_desc = StringFormat("Added via Quest :: Cursor to Item :: alt_currency_id:%i amount:%i in zoneid:%i instid:%i", currency_id, this->GetZoneID(), this->GetInstanceID());
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
}
}
if(amount == 0) {
return;
}
@@ -7601,7 +7674,7 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui
tmpValue = current_value + mod + npc_value[i];
int16 FactionModPct = spellbonuses.FactionModPct + itembonuses.FactionModPct + aabonuses.FactionModPct;
tmpValue += (tmpValue * FactionModPct) / 100;
tmpValue += (tmpValue * FactionModPct) / 100;
// Make sure faction hits don't go to GMs...
if (m_pp.gm==1 && (tmpValue < current_value)) {
@@ -7738,30 +7811,41 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalval
void Client::LoadAccountFlags()
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
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;
}
for (auto row = results.begin(); row != results.end(); ++row) {
std::string fname(row[0]);
std::string fval(row[1]);
accountflags[fname] = fval;
}
MakeAnyLenString(&query, "SELECT p_flag, p_value FROM account_flags WHERE p_accid = '%d'", account_id);
if(database.RunQuery(query, strlen(query), errbuf, &result))
{
while(row = mysql_fetch_row(result))
{
std::string fname(row[0]);
std::string fval(row[1]);
accountflags[fname] = fval;
}
mysql_free_result(result);
}
else
{
std::cerr << "Error in LoadAccountFlags query '" << query << "' " << errbuf << std::endl;
}
safe_delete_array(query);
}
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);
if(!results.Success())
std::cerr << "Error in SetAccountFlags query '" << query << "' " << results.ErrorMessage() << std::endl;
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MakeAnyLenString(&query, "REPLACE INTO account_flags (p_accid, p_flag, p_value) VALUES( '%d', '%s', '%s')", account_id, flag.c_str(), val.c_str());
if(!database.RunQuery(query, strlen(query), errbuf))
{
std::cerr << "Error in SetAccountFlags query '" << query << "' " << errbuf << std::endl;
}
safe_delete_array(query);
accountflags[flag] = val;
}
@@ -7866,7 +7950,7 @@ void Client::TryItemTimer(int slot)
}
++it_iter;
}
if(slot > EmuConstants::EQUIPMENT_END) {
return;
}
@@ -8170,21 +8254,29 @@ void Client::PlayMP3(const char* fname)
safe_delete(outapp);
}
void Client::ExpeditionSay(const char *str, int expID) {
void Client::ExpeditionSay(const char *str, int ExpID) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
std::string query = StringFormat("SELECT `player_name` FROM "
"`cust_inst_players` WHERE "
"`inst_id` = %i", expID);
auto results = database.QueryDatabase(query);
if (!results.Success())
if (!database.RunQuery(query,MakeAnyLenString(&query, "SELECT `player_name` FROM `cust_inst_players` WHERE `inst_id` = %i", ExpID),errbuf,&result)){
safe_delete_array(query);
return;
this->Message(14, "You say to the expedition, '%s'", str);
for (auto row = results.begin(); row != results.end(); ++row) {
const char* charName = row[0];
if(strcmp(charName, this->GetCleanName()) != 0)
worldserver.SendEmoteMessage(charName, 0, 0, 14, "%s says to the expedition, '%s'", this->GetCleanName(), str);
}
safe_delete_array(query);
if(result)
this->Message(14, "You say to the expedition, '%s'", str);
while((row = mysql_fetch_row(result))) {
const char* CharName = row[0];
if(strcmp(CharName, this->GetCleanName()) != 0)
worldserver.SendEmoteMessage(CharName, 0, 0, 14, "%s says to the expedition, '%s'", this->GetCleanName(), str);
// ChannelList->CreateChannel(ChannelName, ChannelOwner, ChannelPassword, true, atoi(row[3]));
}
mysql_free_result(result);
}