Extended server spellbook entries to RoF2 standard and added per-client restriction of spell id max

This commit is contained in:
Uleat
2019-01-24 03:53:41 -05:00
parent 2d5f0dce42
commit 4658ad676f
17 changed files with 205 additions and 49 deletions
+6 -1
View File
@@ -2640,6 +2640,11 @@ bool Client::CheckAccess(int16 iDBLevel, int16 iDefaultLevel) {
}
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing){
if (slot < 0 || slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
return;
if (spellid < 3 || spellid > EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellIdMax)
return;
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
mss->scribing=scribing;
@@ -9126,4 +9131,4 @@ bool Client::GotoPlayer(std::string player_name)
}
return false;
}
}
+15 -7
View File
@@ -530,10 +530,14 @@ void Client::CompleteConnect()
SendAppearancePacket(AT_GuildID, GuildID(), false);
SendAppearancePacket(AT_GuildRank, rank, false);
}
for (uint32 spellInt = 0; spellInt < EQEmu::spells::SPELLBOOK_SIZE; spellInt++) {
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > 50000)
// moved to dbload and translators since we iterate there also .. keep m_pp values whatever they are when they get here
/*const auto sbs = EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize;
for (uint32 spellInt = 0; spellInt < sbs; ++spellInt) {
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > EQEmu::spells::SPELL_ID_MAX)
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
}
}*/
//SendAATable();
if (GetHideMe()) Message(13, "[GM] You are currently hidden to all clients");
@@ -1154,6 +1158,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
SetClientVersion(Connection()->ClientVersion());
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(Connection()->ClientVersion());
m_pp.SetPlayerProfileVersion(m_ClientVersion);
m_inv.SetInventoryVersion(m_ClientVersion);
/* Antighost code
@@ -1587,8 +1592,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
m_pp.RestTimer = 0;
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */
CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - 4);
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */ // looks to be in place now
CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - sizeof(m_pp.m_player_profile_version) - 4);
outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct));
@@ -5263,7 +5268,7 @@ void Client::Handle_OP_DeleteSpell(const EQApplicationPacket *app)
EQApplicationPacket* outapp = app->Copy();
DeleteSpell_Struct* dss = (DeleteSpell_Struct*)outapp->pBuffer;
if (dss->spell_slot < 0 || dss->spell_slot > int(EQEmu::spells::SPELLBOOK_SIZE))
if (dss->spell_slot < 0 || dss->spell_slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
return;
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
@@ -13337,7 +13342,10 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app)
const SwapSpell_Struct* swapspell = (const SwapSpell_Struct*)app->pBuffer;
int swapspelltemp;
if (swapspell->from_slot < 0 || swapspell->from_slot > EQEmu::spells::SPELLBOOK_SIZE || swapspell->to_slot < 0 || swapspell->to_slot > EQEmu::spells::SPELLBOOK_SIZE)
const auto sbs = EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize;
if (swapspell->from_slot < 0 || swapspell->from_slot >= sbs)
return;
if (swapspell->to_slot < 0 || swapspell->to_slot >= sbs)
return;
swapspelltemp = m_pp.spell_book[swapspell->from_slot];
+9 -1
View File
@@ -6441,7 +6441,15 @@ void command_scribespells(Client *c, const Seperator *sep)
c->Message(0, "Scribing spells for %s.", t->GetName());
Log(Logs::General, Logs::Normal, "Scribe spells request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level);
for(curspell = 0, book_slot = t->GetNextAvailableSpellBookSlot(), count = 0; curspell < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; curspell++, book_slot = t->GetNextAvailableSpellBookSlot(book_slot))
for (
curspell = 0,
book_slot = t->GetNextAvailableSpellBookSlot(),
count = 0; // ;
curspell < SPDAT_RECORDS &&
book_slot < EQEmu::spells::SPELLBOOK_SIZE; // ;
curspell++,
book_slot = t->GetNextAvailableSpellBookSlot(book_slot)
)
{
if
(
+9 -2
View File
@@ -984,8 +984,15 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
bool SpellGlobalCheckResult = 0;
bool SpellBucketCheckResult = 0;
for(spell_id = 0, book_slot = initiator->GetNextAvailableSpellBookSlot(), count = 0; spell_id < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; spell_id++, book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot))
for (
spell_id = 0,
book_slot = initiator->GetNextAvailableSpellBookSlot(),
count = 0; // ;
spell_id < SPDAT_RECORDS &&
book_slot < EQEmu::spells::SPELLBOOK_SIZE; // ;
spell_id++,
book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot)
)
{
if
(
+2 -4
View File
@@ -5053,7 +5053,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
m_pp.spell_book[slot] = 0xFFFFFFFF;
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot);
if(update_client)
if(update_client && slot < EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
{
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
DeleteSpell_Struct* del = (DeleteSpell_Struct*)outapp->pBuffer;
@@ -5066,9 +5066,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
void Client::UnscribeSpellAll(bool update_client)
{
int i;
for(i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
for(int i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
{
if(m_pp.spell_book[i] != 0xFFFFFFFF)
UnscribeSpell(i, update_client);
+19 -8
View File
@@ -1225,17 +1225,28 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str
"`character_spells` "
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
auto results = database.QueryDatabase(query);
int i = 0;
/* Initialize Spells */
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++){
pp->spell_book[i] = 0xFFFFFFFF;
}
memset(pp->spell_book, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELLBOOK_SIZE));
// We have the ability to block loaded spells by max id on a per-client basis..
// but, we do not have to ability to keep players from using older clients after
// they have scribed spells on a newer one that exceeds the older one's limit.
// Load them all so that server actions are valid..but, nix them in translators.
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
if (i < EQEmu::spells::SPELLBOOK_SIZE && atoi(row[1]) <= SPDAT_RECORDS){
pp->spell_book[i] = atoi(row[1]);
}
int idx = atoi(row[0]);
int id = atoi(row[1]);
if (idx < 0 || idx >= EQEmu::spells::SPELLBOOK_SIZE)
continue;
if (id < 3 || id > SPDAT_RECORDS) // 3 ("Summon Corpse") is the first scribable spell in spells_us.txt
continue;
pp->spell_book[idx] = id;
}
return true;
}