mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 05:11:29 +00:00
commit
d9bdcf2aec
@ -4389,6 +4389,19 @@ namespace RoF2
|
|||||||
delete in;
|
delete in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_CrystalCountUpdate)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(CrystalCountUpdate_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(CrystalCountUpdate_Struct, structs::CrystalCountUpdate_Struct);
|
||||||
|
|
||||||
|
OUT(CurrentRadiantCrystals);
|
||||||
|
OUT(CareerRadiantCrystals);
|
||||||
|
OUT(CurrentEbonCrystals);
|
||||||
|
OUT(CareerEbonCrystals);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
// DECODE methods
|
// DECODE methods
|
||||||
|
|
||||||
DECODE(OP_AdventureMerchantSell)
|
DECODE(OP_AdventureMerchantSell)
|
||||||
|
|||||||
@ -141,6 +141,7 @@ E(OP_ZoneEntry)
|
|||||||
E(OP_ZonePlayerToBind)
|
E(OP_ZonePlayerToBind)
|
||||||
E(OP_ZoneServerInfo)
|
E(OP_ZoneServerInfo)
|
||||||
E(OP_ZoneSpawns)
|
E(OP_ZoneSpawns)
|
||||||
|
E(OP_CrystalCountUpdate)
|
||||||
// Begin RoF Decodes
|
// Begin RoF Decodes
|
||||||
D(OP_AdventureMerchantSell)
|
D(OP_AdventureMerchantSell)
|
||||||
D(OP_AltCurrencySell)
|
D(OP_AltCurrencySell)
|
||||||
|
|||||||
@ -5081,6 +5081,15 @@ struct MercenaryMerchantResponse_Struct {
|
|||||||
/*0004*/
|
/*0004*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sent by Server to update character crystals.
|
||||||
|
struct CrystalCountUpdate_Struct
|
||||||
|
{
|
||||||
|
/*000*/ uint32 CurrentRadiantCrystals;
|
||||||
|
/*004*/ uint32 CareerRadiantCrystals;
|
||||||
|
/*008*/ uint32 CurrentEbonCrystals;
|
||||||
|
/*012*/ uint32 CareerEbonCrystals;
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*RoF2*/
|
}; /*RoF2*/
|
||||||
|
|||||||
@ -5004,38 +5004,49 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app)
|
|||||||
VERIFY_PACKET_LENGTH(OP_CrystalCreate, app, CrystalReclaim_Struct);
|
VERIFY_PACKET_LENGTH(OP_CrystalCreate, app, CrystalReclaim_Struct);
|
||||||
CrystalReclaim_Struct *cr = (CrystalReclaim_Struct*)app->pBuffer;
|
CrystalReclaim_Struct *cr = (CrystalReclaim_Struct*)app->pBuffer;
|
||||||
|
|
||||||
if (cr->type == 5) {
|
const uint32 requestQty = cr->amount;
|
||||||
if (cr->amount > GetEbonCrystals()) {
|
const bool isRadiant = cr->type == 4;
|
||||||
SummonItem(RuleI(Zone, EbonCrystalItemID), GetEbonCrystals());
|
const bool isEbon = cr->type == 5;
|
||||||
m_pp.currentEbonCrystals = 0;
|
|
||||||
m_pp.careerEbonCrystals = 0;
|
// Check: Valid type requested.
|
||||||
SaveCurrency();
|
if (!isRadiant && !isEbon) {
|
||||||
SendCrystalCounts();
|
return;
|
||||||
}
|
|
||||||
else {
|
|
||||||
SummonItem(RuleI(Zone, EbonCrystalItemID), cr->amount);
|
|
||||||
m_pp.currentEbonCrystals -= cr->amount;
|
|
||||||
m_pp.careerEbonCrystals -= cr->amount;
|
|
||||||
SaveCurrency();
|
|
||||||
SendCrystalCounts();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (cr->type == 4) {
|
// Check: Valid quantity requested.
|
||||||
if (cr->amount > GetRadiantCrystals()) {
|
if (requestQty < 1) {
|
||||||
SummonItem(RuleI(Zone, RadiantCrystalItemID), GetRadiantCrystals());
|
return;
|
||||||
m_pp.currentRadCrystals = 0;
|
|
||||||
m_pp.careerRadCrystals = 0;
|
|
||||||
SaveCurrency();
|
|
||||||
SendCrystalCounts();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SummonItem(RuleI(Zone, RadiantCrystalItemID), cr->amount);
|
|
||||||
m_pp.currentRadCrystals -= cr->amount;
|
|
||||||
m_pp.careerRadCrystals -= cr->amount;
|
|
||||||
SaveCurrency();
|
|
||||||
SendCrystalCounts();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check: Valid client state to make request.
|
||||||
|
// In this situation the client is either desynced or attempting an exploit.
|
||||||
|
const uint32 currentQty = isRadiant ? GetRadiantCrystals() : GetEbonCrystals();
|
||||||
|
if (currentQty == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent the client from creating more than they have.
|
||||||
|
const uint32 amount = EQEmu::ClampUpper(requestQty, currentQty);
|
||||||
|
const uint32 itemID = isRadiant ? RuleI(Zone, RadiantCrystalItemID) : RuleI(Zone, EbonCrystalItemID);
|
||||||
|
|
||||||
|
// Summon crystals for player.
|
||||||
|
const bool success = SummonItem(itemID, amount);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deduct crystals from client and update them.
|
||||||
|
if (isRadiant) {
|
||||||
|
m_pp.currentRadCrystals -= amount;
|
||||||
|
m_pp.careerRadCrystals -= amount;
|
||||||
|
}
|
||||||
|
else if (isEbon) {
|
||||||
|
m_pp.currentEbonCrystals -= amount;
|
||||||
|
m_pp.careerEbonCrystals -= amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveCurrency();
|
||||||
|
SendCrystalCounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_CrystalReclaim(const EQApplicationPacket *app)
|
void Client::Handle_OP_CrystalReclaim(const EQApplicationPacket *app)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user