Core/Players: convert SMSG_SETUP_CURRENCY to packet class and backportet currency handling from master branch

This commit is contained in:
Ovahlord committed 2020-01-05 23:32:23 +01:00
1 parent 61d579601f
commit 2715301823
12 files changed
+195 -97

No files matched your search

@@ -0,0 +1,7 @@
ALTER TABLE `character_currency`
CHANGE `guid` `CharacterGuid` INT(10) UNSIGNED NOT NULL,
CHANGE `currency` `Currency` SMALLINT(5) UNSIGNED NOT NULL,
CHANGE `total_count` `Quantity` INT(10) UNSIGNED NOT NULL,
CHANGE `week_count` `WeeklyQuantity` INT(10) UNSIGNED NOT NULL,
CHANGE `season_count` `TrackedQuantity` INT(10) UNSIGNED NOT NULL,
ADD COLUMN `Flags` TINYINT(2) UNSIGNED NOT NULL AFTER `TrackedQuantity`;
@@ -276,9 +276,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
// Currency
PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT currency, week_count, total_count, season_count FROM character_currency WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_PLAYER_CURRENCY, "UPDATE character_currency SET week_count = ?, total_count = ?, season_count = ? WHERE guid = ? AND currency = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_PLAYER_CURRENCY, "REPLACE INTO character_currency (guid, currency, week_count, total_count, season_count) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT Currency, Quantity, WeeklyQuantity, TrackedQuantity, Flags FROM character_currency WHERE CharacterGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_PLAYER_CURRENCY, "UPDATE character_currency SET Quantity = ?, WeeklyQuantity = ?, TrackedQuantity = ?, Flags = ? WHERE CharacterGuid = ? AND Currency = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_PLAYER_CURRENCY, "REPLACE INTO character_currency (CharacterGuid, Currency, Quantity, WeeklyQuantity, TrackedQuantity, Flags) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_CURRENCY, "DELETE FROM character_currency WHERE CharacterGuid = ?", CONNECTION_ASYNC);
// Account data
PrepareStatement(CHAR_SEL_ACCOUNT_DATA, "SELECT type, time, data FROM account_data WHERE accountId = ?", CONNECTION_ASYNC);
@@ -235,6 +235,7 @@ enum CharacterDatabaseStatements : uint32
CHAR_SEL_PLAYER_CURRENCY,
CHAR_UPD_PLAYER_CURRENCY,
CHAR_REP_PLAYER_CURRENCY,
CHAR_DEL_PLAYER_CURRENCY,
CHAR_SEL_ACCOUNT_DATA,
CHAR_REP_ACCOUNT_DATA,
+62 -84
View File
@@ -65,6 +65,7 @@
#include "Mail.h"
#include "MapInstanced.h"
#include "MapManager.h"
#include "MiscPackets.h"
#include "MotionMaster.h"
#include "MovementStructures.h"
#include "ObjectAccessor.h"
@@ -4388,6 +4389,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt32(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_CURRENCY);
stmt->setUInt32(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GIFT);
stmt->setUInt32(0, guid);
trans->Append(stmt);
@@ -7039,9 +7044,10 @@ void Player::_LoadCurrency(PreparedQueryResult result)
PlayerCurrency cur;
cur.state = PLAYERCURRENCY_UNCHANGED;
cur.weekCount = fields[1].GetUInt32();
cur.totalCount = fields[2].GetUInt32();
cur.seasonCount = fields[3].GetUInt32();
cur.Quantity = fields[1].GetUInt32();
cur.WeeklyQuantity = fields[2].GetUInt32();
cur.TrackedQuantity = fields[3].GetUInt32();
cur.Flags = fields[4].GetUInt8();
_currencyStorage.insert(PlayerCurrenciesMap::value_type(currencyID, cur));
@@ -7063,18 +7069,20 @@ void Player::_SaveCurrency(SQLTransaction& trans)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_PLAYER_CURRENCY);
stmt->setUInt32(0, GetGUID().GetCounter());
stmt->setUInt16(1, itr->first);
stmt->setUInt32(2, itr->second.weekCount);
stmt->setUInt32(3, itr->second.totalCount);
stmt->setUInt32(4, 0);
stmt->setUInt32(2, itr->second.Quantity);
stmt->setUInt32(3, itr->second.WeeklyQuantity);
stmt->setUInt32(4, itr->second.TrackedQuantity);
stmt->setUInt8(5, itr->second.Flags);
trans->Append(stmt);
break;
case PLAYERCURRENCY_CHANGED:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PLAYER_CURRENCY);
stmt->setUInt32(0, itr->second.weekCount);
stmt->setUInt32(1, itr->second.totalCount);
stmt->setUInt32(2, itr->second.seasonCount);
stmt->setUInt32(3, GetGUID().GetCounter());
stmt->setUInt16(4, itr->first);
stmt->setUInt32(0, itr->second.Quantity);
stmt->setUInt32(1, itr->second.WeeklyQuantity);
stmt->setUInt32(2, itr->second.TrackedQuantity);
stmt->setUInt8(3, itr->second.Flags);
stmt->setUInt32(4, GetGUID().GetCounter());
stmt->setUInt16(5, itr->first);
trans->Append(stmt);
break;
default:
@@ -7091,47 +7099,28 @@ void Player::SendNewCurrency(uint32 id) const
if (itr == _currencyStorage.end())
return;
ByteBuffer currencyData;
WorldPacket packet(SMSG_INIT_CURRENCY, 4 + (5*4 + 1));
packet.WriteBits(1, 23);
CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(id);
if (!entry) // should never happen
return;
uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
uint32 weekCount = itr->second.weekCount / precision;
uint32 weekCap = GetCurrencyWeekCap(entry) / precision;
WorldPackets::Misc::SetupCurrency packet;
WorldPackets::Misc::SetupCurrency::Record record;
record.Type = entry->ID;
record.Quantity = itr->second.Quantity;
record.WeeklyQuantity = itr->second.WeeklyQuantity;
record.MaxWeeklyQuantity = GetCurrencyWeekCap(entry);
record.TrackedQuantity = itr->second.TrackedQuantity;
record.Flags = itr->second.Flags;
packet.WriteBit(weekCount);
packet.WriteBits(0, 4); // some flags
packet.WriteBit(weekCap);
packet.WriteBit(0); // season total earned
packet.Data.push_back(record);
currencyData << uint32(itr->second.totalCount / precision);
if (weekCap)
currencyData << uint32(weekCap);
//if (seasonTotal)
// currencyData << uint32(seasonTotal / precision);
currencyData << uint32(entry->ID);
if (weekCount)
currencyData << uint32(weekCount);
packet.FlushBits();
packet.append(currencyData);
SendDirectMessage(&packet);
GetSession()->SendPacket(packet.Write());
}
void Player::SendCurrencies() const
{
ByteBuffer currencyData;
WorldPacket packet(SMSG_INIT_CURRENCY, 4 + _currencyStorage.size()*(5*4 + 1));
size_t count_pos = packet.bitwpos();
packet.WriteBits(_currencyStorage.size(), 23);
WorldPackets::Misc::SetupCurrency packet;
size_t count = 0;
for (PlayerCurrenciesMap::const_iterator itr = _currencyStorage.begin(); itr != _currencyStorage.end(); ++itr)
{
CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(itr->first);
@@ -7141,34 +7130,21 @@ void Player::SendCurrencies() const
continue;
uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
uint32 weekCount = itr->second.weekCount / precision;
uint32 weekCap = GetCurrencyWeekCap(entry) / precision;
uint32 seasonCount = itr->second.seasonCount / precision;
bool seasonTotal = entry->Flags & CURRENCY_FLAG_COUNT_SEASON_TOTAL;
packet.WriteBit(weekCount);
packet.WriteBits(0, 4); // some flags
packet.WriteBit(weekCap);
packet.WriteBit(seasonTotal ? 1 : 0); // season total earned
WorldPackets::Misc::SetupCurrency::Record record;
record.Type = entry->ID;
record.Quantity = itr->second.Quantity / precision;
record.WeeklyQuantity = itr->second.WeeklyQuantity / precision;
record.MaxWeeklyQuantity = GetCurrencyWeekCap(entry) / precision;
currencyData << uint32(itr->second.totalCount / precision);
if (weekCap)
currencyData << uint32(weekCap);
if (entry->Flags & CURRENCY_FLAG_COUNT_SEASON_TOTAL)
record.TrackedQuantity = itr->second.TrackedQuantity / precision;
if (seasonTotal)
currencyData << uint32(seasonCount);
currencyData << uint32(entry->ID);
if (weekCount)
currencyData << uint32(weekCount);
++count;
record.Flags = itr->second.state;
packet.Data.push_back(record);
}
packet.FlushBits();
packet.append(currencyData);
packet.PutBits(count_pos, count, 23);
SendDirectMessage(&packet);
SendDirectMessage(packet.Write());
}
void Player::SendPvpRewards() const
@@ -7193,7 +7169,7 @@ uint32 Player::GetCurrency(uint32 id, bool usePrecision) const
CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
return itr->second.totalCount / precision;
return itr->second.Quantity / precision;
}
uint32 Player::GetCurrencyOnWeek(uint32 id, bool usePrecision) const
@@ -7205,7 +7181,7 @@ uint32 Player::GetCurrencyOnWeek(uint32 id, bool usePrecision) const
CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
return itr->second.weekCount / precision;
return itr->second.WeeklyQuantity / precision;
}
uint32 Player::GetCurrencyOnSeason(uint32 id) const
@@ -7214,13 +7190,13 @@ uint32 Player::GetCurrencyOnSeason(uint32 id) const
if (itr == _currencyStorage.end())
return 0;
return itr->second.seasonCount;
return itr->second.TrackedQuantity;
}
bool Player::HasCurrency(uint32 id, uint32 count) const
{
PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
return itr != _currencyStorage.end() && itr->second.totalCount >= count;
return itr != _currencyStorage.end() && itr->second.Quantity >= count;
}
void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bool ignoreMultipliers/* = false*/, bool isRefund/* = false*/)
@@ -7237,24 +7213,25 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bo
int32 precision = currency->Flags & CURRENCY_FLAG_HIGH_PRECISION ? CURRENCY_PRECISION : 1;
uint32 oldTotalCount = 0;
uint32 oldWeekCount = 0;
uint32 seasonCount = 0;
uint32 oldTrackedCount = 0;
bool hasSeasonCount = false;
PlayerCurrenciesMap::iterator itr = _currencyStorage.find(id);
if (itr == _currencyStorage.end())
{
PlayerCurrency cur;
cur.state = PLAYERCURRENCY_NEW;
cur.totalCount = 0;
cur.weekCount = 0;
cur.seasonCount = 0;
cur.Quantity = 0;
cur.WeeklyQuantity = 0;
cur.TrackedQuantity = 0;
cur.Flags = 0;
_currencyStorage[id] = cur;
itr = _currencyStorage.find(id);
}
else
{
oldTotalCount = itr->second.totalCount;
oldWeekCount = itr->second.weekCount;
seasonCount = itr->second.seasonCount;
oldTotalCount = itr->second.Quantity;
oldWeekCount = itr->second.WeeklyQuantity;
oldTrackedCount = itr->second.TrackedQuantity;
}
// count can't be more then weekCap if used (weekCap > 0)
@@ -7311,15 +7288,15 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bo
if (itr->second.state != PLAYERCURRENCY_NEW)
itr->second.state = PLAYERCURRENCY_CHANGED;
itr->second.totalCount = newTotalCount;
itr->second.weekCount = isRefund ? oldWeekCount : newWeekCount;
itr->second.Quantity = newTotalCount;
itr->second.WeeklyQuantity = isRefund ? oldWeekCount : newWeekCount;
if (!isRefund && count > 0)
{
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count);
if (hasSeasonCount)
seasonCount += count;
itr->second.seasonCount = seasonCount;
oldTrackedCount += count;
itr->second.TrackedQuantity = oldTrackedCount;
}
if (currency->Category == CURRENCY_CATEGORY_META_CONQUEST)
@@ -7340,7 +7317,7 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bo
packet.WriteBit(!printLog); // print in log
if (hasSeasonCount)
packet << uint32(seasonCount / precision);
packet << uint32(oldTrackedCount / precision);
packet << uint32(newTotalCount / precision);
packet << uint32(id);
@@ -7358,9 +7335,10 @@ void Player::SetCurrency(uint32 id, uint32 count, bool /*printLog*/ /*= true*/)
{
PlayerCurrency cur;
cur.state = PLAYERCURRENCY_NEW;
cur.totalCount = count;
cur.weekCount = 0;
cur.seasonCount = 0;
cur.Quantity = count;
cur.WeeklyQuantity = 0;
cur.TrackedQuantity = 0;
cur.Flags = 0;
_currencyStorage[id] = cur;
}
}
@@ -7391,7 +7369,7 @@ void Player::ResetCurrencyWeekCap()
for (PlayerCurrenciesMap::iterator itr = _currencyStorage.begin(); itr != _currencyStorage.end(); ++itr)
{
itr->second.weekCount = 0;
itr->second.WeeklyQuantity = 0;
itr->second.state = PLAYERCURRENCY_CHANGED;
}
+5 -4
View File
@@ -204,10 +204,11 @@ enum PlayerCurrencyState
struct PlayerCurrency
{
PlayerCurrencyState state;
uint32 totalCount;
uint32 weekCount;
uint32 seasonCount;
PlayerCurrencyState state;
uint32 Quantity;
uint32 WeeklyQuantity;
uint32 TrackedQuantity;
uint8 Flags;
};
typedef std::unordered_map<uint32, PlayerTalent*> PlayerTalentMap;
@@ -0,0 +1,52 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MiscPackets.h"
#include "Common.h"
WorldPacket const* WorldPackets::Misc::SetupCurrency::Write()
{
_worldPacket.WriteBits(Data.size(), 23);
for (Record const& data : Data)
{
_worldPacket.WriteBit(data.WeeklyQuantity.is_initialized());
_worldPacket.WriteBits(data.Flags, 4);
_worldPacket.WriteBit(data.MaxWeeklyQuantity.is_initialized());
_worldPacket.WriteBit(data.TrackedQuantity.is_initialized());
}
_worldPacket.FlushBits();
for (Record const& data : Data)
{
_worldPacket << uint32(data.Quantity);
if (data.MaxWeeklyQuantity.is_initialized())
_worldPacket << uint32(*data.MaxWeeklyQuantity);
if (data.TrackedQuantity.is_initialized())
_worldPacket << uint32(*data.TrackedQuantity);
_worldPacket << uint32(data.Type);
if (data.WeeklyQuantity.is_initialized())
_worldPacket << uint32(*data.WeeklyQuantity);
}
return &_worldPacket;
}
@@ -0,0 +1,52 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MiscPackets_h__
#define MiscPackets_h__
#include "Packet.h"
#include "ObjectGuid.h"
#include "Optional.h"
namespace WorldPackets
{
namespace Misc
{
class SetupCurrency final : public ServerPacket
{
public:
struct Record
{
int32 Type = 0; // ID from CurrencyTypes.dbc
int32 Quantity = 0;
Optional<int32> WeeklyQuantity; // Currency count obtained this Week.
Optional<int32> MaxWeeklyQuantity; // Weekly Currency cap.
Optional<int32> TrackedQuantity; // Currency count obtained this season.
Optional<int32> MaxQuantity;
uint8 Flags = 0; // 0 = none,
};
SetupCurrency() : ServerPacket(SMSG_SETUP_CURRENCY, 22) { }
WorldPacket const* Write() override;
std::vector<Record> Data;
};
}
}
#endif // MiscPackets_h__
+1 -1
View File
@@ -933,7 +933,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+1 -1
View File
@@ -879,7 +879,7 @@ enum OpcodeServer
SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x4E36,
SMSG_INITIALIZE_FACTIONS = 0x4634,
SMSG_INITIAL_SPELLS = 0x0104,
SMSG_INIT_CURRENCY = 0x15A5,
SMSG_SETUP_CURRENCY = 0x15A5,
SMSG_INIT_WORLD_STATES = 0x4C15,
SMSG_INSPECT = 0x0000,
SMSG_INSPECT_HONOR_STATS = 0x79A5,
+6 -1
View File
@@ -91,7 +91,7 @@ DumpTable const DumpTables[] =
{ "character_achievement_progress", DTT_CHAR_TABLE },
{ "character_action", DTT_CHAR_TABLE },
{ "character_aura", DTT_CHAR_TABLE },
{ "character_currency", DTT_CHAR_TABLE },
{ "character_currency", DTT_CURRENCY },
{ "character_cuf_profiles", DTT_CHAR_TABLE },
{ "character_declinedname", DTT_CHAR_TABLE },
{ "character_equipmentsets", DTT_EQSET_TABLE},
@@ -296,6 +296,11 @@ void PlayerDump::InitializeTables()
MarkDependentColumn(t, "guid", GUID_TYPE_CHAR);
break;
case DTT_CURRENCY:
MarkWhereField(t, "CharacterGuid");
MarkDependentColumn(t, "CharacterGuid", GUID_TYPE_CHAR);
break;
case DTT_EQSET_TABLE:
MarkWhereField(t, "guid");
+3 -2
View File
@@ -31,7 +31,7 @@ enum DumpTableType
// character_action, character_aura, character_homebind,
// character_queststatus, character_queststatus_rewarded, character_reputation,
// character_spell, character_spell_cooldown, character_ticket, character_talent.
// character_cuf_profiles, character_currency
// character_cuf_profiles
DTT_EQSET_TABLE, // <- guid // character_equipmentsets
@@ -49,7 +49,8 @@ enum DumpTableType
DTT_ITEM_GIFT, // <- item guids // character_gifts
DTT_PET, // -> pet guids collection // character_pet
DTT_PET_TABLE // <- pet guids // pet_aura, pet_spell, pet_spell_cooldown
DTT_PET_TABLE, // <- pet guids // pet_aura, pet_spell, pet_spell_cooldown
DTT_CURRENCY // // character_currency
};
enum DumpReturn
+1 -1
View File
@@ -3357,7 +3357,7 @@ void World::ResetDailyQuestsAndRewards()
void World::ResetCurrencyWeekCap()
{
CharacterDatabase.Execute("UPDATE `character_currency` SET `week_count` = 0");
CharacterDatabase.Execute("UPDATE `character_currency` SET `WeeklyQuantity` = 0");
for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if (itr->second->GetPlayer())