Compare commits

..

473 Commits

Author SHA1 Message Date
Chris Miles c968a0acdc [Release] 22.22.0 (#3513)
* [Release] 22.22.0

* Version other areas
2023-07-28 11:35:40 -05:00
Alex King 8c4cd34e01 [Quest API] Add GetMobTypeIdentifier() to Perl/Lua (#3512)
# Perl
- Add `$mob->GetMobTypeIdentifier()`.

# Lua
- Add `mob:GetMobTypeIdentifier()`.

# Notes
- Gets unique identifier independent of mob type.
2023-07-27 23:16:41 -05:00
Akkadius 0dbcf83a11 [Database] Fix console output in database:dump --dump-output-to-console 2023-07-25 11:45:26 -05:00
Alex King a75648f73f [Data Buckets] Distributed Databucket Caching (#3500)
* [Data Buckets] Zone-Based Data Bucket Caching

# Notes
- Adds a data bucket cache so we're not needlessly hitting the database every time we need to read a data bucket value.

* Cleanup and unify GetData access patterns

* Cache work

* Push

* Add to cache when we fetch and do a db hit

* Handle bucket misses in cache

* Formatting

* Logging

* [Data Buckets] Zone-Based Data Bucket Caching

- Adds a data bucket cache so we're not needlessly hitting the database every time we need to read a data bucket value.

* Cleanup and unify GetData access patterns

* Cache work

* Push

* Add to cache when we fetch and do a db hit

* Handle bucket misses in cache

* Formatting

* Remove redundant fetches from cache since GetData does the same thing

* Push progress

* Distributed cache work

* Logging

* Fix issue with scoping where same named keys could return overlapping results

* Misses cache tweak, logging, comments

* Add bot, client, and NPC bucket methods to Lua.

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-07-24 12:22:50 -05:00
Alex King 6c2886a71d [Cleanup] Fix casing in corpse money and decay time. (#3511)
# Notes
- These were uppercase and should be lowercase.
2023-07-23 16:19:07 -04:00
Alex King 1d96ddb60d [Bug Fix] Escape search string in #find item (#3510) 2023-07-22 18:20:00 -04:00
Vayle c30074be66 [Crash Fix] Guard against Spells:MaxTotalSlotsPET being set above client allowed maximum. (#3507)
* Guard against MaxTotalSlotsPET being set too high

This prevents a crash from MaxTotalSlotsPET being set too high.

* Tweak
2023-07-22 10:20:22 -04:00
Chris Miles b5652e6010 [Saylink] Fix cases where saylinks were not being cached (#3508)
* [Saylink] Fix cases where saylinks were not being cached

* Update say_link.cpp
2023-07-19 23:57:04 -05:00
Akkadius 202d2ed496 [Release] 22.21.2 2023-07-19 23:50:47 -05:00
Chris Miles 81cee49ea1 [Databuckets] Fix rarer same bucket name scoping overlap issue (#3509) 2023-07-19 23:49:11 -05:00
Akkadius 2d61cd2b9a [Release] 22.21.1 2023-07-18 20:50:56 -05:00
Vayle b06505b80a [Cleanup] Remove arbitrary teleport blocking in Tutorial and Load zones (#3506) 2023-07-18 20:56:21 -04:00
Chris Miles 4c2f9a4423 [Databuckets] Fix issue with expired databuckets not being expired and returned properly (#3504) 2023-07-18 17:18:36 -05:00
Alex King fb3159b657 [Bug Fix] #set title_suffix Argument Position (#3505)
# Notes
- Off by one on argument index.
2023-07-18 18:02:25 -04:00
Michael 8ebf5bbb78 [Bug] Show Petition and Show Petition_Info fix (#3503)
Where Statement was using incorrect field name.
2023-07-18 17:15:21 -04:00
Akkadius d2aae4d79c [Release] 22.21.0 2023-07-18 02:54:20 -05:00
Chris Miles f9dc9da42b [Pathing] Improvements to roambox logic, pathing (#3502)
* [Roambox] Improvements to roambox logic

* Update npc.cpp

* Update npc.cpp

* More pathing fixes
2023-07-18 02:52:04 -05:00
Chris Miles 3f3bbe98b5 [Data Buckets] Implement scoped data buckets (#3498)
* [Data Buckets] Implement scoped data buckets

* Update database_update_manifest.cpp

* Update data_bucket.cpp

* Update data_bucket.cpp

* Update data_bucket.cpp

* Update data_bucket.h

* Update database_update_manifest.cpp

* Add GetScopedDbFilters references

* Scope transfer
2023-07-16 14:52:28 -04:00
Chris Miles 59537ae977 [Z Clipping] Don't issue zclip adjustments when NPC is not moving (#3499) 2023-07-16 14:52:17 -04:00
Alex King ee45a28efe [Quest API] Add SetLDoNPoints() to Perl/Lua (#3496)
# Perl
- Add `$client->SetLDoNPoints(theme_id, points)`.

# Lua
- Add `client:SetLDoNPoints(theme_id, points)`.

# Notes
- Allows operators to directly set LDoN Points.
2023-07-15 21:46:49 -05:00
Jonathan Sider 70ce81fb0a [Bug Fix] Fix rule check and add rule for pickpocket command (#3492)
* Fix bugs in skills

-Add rule for allowing pickpocket
-Fix method that is supposed to check rule
-Changed Z axis range for pickpocket (was failing on giants)

* Add zoffset to account for taller models
2023-07-15 21:46:26 -05:00
Akkadius e06d28ad20 [Release] 22.20.1 2023-07-15 13:30:36 -05:00
Mitch Freeman d57489781c [Database] Fix database manifest entry for #3443
Updates the syntax for mariadb 10.1
2023-07-15 13:29:34 -05:00
Chris Miles 21d65c73b7 [Release] 22.20.0 (#3495) 2023-07-15 00:46:42 -05:00
Alex King 8f6d606f53 [Bug Fix] Fix Tradeskill Combines with augmented items (#3490)
* [Bug Fix] Fix Tradeskill Combines with augmented items

# Notes
- Keeps players from doing tradeskill combines with augmented items.
- Behavior is Live-like, we don't need a rule since `EVENT_COMBINE` is separate and processed prior to the recipe check.

* Update tradeskills.cpp

* Update tradeskills.cpp

* Cleanup

* Update tradeskills.cpp
2023-07-15 00:39:19 -05:00
Alex King f25e37d0c5 [Commands] Consolidate #set-like commands into a singular #set command (#3486)
* First push

* Final push.

* Consolidate zone commands in to one.

* Update command.cpp

* Remove debug messages.

* Test

* Add support for sub command status levels.

* Update command.cpp

* Update client.cpp

* Update database_update_manifest.cpp

* Update version.h

* Update item.cpp

* Update version.h

* Update database_update_manifest.cpp

* Fix command arguments.

* Help message.

* Update command.cpp

* Do DB injection/deletion

* Indent

* Update server_locked.cpp

* Update set.cpp

* Lock aliases

* Update command_subsettings_repository.h

* Update set.cpp

* Fix

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-07-15 00:37:51 -05:00
Alex King e55f9b9d27 [Feature] Add Support for item textures higher than 65,535 (#3494)
* [Feature] Add Support for item textures higher than 65,535

# Notes
- We were previously using `uint16` which has a max of `65,535`, but some of the new Live textures that are being used have values way beyond this.
- Updates quest API, commands, and database tables that also used `uint16`.

* Update version.h
2023-07-14 18:49:59 -04:00
Mitch Freeman b01486d767 [Feature] Update raid features (#3443)
* [RAID] Add Raid Features

[RAID] Add Raid Features

- Add delegate main assist
- Add delegate main marker
- Add target ring for main assisters.  Uses MA1, then MA2, then MA3
- Add /assist raid respecting /assist on and /assist off
- Add Raid Notes.  Functions across zones
- Add Raid XTarget functional
- Raid Leader can mark without being delegated Main Marker.  Must have the appropriate AA

* Update to new db routines

* Updated several formatting issues based on review

* Update to pp->tribute_time_remaining to avoid edge case.  Unrelated to raid updates.

* Updates to resolve comments/review.
Added a few edge case updates as well.

* Refactored to use database repositories for raid_details and raid_members.  Other updates as noted in review.

* Updated database manifest and fixed potential leak within Client::Handle_OP_AssistGroup

* Update for remaining review items

* Refactor SendAssistTarget to use struct/vector loop

* Have IsAssister use range based for loop and return bool

* General cleanup

* Simplify SendRaidAssistTarget to use struct / vector

* Formatting in Handle_OP_RaidDelegateAbility

* Format SendRemoveRaidXTargets and clean up error statements

* Format SendRemoveAllRaidXTargets

* Formatting

* Default return FindNextRaidDelegateSlot to -1

* Change fields to marked_npc_1/2/3 (missing last underscore)

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-07-12 22:04:50 -05:00
Jonathan Sider 50ce99ce3e [Bug Fix] Update bot naming check and add more explanation (#3491)
* Refactor my original PR

Block all puncation,numbers, and _

* Add error message
2023-07-12 21:59:17 -05:00
Alex King 4854201b2a [Quest API] Add Mob/Entity type check methods to Perl/Lua (#3493)
* [Quest API] Add Mob/Entity type check methods to Perl/Lua

# Perl
- Add `$mob->IsAura()`.
- Add `$mob->IsEncounter()`.
- Add `$mob->IsMerc()`.
- Add `$mob->IsOfClientBot()`.
- Add `$mob->IsOfClientBotMerc()`.
- Add `$mob->IsTemporaryPet()`.

# Lua
- Add `entity:IsAura()`.
- Add `entity:IsOfClientBot()`.
- Add `entity:IsOfClientBotMerc()`.
- Add `mob:IsTemporaryPet()`.

* Update lua_entity.cpp

* Update lua_mob.cpp
2023-07-12 21:20:07 -05:00
Jonathan Sider c81d05940a [Bots] Remove orphaned commands related to botgroup (#3489) 2023-07-09 00:00:28 -04:00
Paul Coene 47be17e2af [Bug Fix] Fix charmed pets to follow when charmed. (#3488)
* [Bug Fix] Fix charmed pets to follow when charmed.

* Added STOP (missed this on a local merge)
2023-07-08 19:58:45 -04:00
Chris Miles 809b3b6099 [Release] 22.19.0 (#3487) 2023-07-08 16:54:15 -05:00
Jonathan Sider f06c7e8834 [Bots] Add Pickpocket Command (#3484)
* Add Pickpocket Command

* Formatting

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-07-08 16:51:52 -05:00
Alex King 096448d23c [Commands] Add #itemsearch alias to #find aliases (#3485)
# Notes
- `#itemsearch` did not exist in this alias list.
2023-07-08 16:33:29 -05:00
Alex King e55fb1cafd [Commands] Consolidate #show commands into a singular #show command (#3478)
* [Cleanup] Consolidate #show commands into a singular #show command

# Notes
- All `#show` commands like `#showbuffs` are now subcommands of `#show`.
- All aliases like `#showbuffs` still function.

* Push up progress.

* Final push.

* Cleanup.

* Update ip_lookup.cpp

* emotes not emote

* Cleanup

* Update servertalk.h

* Update show.cpp

* Fix

* Final push.

* #aggro

* #who
2023-07-08 11:06:25 -04:00
Alex King d4962bb2ab [Cleanup] Move #find item summon links to front (#3483)
# Notes
- Move the summon links to the front so they're in a consistent location.
2023-07-04 23:08:29 -04:00
Jasdac 98e56bdfe9 [Rules] Add Skills:TrivialTradeskillCombinesNoFail Rule (#3481)
* Add TrivialNoFail rule

* feedback fixes

* Update tradeskills.cpp

* Update 1392_recipe_learning.sql

* Update ruletypes.h

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-07-04 22:47:56 -04:00
Akkadius 5c1be3643e [Release] 22.18.0 2023-07-04 15:21:35 -05:00
Alex King c2fa61b3a2 [Bug Fix] Add chatchannel_reserved_names to a new manifest (#3482)
# Notes
- This should resolve issues where the old query fails because it's adding an already existing column to another table.
2023-07-04 15:19:24 -05:00
Alex King 01a1186e63 [Commands] Add #emotesearch to #find command (#3480)
# Notes
- Missed this with initial `#find` command consolidation.
2023-07-04 14:17:42 -05:00
Alex King 7427318213 [Commands] Cleanup #copycharacter Command (#3479)
# Notes
- Cleanup messages and logic.
2023-07-04 14:14:33 -05:00
Alex King d3c3d7b384 [Bug Fix] Fix issue in zone store of returning reference to local variable (#3477)
# Notes
- Compiler did not like possibly returning a reference to a local variable.
2023-07-04 03:08:44 -05:00
Alex King e9e8143778 [Release] 22.17.0 (#3476)
## [22.17.0] - 07/03/2023

### Cleanup/Feature

* Add support for bots to #showstats/#mystats ([#3427](https://github.com/EQEmu/Server/pull/3427)) @Kinglykrab 2023-07-01

### Code

* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04
* Remove handle_npc_single_npc from zone/lua_parser_events.cpp and zone/lua_parser_events.h ([#3467](https://github.com/EQEmu/Server/pull/3467)) @Kinglykrab 2023-07-03

### Database

* Set multi statements off when returning early ([#3462](https://github.com/EQEmu/Server/pull/3462)) @Akkadius 2023-07-01

### Feature

* Add Strings::BeginsWith() and Strings::EndsWith() ([#3471](https://github.com/EQEmu/Server/pull/3471)) @Kinglykrab 2023-07-03

### Fixes

* Add check for underscores in botcreate command ([#3458](https://github.com/EQEmu/Server/pull/3458)) @tuday2 2023-06-29
* EVENT_LANGUAGE_SKILL_UP in Lua was using EVENT_SKILL_UP logic ([#3466](https://github.com/EQEmu/Server/pull/3466)) @Kinglykrab 2023-07-03
* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04
* Fix data type of GetAggroCount() ([#3470](https://github.com/EQEmu/Server/pull/3470)) @Kinglykrab 2023-07-03

### Logging

* Fix logging crash when % are sent through query logs ([#3461](https://github.com/EQEmu/Server/pull/3461)) @Akkadius 2023-07-01

### Quest API

* Add ClearAccountFlag() and GetAccountFlags() to Perl/Lua ([#3469](https://github.com/EQEmu/Server/pull/3469)) @Kinglykrab 2023-07-03
* Add GetClassAbbreviation() and GetRaceAbbreviation() to Perl/Lua ([#3463](https://github.com/EQEmu/Server/pull/3463)) @Kinglykrab 2023-07-02
* Add GetClassPlural() and GetRacePlural() to Perl/Lua ([#3468](https://github.com/EQEmu/Server/pull/3468)) @Kinglykrab 2023-07-03
* Add GetCloseMobList() and CalculateDistance() overload to Perl/Lua ([#3455](https://github.com/EQEmu/Server/pull/3455)) @Kinglykrab 2023-07-02
* Add Hate Entry Methods to Perl ([#3459](https://github.com/EQEmu/Server/pull/3459)) @Kinglykrab 2023-07-02
* Add ItemData Class to Perl ([#3465](https://github.com/EQEmu/Server/pull/3465)) @Kinglykrab 2023-07-02
* Add Spawn2 Class to Perl ([#3456](https://github.com/EQEmu/Server/pull/3456)) @Kinglykrab 2023-07-02
* Add StatBonuses Class to Perl ([#3460](https://github.com/EQEmu/Server/pull/3460)) @Kinglykrab 2023-07-02
* Add missing Item Methods to Perl/Lua. ([#3464](https://github.com/EQEmu/Server/pull/3464)) @Kinglykrab 2023-07-02
2023-07-03 19:46:15 -05:00
Alex King bc71997518 [Bug Fix] Fix _PutItem having a slot_id of -1 on mobs with no items (#3474)
# Notes
- This was causing an insane amount of error logs because we were always using `PutItem`, even with a `slot_id` of `-1`.
2023-07-03 20:33:21 -04:00
Alex King 4a9a9fa197 [Cleanup] Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h (#3473)
# Notes
- This is unused.
2023-07-03 19:20:34 -05:00
Alex King ee14aed8de [Feature] Add Strings::BeginsWith() and Strings::EndsWith() (#3471)
* [Strings] Add Strings::BeginsWith() and Strings::EndsWith()

# Notes
- These are useful so that we don't have to manually calculate size or perform a substring.

* Update questmgr.cpp

* Update client.cpp
2023-07-03 09:40:44 -04:00
Alex King 2717fcc339 [Quest API] Add ClearAccountFlag() and GetAccountFlags() to Perl/Lua (#3469)
* [Quest API] Add ClearAccountFlag() and GetAccountFlags() to Perl/Lua

# Perl
- Add `$client->ClearAccountFlag(flag)`.
- Add `$client->GetAccountFlags()`.

# Lua
- Add `client:ClearAccountFlag(flag)`.
- Add `client:GetAccountFlags()`.

# Notes
- Made use of repositories and cleaned up existing code.

* Update lua_client.cpp

* Don't use auto.
2023-07-03 01:19:48 -05:00
Alex King dc28c8d485 [Bug Fix] Fix data type of GetAggroCount() (#3470)
# Notes
- This is an `unsigned int`, not an `int`, so this fixes that.
2023-07-03 00:10:27 -05:00
Alex King a633784f78 [Quest API] Add GetClassPlural() and GetRacePlural() to Perl/Lua (#3468)
* [Quest API] Add GetClassPlural() and GetRacePlural() to Perl/Lua

# Perl
- Add `$mob->GetClassPlural()`.
- Add `$mob->GetRacePlural()`.

# Lua
- Add `mob:GetClassPlural()`.
- Add `mob:GetRacePlural()`.

# Notes
- Allows operators to get the plural of a player class or race, example being `Warrior` as `Warriors` or `Dark Elf` as `Dark Elves`.

* Update mob.cpp
2023-07-03 00:08:04 -05:00
Alex King 5519c3e781 [Cleanup] Remove handle_npc_single_npc from zone/lua_parser_events.cpp and zone/lua_parser_events.h (#3467)
# Notes
- This is unused.
2023-07-02 23:56:04 -05:00
Alex King 9401323708 [Bug Fix] EVENT_LANGUAGE_SKILL_UP in Lua was using EVENT_SKILL_UP logic (#3466)
# Notes
- `EVENT_LANGUAGE_SKILL_UP` only takes `3` values whereas `EVENT_SKILL_UP` takes `4`.
2023-07-02 20:41:53 -04:00
Alex King 251993c61b [Quest API] Add ItemData Class to Perl (#3465)
* [Quest API] Add ItemData Class to Perl

- Add `$questitem->GetItem()`.
- Add `$questitem->GetUnscaledItem()`.
- Add `$questitemdata->GetAGI()`.
- Add `$questitemdata->GetAC()`.
- Add `$questitemdata->GetCHA()`.
- Add `$questitemdata->GetDEX()`.
- Add `$questitemdata->GetINT()`.
- Add `$questitemdata->GetSTA()`.
- Add `$questitemdata->GetSTR()`.
- Add `$questitemdata->GetAWis()`.
- Add `$questitemdata->GetAccuracy()`.
- Add `$questitemdata->GetArtifactFlag()`.
- Add `$questitemdata->GetAttack()`.
- Add `$questitemdata->GetAttuneable()`.
- Add `$questitemdata->GetAugmentDistiller()`.
- Add `$questitemdata->GetAugmentRestrict()`.
- Add `$questitemdata->GetAugmentSlotType(slot_id)`.
- Add `$questitemdata->GetAugmentSlotUnk2(slot_id)`.
- Add `$questitemdata->GetAugmentSlotVisible(slot_id)`.
- Add `$questitemdata->GetAugmentType()`.
- Add `$questitemdata->GetAvoidance()`.
- Add `$questitemdata->GetBackstabDamage()`.
- Add `$questitemdata->GetBagSize()`.
- Add `$questitemdata->GetBagSlots()`.
- Add `$questitemdata->GetBagType()`.
- Add `$questitemdata->GetBagWeightReduction()`.
- Add `$questitemdata->GetBaneDamageAmount()`.
- Add `$questitemdata->GetBaneDamageBody()`.
- Add `$questitemdata->GetBaneDamageRace()`.
- Add `$questitemdata->GetBaneDamageRaceAmount()`.
- Add `$questitemdata->GetBardEffect()`.
- Add `$questitemdata->GetBardLevel()`.
- Add `$questitemdata->GetBardLevel2()`.
- Add `$questitemdata->GetBardType()`.
- Add `$questitemdata->GetBardSkillType()`.
- Add `$questitemdata->GetBardSkillValue()`.
- Add `$questitemdata->GetBenefitFlag()`.
- Add `$questitemdata->GetBook()`.
- Add `$questitemdata->GetBookType()`.
- Add `$questitemdata->GetCR()`.
- Add `$questitemdata->GetCastTime()`.
- Add `$questitemdata->GetCastTime_()`.
- Add `$questitemdata->GetCharmFile()`.
- Add `$questitemdata->GetCharmFileID()`.
- Add `$questitemdata->GetClairvoyance()`.
- Add `$questitemdata->GetClasses()`.
- Add `$questitemdata->GetClickName()`.
- Add `$questitemdata->GetClickEffect()`.
- Add `$questitemdata->GetClickLevel()`.
- Add `$questitemdata->GetClickLevel2()`.
- Add `$questitemdata->GetClickType()`.
- Add `$questitemdata->GetColor()`.
- Add `$questitemdata->GetCombatEffects()`.
- Add `$questitemdata->GetCorruption()`.
- Add `$questitemdata->GetDR()`.
- Add `$questitemdata->GetDSMitigation()`.
- Add `$questitemdata->GetDamage()`.
- Add `$questitemdata->GetDamageShield()`.
- Add `$questitemdata->GetDeity()`.
- Add `$questitemdata->GetDelay()`.
- Add `$questitemdata->GetDOTShielding()`.
- Add `$questitemdata->GetElementalDamageAmount()`.
- Add `$questitemdata->GetElementalDamageType()`.
- Add `$questitemdata->GetEliteMaterial()`.
- Add `$questitemdata->GetEndurance()`.
- Add `$questitemdata->GetEnduranceRegen()`.
- Add `$questitemdata->GetExpendableArrow()`.
- Add `$questitemdata->GetExtraDamageAmount()`.
- Add `$questitemdata->GetExtraDamageSkill()`.
- Add `$questitemdata->GetFR()`.
- Add `$questitemdata->GetFVNoDrop()`.
- Add `$questitemdata->GetFactionAmount1()`.
- Add `$questitemdata->GetFactionAmount2()`.
- Add `$questitemdata->GetFactionAmount3()`.
- Add `$questitemdata->GetFactionAmount4()`.
- Add `$questitemdata->GetFactionModifier1()`.
- Add `$questitemdata->GetFactionModifier2()`.
- Add `$questitemdata->GetFactionModifier3()`.
- Add `$questitemdata->GetFactionModifier4()`.
- Add `$questitemdata->GetFavor()`.
- Add `$questitemdata->GetFilename()`.
- Add `$questitemdata->GetFocusEffect()`.
- Add `$questitemdata->GetFocusName()`.
- Add `$questitemdata->GetFocusLevel()`.
- Add `$questitemdata->GetFocusLevel2()`.
- Add `$questitemdata->GetFocusType()`.
- Add `$questitemdata->GetFulfilment()`.
- Add `$questitemdata->GetGuildFavor()`.
- Add `$questitemdata->GetHP()`.
- Add `$questitemdata->GetHaste()`.
- Add `$questitemdata->GetHealAmount()`.
- Add `$questitemdata->GetHeroicAGI()`.
- Add `$questitemdata->GetHeroicCR()`.
- Add `$questitemdata->GetHeroicCHA()`.
- Add `$questitemdata->GetHeroicCorruption()`.
- Add `$questitemdata->GetHeroicDR()`.
- Add `$questitemdata->GetHeroicDEX()`.
- Add `$questitemdata->GetHeroicFR()`.
- Add `$questitemdata->GetHeroicINT()`.
- Add `$questitemdata->GetHeroicMR()`.
- Add `$questitemdata->GetHeroicPR()`.
- Add `$questitemdata->GetHeroicSTA()`.
- Add `$questitemdata->GetHeroicSTR()`.
- Add `$questitemdata->GetHeroicWIS()`.
- Add `$questitemdata->GetID()`.
- Add `$questitemdata->GetIDFile()`.
- Add `$questitemdata->GetIcon()`.
- Add `$questitemdata->GetItemClass()`.
- Add `$questitemdata->GetItemType()`.
- Add `$questitemdata->GetLDoNPrice()`.
- Add `$questitemdata->GetLDoNSellBackRate()`.
- Add `$questitemdata->GetLDoNSold()`.
- Add `$questitemdata->GetLDoNTheme()`.
- Add `$questitemdata->GetLight()`.
- Add `$questitemdata->GetLore()`.
- Add `$questitemdata->GetLoreFlag()`.
- Add `$questitemdata->GetLoreGroup()`.
- Add `$questitemdata->GetMR()`.
- Add `$questitemdata->GetMagic()`.
- Add `$questitemdata->GetMana()`.
- Add `$questitemdata->GetManaRegen()`.
- Add `$questitemdata->GetMaterial()`.
- Add `$questitemdata->GetMaximumCharges()`.
- Add `$questitemdata->GetMinimumStatus()`.
- Add `$questitemdata->GetName()`.
- Add `$questitemdata->GetNoDrop()`.
- Add `$questitemdata->GetNoPet()`.
- Add `$questitemdata->GetNoRent()`.
- Add `$questitemdata->GetNoTransfer()`.
- Add `$questitemdata->GetPR()`.
- Add `$questitemdata->GetPendingLoreFlag()`.
- Add `$questitemdata->GetPointType()`.
- Add `$questitemdata->GetPotionBelt()`.
- Add `$questitemdata->GetPotionBeltSlots()`.
- Add `$questitemdata->GetPrice()`.
- Add `$questitemdata->GetProcEffect()`.
- Add `$questitemdata->GetProcName()`.
- Add `$questitemdata->GetProcRate()`.
- Add `$questitemdata->GetProcLevel()`.
- Add `$questitemdata->GetProcLevel2()`.
- Add `$questitemdata->GetProcType()`.
- Add `$questitemdata->GetPurity()`.
- Add `$questitemdata->GetQuestItemFlag()`.
- Add `$questitemdata->GetRaces()`.
- Add `$questitemdata->GetRange()`.
- Add `$questitemdata->GetRecLevel()`.
- Add `$questitemdata->GetRecSkill()`.
- Add `$questitemdata->GetRecastDelay()`.
- Add `$questitemdata->GetRecastType()`.
- Add `$questitemdata->GetRegen()`.
- Add `$questitemdata->GetReqLevel()`.
- Add `$questitemdata->GetScriptFileID()`.
- Add `$questitemdata->GetScrollEffect()`.
- Add `$questitemdata->GetScrollName()`.
- Add `$questitemdata->GetScrollLevel()`.
- Add `$questitemdata->GetScrollLevel2()`.
- Add `$questitemdata->GetScrollType()`.
- Add `$questitemdata->GetSellRate()`.
- Add `$questitemdata->GetShielding()`.
- Add `$questitemdata->GetSize()`.
- Add `$questitemdata->GetSkillModifierType()`.
- Add `$questitemdata->GetSkillModifierValue()`.
- Add `$questitemdata->GetSlots()`.
- Add `$questitemdata->GetSpellDamage()`.
- Add `$questitemdata->GetSpellShield()`.
- Add `$questitemdata->GetStackSize()`.
- Add `$questitemdata->GetStackable()`.
- Add `$questitemdata->GetStrikeThrough()`.
- Add `$questitemdata->GetStunResist()`.
- Add `$questitemdata->GetSummonedFlag()`.
- Add `$questitemdata->GetTradeskills()`.
- Add `$questitemdata->GetWeight()`.
- Add `$questitemdata->GetWornName()`.
- Add `$questitemdata->GetWornEffect()`.
- Add `$questitemdata->GetWornLevel()`.
- Add `$questitemdata->GetWornLevel2()`.
- Add `$questitemdata->GetWornType()`.

- Fixed data type of parameters in a handful of methods.

- Allows operators to directly interact with item data without the need for `quest::getitemstat` or DBI or anything of the sort.

* Update perl_questitem.cpp

* Update lua_iteminst.cpp

* Update lua_iteminst.h

* Update lua_iteminst.h
2023-07-02 11:26:49 -04:00
Alex King 728ce0c519 [Quest API] Add GetCloseMobList() and CalculateDistance() overload to Perl/Lua (#3455)
* [Quest API] Add GetCloseMobList() and CalculateDistance() overload to Perl/Lua

# Perl
- Add `$entity_list->GetCloseMobList(mob)`.
- Add `$entity_list->GetCloseMobList(mob, distance)`.
- Add `$mob->CalculateDistance(mob)`.
- Add `$mob->GetCloseMobList()`.
- Add `$mob->GetCloseMobList(distance)`.

# Lua
- Add `eq.get_entity_list():GetCloseMobList(mob)`.
- Add `eq.get_entity_list():GetCloseMobList(mob, distance)`.
- Add `mob:CalculateDistance(mob)`.
- Add `mob:GetCloseMobList()`.
- Add `mob:GetCloseMobList(distance)`.

* Ignore Self

* Update lua_entity_list.cpp

* Cleanup
2023-07-02 10:55:27 -04:00
Alex King 6a80bcecc7 [Quest API] Add missing Item Methods to Perl/Lua. (#3464)
# Perl
- Add `$questitem->AddEXP(exp)`.
- Add `$questitem->ClearTimers()`.
- Add `$questitem->Clone()`.
- Add `$questitem->DeleteCustomData(identifier)`.
- Add `$questitem->GetAugmentItemID(slot_id)`.
- Add `$questitem->GetAugmentType()`.
- Add `$questitem->GetColor()`.
- Add `$questitem->GetCustomData(identifier)`.
- Add `$questitem->GetCustomDataString()`.
- Add `$questitem->GetEXP()`.
- Add `$questitem->GetItem(slot_id)`.
- Add `$questitem->GetItemID(slot_id)`.
- Add `$questitem->GetItemScriptID()`.
- Add `$questitem->GetKillsNeeded()`.
- Add `$questitem->GetMaxEvolveLevel()`.
- Add `$questitem->GetPrice()`.
- Add `$questitem->GetTotalItemCount()`.
- Add `$questitem->IsAmmo()`.
- Add `$questitem->IsAugmentable()`.
- Add `$questitem->IsAugmented()`.
- Add `$questitem->IsEquipable(slot_id)`.
- Add `$questitem->IsEquipable(race_bitmask, class_bitmask)`.
- Add `$questitem->IsExpendable()`.
- Add `$questitem->IsInstanceNoDrop()`.
- Add `$questitem->IsWeapon()`.
- Add `$questitem->SetAttuned(is_attuned)`.
- Add `$questitem->SetColor(color)`.
- Add `$questitem->SetCustomData(identifier, bool_value)`.
- Add `$questitem->SetCustomData(identifier, float_value)`.
- Add `$questitem->SetCustomData(identifier, int_value)`.
- Add `$questitem->SetCustomData(identifier, string_value)`.
- Add `$questitem->SetEXP(exp)`.
- Add `$questitem->SetInstanceNoDrop(is_attuned)`.
- Add `$questitem->SetPrice(price)`.
- Add `$questitem->SetScaling(is_scaling)`.
- Add `$questitem->SetTimer(timer_name, timer)`.
- Add `$questitem->StopTimer(timer_name)`.

# Lua
- Add `iteminst:GetName()`.
- Add `iteminst:IsAttuned()`.
- Add `iteminst:ItemSay(text)`.
- Add `iteminst:ItemSay(text, language_id)`.
- Add `iteminst:SetAttuned(is_attuned)`.

# Notes
- Cleaned up return types and parameter types that were mismatched.
- Removed `SetItem` from Lua as it wasn't used.
- Removed unused parameter in `GetUnscaledItem` in Lua.
- I plan to add Perl ItemData support after this makes its way in, so the missing methods like the `GetItem` overload will be added then.
2023-07-02 10:27:05 -04:00
Alex King 6324e3687a [Quest API] Add GetClassAbbreviation() and GetRaceAbbreviation() to Perl/Lua (#3463)
# Perl
- Add `$bot->GetClassAbbreviation()`.
- Add `$bot->GetRaceAbbreviation()`.
- Add `$client->GetClassAbbreviation()`.
- Add `$client->GetRaceAbbreviation()`.

# Lua
- Add `bot:GetClassAbbreviation()`.
- Add `bot:GetRaceAbbreviation()`.
- Add `client:GetClassAbbreviation()`.
- Add `client:GetRaceAbbreviation()`.

# Notes
- Allows operators to easily get a player race/class abbreviation, example being `Warrior` as `WAR`.
2023-07-02 10:26:51 -04:00
Alex King d16ac99033 [Quest API] Add StatBonuses Class to Perl (#3460)
* [Quest API] Add StatBonuses Class to Perl

# Perl
- Add `$mob->GetAABonuses()`.
- Add `$mob->GetItemBonuses()`.
- Add `$mob->GetSpellBonuses()`.
- Add `$statbonuses->GetAbsorbMagicAttack(slot)`.
- Add `$statbonuses->GetAC()`.
- Add `$statbonuses->GetAccuracy(slot)`.
- Add `$statbonuses->GetAdjustedCastingSkill()`.
- Add `$statbonuses->GetAggroRange()`.
- Add `$statbonuses->GetAGI()`.
- Add `$statbonuses->GetAGICapModifier()`.
- Add `$statbonuses->GetAlterNPCLevel()`.
- Add `$statbonuses->GetAmbidexterity()`.
- Add `$statbonuses->GetAmplification()`.
- Add `$statbonuses->GetAntiGate()`.
- Add `$statbonuses->GetArcheryDamageModifier()`.
- Add `$statbonuses->GetAssassinate(slot)`.
- Add `$statbonuses->GetAssassinateLevel(slot)`.
- Add `$statbonuses->GetAssistRange()`.
- Add `$statbonuses->GetAStacker(slot)`.
- Add `$statbonuses->GetATK()`.
- Add `$statbonuses->GetAvoidMeleeChance()`.
- Add `$statbonuses->GetAvoidMeleeChanceEffect()`.
- Add `$statbonuses->GetBaseMovementSpeed()`.
- Add `$statbonuses->GetBerserkSPA()`.
- Add `$statbonuses->GetBindWound()`.
- Add `$statbonuses->GetBlockBehind()`.
- Add `$statbonuses->GetBrassModifier()`.
- Add `$statbonuses->GetBStacker(slot)`.
- Add `$statbonuses->GetBuffSlotIncrease()`.
- Add `$statbonuses->GetCHA()`.
- Add `$statbonuses->GetCHACapModifier()`.
- Add `$statbonuses->GetChannelChanceItems()`.
- Add `$statbonuses->GetChannelChanceSpells()`.
- Add `$statbonuses->GetCharmBreakChance()`.
- Add `$statbonuses->GetClairvoyance()`.
- Add `$statbonuses->GetCombatStability()`.
- Add `$statbonuses->GetConsumeProjectile()`.
- Add `$statbonuses->GetCorrup()`.
- Add `$statbonuses->GetCorrupCapModifier()`.
- Add `$statbonuses->GetCR()`.
- Add `$statbonuses->GetCRCapModifier()`.
- Add `$statbonuses->GetCripplingBlowChance()`.
- Add `$statbonuses->GetCriticalDamageModifier(slot)`.
- Add `$statbonuses->GetCriticalDoTChance()`.
- Add `$statbonuses->GetCriticalDOTDecay()`.
- Add `$statbonuses->GetCriticalHealChance()`.
- Add `$statbonuses->GetCriticalHealDecay()`.
- Add `$statbonuses->GetCriticalHealOverTime()`.
- Add `$statbonuses->GetCriticalHitChance(slot)`.
- Add `$statbonuses->GetCriticalMend()`.
- Add `$statbonuses->GetCriticalRegenDecay()`.
- Add `$statbonuses->GetCriticalSpellChance()`.
- Add `$statbonuses->GetCStacker(slot)`.
- Add `$statbonuses->GetDamageModifier(slot)`.
- Add `$statbonuses->GetDamageModifier2(slot)`.
- Add `$statbonuses->GetDamageShield()`.
- Add `$statbonuses->GetDamageShieldSpellID()`.
- Add `$statbonuses->GetDamageShieldType()`.
- Add `$statbonuses->GetDeathSave(slot)`.
- Add `$statbonuses->GetDelayDeath()`.
- Add `$statbonuses->GetDEX()`.
- Add `$statbonuses->GetDEXCapModifier()`.
- Add `$statbonuses->GetDistanceRemoval()`.
- Add `$statbonuses->GetDivineAura()`.
- Add `$statbonuses->GetDivineSaveChance(slot)`.
- Add `$statbonuses->GetDodgeChance()`.
- Add `$statbonuses->GetDOTCriticalDamageIncrease()`.
- Add `$statbonuses->GetDoTShielding()`.
- Add `$statbonuses->GetDoubleAttackChance()`.
- Add `$statbonuses->GetDoubleRangedAttack()`.
- Add `$statbonuses->GetDoubleRiposte()`.
- Add `$statbonuses->GetDoubleSpecialAttack()`.
- Add `$statbonuses->GetDR()`.
- Add `$statbonuses->GetDRCapModifier()`.
- Add `$statbonuses->GetDSMitigation()`.
- Add `$statbonuses->GetDSMitigationOffHand()`.
- Add `$statbonuses->GetDStacker(slot)`.
- Add `$statbonuses->GetDualWieldChance()`.
- Add `$statbonuses->GetEffectiveCastingLevel()`.
- Add `$statbonuses->GetEndurancePercentCap(slot)`.
- Add `$statbonuses->GetEndurance()`.
- Add `$statbonuses->GetEnduranceReduction()`.
- Add `$statbonuses->GetEnduranceRegen()`.
- Add `$statbonuses->GetExtraXTargets()`.
- Add `$statbonuses->GetExtraAttackChance()`.
- Add `$statbonuses->GetFactionModifierPercent()`.
- Add `$statbonuses->GetFearless()`.
- Add `$statbonuses->GetFeignedCastOnChance()`.
- Add `$statbonuses->GetFinishingBlow(slot)`.
- Add `$statbonuses->GetFinishingBlowLevel(slot)`.
- Add `$statbonuses->GetFlurryChance()`.
- Add `$statbonuses->GetFocusEffects(slot)`.
- Add `$statbonuses->GetFocusEffectsWorn(slot)`.
- Add `$statbonuses->GetForageAdditionalItems()`.
- Add `$statbonuses->GetFR()`.
- Add `$statbonuses->GetFRCapModifier()`.
- Add `$statbonuses->GetFrenziedDevastation()`.
- Add `$statbonuses->GetFrontalBackstabChance()`.
- Add `$statbonuses->GetFrontalBackstabMinimumDamage()`.
- Add `$statbonuses->GetFrontalStunResist()`.
- Add `$statbonuses->GetGiveDoubleAttack()`.
- Add `$statbonuses->GetGiveDoubleRiposte(slot)`.
- Add `$statbonuses->GetGivePetGroupTarget()`.
- Add `$statbonuses->GetGravityEffect()`.
- Add `$statbonuses->GetHaste()`.
- Add `$statbonuses->GetHasteType2()`.
- Add `$statbonuses->GetHasteType3()`.
- Add `$statbonuses->GetHateModifier()`.
- Add `$statbonuses->GetHeadShot(slot)`.
- Add `$statbonuses->GetHeadShotLevel(slot)`.
- Add `$statbonuses->GetHealAmt()`.
- Add `$statbonuses->GetHealRate()`.
- Add `$statbonuses->GetHeroicAGI()`.
- Add `$statbonuses->GetHeroicCHA()`.
- Add `$statbonuses->GetHeroicCorrup()`.
- Add `$statbonuses->GetHeroicCR()`.
- Add `$statbonuses->GetHeroicDEX()`.
- Add `$statbonuses->GetHeroicDR()`.
- Add `$statbonuses->GetHeroicFR()`.
- Add `$statbonuses->GetHeroicINT()`.
- Add `$statbonuses->GetHeroicMR()`.
- Add `$statbonuses->GetHeroicPR()`.
- Add `$statbonuses->GetHeroicSTA()`.
- Add `$statbonuses->GetHeroicSTR()`.
- Add `$statbonuses->GetHeroicWIS()`.
- Add `$statbonuses->GetHitChance()`.
- Add `$statbonuses->GetHitChanceEffect(slot)`.
- Add `$statbonuses->GetHP()`.
- Add `$statbonuses->GetHPPercentCap(slot)`.
- Add `$statbonuses->GetHPRegen()`.
- Add `$statbonuses->GetHPToManaConvert()`.
- Add `$statbonuses->GetHundredHands()`.
- Add `$statbonuses->GetIllusionPersistence()`.
- Add `$statbonuses->GetImmuneToFlee()`.
- Add `$statbonuses->GetImprovedReclaimEnergy()`.
- Add `$statbonuses->GetImprovedTauntslot()`.
- Add `$statbonuses->GetIncreaseBlockChance()`.
- Add `$statbonuses->GetIncreaseChanceMemoryWipe()`.
- Add `$statbonuses->GetIncreaseRunSpeedCap()`.
- Add `$statbonuses->GetInhibitMelee()`.
- Add `$statbonuses->GetINT()`.
- Add `$statbonuses->GetINTCapModifier()`.
- Add `$statbonuses->GetIsBlind()`.
- Add `$statbonuses->GetIsFeared()`.
- Add `$statbonuses->GetItemATKCap()`.
- Add `$statbonuses->GetItemHPRegenCap()`.
- Add `$statbonuses->GetItemManaRegenCap()`.
- Add `$statbonuses->GetLimitToSkill(slot)`.
- Add `$statbonuses->GetMagicWeapon()`.
- Add `$statbonuses->GetMana()`.
- Add `$statbonuses->GetManaAbsorbPercentDamage(slot)`.
- Add `$statbonuses->GetManaPercentCap(slot)`.
- Add `$statbonuses->GetManaRegen()`.
- Add `$statbonuses->GetMasteryOfPast()`.
- Add `$statbonuses->GetMaxBindWound()`.
- Add `$statbonuses->GetMaxHP()`.
- Add `$statbonuses->GetMaxHPChange()`.
- Add `$statbonuses->GetMeleeLifetap()`.
- Add `$statbonuses->GetMeleeMitigation()`.
- Add `$statbonuses->GetMeleeMitigationEffect()`.
- Add `$statbonuses->GetMeleeRune(slot)`.
- Add `$statbonuses->GetMeleeSkillCheck()`.
- Add `$statbonuses->GetMeleeSkillCheckSkill()`.
- Add `$statbonuses->GetMeleeThresholdGuard(slot)`.
- Add `$statbonuses->GetMetabolism()`.
- Add `$statbonuses->GetMinimumDamageModifier(slot)`.
- Add `$statbonuses->GetMitigateDOTRune(slot)`.
- Add `$statbonuses->GetMitigateMeleeRune(slot)`.
- Add `$statbonuses->GetMitigateSpellRune(slot)`.
- Add `$statbonuses->GetMovementSpeed()`.
- Add `$statbonuses->GetMR()`.
- Add `$statbonuses->GetMRCapModifier()`.
- Add `$statbonuses->GetNegateAttacks(slot)`.
- Add `$statbonuses->GetNegateEffects()`.
- Add `$statbonuses->GetNegateIfCombat()`.
- Add `$statbonuses->GetNoBreakAESneak()`.
- Add `$statbonuses->GetOffhandRiposteFail()`.
- Add `$statbonuses->GetPackrat()`.
- Add `$statbonuses->GetParryChance()`.
- Add `$statbonuses->GetPCPetFlurry(slot)`.
- Add `$statbonuses->GetPCPetRampage(slot)`.
- Add `$statbonuses->GetPercussionModifier()`.
- Add `$statbonuses->GetPersistentCasting()`.
- Add `$statbonuses->GetPetAvoidance()`.
- Add `$statbonuses->GetPetCriticalHit()`.
- Add `$statbonuses->GetPetFlurry()`.
- Add `$statbonuses->GetPetMaxHP()`.
- Add `$statbonuses->GetPetMeleeMitigation()`.
- Add `$statbonuses->GetPR()`.
- Add `$statbonuses->GetPRCapModifier()`.
- Add `$statbonuses->GetProcChance()`.
- Add `$statbonuses->GetProcChanceSPA()`.
- Add `$statbonuses->GetRaiseSkillCap(slot)`.
- Add `$statbonuses->GetReduceFallDamage()`.
- Add `$statbonuses->GetReduceTradeskillFail(slot)`.
- Add `$statbonuses->GetReflectChance()`.
- Add `$statbonuses->GetResistFearChance()`.
- Add `$statbonuses->GetResistSpellChance()`.
- Add `$statbonuses->GetReverseDamageShield()`.
- Add `$statbonuses->GetReverseDamageShieldSpellID()`.
- Add `$statbonuses->GetReverseDamageShieldType()`.
- Add `$statbonuses->GetRiposteChance()`.
- Add `$statbonuses->GetRoot(slot)`.
- Add `$statbonuses->GetRootBreakChance()`.
- Add `$statbonuses->GetSalvageChance()`.
- Add `$statbonuses->GetSanctuary()`.
- Add `$statbonuses->GetScreech()`.
- Add `$statbonuses->GetSecondaryDamageIncrease()`.
- Add `$statbonuses->GetSeeInvis()`.
- Add `$statbonuses->GetSEResist(slot)`.
- Add `$statbonuses->GetShieldBlock()`.
- Add `$statbonuses->GetShieldEquipDamageModifier()`.
- Add `$statbonuses->GetShroudOfStealth()`.
- Add `$statbonuses->GetSingingModifier()`.
- Add `$statbonuses->GetSkillAttackProc(slot)`.
- Add `$statbonuses->GetSkillDamageAmount(slot)`.
- Add `$statbonuses->GetSkillDamageAmount2(slot)`.
- Add `$statbonuses->GetSkillDamageTaken(slot)`.
- Add `$statbonuses->GetSkillModifier(slot)`.
- Add `$statbonuses->GetSkillModifierMax(slot)`.
- Add `$statbonuses->GetSkillProc(slot)`.
- Add `$statbonuses->GetSkillProcSuccess(slot)`.
- Add `$statbonuses->GetSkillReuseTime(slot)`.
- Add `$statbonuses->GetSlayUndead(slot)`.
- Add `$statbonuses->GetSongModifierCap()`.
- Add `$statbonuses->GetSongRange()`.
- Add `$statbonuses->GetSpellCriticalDamageIncreaseNOStack()`.
- Add `$statbonuses->GetSpellCriticalDamageIncrease()`.
- Add `$statbonuses->GetSpellDamageShield()`.
- Add `$statbonuses->GetSpellDamage()`.
- Add `$statbonuses->GetSpellOnDeath(slot)`.
- Add `$statbonuses->GetSpellOnKill(slot)`.
- Add `$statbonuses->GetSpellProcChance()`.
- Add `$statbonuses->GetSpellShield()`.
- Add `$statbonuses->GetSpellThresholdGuard(slot)`.
- Add `$statbonuses->GetSpellTriggers(slot)`.
- Add `$statbonuses->GetSTA()`.
- Add `$statbonuses->GetSTACapModifier()`.
- Add `$statbonuses->GetSTR()`.
- Add `$statbonuses->GetSTRCapModifier()`.
- Add `$statbonuses->GetStrikeThrough()`.
- Add `$statbonuses->GetStringedModifier()`.
- Add `$statbonuses->GetStunBashChance()`.
- Add `$statbonuses->GetStunResist()`.
- Add `$statbonuses->GetTradeSkillMastery()`.
- Add `$statbonuses->GetTriggerMeleeThreshold()`.
- Add `$statbonuses->GetTriggerOnValueAmount()`.
- Add `$statbonuses->GetTriggerSpellThreshold()`.
- Add `$statbonuses->GetTripleAttackChance()`.
- Add `$statbonuses->GetTripleBackstab()`.
- Add `$statbonuses->GetTwoHandBluntBlock()`.
- Add `$statbonuses->GetUnfailingDivinity()`.
- Add `$statbonuses->GetVampirism()`.
- Add `$statbonuses->GetVoiceGraft()`.
- Add `$statbonuses->GetWindModifier()`.
- Add `$statbonuses->GetWIS()`.
- Add `$statbonuses->GetWISCapModifier()`.
- Add `$statbonuses->GetXPRateModifier()`.

# Notes
- Adds methods to get mob's stat bonuses to Mob methods.
- Adds support for stat bonuses class to Perl similar to Lua.

* Update perl_stat_bonuses.cpp

* Update perl_stat_bonuses.cpp
2023-07-02 10:26:46 -04:00
Alex King e12368f002 [Quest API] Add Hate Entry Methods to Perl (#3459)
# Perl
- Add `$hate_entry->GetFrenzy()`.
- Add `$hate_entry->SetDamage(value)`.
- Add `$hate_entry->SetEnt(mob)`.
- Add `$hate_entry->SetFrenzy(is_frenzy)`.
- Add `$hate_entry->SetHate(value)`.

# Lua
- Convert `hate_entry:GetFrenzy()` to `bool` instead of `int`, as `is_entity_frenzy` is a `bool`.
2023-07-02 10:26:37 -04:00
Alex King a13fa07e68 [Quest API] Add Spawn2 Class to Perl (#3456)
# Perl
- Add `$spawn->Depop()`.
- Add `$spawn->Disable()`.
- Add `$spawn->Enable()`.
- Add `$spawn->ForceDespawn()`.
- Add `$spawn->GetCurrentNPCID()`.
- Add `$spawn->GetHeading()`.
- Add `$spawn->GetID()`.
- Add `$spawn->GetKillCount()`.
- Add `$spawn->GetRespawnTimer()`.
- Add `$spawn->GetSpawnCondition()`.
- Add `$spawn->GetSpawnGroupID()`.
- Add `$spawn->GetVariance()`.
- Add `$spawn->GetX()`.
- Add `$spawn->GetY()`.
- Add `$spawn->GetZ()`.
- Add `$spawn->IsEnabled()`.
- Add `$spawn->IsNPCPointerValid()`.
- Add `$spawn->LoadGrid()`.
- Add `$spawn->Repop()`.
- Add `$spawn->Repop(delay)`.
- Add `$spawn->Reset()`.
- Add `$spawn->SetCurrentNPCID(npc_id)`.
- Add `$spawn->SetNPCPointer(npc_pointer)`.
- Add `$spawn->SetRespawnTimer(new_respawn_time)`.
- Add `$spawn->SetTimer(duration)`.
- Add `$spawn->SetVariance(variance)`.

# Notes
- Adds support for Spawn2 class to Perl.
2023-07-02 10:26:32 -04:00
Chris Miles 7873ad3771 [Database] Set multi statements off when returning early (#3462) 2023-07-01 19:49:09 -04:00
Chris Miles dfadc237e5 [Logging] Fix logging crash when % are sent through query logs (#3461) 2023-07-01 19:49:01 -04:00
Alex King a1f2764978 [Cleanup/Feature] Add support for bots to #showstats/#mystats (#3427)
* Initial Push

* Update classes.cpp

* Update mob.cpp

* Update mob.cpp

* Update showstats.cpp

* Update mystats.cpp

* Remove unused variables.

* Update mob.cpp

* Update class.cpp

* Update race.cpp

* Update mob.h
2023-07-01 19:47:54 -04:00
Jonathan Sider 927d379e75 [Bug Fix] Add check for underscores in botcreate command (#3458)
* Update bot_command.cpp with botcreate check

Check for underscores in bot names as the server will replace with a space and add to the database. The bot can't be deleted/summoned or changed except by editing the database

* Update bot_command.cpp

* Update bot_command.cpp

---------

Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
2023-06-28 20:18:44 -04:00
Chris Miles a1f154749c [Release] 22.16.0 (#3457) 2023-06-28 17:51:05 -04:00
Alex King 42a2e19e73 [Commands] Consolidate #findX commands to a singular #find Command (#3452)
* Push up example for Kingly

* Update aa.cpp

* Update find.cpp

* Bulk push.

* Update aa.cpp

* Cleanup

* Repository method.

* Static aliasing

* Aliases

* Fix alias error.

* Update zone.cpp

* Update command.cpp

* Update find.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-06-27 21:53:20 -05:00
mibastian c56b2e3e03 [Fix] Fix error in 023_01_21_bots_raid_members.sql (#3453)
world process did not start. An strace showed something wrong in 023_01_21_bots_raid_members.sql.  Seemed like a snap&paste error.
2023-06-27 21:52:27 -05:00
Alex King b05f1d3218 [Bug Fix] Merchant Open Flag set only for regular Merchants (#3454)
* [Bug Fix] Merchant Open Flag set only for regular Merchants

* Update npc.cpp
2023-06-27 16:23:48 -04:00
Alex King a004924112 [Bug Fix] Fix NPC Item Stat Bonuses (#3444)
* [Bug Fix] Fix NPC Item Stat Bonuses

# Notes
- Due to https://github.com/EQEmu/Server/pull/3136 NPCs/Mercs were not receiving stat bonuses from their items, this fixes that.

* Update npc.h

* Changes.

* Cleanup

* Cleanup

* Update loottables.cpp

* Update npc.cpp

* Update loottables.cpp
2023-06-26 00:22:10 -04:00
Alex King 8d986c95cd [Commands] Add #finddeity Command (#3435)
# Notes
- Add `#finddeity` command.
- Remove `ConvertDeityTypeBitToDeityType` as it's unused.
- Rename `ConvertDeityTypeToDeityTypeBit` to `GetDeityBitmask`.
2023-06-25 23:00:32 -05:00
Alex King ef7a3cae17 [Commands] Cleanup #showbuffs Command (#3439)
* [Commands] Cleanup #showbuffs Command

# Notes
- Cleaned up messages and logic.
- Removed unnecessary itembonuses/spellbonuses stuff.
- Removed `Mob::ShowBuffList` as it's just a copy of this method.

* Update mob.cpp

* Further cleanup.

* Update mob.cpp

* Update mob.cpp
2023-06-25 22:59:47 -05:00
Alex King 050aba65b6 [Commands] Cleanup #viewcurrencies Command (#3441)
# Notes
- Utilize Dialogue Window table for cleanliness and readability.
2023-06-24 20:26:41 -04:00
Alex King 9154c90418 [Commands] Add #findlanguage Command (#3434)
# Notes
- Add `#findlanguage` command.
2023-06-24 20:26:29 -04:00
Alex King d558f9ece2 [Rules] Add ClientPetsUserOwnerNameInLastName rule (#3442)
* [Rules] Add ClientPetsUserOwnerNameInLastName rule

# Notes
- This rule defaults to `true` and maintains `Kinglykrab's Pet` as my pet's name, disabling allows you to manually modify the last name or have pets with no last name.

* Update npc.cpp
2023-06-24 20:01:40 -04:00
Alex King 327dacdbe1 [Cleanup] Remove GetACAvoid() from zone/merc.h (#3447)
- This is unused.
2023-06-24 20:00:56 -04:00
Alex King f2ff4245c0 [Commands] Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop (#3433)
* [Commands] Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop

# Notes
- `#merchant_close_shop` and `#merchant_open_shop` are now consolidated into `#merchantshop`.
- Command now works on any type of merchant instead of just regular merchants.
- Can be used on Merchants, Discord Merchants, Adventure Merchants, Norrath's Keepers Merchants, Dark Reign Merchants, and Alternate Currency Merchants.

* Update merchantshop.cpp

* Update merchantshop.cpp

* Update merchantshop.cpp
2023-06-24 13:14:19 -05:00
Alex King 3ceb743195 [Commands] Add #showspells Command (#3429)
* [Commands] Add #showspells Command

# Notes
- Add `#showspells` command to show your or your target's memorized spells or learned disciplines.

* Update client.cpp
2023-06-24 13:13:02 -05:00
Alex King 021f04c17d [Cleanup] Remove command_unlock from zone/command.h (#3431)
# Notes
- This is unused.
2023-06-24 13:10:19 -05:00
Alex King f7e2dbdce6 [Cleanup] Remove command_packetprofile from zone/command.h (#3432)
* [Cleanup] Remove command_packetprofile from zone/command.h

# Notes
- This is unused.

* Update command.h
2023-06-24 13:10:05 -05:00
Alex King 2a679f1002 [Cleanup] Remove command_showpetspell in zone/command.h (#3430)
# Notes
- This is unused.
2023-06-24 13:09:51 -05:00
Alex King 8c9849ec73 [Commands] Delete #showbonusstats Command (#3437)
# Notes
- Never seen this used, also missing 99% of the bonuses data.
2023-06-24 13:09:39 -05:00
Alex King 10086ce97c [Commands] Delete #spellinfo Command (#3438)
# Notes
- Never seen this used, also missing 99% of the spell data.
2023-06-24 13:09:23 -05:00
Alex King 223ae22f73 [Cleanup] Delete common/worldconn.cpp (#3436)
# Notes
- This is unused.
2023-06-24 13:05:45 -05:00
Alex King 4330494f57 [Commands] Cleanup #shownpcgloballoot and #showzonegloballoot Commands (#3440)
# Notes
- Cleanup messages and logic.
- Utilize Dialogue Window tables.
2023-06-24 13:03:37 -05:00
Alex King 64ae7e4529 [Cleanup] Remove _ClearWaypints() from zone/npc.h (#3445)
# Notes
- This is unused.
2023-06-24 12:58:28 -05:00
Alex King 58c3e267e1 [Cleanup] Remove GetACMit() from zone/merc.h (#3446)
# Notes
- This is unused.
2023-06-24 12:58:13 -05:00
Alex King 598483a1a4 [Cleanup] Remove acmod() from zone/merc.h (#3448)
# Notes
- This is unused.
2023-06-24 12:57:43 -05:00
Alex King c1122022b9 [Cleanup] Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h (#3449)
* [Cleanup] Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h

# Notes
- This is unused.

* Update npc.h
2023-06-24 12:57:21 -05:00
Chris Miles f2c4babd8d [Database] Fix database version checking edge case issue (#3428) 2023-06-22 18:00:23 -05:00
Akkadius 5249b065d3 [Release] 22.15.3 2023-06-19 19:15:42 -05:00
Alex King 9312261444 [Bug Fix] Fix improper condition in Water LOS checks (#3426)
# Notes
- Oversight on my part, should've been `==`, not `&&`.
2023-06-19 18:53:19 -04:00
Akkadius 85054fedf8 [Release] 22.15.2 (Hotfix) 2023-06-19 12:00:41 -05:00
Chris Miles 6d7beb1796 [Database] Fix multi-statement error reporting (#3425) 2023-06-19 11:55:32 -05:00
JJ 66e377fd4a [Readme] Update new location of database updates (#3424) 2023-06-19 12:12:59 -04:00
Akkadius 67c4c26f70 [Release] 22.15.1 2023-06-19 02:21:09 -05:00
Akkadius b1c8e3890a [Release] 22.15.0 2023-06-19 01:41:55 -05:00
Alex King d6e06a19a7 [Commands] Add missing subcommands to #npcedit (#3423)
# Notes
- Add `#npcedit model [Race ID]` to edit an NPC's race model.
- Add `#npcedit heroic_strikethrough [Heroic Strikethrough]` to edit an NPC's heroic strikethrough.
- Add `#npcedit faction_amount [Faction Amount]` to edit an NPC's faction amount.
2023-06-19 01:40:27 -05:00
Akkadius 4092b3a2cb [Release] 22.15.0 2023-06-19 01:38:12 -05:00
Alex King f4f0619618 [Bug Fix] Fix possible crash with #npcedit weapon (#3421)
# Notes
- Using `#npcedit weapon` without the secondary model had a chance to crash the zone you were in, i.e `#npcedit weapon 1`.

# Crash Logs
```txt
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802548]
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802549]
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802550]
[06-18-2023 16:26:55] [Zone] [Crash] [New LWP 802551]
[06-18-2023 16:26:55] [Zone] [Crash] [Thread debugging using libthread_db enabled]
[06-18-2023 16:26:55] [Zone] [Crash] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[06-18-2023 16:26:55] [Zone] [Crash] 0x00007f22b2b14207 in __GI___wait4 (pid=819104, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:26:55] [Zone] [Crash] [Current thread is 1 (Thread 0x7f22b29eab00 (LWP 802540))]
[06-18-2023 16:26:55] [Zone] [Crash] #0  0x00007f22b2b14207 in __GI___wait4 (pid=819104, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:26:55] [Zone] [Crash] #1  0x000055e4451b6b6e in print_trace () at /home/eqemu/code/common/crash.cpp:281
[06-18-2023 16:26:55] [Zone] [Crash] #2  <signal handler called>
[06-18-2023 16:26:55] [Zone] [Crash] #3  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[06-18-2023 16:26:55] [Zone] [Crash] #4  0x00007f22b2a6e537 in __GI_abort () at abort.c:79
[06-18-2023 16:26:55] [Zone] [Crash] #5  0x00007f22b2e067ec in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #6  0x00007f22b2e11966 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #7  0x00007f22b2e119d1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #8  0x00007f22b2e11c65 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #9  0x00007f22b2e08faa in std::__throw_logic_error(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:26:55] [Zone] [Crash] #10 0x000055e444216b48 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7fff9bd06620, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.tcc:212
[06-18-2023 16:26:55] [Zone] [Crash] #11 0x000055e44420dd09 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char const*> (this=0x7fff9bd06620, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:247
[06-18-2023 16:26:55] [Zone] [Crash] #12 0x000055e444203977 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7fff9bd06620, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:266
[06-18-2023 16:26:55] [Zone] [Crash] #13 0x000055e4441f93ef in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> > (this=0x7fff9bd06620, __s=0x0, __a=...) at /usr/include/c++/10/bits/basic_string.h:527
[06-18-2023 16:26:55] [Zone] [Crash] #14 0x000055e4445469df in command_npcedit (c=0x55e448292480, sep=0x7fff9bd09a20) at /home/eqemu/code/zone/gm_commands/npcedit.cpp:540
[06-18-2023 16:26:55] [Zone] [Crash] #15 0x000055e4444e2039 in command_realdispatch (c=0x55e448292480, message="#npcedit weapon 1", ignore_status=false) at /home/eqemu/code/zone/command.cpp:602
[06-18-2023 16:26:55] [Zone] [Crash] #16 0x000055e4443b03d3 in Client::ChannelMessageReceived (this=0x55e448292480, chan_num=8 '\b', language=0 '\000', lang_skill=100 'd', orig_message=0x55e44a69e314 "#npcedit weapon 1", targetname=0x55e44a69e280 "a_willowisp000", is_silent=false) at /home/eqemu/code/zone/client.cpp:1122
[06-18-2023 16:26:55] [Zone] [Crash] #17 0x000055e444454597 in Client::Handle_OP_ChannelMessage (this=0x55e448292480, app=0x55e449156a70) at /home/eqemu/code/zone/client_packet.cpp:4478
[06-18-2023 16:26:55] [Zone] [Crash] #18 0x000055e44443c5d2 in Client::HandlePacket (this=0x55e448292480, app=0x55e449156a70) at /home/eqemu/code/zone/client_packet.cpp:495
[06-18-2023 16:26:55] [Zone] [Crash] #19 0x000055e4444b7add in Client::Process (this=0x55e448292480) at /home/eqemu/code/zone/client_process.cpp:587
[06-18-2023 16:26:55] [Zone] [Crash] #20 0x000055e44472df12 in EntityList::MobProcess (this=0x55e445df07c0 <entity_list>) at /home/eqemu/code/zone/entity.cpp:510
[06-18-2023 16:26:55] [Zone] [Crash] #21 0x000055e444c149b0 in operator() (__closure=0x55e448dc9170, t=0x7fff9bd0c4a0) at /home/eqemu/code/zone/main.cpp:562
[06-18-2023 16:26:55] [Zone] [Crash] #22 0x000055e444c19fd2 in std::__invoke_impl<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/10/bits/invoke.h:60
[06-18-2023 16:26:55] [Zone] [Crash] #23 0x000055e444c19da1 in std::__invoke_r<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(struct {...} &) (__fn=...) at /usr/include/c++/10/bits/invoke.h:110
[06-18-2023 16:26:55] [Zone] [Crash] #24 0x000055e444c19ac8 in std::_Function_handler<void(EQ::Timer*), main(int, char**)::<lambda(EQ::Timer*)> >::_M_invoke(const std::_Any_data &, EQ::Timer *&&) (__functor=..., __args#0=@0x7fff9bd0bea0: 0x7fff9bd0c4a0) at /usr/include/c++/10/bits/std_function.h:291
[06-18-2023 16:26:55] [Zone] [Crash] #25 0x000055e444c1f4c5 in std::function<void (EQ::Timer*)>::operator()(EQ::Timer*) const (this=0x7fff9bd0c4a8, __args#0=0x7fff9bd0c4a0) at /usr/include/c++/10/bits/std_function.h:622
[06-18-2023 16:26:55] [Zone] [Crash] #26 0x000055e444c1d265 in EQ::Timer::Execute (this=0x7fff9bd0c4a0) at /home/eqemu/code/zone/../common/net/../event/timer.h:61
[06-18-2023 16:26:55] [Zone] [Crash] #27 0x000055e444c1d023 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::operator()(uv_timer_s*) const (__closure=0x0, handle=0x55e44832b570) at /home/eqemu/code/zone/../common/net/../event/timer.h:38
[06-18-2023 16:26:55] [Zone] [Crash] #28 0x000055e444c1d043 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::_FUN(uv_timer_s*) () at /home/eqemu/code/zone/../common/net/../event/timer.h:39
[06-18-2023 16:26:55] [Zone] [Crash] #29 0x000055e4454afb5d in uv__run_timers (loop=loop@entry=0x7f22b29ea7a8) at /home/eqemu/code/submodules/libuv/src/timer.c:178
[06-18-2023 16:26:55] [Zone] [Crash] #30 0x000055e4454b3182 in uv_run (loop=0x7f22b29ea7a8, mode=UV_RUN_DEFAULT) at /home/eqemu/code/submodules/libuv/src/unix/core.c:393
[06-18-2023 16:26:55] [Zone] [Crash] #31 0x000055e444c1ceeb in EQ::EventLoop::Run (this=0x7f22b29ea7a8) at /home/eqemu/code/zone/../common/net/../event/event_loop.h:25
[06-18-2023 16:26:55] [Zone] [Crash] #32 0x000055e444c18b6e in main (argc=1, argv=0x7fff9bd0d568) at /home/eqemu/code/zone/main.cpp:591
[06-18-2023 16:26:55] [Zone] [Crash] [Inferior 1 (process 802540) detached]
```

```txt
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819434]
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819436]
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819438]
[06-18-2023 16:29:51] [Zone] [Crash] [New LWP 819440]
[06-18-2023 16:29:51] [Zone] [Crash] [Thread debugging using libthread_db enabled]
[06-18-2023 16:29:51] [Zone] [Crash] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[06-18-2023 16:29:51] [Zone] [Crash] 0x00007f489d185207 in __GI___wait4 (pid=819646, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:29:51] [Zone] [Crash] [Current thread is 1 (Thread 0x7f489d05bb00 (LWP 819417))]
[06-18-2023 16:29:51] [Zone] [Crash] #0  0x00007f489d185207 in __GI___wait4 (pid=819646, stat_loc=0x0, options=0, usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
[06-18-2023 16:29:51] [Zone] [Crash] #1  0x000055d58e442b6e in print_trace () at /home/eqemu/code/common/crash.cpp:281
[06-18-2023 16:29:51] [Zone] [Crash] #2  <signal handler called>
[06-18-2023 16:29:51] [Zone] [Crash] #3  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[06-18-2023 16:29:51] [Zone] [Crash] #4  0x00007f489d0df537 in __GI_abort () at abort.c:79
[06-18-2023 16:29:51] [Zone] [Crash] #5  0x00007f489d4777ec in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #6  0x00007f489d482966 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #7  0x00007f489d4829d1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #8  0x00007f489d482c65 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #9  0x00007f489d479faa in std::__throw_logic_error(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
[06-18-2023 16:29:51] [Zone] [Crash] #10 0x000055d58d4a2b48 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7ffdbbca2500, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.tcc:212
[06-18-2023 16:29:51] [Zone] [Crash] #11 0x000055d58d499d09 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char const*> (this=0x7ffdbbca2500, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:247
[06-18-2023 16:29:51] [Zone] [Crash] #12 0x000055d58d48f977 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (this=0x7ffdbbca2500, __beg=0x0, __end=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/10/bits/basic_string.h:266
[06-18-2023 16:29:51] [Zone] [Crash] #13 0x000055d58d4853ef in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> > (this=0x7ffdbbca2500, __s=0x0, __a=...) at /usr/include/c++/10/bits/basic_string.h:527
[06-18-2023 16:29:51] [Zone] [Crash] #14 0x000055d58d7d29df in command_npcedit (c=0x55d59219f080, sep=0x7ffdbbca5900) at /home/eqemu/code/zone/gm_commands/npcedit.cpp:540
[06-18-2023 16:29:51] [Zone] [Crash] #15 0x000055d58d76e039 in command_realdispatch (c=0x55d59219f080, message="#npcedit weapon 1", ignore_status=false) at /home/eqemu/code/zone/command.cpp:602
[06-18-2023 16:29:51] [Zone] [Crash] #16 0x000055d58d63c3d3 in Client::ChannelMessageReceived (this=0x55d59219f080, chan_num=8 '\b', language=0 '\000', lang_skill=100 'd', orig_message=0x55d591b59b44 "#npcedit weapon 1", targetname=0x55d591b59ab0 "a_whiskered_bat002", is_silent=false) at /home/eqemu/code/zone/client.cpp:1122
[06-18-2023 16:29:51] [Zone] [Crash] #17 0x000055d58d6e0597 in Client::Handle_OP_ChannelMessage (this=0x55d59219f080, app=0x55d592711c60) at /home/eqemu/code/zone/client_packet.cpp:4478
[06-18-2023 16:29:51] [Zone] [Crash] #18 0x000055d58d6c85d2 in Client::HandlePacket (this=0x55d59219f080, app=0x55d592711c60) at /home/eqemu/code/zone/client_packet.cpp:495
[06-18-2023 16:29:51] [Zone] [Crash] #19 0x000055d58d743add in Client::Process (this=0x55d59219f080) at /home/eqemu/code/zone/client_process.cpp:587
[06-18-2023 16:29:51] [Zone] [Crash] #20 0x000055d58d9b9f12 in EntityList::MobProcess (this=0x55d58f07c7c0 <entity_list>) at /home/eqemu/code/zone/entity.cpp:510
[06-18-2023 16:29:51] [Zone] [Crash] #21 0x000055d58dea09b0 in operator() (__closure=0x55d591a07f10, t=0x7ffdbbca8380) at /home/eqemu/code/zone/main.cpp:562
[06-18-2023 16:29:51] [Zone] [Crash] #22 0x000055d58dea5fd2 in std::__invoke_impl<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/10/bits/invoke.h:60
[06-18-2023 16:29:51] [Zone] [Crash] #23 0x000055d58dea5da1 in std::__invoke_r<void, main(int, char**)::<lambda(EQ::Timer*)>&, EQ::Timer*>(struct {...} &) (__fn=...) at /usr/include/c++/10/bits/invoke.h:110
[06-18-2023 16:29:51] [Zone] [Crash] #24 0x000055d58dea5ac8 in std::_Function_handler<void(EQ::Timer*), main(int, char**)::<lambda(EQ::Timer*)> >::_M_invoke(const std::_Any_data &, EQ::Timer *&&) (__functor=..., __args#0=@0x7ffdbbca7d80: 0x7ffdbbca8380) at /usr/include/c++/10/bits/std_function.h:291
[06-18-2023 16:29:51] [Zone] [Crash] #25 0x000055d58deab4c5 in std::function<void (EQ::Timer*)>::operator()(EQ::Timer*) const (this=0x7ffdbbca8388, __args#0=0x7ffdbbca8380) at /usr/include/c++/10/bits/std_function.h:622
[06-18-2023 16:29:51] [Zone] [Crash] #26 0x000055d58dea9265 in EQ::Timer::Execute (this=0x7ffdbbca8380) at /home/eqemu/code/zone/../common/net/../event/timer.h:61
[06-18-2023 16:29:51] [Zone] [Crash] #27 0x000055d58dea9023 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::operator()(uv_timer_s*) const (__closure=0x0, handle=0x55d590f6a610) at /home/eqemu/code/zone/../common/net/../event/timer.h:38
[06-18-2023 16:29:51] [Zone] [Crash] #28 0x000055d58dea9043 in EQ::Timer::Start(unsigned long, bool)::{lambda(uv_timer_s*)#1}::_FUN(uv_timer_s*) () at /home/eqemu/code/zone/../common/net/../event/timer.h:39
[06-18-2023 16:29:51] [Zone] [Crash] #29 0x000055d58e73bb5d in uv__run_timers (loop=loop@entry=0x7f489d05b7a8) at /home/eqemu/code/submodules/libuv/src/timer.c:178
[06-18-2023 16:29:51] [Zone] [Crash] #30 0x000055d58e73f182 in uv_run (loop=0x7f489d05b7a8, mode=UV_RUN_DEFAULT) at /home/eqemu/code/submodules/libuv/src/unix/core.c:393
[06-18-2023 16:29:51] [Zone] [Crash] #31 0x000055d58dea8eeb in EQ::EventLoop::Run (this=0x7f489d05b7a8) at /home/eqemu/code/zone/../common/net/../event/event_loop.h:25
[06-18-2023 16:29:51] [Zone] [Crash] #32 0x000055d58dea4b6e in main (argc=1, argv=0x7ffdbbca9448) at /home/eqemu/code/zone/main.cpp:591
[06-18-2023 16:29:51] [Zone] [Crash] [Inferior 1 (process 819417) detached]
```
2023-06-19 01:32:36 -05:00
Alex King 71ca7f9b39 [Cleanup] Default skill type to Hand to Hand in #npcedit meleetype (#3422)
# Notes
- We default to `28` in the database, so we need to default to this in `#npcedit meleetype` in case the operator only sets the first melee type this avoids the NPC hitting with `1H Blunt (Skill ID 0)`.
2023-06-19 01:32:13 -05:00
Chris Miles 5fcc83b4b6 [Database] Implement native database migrations in server (#2857)
* [Database] Implement native database updates in server

* Cleanup

* Delete db_update_manifest.txt

* Bots updates

* Final tweaks

* Revert manifest

* Tweaks

* Remove code from eqemu_server.pl

* Update database_update.cpp

* Add user prompt update skipping with timeouts

* Add termcolor IS_TTY is check

* Update database_conversions.cpp

* Remove large migrations

* Push

* fix headers.

* Remove last of non-bot large migrations

* Update database_update_manifest.cpp

* More purging

* Tweaks

* Bot migrations

* More work

* Tweaks

* Implement multi-statement query execution only for migrations

* Add CLI database:updates

* Add bootstrap commands

* Upload bootstrap sql's

* Update bot_tables_bootstrap.sql

* Update bot_tables_bootstrap.sql

* Add mercs:bootstrap and bots:bootstrap

* Update bot_tables_bootstrap.sql

* Update database.cpp

* Update bot_tables_bootstrap.sql

* More cleanup

* Add mercs:disable and bots:disable

* Update eqemu_server.pl

* Update eqemu_server.pl

* Update eqemu_server.pl

* Test cases

* Update eqemu_server.pl

* Delete 2023_05_08_character_tribute_primary_key.sql

* Post rebase fixes

* Post rebase tweaks

* Delete errant files

* Rebase files from master

* More adjustments

* Delete files no longer used

* Add missing migrations

* bots:bootstrap is now bots:enable

---------

Co-authored-by: Aeadoin <109764533+Aeadoin@users.noreply.github.com>
2023-06-19 01:31:07 -05:00
Chris Miles 1f25639dd3 [Release] 22.14.1 (#3420) 2023-06-18 15:38:50 -05:00
Chris Miles 2a176835b1 [CI] Build static linux binaries (#3419)
* [CI] Build static linux binaries

* Fix tests

* Update linux-build.sh
2023-06-18 15:19:25 -05:00
Chris Miles fff3e77a6e [Binaries] Add support for static linking (portable) binaries (#3417)
* [Binaries] Add support for static linking (portable) binaries

* Update CMakeLists.txt
2023-06-18 14:41:39 -05:00
Alex King 6efb9ec228 [Quest API] Add convert_money_to_string() to Perl/Lua (#3418)
* [Quest API] Add convert_money_to_string() to Perl/Lua

# Perl
- Add `quest::convert_money_to_string(money_hash)`.

# Lua
- Add `eq.convert_money_to_string(money_table)`.

# Notes
- Allows operators to convert money in to a readable string using `Strings::Money`.

# Examples

## Perl
```pl
sub EVENT_SAY {
	if ($text=~/#a/i) {
		my %money_data = (
			"platinum" => 3123,
			"gold" => 5692,
			"copper" => 9
		);
		quest::message(315, quest::convert_money_to_string(%money_data));
	}
}
```

## Lua
```lua
function event_say(e)
	if e.message:find("#a") then
		local money_data = {
			gold = 12,
			silver = 523904,
			copper = 3
		}
		eq.message(315, "Lua: " .. eq.convert_money_to_string(money_data))
	end
end```

* Update lua_general.cpp
2023-06-18 15:29:14 -04:00
Chris Miles a663c822e8 [CLI] Add mercs:enable and mercs:disable commands (#3416)
* [CLI] Add `mercs:enable` and `mercs:disable` commands

* Update descriptions
2023-06-17 19:30:36 -05:00
Chris Miles cf49b2fe49 [CLI] Add bots:enable and bots:disable commands (#3415)
* [CLI] Add `bots:enable` and `bots:disable` commands

* Add input warning
2023-06-17 18:48:47 -05:00
Chris Miles b45e0e80b5 [Database] Add query multi statement execution support (#3414) 2023-06-17 18:20:13 -05:00
Chris Miles 3200145d01 [CLI] Console menu validation fixes (#3413) 2023-06-17 18:19:55 -05:00
Chris Miles 53563b9720 [Backups] Move world database:dump to use MySQL credentials file (#3410) 2023-06-17 18:16:29 -05:00
Chris Miles 1e22baf267 [Logging] Logging improvements, console silencing, terminal coloring (#3412) 2023-06-17 18:16:21 -05:00
Chris Miles d99c3145ad [Strings] Add more test cases for string utils (#3411) 2023-06-17 18:16:14 -05:00
Alex King 57243c6799 [Telnet] Add cross zone/world wide cast and move functionality to Telnet (#3409)
* [Telnet] Add cross zone/world wide cast and move functionality to Telnet

# Notes
- Add `czcast`, `czmove`, `wwcast`, and `wwmove` to Telnet functionality.
- Allows operators to cast spells across zone/world-wide and move players across zone/world-wide from telnet.

* Update console.cpp

* Update console.cpp

* Validation

* Update console.cpp
2023-06-17 17:50:37 -05:00
Paul Coene 1100668f21 [Targeting] Fix bug when using /tar on invalid target (#3407)
* [Targetting] Fix bug when using /tar on invalid target

* Removed instrumentation.
2023-06-17 16:53:59 -05:00
nytmyr 0cf454dc29 [Feature] Add Water Line of Sight Checks (#3408)
* [Feature] Add Water Line of Sight Checks

This adds rules to enable or disable checks for spells and autofire to prevent casting or autofire from landing if the player or bot do not match their targets plane in regards to water.

Currently players and bots can cast or autofire if they are not in the water but their target is and vice versa, this should not be possible.

RuleB(Combat, WaterMatchRequiredForAutoFireLoS) set to True (default) checks that both parties are in or out of the water for AutoFire to work.

RuleB(Spells, WaterMatchRequiredForLoS) set to True (default) checks that both parties are in or out of the water for spells to land.

* Cleanup.

* Cleanup.

* Cleanup.

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-06-17 12:32:15 -05:00
Paul Coene 75391d96f4 [Release] 22.13.1 (#3406)
* Update version.h for /target Emergency release 22.13.1

* Update CHANGELOG.md for 22.13.1 release

* Update package.json for 22.13.1 emergency patch release

* Update CHANGELOG.md using tool as instructed
2023-06-13 17:50:33 -04:00
Paul Coene 81b07a5aa0 [Targeting] Revert #3383 (#3405) 2023-06-13 15:48:35 -05:00
Alex King 774aa99b29 [Release] 22.13.0 (#3404)
* [Release] 22.13.0

* Update CHANGELOG.md
2023-06-12 20:56:43 -04:00
Alex King 756e835144 [Quest API/Cleanup] Add several spell methods to Perl/Lua (#3379)
* [Quest API/Cleanup] Add several spell methods to Perl/Lua

- Add `quest::CalculateCorruptionCounters(spell_id)`.
- Add `quest::CalculateCounters(spell_id)`.
- Add `quest::CalculateCurseCounters(spell_id)`.
- Add `quest::CalculateDiseaseCounters(spell_id)`.
- Add `quest::CalculatePoisonCounters(spell_id)`.
- Add `quest::GetSpellEffectDescriptionNumber(spell_id)`.
- Add `quest::GetSpellEffectIndex(spell_id, effect_id)`.
- Add `quest::GetSpellFuriousBash(spell_id)`.
- Add `quest::GetSpellMinimumLevel(spell_id)`.
- Add `quest::GetSpellNimbusEffect(spell_id)`.
- Add `quest::GetSpellPartialMagicRuneAmount(spell_id)`.
- Add `quest::GetSpellPartialMagicRuneReduction(spell_id)`.
- Add `quest::GetSpellPartialMeleeRuneAmount(spell_id)`.
- Add `quest::GetSpellPartialMeleeRuneReduction(spell_id)`.
- Add `quest::GetSpellProcLimitTimer(spell_id)`.
- Add `quest::GetSpellResistType(spell_id)`.
- Add `quest::GetSpellResurrectionSicknessCheck(spell_id_one, spell_id_two)`.
- Add `quest::GetSpellTargetType(spell_id)`.
- Add `quest::GetSpellTriggerSpellID(spell_id)`.
- Add `quest::GetSpellViralMaximumSpreadTime(spell_id)`.
- Add `quest::GetSpellViralMinimumSpreadTime(spell_id)`.
- Add `quest::GetSpellViralSpreadRange(spell_id)`.
- Add `quest::IsAEDurationSpell(spell_id)`.
- Add `quest::IsAENukeSpell(spell_id)`.
- Add `quest::IsAERainNukeSpell(spell_id)`.
- Add `quest::IsAllianceSpell(spell_id)`.
- Add `quest::IsBardOnlyStackEffect(effect_id)`.
- Add `quest::IsBardSong(spell_id)`.
- Add `quest::IsBlankSpellEffect(spell_id, effect_index)`.
- Add `quest::IsBlindSpell(spell_id)`.
- Add `quest::IsBuffSpell(spell_id)`.
- Add `quest::IsCastNotStandingSpell(spell_id)`.
- Add `quest::IsCastOnFadeDurationSpell(spell_id)`.
- Add `quest::IsCastRestrictedSpell(spell_id)`.
- Add `quest::IsCastTimeReductionSpell(spell_id)`.
- Add `quest::IsCastWhileInvisibleSpell(spell_id)`.
- Add `quest::IsCharmSpell(spell_id)`.
- Add `quest::IsCombatSkill(spell_id)`.
- Add `quest::IsCompleteHealDurationSpell(spell_id)`.
- Add `quest::IsCompleteHealSpell(spell_id)`.
- Add `quest::IsCureSpell(spell_id)`.
- Add `quest::IsDamageSpell(spell_id)`.
- Add `quest::IsDeathSaveSpell(spell_id)`.
- Add `quest::IsDebuffSpell(spell_id)`.
- Add `quest::IsDetrimentalSpell(spell_id)`.
- Add `quest::IsDiscipline(spell_id)`.
- Add `quest::IsDisciplineBuff(spell_id)`.
- Add `quest::IsDiseaseCounterSpell(spell_id)`.
- Add `quest::IsDistanceModifierSpell(spell_id)`.
- Add `quest::IsEffectIgnoredInStacking(effect_id)`.
- Add `quest::IsFastHealSpell(spell_id)`.
- Add `quest::IsFearSpell(spell_id)`.
- Add `quest::IsFocusLimit(effect_id)`.
- Add `quest::IsFullDeathSaveSpell(spell_id)`.
- Add `quest::IsGateSpell(spell_id)`.
- Add `quest::IsImprovedDamageSpell(spell_id)`.
- Add `quest::IsImprovedHealingSpell(spell_id)`.
- Add `quest::IsIncreaseDurationSpell(spell_id)`.
- Add `quest::IsIncreaseRangeSpell(spell_id)`.
- Add `quest::IsInstrumentModifierAppliedToSpellEffect(spell_id, effect_id)`.
- Add `quest::IsInvisibleSpell(spell_id)`.
- Add `quest::IsInvulnerabilitySpell(spell_id)`.
- Add `quest::IsLDoNObjectSpell(spell_id)`.
- Add `quest::IsLifetapSpell(spell_id)`.
- Add `quest::IsMagicRuneSpell(spell_id)`.
- Add `quest::IsManaCostReductionSpell(spell_id)`.
- Add `quest::IsManaTapSpell(spell_id)`.
- Add `quest::IsMesmerizeSpell(spell_id)`.
- Add `quest::IsNoDetrimentalSpellAggroSpell(spell_id)`.
- Add `quest::IsPBAENukeSpell(spell_id)`.
- Add `quest::IsPartialDeathSaveSpell(spell_id)`.
- Add `quest::IsPartialResistableSpell(spell_id)`.
- Add `quest::IsPercentalHealSpell(spell_id)`.
- Add `quest::IsPersistDeathSpell(spell_id)`.
- Add `quest::IsPetSpell(spell_id)`.
- Add `quest::IsPoisonCounterSpell(spell_id)`.
- Add `quest::IsPulsingBardSong(spell_id)`.
- Add `quest::IsPureNukeSpell(spell_id)`.
- Add `quest::IsRegularGroupHealSpell(spell_id)`.
- Add `quest::IsRegularSingleTargetHealSpell(spell_id)`.
- Add `quest::IsResistDebuffSpell(spell_id)`.
- Add `quest::IsResistableSpell(spell_id)`.
- Add `quest::IsRestAllowedSpell(spell_id)`.
- Add `quest::IsResurrectionEffects(spell_id)`.
- Add `quest::IsRuneSpell(spell_id)`.
- Add `quest::IsRunning(spell_id)`.
- Add `quest::IsSacrificeSpell(spell_id)`.
- Add `quest::IsSelfConversionSpell(spell_id)`.
- Add `quest::IsShadowStepSpell(spell_id)`.
- Add `quest::IsShortDurationBuff(spell_id)`.
- Add `quest::IsSpellUsableInThisZoneType(spell_id)`.
- Add `quest::IsSpellUsableInThisZoneType(spell_id, zone_type)`.
- Add `quest::IsStackableDOT(spell_id)`.
- Add `quest::IsStunSpell(spell_id)`.
- Add `quest::IsSuccorSpell(spell_id)`.
- Add `quest::IsSummonItemSpell(spell_id)`.
- Add `quest::IsSummonPCSpell(spell_id)`.
- Add `quest::IsSummonPetSpell(spell_id)`.
- Add `quest::IsSummonSkeletonSpell(spell_id)`.
- Add `quest::IsSummonSpell(spell_id)`.
- Add `quest::IsSuspendableSpell(spell_id)`.
- Add `quest::IsTargetRequiredForSpell(spell_id)`.
- Add `quest::IsTargetableAESpell(spell_id)`.
- Add `quest::IsTeleportSpell(spell_id)`.
- Add `quest::IsTranslocateSpell(spell_id)`.
- Add `quest::IsValidSpell(spell_id)`.
- Add `quest::IsVeryFastHealSpell(spell_id)`.
- Add `quest::IsVirusSpell(spell_id)`.

- Add `eq.calculate_corruption_counters(spell_id)`.
- Add `eq.calculate_counters(spell_id)`.
- Add `eq.calculate_curse_counters(spell_id)`.
- Add `eq.calculate_disease_counters(spell_id)`.
- Add `eq.calculate_poison_counters(spell_id)`.
- Add `eq.get_spell_effect_description_number(spell_id)`.
- Add `eq.get_spell_effect_index(spell_id, effect_id)`.
- Add `eq.get_spell_furious_bash(spell_id)`.
- Add `eq.get_spell_level(spell_id, class_id)`.
- Add `eq.get_spell_minimum_level(spell_id)`.
- Add `eq.get_spell_nimbus_effect(spell_id)`.
- Add `eq.get_spell_partial_magic_rune_amount(spell_id)`.
- Add `eq.get_spell_partial_magic_rune_reduction(spell_id)`.
- Add `eq.get_spell_partial_melee_rune_amount(spell_id)`.
- Add `eq.get_spell_partial_melee_rune_reduction(spell_id)`.
- Add `eq.get_spell_proc_limit_timer(spell_id)`.
- Add `eq.get_spell_resist_type(spell_id)`.
- Add `eq.get_spell_resurrection_sickness_check(spell_id_one, spell_id_two)`.
- Add `eq.get_spell_target_type(spell_id)`.
- Add `eq.get_spell_trigger_spell_id(spell_id)`.
- Add `eq.get_spell_viral_maximum_spread_time(spell_id)`.
- Add `eq.get_spell_viral_minimum_spread_time(spell_id)`.
- Add `eq.get_spell_viral_spread_range(spell_id)`.
- Add `eq.is_ae_duration_spell(spell_id)`.
- Add `eq.is_ae_nuke_spell(spell_id)`.
- Add `eq.is_ae_rain_nuke_spell(spell_id)`.
- Add `eq.is_alliance_spell(spell_id)`.
- Add `eq.is_bard_only_stack_effect(spell_id)`.
- Add `eq.is_bard_song(spell_id)`.
- Add `eq.is_beneficial_spell(spell_id)`.
- Add `eq.is_blank_spell_effect(spell_id)`.
- Add `eq.is_blind_spell(spell_id)`.
- Add `eq.is_buff_spell(spell_id)`.
- Add `eq.is_cast_not_standing_spell(spell_id)`.
- Add `eq.is_cast_on_fade_duration_spell(spell_id)`.
- Add `eq.is_cast_restricted_spell(spell_id)`.
- Add `eq.is_cast_time_reduction_spell(spell_id)`.
- Add `eq.is_cast_while_invisible_spell(spell_id)`.
- Add `eq.is_charm_spell(spell_id)`.
- Add `eq.is_combat_skill(spell_id)`.
- Add `eq.is_complete_heal_duration_spell(spell_id)`.
- Add `eq.is_complete_heal_spell(spell_id)`.
- Add `eq.is_cure_spell(spell_id)`.
- Add `eq.is_damage_spell(spell_id)`.
- Add `eq.is_death_save_spell(spell_id)`.
- Add `eq.is_debuff_spell(spell_id)`.
- Add `eq.is_detrimental_spell(spell_id)`.
- Add `eq.is_discipline(spell_id)`.
- Add `eq.is_discipline_buff(spell_id)`.
- Add `eq.is_disease_counter_spell(spell_id)`.
- Add `eq.is_distance_modifier_spell(spell_id)`.
- Add `eq.is_effect_ignored_in_stacking(effect_id)`.
- Add `eq.is_effect_in_spell(spell_id, effect_id)`.
- Add `eq.is_fast_heal_spell(spell_id)`.
- Add `eq.is_fear_spell(spell_id)`.
- Add `eq.is_focus_limit(effect_id)`.
- Add `eq.is_full_death_save_spell(spell_id)`.
- Add `eq.is_gate_spell(spell_id)`.
- Add `eq.is_group_complete_heal_spell(spell_id)`.
- Add `eq.is_group_heal_over_time_spell(spell_id)`.
- Add `eq.is_group_only_spell(spell_id)`.
- Add `eq.is_group_spell(spell_id)`.
- Add `eq.is_harmony_spell(spell_id)`.
- Add `eq.is_haste_spell(spell_id)`.
- Add `eq.is_heal_over_time_spell(spell_id)`.
- Add `eq.is_health_spell(spell_id)`.
- Add `eq.is_illusion_spell(spell_id)`.
- Add `eq.is_improved_damage_spell(spell_id)`.
- Add `eq.is_improved_healing_spell(spell_id)`.
- Add `eq.is_increase_duration_spell(spell_id)`.
- Add `eq.is_increase_range_spell(spell_id)`.
- Add `eq.is_instrument_modifier_applied_to_spell_effect(spell_id, effect_id)`.
- Add `eq.is_invisible_spell(spell_id)`.
- Add `eq.is_invulnerability_spell(spell_id)`.
- Add `eq.is_ldon_object_spell(spell_id)`.
- Add `eq.is_lifetap_spell(spell_id)`.
- Add `eq.is_magic_rune_spell(spell_id)`.
- Add `eq.is_mana_cost_reduction_spell(spell_id)`.
- Add `eq.is_mana_tap_spell(spell_id)`.
- Add `eq.is_mesmerize_spell(spell_id)`.
- Add `eq.is_no_detrimental_spell_aggro_spell(spell_id)`.
- Add `eq.is_partial_death_save_spell(spell_id)`.
- Add `eq.is_partial_resistable_spell(spell_id)`.
- Add `eq.is_pbae_nuke_spell(spell_id)`.
- Add `eq.is_percental_heal_spell(spell_id)`.
- Add `eq.is_persist_death_spell(spell_id)`.
- Add `eq.is_pet_spell(spell_id)`.
- Add `eq.is_poison_counter_spell(spell_id)`.
- Add `eq.is_pulsing_bard_song(spell_id)`.
- Add `eq.is_pure_nuke_spell(spell_id)`.
- Add `eq.is_regular_group_heal_spell(spell_id)`.
- Add `eq.is_regular_single_target_heal_spell(spell_id)`.
- Add `eq.is_resist_debuff_spell(spell_id)`.
- Add `eq.is_resistable_spell(spell_id)`.
- Add `eq.is_rest_allowed_spell(spell_id)`.
- Add `eq.is_resurrection_effects(spell_id)`.
- Add `eq.is_rune_spell(spell_id)`.
- Add `eq.is_sacrifice_spell(spell_id)`.
- Add `eq.is_self_conversion_spell(spell_id)`.
- Add `eq.is_shadow_step_spell(spell_id)`.
- Add `eq.is_short_duration_buff(spell_id)`.
- Add `eq.is_spell_usable_in_this_zone_type(spell_id)`.
- Add `eq.is_spell_usable_in_this_zone_type(spell_id, zone_type)`.
- Add `eq.is_stackable_dot(spell_id)`.
- Add `eq.is_stun_spell(spell_id)`.
- Add `eq.is_succor_spell(spell_id)`.
- Add `eq.is_summon_item_spell(spell_id)`.
- Add `eq.is_summon_pc_spell(spell_id)`.
- Add `eq.is_summon_pet_spell(spell_id)`.
- Add `eq.is_summon_skeleton_spell(spell_id)`.
- Add `eq.is_summon_spell(spell_id)`.
- Add `eq.is_suspendable_spell(spell_id)`.
- Add `eq.is_target_required_for_spell(spell_id)`.
- Add `eq.is_targetable_ae_spell(spell_id)`.
- Add `eq.is_teleport_spell(spell_id)`.
- Add `eq.is_tgb_compatible_spell(spell_id)`.
- Add `eq.is_translocate_spell(spell_id)`.
- Add `eq.is_valid_spell(spell_id)`.
- Add `eq.is_very_fast_heal_spell(spell_id)`.
- Add `eq.is_virus_spell(spell_id)`.

- A lot of cleanup in the logic and naming of these methods was done.
- Missing GM restricted spells like Guide spells and GM Health buffs were added as defines.
- Good effect values were added as defines.
- Resurrection effects non-stacking value was added as a define.
- Max fast heal casting time and max very fast heal casting time were added as defines.
- `SE_Display` was uncommented so we could use it instead of the magic number `425`.
- `IsEvacSpell(spell_id)` was removed as it was unnecessary since `IsSuccorSpell(spell_id)` checks for `SE_Succor` as well.
- `GetMorphTrigger(spell_id)` was removed as it was unused.
- `GroupOnlySpell(spell_id)` was removed as it was unnecessary since `IsGroupOnlySpell(spell_id)` exists.
- `CanUseSpell(spell_id)` was removed as it was unnecessary since `GetSpellLevel(spell_id, class_id)` exists.
- `BeneficialSpell(spell_id)` was removed as it was unnecessary since `IsBeneficialSpell(spell_id)` exists.

* Update spell_effects.cpp

* Update spdat.cpp
2023-06-12 20:27:22 -04:00
Alex King c5c575b028 [Quest API] Add GetEXPForLevel() to Perl/Lua (#3403)
# Perl
- Add `$client->GetEXPForLevel(check_level)`.

# Lua
- Add `client:GetEXPForLevel(check_level)`.

# Notes
- This allows operators to see the required experience for a level based on the client provided, this takes race/class modifiers into account as well if enabled.
2023-06-12 19:18:39 -05:00
Alex King 152e99444c [Cleanup] Remove GetClientCount() from zone/entity.cpp and zone/entity.h (#3392)
* [Cleanup] Remove GetClientCount() from zone/entity.cpp and zone/entity.h

# Notes
- This is unused.

* Update entity.cpp
2023-06-12 19:18:17 -05:00
Alex King 795df5c597 [Cleanup] Remove CountTempPets() from zone/entity.cpp and zone/entity.h (#3390)
* [Cleanup] Remove CountTempPets() from zone/entity.cpp and zone/entity.h

# Notes
- This is unused.

* Update entity.h
2023-06-12 19:17:53 -05:00
Alex King 18eff726d0 [Commands] Assign #opcode to a #reload alias (#3401)
* [Commands] Assign #opcode to a #reload alias

# Notes
- Can use `#reload opcodes

* Add ServerOP_ReloadOpcodes
2023-06-12 18:42:39 -04:00
Alex King f06a37a009 [Cleanup] Add GMFind_Struct to packet structures (#3402)
* [Cleanup] Add GMFind_Struct to packet structures

# Notes
- X and Y were swapped in GMSummon_Struct so it displayed XYZ incorrectly in /find, adding its own struct fixes this.

* Update eq_packet_structs.h

* Update eq_packet_structs.h
2023-06-12 18:35:04 -04:00
Paul Coene ae53efc52c [Targeting] /tar <bad target> should not untarget existing target (#3383)
* [Targeting] /tar <bad target> should not untarget existing target

* Forgot string Id file.

* removed unneeded this->
2023-06-12 16:40:09 -05:00
Alex King 548eb65e1d [Cleanup] Remove InteractiveChat() and TakenAction() from zone/npc.h (#3382)
# Notes
- These are unimplemented and unused.
2023-06-12 15:14:34 -05:00
Alex King fede8760d4 [Cleanup] Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h (#3384)
# Notes
- This is unused.
2023-06-12 15:13:03 -05:00
Alex King 6faa202b57 [Cleanup] Remove pDBAsyncWorkID from zone/entity.h (#3385)
# Notes
- This is unused.
2023-06-12 15:12:47 -05:00
Alex King c406710623 [Cleanup] Remove GetClient(ip, port) from zone/entity.h (#3386)
# Notes
- This is unused.
2023-06-12 15:12:22 -05:00
Alex King 662c4012db [Cleanup] Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h (#3387)
# Notes
- These are unused.
2023-06-12 15:12:00 -05:00
Alex King 849e7b910d [Cleanup] Remove SendAATimer() from zone/entity.h (#3388)
# Notes
- This is unused.
2023-06-12 15:11:32 -05:00
Alex King 8e33755f02 [Cleanup] Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h (#3389)
# Notes
- These are unused.
2023-06-12 15:11:17 -05:00
Alex King dfaa929778 [Cleanup] Remove GateAllClients() from zone/entity.cpp and zone/entity.h (#3391)
# Notes
- This is unused.
2023-06-12 15:10:36 -05:00
Alex King 306b06745f [Cleanup] Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h (#3393)
# Notes
- This is unused.
2023-06-12 15:05:39 -05:00
Alex King 108fc82ee0 [Cleanup] Remove Evade() from zone/entity.cpp and zone/entity.h (#3394)
# Notes
- This is unused.
2023-06-12 15:05:23 -05:00
Alex King 577f61b082 [Cleanup] Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h (#3395)
# Notes
- This is unused.
2023-06-12 15:05:09 -05:00
Alex King a01cf0718d [Cleanup] Remove struct DynamicZoneSafeReturn from zone/entity.h (#3396)
# Notes
- This is unused.
2023-06-12 15:04:54 -05:00
Alex King 90412ba61b [Cleanup] Remove struct TradeEntity from zone/common.h (#3397)
# Notes
- This is unused.
2023-06-12 15:04:38 -05:00
Alex King 5cbc380c62 [Cleanup] Remove CHECK_LOS_STEP from zone/common.h (#3398)
# Notes
- This is unused.
2023-06-12 15:04:25 -05:00
Alex King 6c289a7c71 [Cleanup] Remove _BECOMENPCPET() and _NPCPET() from zone/common.h (#3399)
# Notes
- These are unused.
2023-06-12 15:04:09 -05:00
Alex King 57335b188f [Cleanup] Remove SPECIALIZE_MANA_REDUCE from zone/common.h (#3400)
# Notes
- This is unused.
2023-06-12 15:03:55 -05:00
Alex King 056e429100 [Cleanup] Remove NPC::AddCash() from npc.cpp/npc.h (#3380)
# Notes
- This is unused.
2023-06-09 11:50:52 -04:00
Paul Coene f548aeddb2 [Logging] Fixed statements that logged incorrect data (#3381) 2023-06-07 08:26:04 -04:00
Paul Coene 4ff9faa4e6 [Illusions] RandomizeFeatures and SetGender were killing db texture (#3376)
* [Illusions] RandomizeFeatures and SetGender were killing db texture

* Found actual source of the problem.
2023-06-06 08:30:41 -04:00
Alex King 17fc350d46 [Quest API] Add SendChannelMessage() to Perl/Lua (#3378)
* [Quest API] Add SendChannelMessage() to Perl/Lua

# Perl
- Add `quest::send_channel_message(channel_number, guild_id, language_id, language_skill, message)`.
- Add `quest::send_channel_message(from, channel_number, guild_id, language_id, language_skill, message)`.
- Add `quest::send_channel_message(from, to, channel_number, guild_id, language_id, language_skill, message)`.

# Lua
- Add `eq.send_channel_message(channel_number, guild_id, language_id, language_skill, message)`.
- Add `eq.send_channel_message(from, channel_number, guild_id, language_id, language_skill, message)`.
- Add `eq.send_channel_message(from, to, channel_number, guild_id, language_id, language_skill, message)`.

# Notes
- This allows operators to send channel messages from scripts like a broadcast or tell.

* Update zoneserver.cpp

* Update lua_general.cpp

* Update questmgr.h
2023-06-03 19:06:40 -05:00
Chris Miles b18bc66b42 [Release] 22.12.0 (#3377) 2023-05-30 00:10:44 -05:00
Alex King 324bfd448e [Commands] Add entity variable command (#3345)
* [Commands] Add entity variable commands

# Commands
- Add `#clearentityvariables` to clear all entity variables from yourself or your target.
- Add `#deleteentityvariable [Variable Name]` to delete an entity variable from yourself or your target.
- Add `#setentityvariable [Variable Name] [Variable Value]` to set an entity variable for yourself or your target.
- Add `#viewentityvariables [Search Criteria]` to view your or your target's entity variables.

# Notes
- `#setentityvariable` can use multi-word names/values by using double quotes like `#setentityvariable "Test Variable" "Test Value"`.
- `#viewentityvariable` does not require a search criteria, not using one shows all entity variables on yourself or your target.

* Update viewentityvariables.cpp

* Unnecessary parameter.

* Consolidate commands.

* Update entityvariable.cpp

* Update command.cpp

* Proper arguments.
2023-05-25 19:49:09 -04:00
Alex King 75560ee830 [Performance] Character tribute is now bulk saved (#3340)
* [Performance] Character tribute is now bulk saved

This pull request combines individual `character_tribute` queries during `Save()` into one.

This pull request also adds a primary key of `id` to `character_tribute` and renames the pre-existing `id` column to `character_id`, this allows us to use repositories for this table.

* Update zonedb.cpp

* Update zonedb.cpp
2023-05-25 19:21:18 -04:00
Alex King 50db7637aa [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua (#3363)
* [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua

# Perl
- Add `EVENT_MEMORIZE_SPELL`.
- Add `EVENT_UNMEMORIZE_SPELL`.
- Add `EVENT_SCRIBE_SPELL`.
- Add `EVENT_UNSCRIBE_SPELL`.

# Lua
- Add `event_memorize_spell`.
- Add `event_unmemorize_spell`.
- Add `event_scribe_spell`.
- Add `event_unscribe_spell`.

# Notes
- Allows operators to perform events on memorization, unmemorization, scribe, or unscribe.
- Cleaned up target description messages for `#unscribespell`.

* Update client.cpp
2023-05-25 18:18:14 -05:00
Alex King 67fdc75df3 [Commands] Cleanup #setanim (#3350)
# Notes
- Make use of constants instead of hard-coded strings.
2023-05-25 18:04:09 -05:00
Chris Miles 9993022418 [Pets] Fix saving inconsistencies with pets (#3375) 2023-05-25 11:33:34 -04:00
Alex King bd95ed44fd [Cleanup] Remove GetMaxRank() from aa_ability.cpp/aa_ability.h (#3347)
# Notes
- This is unused.
2023-05-24 22:44:53 -05:00
Alex King 65fd323eab [Cleanup] Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h (#3344)
# Notes
- These are unused.
2023-05-24 22:42:20 -05:00
Aeadoin 290c58741e [Bug Fix] Fix issue with Group Pointers/Member roles (#3374)
* [Bug Fix] Fix issue with Group Corruption

* cleanup

* Fix for Group Roles

* Fix for Group Roles
2023-05-24 22:40:59 -05:00
Alex King 39d0772a01 [Cleanup] Remove IsRaid() from raids.h (#3361)
# Notes
- This is unused.
2023-05-24 22:40:32 -05:00
Alex King 622fe50479 [Cleanup] Remove numMembers from raids.h (#3362)
# Notes
- This is unused.
2023-05-24 22:40:20 -05:00
Alex King f41a219309 [Cleanup] Remove CalcPetHp from spdat.h (#3364)
# Notes
- This is unused.
2023-05-24 22:37:04 -05:00
Alex King 23bc3c7fd6 [Cleanup] Remove Z_AGGRO from spdat.h (#3365)
# Notes
- This is unused.
2023-05-24 22:36:52 -05:00
Alex King 3144ac1a28 [Cleanup] Cleanup #setskill and #setskillall Commands (#3367)
# Notes
- No need to cap at 400 for max skill.
- When setting skill/skills, if we go over cap, set to cap.
2023-05-24 22:36:38 -05:00
Alex King a5106420e8 [Commands] Add #findcurrency Command (#3368)
* [Commands] Add #findcurrency Command

# Notes
- Allows you to find alternate currencies by item ID or name.
- Has a saylink for summoning a stack of the currency if the GM can use the `#summonitem` command.

* Update findcurrency.cpp

* Update findcurrency.cpp
2023-05-24 22:30:06 -05:00
Alex King 5a42c4f667 [Quest API] Add zone data methods to Perl/Lua (#3342)
# Perl
- Add `quest::GetZoneSafeX(zone_id)`.
- Add `quest::GetZoneSafeX(zone_id, version)`.
- Add `quest::GetZoneSafeY(zone_id)`.
- Add `quest::GetZoneSafeY(zone_id, version)`.
- Add `quest::GetZoneSafeZ(zone_id)`.
- Add `quest::GetZoneSafeZ(zone_id, version)`.
- Add `quest::GetZoneSafeHeading(zone_id)`.
- Add `quest::GetZoneSafeHeading(zone_id, version)`.
- Add `quest::GetZoneMinimumLevel(zone_id)`.
- Add `quest::GetZoneMinimumLevel(zone_id, version)`.
- Add `quest::GetZoneMaximumLevel(zone_id)`.
- Add `quest::GetZoneMaximumLevel(zone_id, version)`.
- Add `quest::GetZoneMinimumStatus(zone_id)`.
- Add `quest::GetZoneMinimumStatus(zone_id, version)`.
- Add `quest::GetZoneTimeZone(zone_id)`.
- Add `quest::GetZoneTimeZone(zone_id, version)`.
- Add `quest::GetZoneMaximumPlayers(zone_id)`.
- Add `quest::GetZoneMaximumPlayers(zone_id, version)`.
- Add `quest::GetZoneRuleSet(zone_id)`.
- Add `quest::GetZoneRuleSet(zone_id, version)`.
- Add `quest::GetZoneNote(zone_id)`.
- Add `quest::GetZoneNote(zone_id, version)`.
- Add `quest::GetZoneUnderworld(zone_id)`.
- Add `quest::GetZoneUnderworld(zone_id, version)`.
- Add `quest::GetZoneMinimumClip(zone_id)`.
- Add `quest::GetZoneMinimumClip(zone_id, version)`.
- Add `quest::GetZoneMaximumClip(zone_id)`.
- Add `quest::GetZoneMaximumClip(zone_id, version)`.
- Add `quest::GetZoneFogMinimumClip(zone_id)`.
- Add `quest::GetZoneFogMinimumClip(zone_id, slot)`.
- Add `quest::GetZoneFogMinimumClip(zone_id, slot, version)`.
- Add `quest::GetZoneFogMaximumClip(zone_id)`.
- Add `quest::GetZoneFogMaximumClip(zone_id, slot)`.
- Add `quest::GetZoneFogMaximumClip(zone_id, slot, version)`.
- Add `quest::GetZoneFogRed(zone_id)`.
- Add `quest::GetZoneFogRed(zone_id, slot)`.
- Add `quest::GetZoneFogRed(zone_id, slot, version)`.
- Add `quest::GetZoneFogGreen(zone_id)`.
- Add `quest::GetZoneFogGreen(zone_id, slot)`.
- Add `quest::GetZoneFogGreen(zone_id, slot, version)`.
- Add `quest::GetZoneFogBlue(zone_id)`.
- Add `quest::GetZoneFogBlue(zone_id, slot)`.
- Add `quest::GetZoneFogBlue(zone_id, slot, version)`.
- Add `quest::GetZoneSky(zone_id)`.
- Add `quest::GetZoneSky(zone_id, version)`.
- Add `quest::GetZoneZType(zone_id)`.
- Add `quest::GetZoneZType(zone_id, version)`.
- Add `quest::GetZoneExperienceMultiplier(zone_id)`.
- Add `quest::GetZoneExperienceMultiplier(zone_id, version)`.
- Add `quest::GetZoneWalkSpeed(zone_id)`.
- Add `quest::GetZoneWalkSpeed(zone_id, version)`.
- Add `quest::GetZoneTimeType(zone_id)`.
- Add `quest::GetZoneTimeType(zone_id, version)`.
- Add `quest::GetZoneFogDensity(zone_id)`.
- Add `quest::GetZoneFogDensity(zone_id, version)`.
- Add `quest::GetZoneFlagNeeded(zone_id)`.
- Add `quest::GetZoneFlagNeeded(zone_id, version)`.
- Add `quest::GetZoneCanBind(zone_id)`.
- Add `quest::GetZoneCanBind(zone_id, version)`.
- Add `quest::GetZoneCanCombat(zone_id)`.
- Add `quest::GetZoneCanCombat(zone_id, version)`.
- Add `quest::GetZoneCanLevitate(zone_id)`.
- Add `quest::GetZoneCanLevitate(zone_id, version)`.
- Add `quest::GetZoneCastOutdoor(zone_id)`.
- Add `quest::GetZoneCastOutdoor(zone_id, version)`.
- Add `quest::GetZoneHotzone(zone_id)`.
- Add `quest::GetZoneHotzone(zone_id, version)`.
- Add `quest::GetZoneInstanceType(zone_id)`.
- Add `quest::GetZoneInstanceType(zone_id, version)`.
- Add `quest::GetZoneShutdownDelay(zone_id)`.
- Add `quest::GetZoneShutdownDelay(zone_id, version)`.
- Add `quest::GetZonePEQZone(zone_id)`.
- Add `quest::GetZonePEQZone(zone_id, version)`.
- Add `quest::GetZoneExpansion(zone_id)`.
- Add `quest::GetZoneExpansion(zone_id, version)`.
- Add `quest::GetZoneBypassExpansionCheck(zone_id)`.
- Add `quest::GetZoneBypassExpansionCheck(zone_id, version)`.
- Add `quest::GetZoneSuspendBuffs(zone_id)`.
- Add `quest::GetZoneSuspendBuffs(zone_id, version)`.
- Add `quest::GetZoneRainChance(zone_id)`.
- Add `quest::GetZoneRainChance(zone_id, slot)`.
- Add `quest::GetZoneRainChance(zone_id, slot, version)`.
- Add `quest::GetZoneRainDuration(zone_id)`.
- Add `quest::GetZoneRainDuration(zone_id, slot)`.
- Add `quest::GetZoneRainDuration(zone_id, slot, version)`.
- Add `quest::GetZoneSnowChance(zone_id)`.
- Add `quest::GetZoneSnowChance(zone_id, slot)`.
- Add `quest::GetZoneSnowChance(zone_id, slot, version)`.
- Add `quest::GetZoneSnowDuration(zone_id)`.
- Add `quest::GetZoneSnowDuration(zone_id, slot)`.
- Add `quest::GetZoneSnowDuration(zone_id, slot, version)`.
- Add `quest::GetZoneGravity(zone_id)`.
- Add `quest::GetZoneGravity(zone_id, version)`.
- Add `quest::GetZoneType(zone_id)`.
- Add `quest::GetZoneType(zone_id, version)`.
- Add `quest::GetZoneSkyLock(zone_id)`.
- Add `quest::GetZoneSkyLock(zone_id, version)`.
- Add `quest::GetZoneFastRegenHP(zone_id)`.
- Add `quest::GetZoneFastRegenHP(zone_id, version)`.
- Add `quest::GetZoneFastRegenMana(zone_id)`.
- Add `quest::GetZoneFastRegenMana(zone_id, version)`.
- Add `quest::GetZoneFastRegenEndurance(zone_id)`.
- Add `quest::GetZoneFastRegenEndurance(zone_id, version)`.
- Add `quest::GetZoneNPCMaximumAggroDistance(zone_id)`.
- Add `quest::GetZoneNPCMaximumAggroDistance(zone_id, version)`.
- Add `quest::GetZoneMaximumMovementUpdateRange(zone_id)`.
- Add `quest::GetZoneMaximumMovementUpdateRange(zone_id, version)`.
- Add `quest::GetZoneMinimumExpansion(zone_id)`.
- Add `quest::GetZoneMinimumExpansion(zone_id, version)`.
- Add `quest::GetZoneMaximumExpansion(zone_id)`.
- Add `quest::GetZoneMaximumExpansion(zone_id, version)`.
- Add `quest::GetZoneContentFlags(zone_id)`.
- Add `quest::GetZoneContentFlags(zone_id, version)`.
- Add `quest::GetZoneContentFlagsDisabled(zone_id)`.
- Add `quest::GetZoneContentFlagsDisabled(zone_id, version)`.
- Add `quest::GetZoneUnderworldTeleportIndex(zone_id)`.
- Add `quest::GetZoneUnderworldTeleportIndex(zone_id, version)`.
- Add `quest::GetZoneLavaDamage(zone_id)`.
- Add `quest::GetZoneLavaDamage(zone_id, version)`.
- Add `quest::GetZoneMinimumLavaDamage(zone_id)`.
- Add `quest::GetZoneMinimumLavaDamage(zone_id, version)`.

# Lua
- Add `eq.get_zone_safe_x(zone_id)`.
- Add `eq.get_zone_safe_x(zone_id, version)`.
- Add `eq.get_zone_safe_y(zone_id)`.
- Add `eq.get_zone_safe_y(zone_id, version)`.
- Add `eq.get_zone_safe_z(zone_id)`.
- Add `eq.get_zone_safe_z(zone_id, version)`.
- Add `eq.get_zone_safe_heading(zone_id)`.
- Add `eq.get_zone_safe_heading(zone_id, version)`.
- Add `eq.get_zone_minimum_level(zone_id)`.
- Add `eq.get_zone_minimum_level(zone_id, version)`.
- Add `eq.get_zone_maximum_level(zone_id)`.
- Add `eq.get_zone_maximum_level(zone_id, version)`.
- Add `eq.get_zone_minimum_status(zone_id)`.
- Add `eq.get_zone_minimum_status(zone_id, version)`.
- Add `eq.get_zone_time_zone(zone_id)`.
- Add `eq.get_zone_time_zone(zone_id, version)`.
- Add `eq.get_zone_maximum_players(zone_id)`.
- Add `eq.get_zone_maximum_players(zone_id, version)`.
- Add `eq.get_zone_rule_set(zone_id)`.
- Add `eq.get_zone_rule_set(zone_id, version)`.
- Add `eq.get_zone_note(zone_id)`.
- Add `eq.get_zone_note(zone_id, version)`.
- Add `eq.get_zone_underworld(zone_id)`.
- Add `eq.get_zone_underworld(zone_id, version)`.
- Add `eq.get_zone_minimum_clip(zone_id)`.
- Add `eq.get_zone_minimum_clip(zone_id, version)`.
- Add `eq.get_zone_maximum_clip(zone_id)`.
- Add `eq.get_zone_maximum_clip(zone_id, version)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id, slot)`.
- Add `eq.get_zone_fog_minimum_clip(zone_id, slot, version)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id, slot)`.
- Add `eq.get_zone_fog_maximum_clip(zone_id, slot, version)`.
- Add `eq.get_zone_fog_red(zone_id)`.
- Add `eq.get_zone_fog_red(zone_id, slot)`.
- Add `eq.get_zone_fog_red(zone_id, slot, version)`.
- Add `eq.get_zone_fog_green(zone_id)`.
- Add `eq.get_zone_fog_green(zone_id, slot)`.
- Add `eq.get_zone_fog_green(zone_id, slot, version)`.
- Add `eq.get_zone_fog_blue(zone_id)`.
- Add `eq.get_zone_fog_blue(zone_id, slot)`.
- Add `eq.get_zone_fog_blue(zone_id, slot, version)`.
- Add `eq.get_zone_sky(zone_id)`.
- Add `eq.get_zone_sky(zone_id, version)`.
- Add `eq.get_zone_ztype(zone_id)`.
- Add `eq.get_zone_ztype(zone_id, version)`.
- Add `eq.get_zone_experience_multiplier(zone_id)`.
- Add `eq.get_zone_experience_multiplier(zone_id, version)`.
- Add `eq.get_zone_walk_speed(zone_id)`.
- Add `eq.get_zone_walk_speed(zone_id, version)`.
- Add `eq.get_zone_time_type(zone_id)`.
- Add `eq.get_zone_time_type(zone_id, version)`.
- Add `eq.get_zone_fog_density(zone_id)`.
- Add `eq.get_zone_fog_density(zone_id, version)`.
- Add `eq.get_zone_flag_needed(zone_id)`.
- Add `eq.get_zone_flag_needed(zone_id, version)`.
- Add `eq.get_zone_can_bind(zone_id)`.
- Add `eq.get_zone_can_bind(zone_id, version)`.
- Add `eq.get_zone_can_combat(zone_id)`.
- Add `eq.get_zone_can_combat(zone_id, version)`.
- Add `eq.get_zone_can_levitate(zone_id)`.
- Add `eq.get_zone_can_levitate(zone_id, version)`.
- Add `eq.get_zone_cast_outdoor(zone_id)`.
- Add `eq.get_zone_cast_outdoor(zone_id, version)`.
- Add `eq.get_zone_hotzone(zone_id)`.
- Add `eq.get_zone_hotzone(zone_id, version)`.
- Add `eq.get_zone_instance_type(zone_id)`.
- Add `eq.get_zone_instance_type(zone_id, version)`.
- Add `eq.get_zone_shutdown_delay(zone_id)`.
- Add `eq.get_zone_shutdown_delay(zone_id, version)`.
- Add `eq.get_zone_peqzone(zone_id)`.
- Add `eq.get_zone_peqzone(zone_id, version)`.
- Add `eq.get_zone_expansion(zone_id)`.
- Add `eq.get_zone_expansion(zone_id, version)`.
- Add `eq.get_zone_bypass_expansion_check(zone_id)`.
- Add `eq.get_zone_bypass_expansion_check(zone_id, version)`.
- Add `eq.get_zone_suspend_buffs(zone_id)`.
- Add `eq.get_zone_suspend_buffs(zone_id, version)`.
- Add `eq.get_zone_rain_chance(zone_id)`.
- Add `eq.get_zone_rain_chance(zone_id, slot)`.
- Add `eq.get_zone_rain_chance(zone_id, slot, version)`.
- Add `eq.get_zone_rain_duration(zone_id)`.
- Add `eq.get_zone_rain_duration(zone_id, slot)`.
- Add `eq.get_zone_rain_duration(zone_id, slot, version)`.
- Add `eq.get_zone_snow_chance(zone_id)`.
- Add `eq.get_zone_snow_chance(zone_id, slot)`.
- Add `eq.get_zone_snow_chance(zone_id, slot, version)`.
- Add `eq.get_zone_snow_duration(zone_id)`.
- Add `eq.get_zone_snow_duration(zone_id, slot)`.
- Add `eq.get_zone_snow_duration(zone_id, slot, version)`.
- Add `eq.get_zone_gravity(zone_id)`.
- Add `eq.get_zone_gravity(zone_id, version)`.
- Add `eq.get_zone_type(zone_id)`.
- Add `eq.get_zone_type(zone_id, version)`.
- Add `eq.get_zone_sky_lock(zone_id)`.
- Add `eq.get_zone_sky_lock(zone_id, version)`.
- Add `eq.get_zone_fast_regen_hp(zone_id)`.
- Add `eq.get_zone_fast_regen_hp(zone_id, version)`.
- Add `eq.get_zone_fast_regen_mana(zone_id)`.
- Add `eq.get_zone_fast_regen_mana(zone_id, version)`.
- Add `eq.get_zone_fast_regen_endurance(zone_id)`.
- Add `eq.get_zone_fast_regen_endurance(zone_id, version)`.
- Add `eq.get_zone_npc_maximum_aggro_distance(zone_id)`.
- Add `eq.get_zone_npc_maximum_aggro_distance(zone_id, version)`.
- Add `eq.get_zone_maximum_movement_update_range(zone_id)`.
- Add `eq.get_zone_maximum_movement_update_range(zone_id, version)`.
- Add `eq.get_zone_minimum_expansion(zone_id)`.
- Add `eq.get_zone_minimum_expansion(zone_id, version)`.
- Add `eq.get_zone_maximum_expansion(zone_id)`.
- Add `eq.get_zone_maximum_expansion(zone_id, version)`.
- Add `eq.get_zone_content_flags(zone_id)`.
- Add `eq.get_zone_content_flags(zone_id, version)`.
- Add `eq.get_zone_content_flags_disabled(zone_id)`.
- Add `eq.get_zone_content_flags_disabled(zone_id, version)`.
- Add `eq.get_zone_underworld_teleport_index(zone_id)`.
- Add `eq.get_zone_underworld_teleport_index(zone_id, version)`.
- Add `eq.get_zone_lava_damage(zone_id)`.
- Add `eq.get_zone_lava_damage(zone_id, version)`.
- Add `eq.get_zone_minimum_lava_damage(zone_id)`.
- Add `eq.get_zone_minimum_lava_damage(zone_id, version)`.

# Notes
- These methods add support for reading every value that the `zone` table contains, allowing operators to get any information about a specific zone and version they could need.
2023-05-24 17:59:18 -04:00
Alex King a3107cc54d [Bug Fix] Fix duplicate messages in #npcedit (#3372)
# Notes
- `#npcedit special_attacks` and `#npcedit special_abilities` send duplicate messages since the `d` variable wasn't being set and a message was being sent instead, meaning a message was sent inside the condition as well as a blank message at the bottom of the command.
2023-05-21 18:56:51 -04:00
Alex King f0152cef66 [Rules] Add World:MaximumQuestErrors Rule (#3349)
* [Rules] Add World:MaximumQuestErrors Rule

# Notes
- Allows operators to display more than 30 errors with #questerrors if they want.

* Update quest_interface.h
2023-05-21 18:48:30 -04:00
Alex King 21755a9f9e [Bug Fix] Fix typos in #zheader (#3370)
# Notes
- Argument 2 and 3 were being used when it should have been arguments 1 and 2.
2023-05-21 18:48:22 -04:00
Alex King b329515a07 [Quest API] Cleanup The Darkened Sea Quest Methods Names (#3369)
# Notes
- These were spelled incorrectly.
2023-05-21 18:48:15 -04:00
Alex King ff4b117cfa [Cleanup] Fix #spawn command NPCs having 0 health (#3371)
# Notes
- NPCs when spawned with this command have 0 health by default, requiring operators to manually edit their health if they're using this NPC as an NPC in their hub.
2023-05-21 18:48:08 -04:00
Paul Coene e305ba852b [Bug Fix] NPC Armor Upgrade to a slot not handled correctly (#3366)
* [NPC Armor - Bug] NPC upgardes in armor not correct

* Revert "[NPC Armor - Bug] NPC upgardes in armor not correct"

This reverts commit d5a68654a7.

* [NPC item bonuses] Upgrades not processed correctly

* Update loottables.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-19 22:28:01 -04:00
RekkasGit b8c91cf4f9 [Bug Fix] Mob scaling issue with min dmg set to zero while max dmg is not (#3351)
* fix for mob scaling issue with min dmg set to zero while max dmg is not.

* Cleanup

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-19 22:11:11 -04:00
Alex King cd82bd8472 [Cleanup] Remove DumpMerchantList() from zone.cpp/zone.h (#3343)
# Notes
- This is unused.
2023-05-17 09:02:14 -04:00
Alex King 20bed20f47 [Cleanup] Delete message.h (#3348)
# Notes
- This is unsued.
2023-05-17 09:00:38 -04:00
Alex King c93054421f [Cleanup] Remove CountNPC() and QueueManaged() from entity.cpp/entity.h (#3346)
# Notes
- These are unused.
2023-05-17 08:58:50 -04:00
Alex King b7a1fc6644 [Cleanup] Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h (#3352)
# Notes
- This is unused.
2023-05-17 08:58:27 -04:00
Alex King 6bfb8fca2e [Cleanup] Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h (#3353)
# Notes
- This is unused.
2023-05-17 08:58:13 -04:00
Alex King 9d6a7ad743 [Cleanup] Remove SetGraveyard() from zone.cpp/zone.h (#3354)
# Notes
- This is unused.
2023-05-17 08:58:02 -04:00
Alex King 076b88be9a [Cleanup] Remove TypeToSkill() from tradeskills.cpp/object.h (#3355)
# Notes
- This is unused.
2023-05-17 08:57:51 -04:00
Alex King 84a779c4df [Cleanup] Remove SetTradeCash() from trading.cpp/common.h (#3356)
# Notes
- This is unused.
2023-05-17 08:57:09 -04:00
Alex King 3fb479e612 [Cleanup] Remove TraderUpdate() from trading.cpp/client.h (#3357)
# Notes
- This is unused.
2023-05-17 08:56:42 -04:00
Alex King c1f4ee0e65 [Cleanup] Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h (#3358)
# Notes
- These are unused.
2023-05-17 08:56:09 -04:00
RekkasGit 32f7dc3d1b [Quest API] Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua (#3359)
* Add HateListClosestClient available for scripting.

* Add other methods.

* Use pre-existing constants.

* Typos

* Update mob.h

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-15 21:23:19 -04:00
RekkasGit fa55fd1664 [Bug Fix] Fix Heroic INT/WIS Bonuses (#3341)
* fix for heroic int/wis for hybrids

* Update classes.cpp

* Update classes.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-05-15 10:52:53 -04:00
Chris Miles c44c0d4efa [Performance] Character buffs now save in bulk (#3336)
* [Performance] Character buffs now save in bulk

* Only insert if we have buffs to insert

* Swap for .empty()
2023-05-09 13:28:34 -05:00
Chris Miles 50c63b95db [Performance] Character pet bulk saving (#3337)
* [Performance] Character pet bulk saving

* Update zonedb.cpp
2023-05-09 13:27:17 -05:00
Chris Miles 612029de6e [Performance] Character bind is now bulk saved (#3338)
* [Performance] Character bind is now bulk saved

* Fix bind heading
2023-05-09 13:22:57 -05:00
Chris Miles dbc6346fe8 [Performance] Mail key is now cached during player load (#3339)
* [Performance] Mail key is now cached during player load

* More refactoring
2023-05-09 13:22:43 -05:00
nytmyr 93a4153a4b [Rules] ResurrectionEffectBlock to prevent/allow/move buffs. (#3288)
* [Rules] ResurrectionEffectsBlock to prevent/allow/move buffs.

This removes the rule ResurrectionEffectsBlock (Bool) and creates ResurrectionEffectsBlock (Int)

Default = 2

Setting to 0 = Functions as it did before any blocking changes, Focus of Spirit and Strength buffs can overwrite Resurrection Effects.

Setting to 1 = Blocks all buffs that could overwrite Resurrection Effects.

Setting to 2 = Allows all buffs that would overwrite Resurrection Effects to land, however they will be moved to a new buff slot if one is available to allow both the beneficial buff to land and detrimental effects of Resurrection Effects to stay in effect until the duration is expired.

* Update logging

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-05-08 08:32:21 -05:00
Akkadius 434f270f68 Revert "[Bug Fix] ReloadQuests() on Zone::Init() to avoid cached global quests/plugins (#3333)"
This reverts commit 8c23eee42a.
2023-05-07 23:33:43 -05:00
Alex King 5ba33b88bd [Cleanup] Set GetAugmentType() to int again (#3335)
# Notes
- Augment type can be `-1` for all augment types.
2023-05-07 21:40:45 -04:00
Alex King ce1de9997b [Quest API] Add GetPet() to Perl (#3309)
# Perl
- Add `$mob->GetPet()`.

# Notes
- This exists in Lua, but not Perl.
2023-05-07 19:13:26 -05:00
Chris Miles 8814ab26cd [Hotfix] Fix mob item bonus calc (#3334) 2023-05-07 18:23:22 -05:00
Alex King 8c23eee42a [Bug Fix] ReloadQuests() on Zone::Init() to avoid cached global quests/plugins (#3333)
# Notes
- Before this, quests/plugins would be cached in an old state, so you'd have to either enter the zone and `#reload quest` or `#reload world` to get them to update.
2023-05-07 14:41:57 -04:00
Alex King 5475615448 [Bug Fix] #augmentitem bypasses augment restrictions (#3332)
* [Bug Fix] #augmentitem bypasses augment restrictions

# Notes
- `Object::HandleAugmentation` did not properly check for `augrestrict` values. This allowed augment restrictions to be bypassed with `#augmentitem` or anything else that uses this method.
- `Client::SummonItem` already properly checked these, so I just broke it out into a `Client::IsAugmentRestricted()` method.

* Update item_instance.h
2023-05-07 11:40:04 -04:00
Chris Miles 4a5559022f [Memory Leak] Fix large memory leak introduced in CalcItemBonuses (#3331) 2023-05-07 09:47:03 -04:00
Paul Coene 5be2041085 [Messages] Remove duplicate heal message for healing yourself (#3329) 2023-05-03 16:50:54 -04:00
Jasdac 9f4d60ec36 [Feature] Intoxication setter/getter for source, getter for Perl/Lua (#3330)
* Add setter and getter methods for intoxication
Add GetIntoxication functions for perl and Lua

* Remove trailing tab

* Use clamp instead of min/max
2023-05-03 16:19:53 -04:00
Chris Miles c64a2aec94 [Release] 22.11.0 (#3328)
* [Release] 22.11.0

* Update version.h
2023-04-29 20:37:04 -05:00
Alex King 0e582eda82 [Quest API] Add HasSpellEffect() to Perl/Lua (#3319)
* [Quest API] Add HasSpellEffect() to Perl/Lua

# Perl
- Add `$mob->HasSpellEffect(effect_id)`.

# Lua
- Add `mob:HasSpellEffect(effect_id)`.

# Notes
- Allows operators to see if a Mob has an effect ID from any of their buffs.

* Update mob.cpp
2023-04-29 20:09:00 -05:00
Alex King 7eff6ada87 [Cleanup] Remove unused code in zone/pets.cpp (#3310)
# Notes
- This code is unused.
2023-04-29 20:00:37 -05:00
Alex King 291997d35b [Cleanup] Remove pDontCastBefore_casting_spell from zone/npc.h (#3311)
# Notes
- This is unused.
2023-04-29 20:00:20 -05:00
Alex King ac4572bf79 [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h (#3312)
* [Cleanup] Remove unused methods in zone/client.cpp and zone/client.h

# Notes
- Remove `CheckAccess()` in `zone/client.cpp`.
- Remove `CheckAccess()` in `zone/client.h`.
- Remove `CheckQuests()` in `zone/client.h`.
- Remove `MakeCorpse()` in `zone/client.h`.
- Remove `HPTick()` in `zone/client.h`.
- These methods are unused.

* Update client.h
2023-04-29 20:00:08 -05:00
Alex King f0a9578b6a [Cleanup] Remove GetClassHPFactor() from zone/merc.h (#3314)
# Notes
- This is unused.
2023-04-29 19:59:50 -05:00
Alex King baa824d8fb [Cleanup] Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h (#3313)
# Notes
- This is unused.
2023-04-29 19:59:19 -05:00
Alex King b19d3ac8a2 [Cleanup] Remove unused methods in zone/bot.cpp and zone/bot.h (#3315)
# Notes
- Remove `DoFinishedSpellAETarget()`.
- Remove `SendBotArcheryWearChange()`.
- These are unused.
2023-04-29 19:59:05 -05:00
Alex King 6a393bf0c3 [Quest API] Add GetDefaultRaceSize() overloads to Perl/Lua (#3320)
# Perl
- Add `$mob->GetDefaultRaceSize(race_id)`.
- Add `$mob->GetDefaultRaceSize(race_id, gender_id)`.

# Lua
- Add `mob:GetDefaultRaceSize(race_id)`.
- Add `mob:GetDefaultRaceSize(race_id, gender_id)`.

# Notes
- This allows you to get a default size for a race and gender that isn't the current mob's race and gender.
2023-04-29 19:53:49 -05:00
Alex King 09a5551de1 [Cleanup] quest::setallskill() had always true condition. (#3301)
# Notes
- Remove unnecessary double check of `initiator`.
- Cleanup logic to use `EQ::skills::GetSkillTypeMap()`.
2023-04-29 19:52:30 -05:00
Alex King 6e2e035d66 [Cleanup] Remove unused variable in common/crash.cpp (#3308)
# Notes
- This variable is unused.
2023-04-29 19:51:41 -05:00
Alex King ac5922bb32 [Cleanup] Use default ctor/dtor in oriented_bounding_box.h (#3307)
# Notes
- Use default ctor/dtor instead of empty ones.
2023-04-29 19:51:21 -05:00
Chris Miles ecf2a369cc [Discord] Add Discord webhook callback processing to world (#3322) 2023-04-29 20:49:06 -04:00
Chris Miles 95b306599f [Maps] Update download with faster releases link (#3321) 2023-04-29 19:39:24 -05:00
Chris Miles 497d20512a [Crash] Fix UCS crash that occurs during log reloading (#3324) 2023-04-29 19:39:13 -05:00
Aeadoin db916e946e [Bug Fix] Fix issue with spawning Mercs (#3327) 2023-04-29 18:45:35 -04:00
Alex King 958549b407 [Bug Fix] Possible issues with SummonItem in Client::QuestReward() methods (#3325)
# Notes
- These methods were ignoring the sixth augment slot and could cause item to be summoned attuned being `EQ::invslot::slotCursor` is a non-zero value.
2023-04-26 21:28:24 -04:00
Paul Coene 71ebf1b2d4 [Messages] Remove duplicate you have lost a level message (#3323) 2023-04-25 17:42:31 -04:00
Paul Coene e19b8d3056 [Bug Fix] Fix issue with NPCs no longer using some armor. (#3318)
* [BugFix/NPCs] Fix issue with NPCs no longer using some armor.

* Removed redundant memory clear
2023-04-24 17:05:29 -04:00
Alex King 8b1d64a043 [Cleanup] quest::createBot() unnecessary check against nullptr (#3302)
# Notes
- We initialize this variable, so it can never be a nullptr.
2023-04-23 15:08:50 -04:00
Alex King 576f99f292 [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp (#3306)
* [Cleanup] Add initiator/owner checks to various methods in questmgr.cpp

# Notes
- Add `initiator` check to `quest::permaclass()`.
- Add `initiator` check to `quest::permarace()`.
- Add `initiator` check to `quest::permagender()`.
- Add `initiator` check to `quest::scribespells()`.
- Add `initiator` check to `quest::traindiscs()`.
- Add `initiator` check to `quest::unscribespells()`.
- Add `initiator` check to `quest::untraindiscs()`.
- Cleanup `initiator` check in `quest::pvp()`.
- Cleanup `initiator` check in `quest::movepc()`.
- Cleanup `initiator` check in `quest::gmmove()`.
- Cleanup `initiator` check in `quest::movegrp()`.
- Add `owner` check to `quest::doanim()`.
- Cleanup `initiator` check in `quest::addskill()`.
- Cleanup `initiator` check in `quest::setlanguage()`.
- Cleanup `initiator` check in `quest::setskill()`.

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp

* Update questmgr.cpp
2023-04-23 15:08:32 -04:00
Alex King e3761cf2a3 [Cleanup] Add check for owner in quest::resumetimer() (#3305)
# Notes
- We didn't check for owner before doing `owner->GetName()`.
2023-04-23 15:07:49 -04:00
Alex King ad1764b464 [Cleanup] Add cehck for owner in quest::pausetimer() (#3304)
# Notes
- We didn't check for `owner` before doing `owner->GetName()`.
2023-04-23 15:07:09 -04:00
Alex King 1c9ea57a4e [Cleanup] Fix possible nullptr in quest::addloot() (#3303)
# Notes
- We didn't check for `owner` before calling `owner->IsNPC()`.
2023-04-23 15:06:53 -04:00
Alex King 03c158b674 [Crash] Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() (#3317)
# Notes
- We could possibly not have a `zone` here, causing a crash.
- http://spire.akkadius.com/dev/release/22.9.1?id=3051
- http://spire.akkadius.com/dev/release/22.9.1?id=3052
- http://spire.akkadius.com/dev/release/22.9.1?id=3073
- http://spire.akkadius.com/dev/release/22.9.1?id=3102
- http://spire.akkadius.com/dev/release/22.9.1?id=3103
- http://spire.akkadius.com/dev/release/22.9.1?id=3104
- http://spire.akkadius.com/dev/release/22.9.1?id=3107
- http://spire.akkadius.com/dev/release/22.9.1?id=3108
- http://spire.akkadius.com/dev/release/22.9.1?id=3109
- http://spire.akkadius.com/dev/release/22.9.1?id=3110
- http://spire.akkadius.com/dev/release/22.9.1?id=3111
- http://spire.akkadius.com/dev/release/22.9.1?id=3112
- http://spire.akkadius.com/dev/release/22.9.1?id=3113
- http://spire.akkadius.com/dev/release/22.9.1?id=3114
2023-04-23 15:05:47 -04:00
Aeadoin 39b5374e92 [Crash] Fix possible dereference of nullptr in Client::CalcHPRegen (#3316) 2023-04-23 14:27:43 -04:00
Aeadoin 2d3ddcb574 [Release] 22.10.0 (#3300) 2023-04-22 10:17:20 -04:00
Aeadoin ed09281f66 [Bug Fix] Camping was causing player to leave raid, causing unexpected behavior (#3299) 2023-04-22 10:03:40 -04:00
Paul Coene 8e51bf8b19 Fix crash when Removing empty password protected channel. (#3298) 2023-04-22 08:49:34 -04:00
Alex King 844efa7e20 [Cleanup] Breaks in wrong spot in cases in spell_effects.cpp (#3297)
* [Cleanup] Breaks in wrong spot in cases in spell_effects.cpp

# Notes
- These breaks were inside conditions, meaning the case wasn't always broken.

* Update spell_effects.cpp
2023-04-22 08:49:13 -04:00
Alex King fa3a5c7a72 [Feature] Make ornamentations work with any augment type (#3281)
* [Feature] Make ornamentations work with any augment type

# Notes
- On Live there are augments that are not type 20/21 and are ornamentations.
- We also only allow a singular augment type to be ornamentation augment types, this will allow you to use any augment type as an ornamentation if it has a proper Hero's Forge model or a non-IT63/non-IT64 idfile.

* Update ruletypes.h

* Update client_packet.cpp

* Update item_instance.cpp

* Cleanup.
2023-04-16 10:26:19 -04:00
Aeadoin 93db35658a [Crash] Add additional raid integrity checks on Bot Spawn. (#3295)
* simple cleanup before changes

* can't be in a raid yet

* change to sizeof

* change to use sizeof
2023-04-16 10:06:19 -04:00
Alex King d45a57056a [Cleanup] Remove getd(), geti(), InUse(), lasterr(), my_get_sv(), and VarExists() in embperl.cpp/embperl.h (#3283)
* [Cleanup] Remove getd(), geti(), InUse(), lasterr(), and VarExists() in embperl.cpp/embperl.h

# Notes
- These are unused.

* Update embperl.h

* Update embperl.cpp
2023-04-15 13:20:18 -04:00
Alex King ff40dbc710 [Cleanup] Utilize IsTaunting(), SetPetPower(), SetPetType(), and SetTaunting() (#3275)
* [Cleanup] Utilize SetPetPower() in zone/pets.cpp

# Notes
- This wasn't used before.

* Utilize other methods.

* Update special_attacks.cpp
2023-04-15 13:20:04 -04:00
Aeadoin 7523c972fa [Crash] Fix crash with uninitialized item instance, and Bot timeout (#3296) 2023-04-15 13:12:48 -04:00
Alex King 4320c1429e [Cleanup] Remove _GetMovementSpeed() from mob.h (#3276)
# Notes
- This is unused.
2023-04-14 19:42:48 -04:00
Alex King dc8bfddd7a [Cleanup] Remove IsFullHP from mob.cpp/mob.h (#3277)
# Notes
- This is unused.
2023-04-14 19:42:39 -04:00
Alex King a8cdfb07e6 [Cleanup] Remove pendinggroup from mob.h (#3278)
# Notes
- This is unused.
2023-04-14 19:42:27 -04:00
Alex King 011de2692e [Cleanup] Remove IsMeleeDmg() from skills.cpp/skills.h (#3279)
# Notes
- This is unused.
2023-04-14 19:42:14 -04:00
Alex King 0cc76ab489 [Cleanup] Remove position_same_update_count from client.cpp/client.h (#3280)
# Notes
- This is unused.
2023-04-14 19:42:01 -04:00
Alex King c5c9985e0d [Cleanup] Remove ExportVarComplex() from embparser.cpp/embparser.h (#3282)
# Notes
- This is unused.
2023-04-14 19:41:23 -04:00
Alex King a7e95d7818 [Cleanup] Delete embxs.cpp/embxs.h (#3284)
* [Cleanup] Delete embxs.cpp/embxs.h

# Notes
- These files and the one method in them are unused.

* Update embperl.cpp
2023-04-14 19:40:51 -04:00
Alex King 933d856b5b [Cleanup] Remove GetQGlobal() from qglobals.cpp/qglobals.h (#3285)
# Notes
- This is unused.
2023-04-14 19:40:35 -04:00
Alex King 285cc3af29 [Cleanup] Remove item_timers from questmgr.cpp/questmgr.h (#3286)
* [Cleanup] Remove item_timers from questmgr.cpp/questmgr.h

# Notes
- This is unused.

* Update questmgr.h
2023-04-14 19:40:21 -04:00
Alex King de8ae7afa6 [Cleanup] Cleanup zone/zoning.cpp (#3289)
# Notes
- Duplicate outcome cases in `Client::Handle_OP_ZoneChange`.
- Use `.length()` over `strlen` in array defintition.
- Remove unnecessary `else if` in `Client::ZonePC`
2023-04-14 19:40:01 -04:00
Alex King 1b272cba50 [Cleanup] Remove unused ctor and use default dtor in xtargetautohaters.h (#3290)
* [Cleanup] Remove unused ctor and use default dtor in xtargetautohaters.h

# Notes
- Utilize default dtor.
- Remove unused ctor.

* Update zone_event_scheduler.cpp
2023-04-14 19:39:25 -04:00
Alex King e35e38b039 [Cleanup] Remove unused variables and use reference in task_manager.cpp (#3291)
# Notes
- Remove unused `query` and `item` variable.
- Use a reference for task data instead of calling `cts->m_completed_tasks[task_index]` over and over.
2023-04-14 19:39:07 -04:00
Alex King 9215ba7a8a [Cleanup] Remove always true statements in task_client_state.cpp (#3292)
# Notes
- `!tasks_enabled.empty()` is always true.
- `tasks_disabled.size()` is always true.
2023-04-14 19:38:35 -04:00
Alex King 3f4334985b [Cleanup] Remove unnecessary condition and cleanup variable name in tasks.cpp (#3293)
# Notes
- `task_state` is verified by `safe_delete`.
- `size` is the name of a member variable, we should just use `sizeof(uint32_t)` instead.
2023-04-14 19:38:28 -04:00
Alex King 21002c2e8a [Quest API] Fix LDoN Methods in Perl/Lua (#3287)
# Perl
- Add `quest::removeldonloss(theme_id)`.
- Add `quest::removeldonwin(theme_id)`.

# Lua
- Fix `eq.remove_ldon_win(theme_id)` as it was using `quest_manager.addldonwin(theme_id)` instead of `quest_manager.removeldonwin(theme_id)`.
2023-04-10 16:16:54 -04:00
Alex King 445f967ed6 [Quest API] Add ApplySpellRaid() and SetSpellDurationRaid() to Bots in Perl/Lua (#3274)
# Perl
- Add `$bot->ApplySpellRaid(spell_id)`.
- Add `$bot->ApplySpellRaid(spell_id, duration)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, allow_pets)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, allow_pets, is_raid_group_only)`.
- Add `$bot->SetSpellDuration(spell_id)`.
- Add `$bot->SetSpellDuration(spell_id, duration)`.
- Add `$bot->SetSpellDuration(spell_id, duration, allow_pets)`.
- Add `$bot->SetSpellDuration(spell_id, duration, allow_pets, is_raid_group_only)`.

# Lua
- Add `bot:ApplySpellRaid(spell_id)`.
- Add `bot:ApplySpellRaid(spell_id, duration)`.
- Add `bot:ApplySpellRaid(spell_id, duration, allow_pets)`.
- Add `bot:ApplySpellRaid(spell_id, duration, allow_pets, is_raid_group_only)`.
- Add `bot:SetSpellDuration(spell_id)`.
- Add `bot:SetSpellDuration(spell_id, duration)`.
- Add `bot:SetSpellDuration(spell_id, duration, allow_pets)`.
- Add `bot:SetSpellDuration(spell_id, duration, allow_pets, is_raid_group_only)`.

# Notes
- These methods weren't added initially as we did not support bots in raid groups until recently.
2023-04-09 12:00:12 -04:00
Alex King 57a15d473f [Quest API] Add GetBuffSpellIDs() to Perl/Lua (#3273)
# Perl
- Add `$mob->GetBuffSpellIDs()`.

# Lua
- Add `$mob->GetBuffSpellIDs()`.

# Notes
- These methods allow operators to get a list of a mob's buff IDs without having to loop through their buffs themselves.
2023-04-09 10:58:35 -04:00
Trent df92c578d2 [Rules] Optional summoning when already in melee range (#3204)
* Add summon melee range rule

* Fix compilation

* Remove redundant range check for HateSummon
2023-04-08 18:04:17 -04:00
Aeadoin 3af43a8e8d [Hotfix] Resolve loading of inventory (#3272) 2023-04-08 17:45:06 -04:00
Aeadoin 647bcce30b [Crash] Resolve crash due to uninitialized pointer. (#3271) 2023-04-08 17:21:53 -04:00
Alex King 25b527156c [Cleanup] Fix possible nullptr inst in GetSharedBank() (#3190)
* [Cleanup] Fix possible nullptr inst in GetSharedBank()

# Notes
- We weren't continuing if we had a `nullptr`.

* Update shareddb.cpp

* Fix.
2023-04-08 09:42:10 -04:00
Aeadoin b3ab7deb80 [Bots] Cleanup GetBotTables() (#3270) 2023-04-06 17:43:57 -05:00
Alex King 4a9cb07132 [Cleanup] Remove unnecessary setting of reuse variable in Bot::DoClassAttacks() (#3233)
# Notes
- Bash, Kick, and Taunt have the same reuse time, no reason to set it to the same value.
2023-04-05 19:17:15 -04:00
Alex King 8f1b62d166 [Cleanup] Remove always true/false conditions from bot.cpp (#3237)
* [Cleanup] Remove always true/false conditions from bot.cpp

# Notes
- Some of these conditions were always true or false based on previous conditions.

* Update bot.cpp
2023-04-05 19:05:49 -04:00
Alex King 7e9994b5d4 [Cleanup] Fix ornamentation augment icons in inspect requests (#3264)
* [Cleanup] Fix ornamentation augment icons in inspect requests

# Notes
- We were not setting `aug_item` to the ornamentation augment when we found one.

* Update client.cpp
2023-04-05 19:04:32 -04:00
Chris Miles f2f8fae58b [Telnet] Telnet encoding fix (#3269) 2023-04-05 12:16:25 -04:00
Alex King 3a1e88f9ed [Cleanup] Remove unused SetConfigFile in common/eqemu_config.h (#3208)
# Notes
- This is unused.
2023-04-05 12:15:10 -04:00
Alex King 4e101aa6d6 [Cleanup] Use default dtor instead of empty dtor for EQTime in eqtime.cpp/eqtime.h (#3210)
# Notes
- This is better than using an empty dtor.
2023-04-05 12:15:02 -04:00
Alex King ef411ee154 [Cleanup] Use default ctor instead of an empty ctor. (#3206)
# Notes
- Use `= default;` instead of an empty ctor.
- https://pvs-studio.com/en/docs/warnings/v832/
2023-04-05 12:14:22 -04:00
Alex King 93b3f97f24 [Cleanup] Cleanup discord.cpp and discord_manager.cpp (#3205)
# Notes
- Unused variables in `discord.cpp`.
- Use `.clear()` instead of setting to `""` in `discord_manager.cpp`.
2023-04-05 12:14:14 -04:00
Alex King c1d4cb90b9 [Cleanup] Cleanup cheap-to-copy reference to use value instead in eq_stream_ident.cpp/eq_stream_ident.h (#3209)
# Notes
- More performant to pass by value than by reference.
2023-04-05 12:14:01 -04:00
Alex King e939c82717 [Cleanup] Convert equipable_slot_list to std::vector from std::list in bot_command.cpp (#3253)
# Notes
- No need to use a `std::list` here.
2023-04-05 11:35:04 -04:00
Alex King 7d03479f41 [Cleanup] Use constant reference and check for empty string properly in dbcore.cpp (#3203)
# Notes
- Passing by constant reference is more performant.
- Checking for empty string with `!= '\0'` is more performant.
- https://pvs-studio.com/en/docs/warnings/v805/
- https://pvs-studio.com/en/docs/warnings/v813/
2023-04-05 11:27:50 -04:00
Alex King ff440e16b6 [Cleanup] Use .clear() and .empty() instead of comparing to empty string or setting to empty string in CheckDatabaseConvertPPBlob() (#3201)
# Notes
- Use these methods to increase performance.
2023-04-05 11:27:12 -04:00
Alex King c6bb0f6495 [Cleanup] Move variable definition to more relevant scope in DatabaseDumpService::Dump() (#3200)
# Notes
- This was unused except for in this one spot, move to scope of condition where it's used.
- https://pvs-studio.com/en/docs/warnings/v821/
2023-04-05 11:26:21 -04:00
Alex King d142bc552a [Cleanuo] Only define row if we have results in Database::GetCharacterID() (#3199)
# Notes
- This is more performant and we don't unnecessarily define a variable we can't use.
- https://pvs-studio.com/en/docs/warnings/v821/
2023-04-05 11:25:28 -04:00
Alex King 7dc57c3b05 [Cleanup] Utilize .empty() instead of checking for an empty string in Database::ReserveName() (#3198)
# Notes
- This is more performant.
- https://pvs-studio.com/en/docs/warnings/v815/
2023-04-05 11:24:54 -04:00
Alex King ea9b09cf1f [Cleanup] Remove unused variable in Database::CopyCharacter() (#3197)
# Notes
- This variable was created but never used.
- https://pvs-studio.com/en/docs/warnings/v808/
2023-04-05 11:24:27 -04:00
Alex King 968278d8f8 [Cleanup] Use .clear() instead of setting string to empty in eqemu_command_handler.cpp (#3195)
# Notes
- `x = ""` has less performance than `x.clear()`.
- https://pvs-studio.com/en/docs/warnings/v815/
2023-04-05 11:24:12 -04:00
Alex King aa910864c8 [Cleanup] Remove unused macros in common/types.h (#3194)
# Notes
- These are unused.
2023-04-05 11:23:37 -04:00
Alex King 1499f3338e [Cleanup] Remove always true condition in Strings::Commify() (#3193)
# Notes
- `i < 0` was always true.
2023-04-05 11:23:24 -04:00
Alex King fef2f9fc61 [Cleanup] Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member (#3192)
* [Cleanup] Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member

# Notes
- This variable was named `m_db_shared_task` which is the same as `SharedTask:;m_db_shared_task`.

* Single letter receiver of complex type.
2023-04-05 11:22:42 -04:00
Alex King 8afbc585da [Cleanup] Remove bool return from GetSharedPlatinum() (#3191)
# Notes
- This was returning `false` and implicitly converting it to an integer.
2023-04-05 11:22:23 -04:00
Alex King 457ce85746 [Cleanup] Cleanup always true/false statements in shareddb.cpp (#3189)
# Notes
- `parent_index < EQ::invslot::SLOT_BEGIN` was always `false`.
- `item->LoreGroup != -1` was always `true`.
2023-04-05 11:21:43 -04:00
Alex King 49c093dc62 [Cleanup] Remove always true statement in say_link.cpp (#3188)
# Notes
- This is always true since we check `!saylinks.empty()` prior to this.
2023-04-05 11:20:52 -04:00
Alex King beccd557a8 [Cleanup] Cleanup item_instance.cpp always true statements and reassigning of same values (#3187)
# Notes
- Some things were always true.
- Some values were reassigned to the value they already were.
2023-04-05 11:20:36 -04:00
Alex King e11610b9fa [Cleanup] Remove unnecessary check for IsStackable() in DeleteItem() (#3186)
# Notes
- We check the opposites therefore we don't need either.
- https://pvs-studio.com/en/docs/warnings/v728/
2023-04-05 11:20:13 -04:00
Alex King 3e652b98bc [Cleanup] Cleanup macros in features.h (#3185)
# Notes
- These needed to either be wrapped in parentheses or simplified to their values.
- https://pvs-studio.com/en/docs/warnings/v1003/
2023-04-05 11:18:22 -04:00
Alex King d43af28de4 [Cleanup] Multiple cases with same outcome in GetDiscordPayloadFromEvent() (#3184)
# Notes
- All 4 of these use `FormatWithNodata`.
2023-04-05 11:17:52 -04:00
Alex King f5106b6af6 [Cleanup] Remove unused code in eq_packet.cpp/eq_packet.h (#3183)
# Notes
- These are unused.
2023-04-05 11:17:29 -04:00
Alex King 3386d13d2d [Cleanup] results variable is assigned but never used in SaveCharacterCreate() (#3180)
# Notes
- This was unnecessary since `QueryDatabase()` runs regardless.
2023-04-05 11:17:10 -04:00
Alex King d1b7c675f9 [Cleanup] Validate for nullptrs in bot.cpp (#3232)
* [Cleanup] Validate for nullptrs in bot.cpp

# Notes
- Validate for nullptrs in these spots in bot.cpp before using the variable.

* Update bot.cpp
2023-04-05 11:15:46 -04:00
Alex King a40e1cf893 [Cleanup] Add missing breaks and returns in bonuses.cpp (#3231)
# Notes
- Many spots were missing a `break;` or a `return` for their value.
2023-04-05 11:15:22 -04:00
Alex King c81ab00764 [Cleanup] Set bonuses to use spell ID instead of boolean (#3230)
# Notes
- Spell bonuses `Illusion` is the spell ID, not a boolean.
2023-04-05 11:14:55 -04:00
Alex King 025ef5e1d6 [Cleanup] Move unreachable code in ApplySpellsBonuses() (#3229)
# Notes
- This code was unreachable since it was inside the switch and should have been checked on its own in the condition where we verify we are using AISpellEffects.
2023-04-05 11:14:28 -04:00
Alex King 1f29a40e6d [Cleanup] Remove extraneous check for NegateAttacks in SE_NegateAttacks (#3228)
# Notes
- We checked both, we only need to check one.
2023-04-05 11:12:02 -04:00
Alex King 66cadd599b [Cleanup] Remove extraneous parentheses around math in Mob::ApplySpellsBonuses() (#3227)
# Notes
- Extra parentheses.
2023-04-05 11:11:41 -04:00
Alex King aa0345c1f1 [Cleanup] Cleanup duplicate conditions in negate bonuses in bonuses.cpp (#3226)
# Notes
- Lots of duplicate conditions.
2023-04-05 11:11:22 -04:00
Alex King 73b11c5036 [Cleanup] SE_StrikeThrough and SE_StrikeThrough2 are the same in bonuses.cpp (#3223)
# Notes
- These were the same code duplicated.
2023-04-05 11:05:59 -04:00
Alex King efbeb2dbb7 [Cleanup] SE_AttackSpeed3 effect_value is always less than 0 (#3222)
# Notes
- This was always false.
2023-04-05 11:05:44 -04:00
Alex King 8c97c20727 [Cleanup] Fix skill_used being used as boolean in Mob::CommonDamage() (#3220)
# Notes
- This is unnecessary as we always have a skill value.
2023-04-05 11:03:28 -04:00
Alex King f2d07e5c69 [Cleanup] Remove unnecessary break in while loop in Mob::AddToHateList() (#3219)
# Notes
- This is unnecessary and breaks the loop for no reason.
2023-04-05 10:31:57 -04:00
Alex King 64d5b54e65 [Cleanup] Fix filter condition in attack.cpp (#3218)
# Notes
- This condition was causing them to be used as `booleans` versus being checked individually.
2023-04-05 10:31:34 -04:00
Alex King 89b3a04eb3 [Cleanup] Identical conditions right beside each other in aa.cpp (#3213)
# Notes
- These conditions were identical and could be consolidated.
2023-04-05 10:30:27 -04:00
Alex King 1bafe0b6b3 [Cleanup] other is always defined in these cases in attack.cpp (#3217)
# Notes
- `other` is always defined since we check it prior to checking here.
2023-04-05 10:30:13 -04:00
Alex King 82762c3f5a [Cleanup] Use variable for character instead of a loop (#3268)
# Notes
- Store character in a variable instead of looping a list of 1 entry.
2023-04-05 10:29:16 -04:00
Alex King 2742eca119 [Cleanup] Remove unnecessary conditions in Client::SendFactionMessage() (#3267)
# Notes
- `faction_value < this_faction_max` and `faction_value > this_faction_min` are always true if they get to that point in the code.
2023-04-05 10:27:15 -04:00
Alex King 8fc7f3a732 [Cleanup] Cleanup unnecessary condition in Client::SendAlternateCurrencyValue() (#3266)
# Notes
- `value == 0` is unnecessary as it can only be 0 if we fail the `value > 0` check.
2023-04-05 10:27:01 -04:00
Alex King 39ce0178f9 [Cleanup] Remove unnecessary conditions in Client::Consume() (#3265)
# Notes
- We check `increase < 0` prior to this, so this can't ever happen.
2023-04-05 10:26:32 -04:00
Alex King 3d2f560436 [Cleanup] Fix GetLastName() length check in Client::SendWindow() (#3263)
# Notes
- `target->GetLastName()` was always true, we need to make sure the target has a last name.
2023-04-05 10:23:54 -04:00
Alex King a0768d2d28 [Cleanup] Remove unnecessary conditions in Client::FilteredMessageCheck() (#3262)
# Notes
- We check `FilterHide` prior to the secondary conditions, so it can never show up.
2023-04-05 10:23:33 -04:00
Alex King 9009a7aa23 [Cleanup] Remove extra assignment of current_endurance in Client ctor (#3261)
# Notes
- We already assign `current_endurance` to `0`, no need to do it again.
2023-04-05 10:23:20 -04:00
Alex King 67b03b4e31 [Cleanup] Combine similar cases in Client::InitInnates() (#3260)
# Notes
- These cases were the same, consolidating them is better.
2023-04-05 10:23:05 -04:00
Alex King b08975aefb [Cleanup] Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines() (#3259)
* [Cleanup] Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines()

# Notes
- Use `.empty()` instead of using a variable storing size in condition.

* Update client.cpp
2023-04-05 10:22:36 -04:00
Alex King ea3a7cae0b [Cleanup] Remove always true conditions and unreachable code in Client::SendMercPersonalInfo() (#3258)
* [Cleanup] Remove unreachable code in Client::SendMercPersonalInfo()

# Notes
- This cannot be reached due to prior returns.

* Update client.cpp

* Update client.cpp
2023-04-05 10:14:07 -04:00
Alex King 81314a3315 [Cleanup] Fix check for !this in Client::SendHPUpdateMarquee() (#3257)
# Notes
- `!this` isn't valid, as `this` can never be nullptr.
2023-04-05 10:13:24 -04:00
Alex King d33cfad567 [Cleanup] Fix always false conditions in Client::IncStats() (#3256)
# Notes
- Value can never be less than `0` as it's unsigned.
2023-04-05 10:12:32 -04:00
Alex King c1698a5bdd [Cleanup] Fix possible overflows in Client::AddPlatinum() and Client::TakePlatinum() (#3255)
# Notes
- Fix possible overflows by casting properly.
2023-04-05 10:10:33 -04:00
Alex King 2a094e8792 [Cleanup] Use variable for c->GetTarget() instead of calling multiple times in bot_command.cpp (#3254)
# Notes
- Calling multiple times is less performant than using a variable.
2023-04-05 10:09:19 -04:00
Alex King 4a0725e278 [Cleanup] Cleanup string -> char* -> string conversions in bot_command.cpp (#3252)
# Notes
- We were converting back and forth between types unnecessarily.
2023-04-05 09:59:43 -04:00
Alex King 218ffbb2c5 [Cleanup] Delete unused strings in bot_command.cpp (#3251)
# Notes
- These are unused.
2023-04-05 09:59:24 -04:00
Chris Miles 3e30e78158 [Backups] Fix database dump error reporting (#3175)
* [Backups] Fix database dump error reporting

* Update database_dump_service.cpp
2023-04-04 00:14:23 -05:00
Aeadoin ff2af0c49e [Release] 22.9.1 (#3250) 2023-04-03 17:49:39 -04:00
Alex King cd5697bc81 [Cleanup] Multiple cases same outcome and set skip variable to same value (#3216)
# Notes
- `skip` is set to `attacker` before it's set to `attacker` again.
- Multiple spots in `Mob::AttackAnimation` use the same animations.
2023-04-03 17:24:27 -04:00
Alex King b1571cd062 [Cleanup] Wake The Dead argument was named the same as a member variable in Mob (#3214)
# Notes
- Member variable is also named `target`.
2023-04-03 17:23:48 -04:00
Alex King 3e5d0a0601 [Cleanup] Unconditional return in for loop in GetRaidByCharID() (#3179)
# Notes
- This is improper and should just check if we have no result, return `0`, otherwise return `row[0]` of the row we queried.
2023-04-03 17:23:32 -04:00
Alex King 6a80a061dd [Cleanup] Multiple cases with same outcome in GetGMSayColorFromCategory() (#3182)
# Notes
- Both cases have the same return.
- https://pvs-studio.com/en/docs/warnings/v1037/
2023-04-03 17:20:43 -04:00
Alex King 509fd0615e [Cleanup] Remove unused query variable in Database::DeleteInstance() (#3202)
# Notes
- Variable was defined but never used.
2023-04-03 17:18:40 -04:00
Alex King da5e672a28 [Cleanup] Remove unnecessary group validation in Bot::Death() (#3235)
# Note
- We already break if there is no group above, revalidation is unnecessary.
2023-04-03 17:15:09 -04:00
Alex King 7090382074 [Cleanup] Remove unnecessary skill_to_use check in Bot::DoClassAttacks() (#3236)
# Notes
- `skill_to_use` will never be `-1` as it passes through the switch and checks class.
2023-04-03 17:11:56 -04:00
Alex King 26eabcd7a4 [Cleanup] Explicitly cast to float for more precision in Bot::GenerateBastHitPoints() (#3238)
# Notes
- Not casting explicitly we lost precision.
2023-04-03 17:05:48 -04:00
Alex King 60091015d3 [Cleanup] Remove unnecessary >= 0 checks for procs in botspellsai.cpp (#3242)
# Notes
- These are always `>= 0` since they're `uint16`.
2023-04-03 17:05:03 -04:00
Alex King 470392021b [Cleanup] Remove unnecessary setting of spell_type_index in Bot::GetChanceToCastBySpellType() (#3243)
# Notes
- The default is already `SPELL_TYPE_COUNT`, no need to set it again.
2023-04-03 17:04:51 -04:00
Alex King 90984c3215 [Cleanup] Remove unnecessary spell_list validation check in botspellsai.cpp (#3244)
# Notes
- We check if valid above, no need to do it again.
2023-04-03 17:03:56 -04:00
Alex King da2296d416 [Cleanup] Remove unnecessary hpr checks in Bot::BotCastHeal() (#3245)
# Notes
- These checks are unnecessary as we know it doesn't pass previous checks.
2023-04-03 17:03:36 -04:00
Alex King c9221f239c [Cleanup] Remove unnecessary botCaster check in Bot::GetDebuffBotSpell() (#3246)
# Notes
- We already check if `botCaster` is invalid above, no need to do so again.
2023-04-03 17:02:48 -04:00
Alex King f4edc69a87 [Cleanup] Cleanup unnecessary string -> char* -> string conversions in eqemu_config.cpp (#3207)
# Notes
- These conversions are unnecessary since we can just use the string itself.
2023-04-03 17:01:44 -04:00
Alex King 7d04608c4d [Cleanup] summon_count > MAX_SWARM_PETS is always false in aa.cpp (#3212)
# Notes
- This was always false.
2023-04-03 17:00:08 -04:00
Alex King 32be049d96 [Cleanup] Remove extraneous loottable_id setting in WakeTheDead in aa.cpp (#3215)
# Notes
- We already set `made_npc->loottable_id` to `0` above.
2023-04-03 16:59:06 -04:00
Alex King 26fd52fb06 [Cleanup] Fix SEResist array settings duplicate code (#3225)
# Notes
- These conditions did the same thing, combining them is simpler.
2023-04-03 16:53:48 -04:00
Alex King 5dd849ac75 [Cleanup] Fix typo where itembonuses should have been used instead of spellbonuses (#3221)
# Notes
- `itembonuses` was the proper name here, not `spellbonuses`.
2023-04-03 16:51:22 -04:00
Alex King f484fe4176 [Cleanup] gid is assigned 2 values simultaneously in bot.cpp (#3234)
# Notes
- Unnecessarily assigning the value twice simultaneously.
2023-04-03 16:47:46 -04:00
Alex King 3d20c0d6aa [Cleanup] Change level to bot_level in Bot::DoClassAttacks() to not overlap member variable (#3239)
# Notes
- Member variable is named `level`, change variable to `bot_level` so we don't cause issues.
2023-04-03 16:47:31 -04:00
Alex King 0297045cc5 [Cleanup] Move cases in Bot::AICastSpell() (#3247)
# Notes
- These all returned `false`, no need to be separate.
2023-04-03 16:46:31 -04:00
Alex King cb90d00832 [Cleanup] Cleanup variable names in Bot::AddSpellToBotList() (#3248)
# Notes
- `max_hp` was named after a member variable.
2023-04-03 16:45:36 -04:00
Aeadoin f752b57a55 [Cleanup] Cleanup uses of insert/push_back when a temp object is used. (#3170) 2023-04-03 16:45:01 -04:00
Alex King 2bb15271c5 [Cleanup] Fix possible dereferencing of invalid iterator in constants (#3181)
# Notes
- Possible dereferencing of invalid iterator based on logic: https://pvs-studio.com/en/docs/warnings/v783/
2023-04-03 16:42:45 -04:00
Alex King 6976e27501 [Cleanup] Use a constant reference for content_flags in SetContentFlags() (#3196)
# Notes
- This is more performant.
- https://pvs-studio.com/en/docs/warnings/v813/
- https://pvs-studio.com/en/docs/warnings/v820/
2023-04-03 16:38:20 -04:00
Alex King c9f27d6f90 [Cleanup] Remove possible dereferenced nullptrs in bot.cpp (#3241)
# Notes
- Possible dereferenced nullptrs based on logic.
2023-04-03 16:30:46 -04:00
Alex King cb129efcad [Cleanup] Fix loop and code duplication for SE_ProcOnKillShot (#3224)
* [Cleanup] Fix loop for SE_ProcOnKillShot

# Notes
- We were doing `e = 3` instead of doing `e += 3`.

* Update bonuses.cpp
2023-04-03 16:28:15 -04:00
Aeadoin d653989b03 [Bug Fix] Fix issue with Bot Raid invites not working. (#3249)
* [Bug Fix] Fix issue with Bot Raid invites not always working.

* ordering
2023-04-03 16:28:05 -04:00
Alex King ea9b373180 [Cleanup] Further bot.cpp nullptr checks (#3240)
# Notes
- `nullptr` validation
2023-04-03 16:25:00 -04:00
Aeadoin a4e006fbfb [Bug Fix] Correct Forward Declaration compilation warning (#3176)
* [Bug Fix] Correct Forward Declaration compilation warning

* no need for include
2023-04-02 12:19:43 -04:00
Aeadoin 1ffdd4cb34 [Performance] Change to use Pass by reference where valid. (#3163)
* [Performance] Change to use Pass by reference where valid.

* typo
2023-04-01 22:55:40 -04:00
Aeadoin 7f7ba2e6c2 [Cleanup] Remove unused Includes under zone files (#3162) 2023-04-01 22:55:28 -04:00
Aeadoin 090086f50c [Release] 22.9.0 (#3174) 2023-04-01 14:27:52 -04:00
Alex King 407b003f7d [Cleanup] Add client pointer validation to Zone::GetClosestZonePoint() (#3173)
# Notes
- We were not validating pointer here, could cause issues.
2023-04-01 14:22:52 -04:00
Alex King b6d315d803 [Cleanup] Remove unnecessary validation check in Zone::ClearBlockedSpells() (#3172)
# Notes
- This is unnecessary, since `safe_delete_array` checks for validity.
2023-04-01 13:59:03 -04:00
Aeadoin 6927177291 [Fix] Correct SE_SlayUndead & SE_HeadShotLevel limit Value when applied. (#3171) 2023-04-01 13:31:13 -04:00
Aeadoin 31ede355a8 [Cleanup] Cleanup excessive type casting: string -> char * -> string (#3169)
* [Cleanup] Cleanup excessive type casting: string -> char * -> string

* [Cleanup] Cleanup excessive type casting: string -> char * -> string
2023-04-01 12:45:16 -04:00
Aeadoin 0df84e1ee6 [Crash] Fix out of bound arrays, other potential crashes (#3166) 2023-04-01 12:44:41 -04:00
Aeadoin 0d509a7f3a [Crash] Add Checks for valid pointers or fix existing. (#3164) 2023-04-01 12:44:00 -04:00
Aeadoin 4c2271ff69 [Fix] Prevent VerifyGroup from setting OOZ membername to Null character. (#3168) 2023-04-01 12:40:55 -04:00
Aeadoin ca2072e7bf [Bots] Remove Bot Groups Functionality (#3165)
* [Bots] Remove Bot Groups Functionality

* in-class initializers for member variables.
2023-03-31 21:37:52 -04:00
Alex King e1eb1ff738 [Quest API] Add missing Luabind definitions to lua_general.cpp (#3167)
# Notes
- These definitions were missing somehow.
2023-03-31 21:05:01 -04:00
Aeadoin 25f5898bae [Release] 22.8.2 (#3161) 2023-03-30 09:22:58 -04:00
Aeadoin 934ff3dadf [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat (#3158)
* [Bug Fix] Correct logic checks for Bot rule AllowOwnerOptionAltCombat

* fix ordering of raid/group checks
2023-03-30 08:31:57 -04:00
Aeadoin e4ff76dceb [Bug Fix] Fix for OOZ Group updates when removing/inviting Bots (#3159)
* [Bug Fix] Fix for Cross Zone Group updates with Bots when disbanding/joining groups.

* check for nullptr
2023-03-30 08:31:50 -04:00
Alex King 6960a1a682 [Bug Fix] Fix issues with Lua tables not starting at index 1 (#3160)
* [Bug Fix] Fix issues with Lua tables not starting at index 1

# Notes
- This would cause the first item in the table to be inaccessible since Lua tables start at index `1` instead of index `0`.
- All other spots using Lua tables have their indexes starting at `1`.

* Update lua_general.cpp
2023-03-30 06:02:53 -04:00
Aeadoin d4174ca236 [Fix] Fix strcpy-param-overlap (#3157) 2023-03-29 08:33:06 -04:00
Aeadoin 7854130a93 [Bug Fix] Check Rule "Bots Enabled" to prevent bot database calls on connect (#3154)
* [Bug Fix] Check for Rule "Bots Enabled" to prevent bot database calls if not enabled.

* formatting

* check if LoadBotsList failed, or is bots_list empty
2023-03-28 22:44:47 -04:00
Alex King e9c63c7d94 [Rules] Remove Guild Bank Zone ID Rule (#3156)
# notes
- This rule is useless as guild bank zone ID is hard-coded into the client.
2023-03-28 21:58:58 -04:00
Aeadoin 27e0665aae [Bug Fix] Fix bot_raid_members.sql for MYSQL. (#3155) 2023-03-28 15:25:16 -04:00
Alex King ea2f431fce [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp (#3153)
* [Fix] Fix an issue with EVENT_DISCONNECT not firing on regular /camp

# Notes
- We were only sending `EVENT_DISCONNECT` on GM instant camps or linkdeads.

* Update client_process.cpp
2023-03-27 21:45:02 -04:00
Aeadoin 8bdcf7cb94 [Crash] Add Checks for out of bounds & dereferencing nullptrs (#3151)
* [Crash] Add Checks for out of bounds/nullptr dereferences

* formatting

* formatting

* formatting

* Update bot.cpp

---------

Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
2023-03-27 21:43:46 -04:00
Aeadoin 87cb74b851 [Release] 22.8.1 (#3152) 2023-03-27 17:55:48 -04:00
Alex King 26c267db1b [Cleanup] "equipped" not "equiped", "dual" not "duel". (#3149)
* [Cleanup] "equipped" not "equiped", "dual" not "duel".

# Notes
- These are spelled incorrectly.

* Update spdat.h

* Formatting further.

* Update api_service.cpp
2023-03-27 17:55:37 -04:00
Aeadoin 99f8e6cef5 [Bug Fix] Fix for NPCs having spells interrupted. (#3150) 2023-03-27 16:57:08 -04:00
Aeadoin b6917ec782 [Release] 22.8.0 (#3148) 2023-03-25 20:48:43 -04:00
Aeadoin eb51550109 [Cleanup] Cleanup Strings::ToInt uses. (#3142)
* [Cleanup] Cleanup Strings::ToInt uses.

* fix for conversion

* remove != 0

* cleanup
2023-03-25 20:32:30 -04:00
Alex King 9d1ace627c [Feature] Add support for -1 extradmgskill to allow all skills to be scaled. (#3136)
* [Feature] Add support for -1 extradmgskill to allow all skills to be scaled.

- `$mob->GetSkillDmgAmt(skill_id)` now uses `int` instead of `uint16`.

- `statbonuses:GetSkillDamageAmount(skill_id)` now uses `-1` properly.
- `mob:GetSkillDmgAmt(skill_id)` now uses `int` instead of `uint16`.

- A `-1` value in `extradmgskill` denotes the ability to scale all skills at once.
- Consolidated `AddItemBonuses()`, `AdditiveWornBonuses()`, `CalcItemBonuses()`, and `CalcRecommendedLevelBonus()` to mob-based methods to avoid code duplication.
- Bots, NPCs, and Mercs can now use additive worn effects if the rule is enabled, as well as all other proper stat bonuses that only clients had before.
- No SQL update required to change `extradmgskill` and `extradmgamt` to `int` as they already are this type in the database, just had to adjust `item_data.h` and `shareddb.cpp`.

* Update mob.cpp

* Cleanup.

* Cleanup.

* Move #include <vector> to header.

* Add method for GetExtraDamageSkills

* fix additembonuses

* Update bonuses.cpp

* Update mob.cpp

* Out of bounds.

* Update bonuses.cpp

---------

Co-authored-by: Aeadoin <109764533+Aeadoin@users.noreply.github.com>
2023-03-25 20:26:01 -04:00
Aeadoin ec3ef411a1 [Fix] Fix for SQL Query in npc_scale_global_base (#3144) 2023-03-25 20:08:40 -04:00
Aeadoin 1394b6a4d2 [Hotfix] Fix for Items looted from corpses. (#3147) 2023-03-25 20:00:31 -04:00
Aeadoin 7f41547963 [Crash] Fix for crash in Raid::QueuePacket (#3145)
* [Crash] Fix for crash in Raid::QueuePacket

* bots can't be a part of BalanceMana

* corrected additions

* adding additional is_bot gates

* updating raid for loops to be range based.

* typo

* formatting

* formatting
2023-03-25 18:02:05 -04:00
Alex King 2e4071cdcf [Cleanup] Remove extern bool Critical (#3146)
# Notes
- This is unused.
2023-03-25 17:48:40 -04:00
Aeadoin dc475a1bd7 [Release] 22.7.0 (#3143) 2023-03-24 15:11:42 -05:00
Aeadoin 59ad91a140 [Feature] Add Data Bucket support for scaling of Heroic Stats. (#3058)
* [Feature] Add Data Bucket support for scaling of Heroic Stats.

* update

* fixes, still reworking logic

* fixes, still reworking logic

* logic done

* logic done

* fixes

* Cleanup

* Cleanup

* Cleanup naming, verify behaviors

* formatting

* formatting

* fix issue with endurance and mana.

* update rule desc

* cleanup

* DataBucket Struct

* Cleanup data_bucket.cpp and add constants

* cleanup

* changes

* formatting

* fix from merge

* escape keyword `key`

* Add `key` to generator, run repository-generator.pl

* fix for change to key

* cleanup

* formatting

* formatting

* typo
2023-03-23 21:42:13 -04:00
Aeadoin abc27ab423 [Bug Fix] Fix edge cases where camped bots would be left in a raid (#3139)
* [Bug Fix] Fix edge cases where camped bots would be left in a raid

* formatting
2023-03-23 19:23:34 -04:00
Aeadoin c975dc2412 [Bug Fix] Fix for transferring Raid Leader (#3140) 2023-03-23 19:04:59 -04:00
Aeadoin e085f271f5 [Bug Fix] Fix for incorrect bindpoint x,y,z,headings (#3141) 2023-03-23 18:55:56 -04:00
Alex 5a6314e1a9 [Fix] Fixes for corpses not properly saving some item instance data correctly. (#3123)
* Convert ZoneDb::LoadCharacterCorpseData to use a cleaner api that has a better layout.

* Update corpse save methods to use a new cleaner api.

* Add item to corpse will use a few new fields that don't yet save.

* Fix for some issues moving data to corpses.

* Make CreateItem more explicit to avoid overlooking places it's used and add more arguments.

* DB changes

* Revert of the changes to the database.CreateItem api change.

* Missed one.

* Fixes for mr Krab

* Small formatting

---------

Co-authored-by: KimLS <KimLS@peqtgc.com>
Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-03-23 01:16:52 -05:00
Aeadoin dc45e0d280 [Fix] Change SPA 193 Weapon Damage to allow values over 65,535 (#3138) 2023-03-23 01:06:51 -05:00
Aeadoin 2e2c4d64fe [Cleanup] Cleanup uses of Strings::ToInt to match correct type. (#3054)
* [Cleanup] Cleanup uses of Strings::ToInt to match correct type.

* cleanup
2023-03-22 12:22:03 -04:00
Aeadoin c5add503ab [Bug Fix] Fix for Raid Disband if leader not in same zone. (#3135) 2023-03-21 19:16:01 -04:00
Aeadoin fe2dcb6544 [Crash] Fix dangling Group member pointers for Bots. (#3134)
* [Crash] Fix dangling Group member pointers for Bots.

* fixes for edge cases
2023-03-21 11:57:04 -04:00
Alex King 4fe44f4cb6 [Quest API] Add Timer related methods to Mobs in Perl/Lua (#3133)
* [Quest API] Add Timer related methods to Mobs in Perl/Lua

# Perl
- Add `quest::ispausedtimer(timer_name)`.
- Add `quest::pausetimer(timer_name)`.
- Add `quest::resumetimer(timer_name)`.
- Add `$mob->GetRemainingTimeMS(timer_name)`.
- Add `$mob->GetTimerDurationMS(timer_name)`.
- Add `$mob->HasTimer(timer_name)`.
- Add `$mob->IsPausedTimer(timer_name)`.
- Add `$mob->PauseTimer(timer_name)`.
- Add `$mob->ResumeTimer(timer_name)`.
- Add `$mob->SetTimer(timer_name)`.
- Add `$mob->SetTimerMS(timer_name)`.
- Add `$mob->StopTimer(timer_name)`.

# Lua
- Add `mob:GetRemainingTimeMS(timer_name)`.
- Add `mob:GetTimerDurationMS(timer_name)`.
- Add `mob:HasTimer(timer_name)`.
- Add `mob:IsPausedTimer(timer_name)`.
- Add `mob:PauseTimer(timer_name)`.
- Add `mob:ResumeTimer(timer_name)`.
- Add `mob:SetTimer(timer_name)`.
- Add `mob:SetTimerMS(timer_name)`.
- Add `mob:StopTimer(timer_name)`.

# Notes
- The mob-based methods allow operators to loop entity list or whatever to set, stop, resume, pause, etc for timers.

* StopAllTimers()

* Update questmgr.cpp
2023-03-20 16:18:51 -04:00
Alex King 63a8d2d641 [Cleanup] Delete zone_numbers.h (#3129)
* [Cleanup] Delete zone_numbers.h

# Notes
- This is unused.

* Update client_packet.cpp

* Update client_packet.cpp
2023-03-20 12:06:40 -04:00
Alex King abcb5d069f [Cleanup] Remove FindPatch() from struct_category.cpp and struct_category.h (#3130)
# Notes
- This is unused.
2023-03-20 12:06:10 -04:00
Aeadoin d6b954a4b9 [Cleanup] Cleaning up Raid.cpp (#3125)
* [Cleanup] Cleanup Raid.cpp

* cleanup

* fix is_bot instances

* bracket cleanup

* bracket cleanup

* rename variables in struct

* fix for merge
2023-03-20 11:39:14 -04:00
Alex King 2415645b86 [Fix] Fix typo for bot_id raid_members column in db_update_manifest.txt (#3132)
# Notes
- This was causing this query to run over and over.
2023-03-19 22:32:35 -04:00
Aeadoin e77a83f8c3 [Rule] Add Rule to allow ExtraDmgSkill/SPA 220 to effect Spell Skills (#3124)
* [Rule] Add Rule to allow ExtraDmgSkill/SPA 220 to effect Spell Skills

* add support for rule "ItemExtraSkillDamageCalcAsPercent"
2023-03-19 12:16:32 -04:00
Alex King a5d564a6fb [Cleanup] Remove ChangeHP() from mob.h (#3128)
# Notes
- This is unused.
2023-03-19 10:18:31 -04:00
Alex King 2f4c91824e [Feature] Add Item Extra Skill Damage Percent Modifier (#3127)
* [Feature] Add Item Extra Skill Damage Percent Modifier

# Notes
- Allows `Character:ItemExtraDmgCap` to be disabled if set to `-1` or lower.
- Allows operators to set `Character:ItemExtraSkillDamageCalcAsPercent` to `true` to allow skill damage for Frenzy, Backstab, Bash, Slam, Kick, and all Monk attacks to scale with a percentage based on `extradmgamt` values from items and spells.

* > 0
2023-03-19 09:59:13 -04:00
Aeadoin 53e6f931c9 [Crash] Fixes Crash when Zoning with XTarget when Bots are in group. (#3126) 2023-03-19 08:26:16 -04:00
Alex King a6efb1e8b5 [Cleanup] Remove GetStartCount() and InitStartTimer() from zone_launch.cpp and zone_launch.h (#3121)
# Notes
- These are unused.
2023-03-17 19:21:50 -04:00
Alex King b2757143a8 [Cleanup] Remove SetConnection() from loginserver/world_server.h (#3120)
# Notes
- This is unused.
2023-03-17 19:21:44 -04:00
Alex King 6e5da0e558 [Cleanup] Remove GetServerByAddress() from server_manager.h (#3119)
# Notes
- This is unused.
2023-03-17 19:21:38 -04:00
Alex King 6b8e74a29f [Cleanup] Remove PlayerLogin_Struct from login_types.h (#3118)
# Notes
- This is unused.
2023-03-17 19:21:30 -04:00
Alex King 203e63101a [Cleanup] Remove IsConnected() from loginserver/database.h (#3117)
# Notes
- This is unused.
2023-03-17 19:21:18 -04:00
Alex King 91257d599b [Cleanup] Remove unused methods in loginserver/client.h (#3116)
* [Cleanup] Remove LoginOnNewConnection(), LoginOnPacketRecv(), and LoginOnStatusChange() from loginserver/client.h

# Notes
- These are unused.

* Cleanup.
2023-03-17 19:21:08 -04:00
Alex King 491b358e28 [Cleanup] Remove UpdateLoginserverWorldAdminAccountPasswordById() from account_management.cpp (#3115)
# Notes
- This is unused.
2023-03-17 19:20:56 -04:00
Alex King 180c3088ca [Cleanup] Remove DBInitVars() and HandleMysqlError() from queryserv/database.h (#3114)
# Notes
- These are unused.
2023-03-17 19:20:47 -04:00
Alex King 97e4547192 [Cleanup] Remove DBInitVars(), HandleMysqlError(), and IsChatChannelInDB() in ucs/database.h (#3113)
# Notes
- These are unused.
2023-03-17 19:20:41 -04:00
Aeadoin 0caee9026a [Rule] Add Task System Rule ExpRewardsIgnoreLevelBasedEXPMods (#3112)
* [Rule] Add Task System Rule ExpRewardsIgnoreLevelBasedEXPMods

* description
2023-03-17 19:15:02 -04:00
Aeadoin 0be7ead1d1 [Bug Fix] Fix Bard Bot Casting (#3122) 2023-03-17 19:07:54 -04:00
Aeadoin 950489bc34 [Bug Fix] Fix Raid methods that could cause crashes with Bots in raid (#3111) 2023-03-17 16:19:29 -04:00
Mitch Freeman 45da8cab61 [Bots] Add Basic Bot Raiding Functionality (#2782)
* Fix for GENERIC_9_STRINGS

* Add Bot Heal Message Display

Creates a new rule to display Bot heal messages to the Bot Owner

* 2021-03-25 11L04pm

Spell and Heal Rule added to allow for Bot spell and heal damage to be sent to the Bot Owner's Group.  Also added a check to remove duplicate message for #damage on self.

* Update .gitignore

* BOT work

Added BOT logging damage/heals to owner
Added BOT message to owner for harmony fails
Made var Critical global to remove duplicate crit messages
Added a NULL check to Mob:GetCleanname()

* Bot Group Work

Fixed botid=charid spawn on zone issue
Added a group_list update on zone to refresh from database to fix a dangling pointer to a Bot object that was camped but was previously in a group within the zone being entered.
Modified Bot::ProcessBotGroupInvite to use the client of the bot when doing the Bot initialization so that a leader can invite another owner's Bot

* Jan 4

Basic structure in place for Raid::AddBot though not working

* Basement Jan 5

* End of day Jan 5
Working Raid Invite to a Bot.

* Update to Client::QueuePacket to not attempt to send a packet to a BoT.  Not clean, but a broad solution.

* Updated Raid::VerifyRaid

* Some Bot Raid working

* Before VS Crash

* Use Case 1, 2, 3,4,7 working.
Need to fix 5, 6, 8

* Work on usecase 5

* A few more use cases working

* New work on Raid invite with a invitor having a group

* Bot Raid inviting working for all use cases

* A few changes

* end of day jan 10

* Jan 11

* end of day Jan 11

* Bot Invite/Accept cleanup

* Start of moving raid bot functions to their own methods

* More bot raid changes

* More raid spell work

* end of day Jan 16

* spawn work

* Spawn on login working

* End of Day Jan 18

* Raid leader and mana/hp updates fixed

* Spell Tracking

* Issue with Bot Death in raid when casted upon.  1741 raid.cpp

* Bot Death fixed and few other crashes

* Working on botgroup removal

* Bot Disbanding Work 90%

* Looks like BOTs are working

* Fixed a bot crash

* bug tracing on entity list mismatch

* safe_delete resoves problem.  No to track down leak

* seems to be working

* Memory corruption found - sending packets to BoTs using Client class

* added Raid::IsRaidMemberBot()

* Update p_raid_instance

* g3

* Final - Bot Raid Working

* Fixed IsRaidMemberBot to remove memory leak
Fixed altcombat crash though RaidMainAssist (428) needs fixing

* add RaidMember.IsBot

* Repaired IsBot function to be more preformant.  Now works on standard performance machine

* Fixed Bard AE Target Spells
Removed assert for buffs

* updated based on Feb 2022 master updates

* Added bot_db_updates and version increment

* Cleanup of bot raid work and inclusion of bot_raid in cmake

* Delete .gitignore

* Revert "Delete .gitignore"

This reverts commit 8523658d3b.

* Fixed a packet issue

* Merged upstream/master

Merged upstream/master and removed ifdef BOTS as per recent dev approach for BOTS.  Functionality is there, compiles and tests ok.  A few problems to be resolved though this is a good baseline.

* Added sql update for raid_members to add isbot

* Updated Bot Follow Function

Bot will now follow the Group Leader if IsClient, otherwise follows the Bot Owner

* Updates to Bot Raid System

When camping a client, remove them from the raid.  If they are leader, place leadership to the next client.
Update a few crash checks in bot_raid.cpp

* [BOTS] Added RuleB Enabled checks and updated base repo for raid_members

Updated several RuleB(Bots, Enabled) checks
Updated the base repo to be autogenerated.
Raid functionality should work with a non-bots enabled database.

* Few quick updates

* Updates

Corrected a number of comments.  Compiled and tested against bot and non-bot database though requires the isbot column in raid_members for both.
Moved the db update out of the bot stream to make bot check code easier.

* Formatting and other small updates

* A few more RuleB(Bots, Enabled) additions

* Fix issue with conflict of bot ID versus character ID.

* Delete CMakeSettings.json

* Comment Updates and other

Several updates including
- fixed comments from PR
- added id to raid_members and unique index on name to avoid botid and charid conflicts
- updated a few raid functions for iterators
- reordered several raid operations to ensure send leader packet to be the last item to ensure proper updating on the client
- update sql to use Replace instead of Insert for botid conflicting with charid

* Exploit fix for Raid Bots

Added item from @Nite to disallow spawning or camping bots if Raid is engaged.  Avoids abusive situations.

* Initial Commit

* fix Raid Window after zoning

The raid window was not fully updating for clients not in the zone.

* Cleanup

* Update

Fixed comments

* Resolve crash for MOTD

Fixed a crash situation sending a raid MOTD to BOTS.

* Update ruletypes.h

* Updated to resolve a few recent comments

Fixed some comments within attack.cpp

* fix sql query

* update repository

* prevent duplicate entries in raid after group invite, and cleanup

* fixes for botgroups not following, and add already in raid messages.

* fix messagestring

* fixes

* Cleanup, and resolving issues with disbanding

* refactoring

* more cleanup/fixing.

* fixes for removing from ground in raid

* Refactoring/fixing multiple clients

* fix for compiling

* Bugs from refactoring fixed

* Testing completed, cleaning up unwanted items/duplicate code.

* Cleaned up AICastSpell

* fix typos

* Refactoring

* Adding Raid checks to AI_Process/cleanup

* Fix a typo

Was getting a SQL error on BOT spawn.  Fixed typo.

* fix for crash

* Fixed crash when inviting player, more refactoring

* AI_Process Refactoring work

* More Refactoring/fixes for follow

* Finish Refactoring AI_Process

* cleanup

* cleanup

* cleanup

* cleanup

* fix melee attack loop

* fix for leashowner.

* fix for leashowner.

* Bots persist in raid after client death/LD/Camp

* Fix Bot Groups when zoning after death.

* Fix Bots in group following after client death

* remove unnecessary query

* Allow Raid members to invite Bots if owner is in raid. cleanup

* optimization of raid verification

* remove this

* Code Cleanup

* formatting

* formatting

* formatting

* fix for macro

* add return for TryClassAttacks

* fix query

* fix for crash

* restrict camping/spawn in combat.

* Fix other crash issue.

* update learnmembers to use Strings::To, cleanup magic numbers

* fix for merge.

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
Co-authored-by: Aeadoin <109764533+Aeadoin@users.noreply.github.com>
2023-03-17 11:19:59 -04:00
Alex King e778041198 [Cleanup] Remove ownHiddenTrigger from trap.cpp and trap.h (#3092)
# Notes
- This is unsued.
2023-03-17 08:37:36 -04:00
Alex King 97e50ced93 [Cleanup] Delete deprecated/perlxs folder (#3110)
# Notes
- This entire folder is unused.
2023-03-17 06:23:30 -04:00
Alex King 4491bb9a70 [Cleanup] Remove is_authenticatd, LSShutDownUpdate(), and SetInstanceID() from zoneserver.h (#3109)
# Notes
- These are unsued.
2023-03-17 06:23:19 -04:00
Alex King 04fba27467 [Cleanup] Remove StoreCharacter() from worlddb.h (#3108)
# Notes
- This is unused.
2023-03-17 06:23:10 -04:00
Alex King fa47dd7f93 [Cleanup] Remove DisableStats(), EnableStats(), DisableLoginserver(), and EnableLoginserver() from world_config.h (#3107)
# Notes
- These are unused.
2023-03-17 06:23:01 -04:00
Alex King b3fb5f00ab [Cleanup] Remove MakeGuildMembers() from wguild_mgr.h (#3106)
# Notes
- This is unused.
2023-03-17 06:22:51 -04:00
Alex King e17fad9ae0 [Cleanup] Cleanup unused methods and variables in world/main.cpp and world/main.h (#3105)
# Notes
- These are unused.
2023-03-17 06:22:41 -04:00
Alex King bbdaacd3b0 [Cleanup] Remove AllConnected(), CanUpdate(), and SendInfo() from login_server_list.cpp and login_server_list.h (#3104)
# Notes
- These are unused.
2023-03-17 06:22:34 -04:00
Alex King 61bd485449 [Cleanup] Remove unused methods in eql_config.cpp, eql_config.h, launcher_list.cpp, and launcher_list.h (#3103)
# Notes
- These are unused.
2023-03-17 06:22:01 -04:00
Alex King 4b405fe9fe [Cleanup] Remove authenticated from launcher_link.cpp and launcher_link.h (#3101)
# Notes
- This is unused.
2023-03-17 06:21:51 -04:00
Alex King d5aaf7cee5 [Cleanup] Remove CountZones() from launcher_link.h (#3100)
# Notes
- This is unused.
2023-03-17 06:21:41 -04:00
Alex King 12e9e0f71d [Cleanup] Delete world/console.old.cpp (#3099)
# Notes
- This is unused.
2023-03-17 06:21:23 -04:00
Alex King 0a64e26672 [Cleanup] Remove FindCLEByLSID(), GetCLE(), GetCLEIPCount(), and RemoveCLEByLSID() from clientlist.h (#3098)
# Notes
- These are unused.
2023-03-17 06:21:14 -04:00
Alex King 11fc5a9e93 [Cleanup] Remove SendGuildPacket() from clientlist.cpp, clientlist.h, and wguild_mgr.cpp (#3097)
# Notes
- This is unused.
2023-03-17 06:21:00 -04:00
Alex King 7bbcdfb479 [Cleanup] Remove FindByName(charname) from clientlist.h (#3096)
# Notes
- This is unused.
2023-03-17 06:20:46 -04:00
Alex King 3a530eb43b [Cleanup] Remove CheckAuth(), SetOnline(), and pMD5Pass from cliententry.h (#3095)
# Notes
- These are unused.
2023-03-17 06:20:36 -04:00
Alex King 48a60114b7 [Cleanup] Remove CommandRequirement() from zonedb.h (#3094)
# Notes
- This is unused.
2023-03-17 06:20:25 -04:00
Alex King 06f1f36c95 [Cleanup] Utilize GetScheduler() in zone/worldserver.cpp (#3093)
# Notes
- This was unused.
2023-03-17 06:20:13 -04:00
Alex King ccd9bd7d4c [Cleanup] Utilize SetHiddenTrigger in trap.cpp (#3091)
# Notes
- This was unused.
2023-03-17 06:17:53 -04:00
Alex King fea6cbf633 [Cleanup] Remove RemoveSpawnGroup() from spawngroup.h (#3090)
# Notes
- This is unused.
2023-03-17 06:17:44 -04:00
Alex King 460739d35c [Cleanup] Delete queues.h (#3089)
# Notes
- This is unsued.
2023-03-17 06:17:32 -04:00
Alex King 11e1edc99f [Cleanup] Remove IsOrigin(glm::vec2) from position.h (#3088)
# Notes
- This is unused.
2023-03-17 06:17:20 -04:00
Alex King 7374660045 [Cleanup] Remove last_insert_id from petitions.h (#3087)
# Notes
- This is unused.
2023-03-17 06:17:10 -04:00
Alex King 9e8d365ca7 [Cleanup] Remove SetSentTime2 in petitions.h (#3086)
# Notes
- This is unused.
2023-03-17 06:17:00 -04:00
Alex King 14d69a0a14 [Cleanup] Remove perlparser.h (#3085)
# Notes
- This is unused.
2023-03-17 06:16:51 -04:00
Alex King fe063637e9 [Cleanup] Remove GetTransformation() and GetInvertedTransformation() from oriented_bounding_box.h (#3084)
# Notes
- These are unused.
2023-03-17 06:16:40 -04:00
Alex King 232b1028d7 [Cleanup] Remove m_inuse, m_z, and m_heading from object.h (#3083)
# Notes
- These are unsued.
2023-03-16 21:47:27 -04:00
Alex King 3624307385 [Cleanup] Remove SetDBID() from object.h (#3082)
# Notes
- This is unused.
2023-03-16 21:36:03 -04:00
Alex King c0055cf357 [Cleanup] Remove npc_ai.cpp/npc_ai.cpp (#3081)
# Notes
- These files were unused.
2023-03-16 21:17:23 -04:00
Alex King f9c1683d36 [Cleanup] Remove GetAILevel() from npc.h (#3080)
# Notes
- This is unused.
2023-03-16 21:06:24 -04:00
Alex King 64df993c10 [Cleanup] Remove FlushLootStats() from npc.h (#3079)
# Notes
- This is unused.
2023-03-16 21:06:10 -04:00
Alex King 890ef696fe [Cleanup] Remove GetDestination() from doors.h (#3078)
# Notes
- This is unused.
2023-03-16 20:47:40 -04:00
Alex King 3f1848b01a [Cleanup] Remove can_corpse_be_rezzed from corpse.h (#3077)
# Notes
- This is unused.
2023-03-16 20:47:25 -04:00
Alex King f7c4f1ff75 [Cleanup] Remove _baseBotStance from bot.h (#3076)
# Notes
- This is unused.
2023-03-16 20:25:45 -04:00
Alex King dcb127f4b6 [Cleanup] Remove _botRole from bot.h (#3075)
# Notes
- This is unused.
2023-03-16 20:25:35 -04:00
Alex King 669b068978 [Cleanup] Remove _previousTarget from bot.h (#3074)
# Notes
- This is unused.
2023-03-16 20:25:25 -04:00
Alex King db2aeca38f [Cleanup] remove _botOrderAttack from bot.h (#3073)
# Notes
- This is unused.
2023-03-16 20:25:16 -04:00
Alex King 1b3ca95f8c [Cleanup] Remove firstlogin and realfirstlogin from world/client.h (#3072)
# Notes
- These are unused.
2023-03-16 20:25:03 -04:00
Alex King c05baac551 [Cleanup] Remove CLIENT_TIMEOUT from world/client.h and zone/client.h (#3071)
# Notes
- This is unused.
2023-03-16 20:24:53 -04:00
Alex King 939fc79d19 [Cleanup] Remove IsAffectedByBuff() (#3068)
# Notes
- This is unused.
2023-03-16 20:24:44 -04:00
Alex King a0e6fce057 [Cleanup] Remove fixedZ from mob.h (#3065)
# Notes
- This is unused.
2023-03-16 20:24:35 -04:00
Alex King 452389b7a5 [Cleanup] Remove class EQStream from client.h (#3070)
# Notes
- This is unused.
2023-03-16 20:24:08 -04:00
Alex King dd184fa8b6 [Cleanup] Remove inWater from mob.h (#3069)
# Notes
- This is unused.
2023-03-16 20:23:56 -04:00
Alex King 4a3e6b5edc [Cleanup] Remove current_buff_count (#3067)
# Notes
- This was unused.
2023-03-16 20:23:41 -04:00
Alex King 7961d7afa8 [Cleanup] Utilize GetPlayerState() in mob methods (#3066)
# Notes
- This method was unused, make use of it.
2023-03-16 20:23:34 -04:00
Alex King cc6bcf3295 [Cleanup] Remove casting_spell_type from mob.h (#3064)
# Notes
- This is unused.
2023-03-16 20:23:21 -04:00
Alex King b73c2016cf [Cleanup] Remove last_max_hp from mob.h (#3063)
# Notes
- This is unused.
2023-03-16 20:23:11 -04:00
Alex King db7e8241ac [Cleanup] Remove DoBuffWearOffEffect() from mob.h (#3062)
# Notes
- This is unused.
2023-03-16 20:12:01 -04:00
Paul Coene b7747b07db [Illusions] Fix bug where spells like Ignite Bones left NPC size incorrect. (#3061) 2023-03-16 18:59:09 -04:00
Alex King 02ada0e496 [Quest API] Add SendIllusion overloads/parameters to Perl/Lua (#3059)
* [Quest API] Add SendIllusion methods to Perl.

# Perl
- Add `$mob->SendIllusion(race, gender, texture, helmtexture, face, hairstyle, haircolor, beard, beardcolor, drakkin_heritage, drakkin_tattoo, drakkin_details, size, target)`.
- Add `$mob->SendIllusionPacket(illusion_table_ref)`.

* Change defaults.

* Remove debug message

* Cleanup.

* Cleanup

* Update perl_mob.cpp
2023-03-15 20:37:37 -04:00
Alex King 7c819539c8 [Quest API] Add Spell GetActX methods to Perl/Lua (#3056)
# Perl
- Add `$mob->GetActDoTDamage(spell_id, value, target)`.
- Add `$mob->GetActDoTDamage(spell_id, value, target, from_buff_tic)`.
- Add `$mob->GetActReflectedSpellDamage(spell_id, value, effectiveness)`.
- Add `$mob->GetActSpellDamage(spell_id, value, target)`.
- Add `$mob->GetActSpellHealing(spell_id, value, target)`.
- Add `$mob->GetActSpellHealing(spell_id, value, target, from_buff_tic)`.

# Lua
- Add `mob:GetActDoTDamage(spell_id, value, target)`.
- Add `mob:GetActDoTDamage(spell_id, value, target, from_buff_tic)`.
- Add `mob:GetActReflectedSpellDamage(spell_id, value, effectiveness)`.
- Add `mob:GetActSpellCasttime(spell_id, cast_time)`.
- Add `mob:GetActSpellCost(spell_id, cost)`.
- Add `mob:GetActSpellDamage(spell_id, value)`.
- Add `mob:GetActSpellDamage(spell_id, value, target)`.
- Add `mob:GetActSpellDuration(spell_id, duration)`.
- Add `mob:GetActSpellHealing(spell_id, value)`.
- Add `mob:GetActSpellHealing(spell_id, value, target)`.
- Add `mob:GetActSpellHealing(spell_id, value, target, from_buff_tic)`.
- Add `mob:GetActSpellRange(spell_id, range)`.

 # Notes
- Allows operators to get various spell related values.
2023-03-12 15:36:43 -04:00
Alex King e670c89163 [Cleanup] Remove unused lua_hate_entry.cpp (#3057)
# Notes
- This is unused and causes duplication of these methods in Spire Quest API Explorer.
2023-03-12 15:36:20 -04:00
Aeadoin 9ecdf057db [Feature] Add Heroic Strikethrough & HP Regen Per Second to GM Entity Info (#3055)
* [Feature] Add Heroic Strikethrough to GM Entity Info

* [Feature] Add Heroic Strikethrough to GM Entity Info

* typo
2023-03-11 20:46:31 -05:00
Aeadoin b6448c840f [Bug Fix] Fix Raid Invites causing client desync issues (#3053) 2023-03-11 11:42:52 -05:00
Aeadoin 0ba90df1f1 [Bug Fix] Fix issue with overflow on min/max hit dmg in npc scaling calculations (#3052)
* [Cleanup] Cleanup npc.cpp and npc scaling

* fix issue with min/max damage overflows

* formatting
2023-03-10 09:36:59 -05:00
Alex King 12dcbd0871 [Bug Fix] Fix Heal Scale and Spell Scale in NPC Scaling (#3051)
# Notes
- These had typos and didn't work.
2023-03-09 22:32:47 -05:00
Aeadoin b0be4ca8bd [Feature] Add Avoidance and HP Regen Per Second too NPC Scaling. (#3050) 2023-03-09 11:07:03 -05:00
nytmyr 412eb5deaa [Bots] Prevent interrupt spam when OOM (#3011)
Notes:

Bots currently do not do a mana check until the spell cast has already been started which results in an interrupt immediately after. If it is the last spell for a bot to cast, it tends to result in interrupt spam until the bot has enough mana. This will block the interrupt spam if the spell is invalid.
2023-03-07 18:17:09 -05:00
Alex King f030461bc7 [Feature] Add Heroic Strikethrough to NPC Scaling (#3028)
* [Feature] Add Heroic Strikethrough to NPC Scaling

# Notes
- Adds Heroic Strikethrough support to NPC scaling.
- Cleans up `std::stoul` to use `Strings::ToUnsignedInt` since recent changes.
- Sets default values to sane values and removes support for `NULL` values.

* Update 2023_03_04_npc_scale_global_base_heroic_strikethrough.sql
2023-03-05 22:36:53 -05:00
Alex King 8f5e7978ab [Commands] Remove #equipitem Command (#3040)
* [Commands] Remove #equipitem Command

# Notes
- This command causes issues with cursor and inventory slot desynchronizations and seems to largely be unused/unnecessary.

* Remove from command files.
2023-03-05 22:36:04 -05:00
Alex King 2e55da2b2d [Fix] Checkmarks and X characters in popup messages (#3041)
# Notes
- Due to changing the popups to use strings, these show as squares, instead of the proper character.
2023-03-05 22:35:52 -05:00
Alex King 16a8f88ae5 [Commands] Cleanup #haste Command (#3042)
* [Commands] Cleanup #haste Command

# Notes
- Cleanup messages and logic.
- No longer requires you to re-equip your weapon for the haste to take effect.
- Can now use on targeted client if you have `#gm on` enabled.

* Update haste.cpp
2023-03-05 22:35:42 -05:00
Alex King 22d7ef6763 [Commands] Cleanup #hideme Command (#3043)
# Notes
- Cleanup messages and logic.
2023-03-05 22:35:30 -05:00
Alex King 457e800c73 [Commands] Cleanup #interrupt Command (#3044)
* [Commands] Cleanup #interrupt Command

# Notes
- Cleanup messages and logic.

* Update command.cpp
2023-03-05 22:35:23 -05:00
Alex King 8393e50aa8 [Commands] Cleanup #level Command (#3045)
# Notes
- Cleanup messages and logic.
- Defaults target to GM so that you don't have to target yourself to use the command.
2023-03-05 22:34:33 -05:00
Alex King b6497cdd6a [Commands] Cleanup #resetaa and #resetaa_timer (#3047)
# Notes
- Cleanup messages and logic.
2023-03-05 22:34:21 -05:00
Alex King 218ef80f96 [Commands] Cleanup #picklock Command (#3046)
* [Commands] Cleanup #picklock Command

# Notes
- Cleanup messages and logic.

* Update picklock.cpp
2023-03-05 22:34:05 -05:00
Alex King a90d41480a [Commands] Cleanup #wc Command (#3049)
# Notes
- Cleanup messages and logic.
2023-03-05 22:18:35 -05:00
933 changed files with 45152 additions and 79352 deletions
+897
View File
@@ -1,3 +1,900 @@
## [22.22.0] - 07/27/2023
### Code
* Fix casing in corpse money and decay time. ([#3511](https://github.com/EQEmu/Server/pull/3511)) @Kinglykrab 2023-07-23
### Crash Fix
* Guard against Spells:MaxTotalSlotsPET being set above client allowed maximum. ([#3507](https://github.com/EQEmu/Server/pull/3507)) @Valorith 2023-07-22
### Data Buckets
* Distributed Databucket Caching ([#3500](https://github.com/EQEmu/Server/pull/3500)) @Kinglykrab 2023-07-24
### Database
* Fix console output in database:dump --dump-output-to-console @Akkadius 2023-07-25
### Fixes
* Escape search string in #find item ([#3510](https://github.com/EQEmu/Server/pull/3510)) @Kinglykrab 2023-07-22
### Quest API
* Add GetMobTypeIdentifier() to Perl/Lua ([#3512](https://github.com/EQEmu/Server/pull/3512)) @Kinglykrab 2023-07-28
### Saylink
* Fix cases where saylinks were not being cached ([#3508](https://github.com/EQEmu/Server/pull/3508)) @Akkadius 2023-07-20
## [22.21.2] - 07/19/2023
### Databuckets
* Fix rarer same bucket name scoping overlap issue ([#3509](https://github.com/EQEmu/Server/pull/3509)) @Akkadius 2023-07-20
## [22.21.1] - 07/18/2023
### Bug
* Show Petition and Show Petition_Info fix ([#3503](https://github.com/EQEmu/Server/pull/3503)) @fryguy503 2023-07-18
### Code
* Remove arbitrary teleport blocking in Tutorial and Load zones ([#3506](https://github.com/EQEmu/Server/pull/3506)) @Valorith 2023-07-19
### Databuckets
* Fix issue with expired databuckets not being expired and returned properly ([#3504](https://github.com/EQEmu/Server/pull/3504)) @Akkadius 2023-07-18
### Fixes
* #set title_suffix Argument Position ([#3505](https://github.com/EQEmu/Server/pull/3505)) @Kinglykrab 2023-07-18
## [22.21.0] - 07/18/2023
### Data Buckets
* Implement scoped data buckets ([#3498](https://github.com/EQEmu/Server/pull/3498)) @Akkadius 2023-07-16
### Fixes
* Fix rule check and add rule for pickpocket command ([#3492](https://github.com/EQEmu/Server/pull/3492)) @tuday2 2023-07-16
### Pathing
* Improvements to roambox logic, pathing ([#3502](https://github.com/EQEmu/Server/pull/3502)) @Akkadius 2023-07-18
### Quest API
* Add SetLDoNPoints() to Perl/Lua ([#3496](https://github.com/EQEmu/Server/pull/3496)) @Kinglykrab 2023-07-16
### Z Clipping
* Don't issue zclip adjustments when NPC is not moving ([#3499](https://github.com/EQEmu/Server/pull/3499)) @Akkadius 2023-07-16
## [22.20.1] - 07/15/2023
### Database
* Fix database manifest entry for #3443 @neckkola 2023-07-15
## [22.20.0] - 07/15/2023
### Bots
* Remove orphaned commands related to botgroup ([#3489](https://github.com/EQEmu/Server/pull/3489)) @tuday2 2023-07-09
### Commands
* Consolidate #set-like commands into a singular #set command ([#3486](https://github.com/EQEmu/Server/pull/3486)) @Kinglykrab 2023-07-15
### Feature
* Add Support for item textures higher than 65,535 ([#3494](https://github.com/EQEmu/Server/pull/3494)) @Kinglykrab 2023-07-14
* Update raid features ([#3443](https://github.com/EQEmu/Server/pull/3443)) @neckkola 2023-07-13
### Fixes
* Fix Tradeskill Combines with augmented items ([#3490](https://github.com/EQEmu/Server/pull/3490)) @Kinglykrab 2023-07-15
* Fix charmed pets to follow when charmed. ([#3488](https://github.com/EQEmu/Server/pull/3488)) @noudess 2023-07-08
* Update bot naming check and add more explanation ([#3491](https://github.com/EQEmu/Server/pull/3491)) @tuday2 2023-07-13
### Quest API
* Add Mob/Entity type check methods to Perl/Lua ([#3493](https://github.com/EQEmu/Server/pull/3493)) @Kinglykrab 2023-07-13
## [22.19.0] - 07/08/2023
### Bots
* Add Pickpocket Command ([#3484](https://github.com/EQEmu/Server/pull/3484)) @tuday2 2023-07-08
### Code
* Move #find item summon links to front ([#3483](https://github.com/EQEmu/Server/pull/3483)) @Kinglykrab 2023-07-05
* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04
### Commands
* Add #itemsearch alias to #find aliases ([#3485](https://github.com/EQEmu/Server/pull/3485)) @Kinglykrab 2023-07-08
* Consolidate #show commands into a singular #show command ([#3478](https://github.com/EQEmu/Server/pull/3478)) @Kinglykrab 2023-07-08
### Fixes
* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04
### Rules
* Add Skills:TrivialTradeskillCombinesNoFail Rule ([#3481](https://github.com/EQEmu/Server/pull/3481)) @JasXSL 2023-07-05
## [22.18.0] - 07/04/2023
### Commands
* Add #emotesearch to #find command ([#3480](https://github.com/EQEmu/Server/pull/3480)) @Kinglykrab 2023-07-04
* Cleanup #copycharacter Command ([#3479](https://github.com/EQEmu/Server/pull/3479)) @Kinglykrab 2023-07-04
### Fixes
* Add chatchannel_reserved_names to a new manifest ([#3482](https://github.com/EQEmu/Server/pull/3482)) @Kinglykrab 2023-07-04
* Fix issue in zone store of returning reference to local variable ([#3477](https://github.com/EQEmu/Server/pull/3477)) @Kinglykrab 2023-07-04
## [22.17.0] - 07/03/2023
### Cleanup/Feature
* Add support for bots to #showstats/#mystats ([#3427](https://github.com/EQEmu/Server/pull/3427)) @Kinglykrab 2023-07-01
### Code
* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04
* Remove handle_npc_single_npc from zone/lua_parser_events.cpp and zone/lua_parser_events.h ([#3467](https://github.com/EQEmu/Server/pull/3467)) @Kinglykrab 2023-07-03
### Database
* Set multi statements off when returning early ([#3462](https://github.com/EQEmu/Server/pull/3462)) @Akkadius 2023-07-01
### Feature
* Add Strings::BeginsWith() and Strings::EndsWith() ([#3471](https://github.com/EQEmu/Server/pull/3471)) @Kinglykrab 2023-07-03
### Fixes
* Add check for underscores in botcreate command ([#3458](https://github.com/EQEmu/Server/pull/3458)) @tuday2 2023-06-29
* EVENT_LANGUAGE_SKILL_UP in Lua was using EVENT_SKILL_UP logic ([#3466](https://github.com/EQEmu/Server/pull/3466)) @Kinglykrab 2023-07-03
* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04
* Fix data type of GetAggroCount() ([#3470](https://github.com/EQEmu/Server/pull/3470)) @Kinglykrab 2023-07-03
### Logging
* Fix logging crash when % are sent through query logs ([#3461](https://github.com/EQEmu/Server/pull/3461)) @Akkadius 2023-07-01
### Quest API
* Add ClearAccountFlag() and GetAccountFlags() to Perl/Lua ([#3469](https://github.com/EQEmu/Server/pull/3469)) @Kinglykrab 2023-07-03
* Add GetClassAbbreviation() and GetRaceAbbreviation() to Perl/Lua ([#3463](https://github.com/EQEmu/Server/pull/3463)) @Kinglykrab 2023-07-02
* Add GetClassPlural() and GetRacePlural() to Perl/Lua ([#3468](https://github.com/EQEmu/Server/pull/3468)) @Kinglykrab 2023-07-03
* Add GetCloseMobList() and CalculateDistance() overload to Perl/Lua ([#3455](https://github.com/EQEmu/Server/pull/3455)) @Kinglykrab 2023-07-02
* Add Hate Entry Methods to Perl ([#3459](https://github.com/EQEmu/Server/pull/3459)) @Kinglykrab 2023-07-02
* Add ItemData Class to Perl ([#3465](https://github.com/EQEmu/Server/pull/3465)) @Kinglykrab 2023-07-02
* Add Spawn2 Class to Perl ([#3456](https://github.com/EQEmu/Server/pull/3456)) @Kinglykrab 2023-07-02
* Add StatBonuses Class to Perl ([#3460](https://github.com/EQEmu/Server/pull/3460)) @Kinglykrab 2023-07-02
* Add missing Item Methods to Perl/Lua. ([#3464](https://github.com/EQEmu/Server/pull/3464)) @Kinglykrab 2023-07-02
## [22.16.0] - 06/27/2023
### Code
* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19
* Delete common/worldconn.cpp ([#3436](https://github.com/EQEmu/Server/pull/3436)) @Kinglykrab 2023-06-24
* Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h ([#3449](https://github.com/EQEmu/Server/pull/3449)) @Kinglykrab 2023-06-24
* Remove GetACAvoid() from zone/merc.h ([#3447](https://github.com/EQEmu/Server/pull/3447)) @Kinglykrab 2023-06-25
* Remove GetACMit() from zone/merc.h ([#3446](https://github.com/EQEmu/Server/pull/3446)) @Kinglykrab 2023-06-24
* Remove _ClearWaypints() from zone/npc.h ([#3445](https://github.com/EQEmu/Server/pull/3445)) @Kinglykrab 2023-06-24
* Remove acmod() from zone/merc.h ([#3448](https://github.com/EQEmu/Server/pull/3448)) @Kinglykrab 2023-06-24
* Remove command_packetprofile from zone/command.h ([#3432](https://github.com/EQEmu/Server/pull/3432)) @Kinglykrab 2023-06-24
* Remove command_showpetspell in zone/command.h ([#3430](https://github.com/EQEmu/Server/pull/3430)) @Kinglykrab 2023-06-24
* Remove command_unlock from zone/command.h ([#3431](https://github.com/EQEmu/Server/pull/3431)) @Kinglykrab 2023-06-24
### Commands
* Add #finddeity Command ([#3435](https://github.com/EQEmu/Server/pull/3435)) @Kinglykrab 2023-06-26
* Add #findlanguage Command ([#3434](https://github.com/EQEmu/Server/pull/3434)) @Kinglykrab 2023-06-25
* Add #showspells Command ([#3429](https://github.com/EQEmu/Server/pull/3429)) @Kinglykrab 2023-06-24
* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19
* Cleanup #showbuffs Command ([#3439](https://github.com/EQEmu/Server/pull/3439)) @Kinglykrab 2023-06-26
* Cleanup #shownpcgloballoot and #showzonegloballoot Commands ([#3440](https://github.com/EQEmu/Server/pull/3440)) @Kinglykrab 2023-06-24
* Cleanup #viewcurrencies Command ([#3441](https://github.com/EQEmu/Server/pull/3441)) @Kinglykrab 2023-06-25
* Consolidate #findX commands to a singular #find Command ([#3452](https://github.com/EQEmu/Server/pull/3452)) @Kinglykrab 2023-06-28
* Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop ([#3433](https://github.com/EQEmu/Server/pull/3433)) @Kinglykrab 2023-06-24
* Delete #showbonusstats Command ([#3437](https://github.com/EQEmu/Server/pull/3437)) @Kinglykrab 2023-06-24
* Delete #spellinfo Command ([#3438](https://github.com/EQEmu/Server/pull/3438)) @Kinglykrab 2023-06-24
### Database
* Fix database version checking edge case issue ([#3428](https://github.com/EQEmu/Server/pull/3428)) @Akkadius 2023-06-22
* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19
* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19
### Fixes
* Fix NPC Item Stat Bonuses ([#3444](https://github.com/EQEmu/Server/pull/3444)) @Kinglykrab 2023-06-26
* Fix error in 023_01_21_bots_raid_members.sql ([#3453](https://github.com/EQEmu/Server/pull/3453)) @mibastian 2023-06-28
* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19
* Merchant Open Flag set only for regular Merchants ([#3454](https://github.com/EQEmu/Server/pull/3454)) @Kinglykrab 2023-06-27
### Readme
* Update new location of database updates ([#3424](https://github.com/EQEmu/Server/pull/3424)) @joligario 2023-06-19
### Rules
* Add ClientPetsUserOwnerNameInLastName rule ([#3442](https://github.com/EQEmu/Server/pull/3442)) @Kinglykrab 2023-06-25
## [22.15.3] - 06/19/2023
### Fixes
* Fix improper condition in Water LOS checks ([#3426](https://github.com/EQEmu/Server/pull/3426)) @Kinglykrab 2023-06-19
## [22.15.2] - 06/19/2023
### Database
* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19
## [22.15.1] - 06/19/2023
### Schema
* Add `chatchannel_reserved_names` table to `database_schema.h`
## [22.15.0] - 06/19/2023
### Code
* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19
### Commands
* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19
### Database
* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19
### Fixes
* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19
## [22.14.1] - 06/18/2023
### Backups
* Move world database:dump to use MySQL credentials file ([#3410](https://github.com/EQEmu/Server/pull/3410)) @Akkadius 2023-06-17
### Binaries
* Add support for static linking (portable) binaries ([#3417](https://github.com/EQEmu/Server/pull/3417)) @Akkadius 2023-06-18
### CI
* Build static linux binaries ([#3419](https://github.com/EQEmu/Server/pull/3419)) @Akkadius 2023-06-18
### CLI
* Add `bots:enable` and `bots:disable` commands ([#3415](https://github.com/EQEmu/Server/pull/3415)) @Akkadius 2023-06-17
* Add `mercs:enable` and `mercs:disable` commands ([#3416](https://github.com/EQEmu/Server/pull/3416)) @Akkadius 2023-06-18
* Console menu validation fixes ([#3413](https://github.com/EQEmu/Server/pull/3413)) @Akkadius 2023-06-17
### Database
* Add query multi statement execution support ([#3414](https://github.com/EQEmu/Server/pull/3414)) @Akkadius 2023-06-17
### Feature
* Add Water Line of Sight Checks ([#3408](https://github.com/EQEmu/Server/pull/3408)) @nytmyr 2023-06-17
### Logging
* Logging improvements, console silencing, terminal coloring ([#3412](https://github.com/EQEmu/Server/pull/3412)) @Akkadius 2023-06-17
### Quest API
* Add convert_money_to_string() to Perl/Lua ([#3418](https://github.com/EQEmu/Server/pull/3418)) @Kinglykrab 2023-06-18
### Strings
* Add more test cases for string utils ([#3411](https://github.com/EQEmu/Server/pull/3411)) @Akkadius 2023-06-17
### Targeting
* Fix bug when using /tar on invalid target ([#3407](https://github.com/EQEmu/Server/pull/3407)) @noudess 2023-06-17
### Telnet
* Add cross zone/world wide cast and move functionality to Telnet ([#3409](https://github.com/EQEmu/Server/pull/3409)) @Kinglykrab 2023-06-17
## [22.13.1] - 06/13/2023
### Targeting
* Revert #3383 ([#3405](https://github.com/EQEmu/Server/pull/3405)) @noudess 2023-06-13
## [22.13.0] - 06/12/2023
### Code
* Add GMFind_Struct to packet structures ([#3402](https://github.com/EQEmu/Server/pull/3402)) @Kinglykrab 2023-06-12
* Remove CHECK_LOS_STEP from zone/common.h ([#3398](https://github.com/EQEmu/Server/pull/3398)) @Kinglykrab 2023-06-12
* Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h ([#3384](https://github.com/EQEmu/Server/pull/3384)) @Kinglykrab 2023-06-12
* Remove CountTempPets() from zone/entity.cpp and zone/entity.h ([#3390](https://github.com/EQEmu/Server/pull/3390)) @Kinglykrab 2023-06-12
* Remove Evade() from zone/entity.cpp and zone/entity.h ([#3394](https://github.com/EQEmu/Server/pull/3394)) @Kinglykrab 2023-06-12
* Remove GateAllClients() from zone/entity.cpp and zone/entity.h ([#3391](https://github.com/EQEmu/Server/pull/3391)) @Kinglykrab 2023-06-12
* Remove GetClient(ip, port) from zone/entity.h ([#3386](https://github.com/EQEmu/Server/pull/3386)) @Kinglykrab 2023-06-12
* Remove GetClientCount() from zone/entity.cpp and zone/entity.h ([#3392](https://github.com/EQEmu/Server/pull/3392)) @Kinglykrab 2023-06-12
* Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h ([#3387](https://github.com/EQEmu/Server/pull/3387)) @Kinglykrab 2023-06-12
* Remove InteractiveChat() and TakenAction() from zone/npc.h ([#3382](https://github.com/EQEmu/Server/pull/3382)) @Kinglykrab 2023-06-12
* Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h ([#3393](https://github.com/EQEmu/Server/pull/3393)) @Kinglykrab 2023-06-12
* Remove NPC::AddCash() from npc.cpp/npc.h ([#3380](https://github.com/EQEmu/Server/pull/3380)) @Kinglykrab 2023-06-09
* Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h ([#3389](https://github.com/EQEmu/Server/pull/3389)) @Kinglykrab 2023-06-12
* Remove SPECIALIZE_MANA_REDUCE from zone/common.h ([#3400](https://github.com/EQEmu/Server/pull/3400)) @Kinglykrab 2023-06-12
* Remove SendAATimer() from zone/entity.h ([#3388](https://github.com/EQEmu/Server/pull/3388)) @Kinglykrab 2023-06-12
* Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h ([#3395](https://github.com/EQEmu/Server/pull/3395)) @Kinglykrab 2023-06-12
* Remove _BECOMENPCPET() and _NPCPET() from zone/common.h ([#3399](https://github.com/EQEmu/Server/pull/3399)) @Kinglykrab 2023-06-12
* Remove pDBAsyncWorkID from zone/entity.h ([#3385](https://github.com/EQEmu/Server/pull/3385)) @Kinglykrab 2023-06-12
* Remove struct DynamicZoneSafeReturn from zone/entity.h ([#3396](https://github.com/EQEmu/Server/pull/3396)) @Kinglykrab 2023-06-12
* Remove struct TradeEntity from zone/common.h ([#3397](https://github.com/EQEmu/Server/pull/3397)) @Kinglykrab 2023-06-12
### Commands
* Assign #opcode to a #reload alias ([#3401](https://github.com/EQEmu/Server/pull/3401)) @Kinglykrab 2023-06-12
### Illusions
* RandomizeFeatures and SetGender were killing db texture ([#3376](https://github.com/EQEmu/Server/pull/3376)) @noudess 2023-06-06
### Logging
* Fixed statements that logged incorrect data ([#3381](https://github.com/EQEmu/Server/pull/3381)) @noudess 2023-06-07
### Quest API
* Add GetEXPForLevel() to Perl/Lua ([#3403](https://github.com/EQEmu/Server/pull/3403)) @Kinglykrab 2023-06-12
* Add SendChannelMessage() to Perl/Lua ([#3378](https://github.com/EQEmu/Server/pull/3378)) @Kinglykrab 2023-06-04
* Add several spell methods to Perl/Lua ([#3379](https://github.com/EQEmu/Server/pull/3379)) @Kinglykrab 2023-06-12
### Targeting
* /tar <bad target> should not untarget existing target ([#3383](https://github.com/EQEmu/Server/pull/3383)) @noudess 2023-06-12
## [22.12.0] - 05/29/2023
### Code
* Cleanup #setskill and #setskillall Commands ([#3367](https://github.com/EQEmu/Server/pull/3367)) @Kinglykrab 2023-05-25
* Delete message.h ([#3348](https://github.com/EQEmu/Server/pull/3348)) @Kinglykrab 2023-05-17
* Fix #spawn command NPCs having 0 health ([#3371](https://github.com/EQEmu/Server/pull/3371)) @Kinglykrab 2023-05-21
* Remove CalcPetHp from spdat.h ([#3364](https://github.com/EQEmu/Server/pull/3364)) @Kinglykrab 2023-05-25
* Remove CountNPC() and QueueManaged() from entity.cpp/entity.h ([#3346](https://github.com/EQEmu/Server/pull/3346)) @Kinglykrab 2023-05-17
* Remove DumpMerchantList() from zone.cpp/zone.h ([#3343](https://github.com/EQEmu/Server/pull/3343)) @Kinglykrab 2023-05-17
* Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h ([#3358](https://github.com/EQEmu/Server/pull/3358)) @Kinglykrab 2023-05-17
* Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h ([#3353](https://github.com/EQEmu/Server/pull/3353)) @Kinglykrab 2023-05-17
* Remove GetMaxRank() from aa_ability.cpp/aa_ability.h ([#3347](https://github.com/EQEmu/Server/pull/3347)) @Kinglykrab 2023-05-25
* Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h ([#3352](https://github.com/EQEmu/Server/pull/3352)) @Kinglykrab 2023-05-17
* Remove IsRaid() from raids.h ([#3361](https://github.com/EQEmu/Server/pull/3361)) @Kinglykrab 2023-05-25
* Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h ([#3344](https://github.com/EQEmu/Server/pull/3344)) @Kinglykrab 2023-05-25
* Remove SetGraveyard() from zone.cpp/zone.h ([#3354](https://github.com/EQEmu/Server/pull/3354)) @Kinglykrab 2023-05-17
* Remove SetTradeCash() from trading.cpp/common.h ([#3356](https://github.com/EQEmu/Server/pull/3356)) @Kinglykrab 2023-05-17
* Remove TraderUpdate() from trading.cpp/client.h ([#3357](https://github.com/EQEmu/Server/pull/3357)) @Kinglykrab 2023-05-17
* Remove TypeToSkill() from tradeskills.cpp/object.h ([#3355](https://github.com/EQEmu/Server/pull/3355)) @Kinglykrab 2023-05-17
* Remove Z_AGGRO from spdat.h ([#3365](https://github.com/EQEmu/Server/pull/3365)) @Kinglykrab 2023-05-25
* Remove numMembers from raids.h ([#3362](https://github.com/EQEmu/Server/pull/3362)) @Kinglykrab 2023-05-25
* Set GetAugmentType() to int again ([#3335](https://github.com/EQEmu/Server/pull/3335)) @Kinglykrab 2023-05-08
### Commands
* Add #findcurrency Command ([#3368](https://github.com/EQEmu/Server/pull/3368)) @Kinglykrab 2023-05-25
* Add entity variable command ([#3345](https://github.com/EQEmu/Server/pull/3345)) @Kinglykrab 2023-05-25
* Cleanup #setanim ([#3350](https://github.com/EQEmu/Server/pull/3350)) @Kinglykrab 2023-05-25
### Feature
* Intoxication setter/getter for source, getter for Perl/Lua ([#3330](https://github.com/EQEmu/Server/pull/3330)) @JasXSL 2023-05-03
### Fixes
* #augmentitem bypasses augment restrictions ([#3332](https://github.com/EQEmu/Server/pull/3332)) @Kinglykrab 2023-05-07
* Fix Heroic INT/WIS Bonuses ([#3341](https://github.com/EQEmu/Server/pull/3341)) @RekkasGit 2023-05-15
* Fix duplicate messages in #npcedit ([#3372](https://github.com/EQEmu/Server/pull/3372)) @Kinglykrab 2023-05-21
* Fix issue with Group Pointers/Member roles ([#3374](https://github.com/EQEmu/Server/pull/3374)) @Aeadoin 2023-05-25
* Fix mob item bonus calc ([#3334](https://github.com/EQEmu/Server/pull/3334)) @Akkadius 2023-05-07
* Fix typos in #zheader ([#3370](https://github.com/EQEmu/Server/pull/3370)) @Kinglykrab 2023-05-21
* Mob scaling issue with min dmg set to zero while max dmg is not ([#3351](https://github.com/EQEmu/Server/pull/3351)) @RekkasGit 2023-05-20
* NPC Armor Upgrade to a slot not handled correctly ([#3366](https://github.com/EQEmu/Server/pull/3366)) @noudess 2023-05-20
* ReloadQuests() on Zone::Init() to avoid cached global quests/plugins ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Kinglykrab 2023-05-07
* Revert " ReloadQuests() on Zone::Init() to avoid cached global quests/plugins " ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Akkadius 2023-05-08
### Memory Leak
* Fix large memory leak introduced in CalcItemBonuses ([#3331](https://github.com/EQEmu/Server/pull/3331)) @Akkadius 2023-05-07
### Messages
* Remove duplicate heal message for healing yourself ([#3329](https://github.com/EQEmu/Server/pull/3329)) @noudess 2023-05-03
### Performance
* Character bind is now bulk saved ([#3338](https://github.com/EQEmu/Server/pull/3338)) @Akkadius 2023-05-09
* Character buffs now save in bulk ([#3336](https://github.com/EQEmu/Server/pull/3336)) @Akkadius 2023-05-09
* Character pet bulk saving ([#3337](https://github.com/EQEmu/Server/pull/3337)) @Akkadius 2023-05-09
* Character tribute is now bulk saved ([#3340](https://github.com/EQEmu/Server/pull/3340)) @Kinglykrab 2023-05-25
* Mail key is now cached during player load ([#3339](https://github.com/EQEmu/Server/pull/3339)) @Akkadius 2023-05-09
### Pets
* Fix saving inconsistencies with pets ([#3375](https://github.com/EQEmu/Server/pull/3375)) @Akkadius 2023-05-25
### Quest API
* Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua ([#3359](https://github.com/EQEmu/Server/pull/3359)) @RekkasGit 2023-05-16
* Add GetPet() to Perl ([#3309](https://github.com/EQEmu/Server/pull/3309)) @Kinglykrab 2023-05-08
* Add Memorize and Scribe Spell Events to Perl/Lua ([#3363](https://github.com/EQEmu/Server/pull/3363)) @Kinglykrab 2023-05-25
* Add zone data methods to Perl/Lua ([#3342](https://github.com/EQEmu/Server/pull/3342)) @Kinglykrab 2023-05-24
* Cleanup The Darkened Sea Quest Methods Names ([#3369](https://github.com/EQEmu/Server/pull/3369)) @Kinglykrab 2023-05-21
### Rules
* Add World:MaximumQuestErrors Rule ([#3349](https://github.com/EQEmu/Server/pull/3349)) @Kinglykrab 2023-05-21
* ResurrectionEffectBlock to prevent/allow/move buffs. ([#3288](https://github.com/EQEmu/Server/pull/3288)) @nytmyr 2023-05-08
## [22.11.0] - 04/29/2023
### Code
* Add check for owner in quest::pausetimer() ([#3304](https://github.com/EQEmu/Server/pull/3304)) @Kinglykrab 2023-04-23
* Add check for owner in quest::resumetimer() ([#3305](https://github.com/EQEmu/Server/pull/3305)) @Kinglykrab 2023-04-23
* Add initiator/owner checks to various methods in questmgr.cpp ([#3306](https://github.com/EQEmu/Server/pull/3306)) @Kinglykrab 2023-04-23
* Fix possible nullptr in quest::addloot() ([#3303](https://github.com/EQEmu/Server/pull/3303)) @Kinglykrab 2023-04-23
* Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h ([#3313](https://github.com/EQEmu/Server/pull/3313)) @Kinglykrab 2023-04-30
* Remove GetClassHPFactor() from zone/merc.h ([#3314](https://github.com/EQEmu/Server/pull/3314)) @Kinglykrab 2023-04-30
* Remove pDontCastBefore_casting_spell from zone/npc.h ([#3311](https://github.com/EQEmu/Server/pull/3311)) @Kinglykrab 2023-04-30
* Remove unused code in zone/pets.cpp ([#3310](https://github.com/EQEmu/Server/pull/3310)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/bot.cpp and zone/bot.h ([#3315](https://github.com/EQEmu/Server/pull/3315)) @Kinglykrab 2023-04-30
* Remove unused methods in zone/client.cpp and zone/client.h ([#3312](https://github.com/EQEmu/Server/pull/3312)) @Kinglykrab 2023-04-30
* Remove unused variable in common/crash.cpp ([#3308](https://github.com/EQEmu/Server/pull/3308)) @Kinglykrab 2023-04-30
* Use default ctor/dtor in oriented_bounding_box.h ([#3307](https://github.com/EQEmu/Server/pull/3307)) @Kinglykrab 2023-04-30
* quest::createBot() unnecessary check against nullptr ([#3302](https://github.com/EQEmu/Server/pull/3302)) @Kinglykrab 2023-04-23
* quest::setallskill() had always true condition. ([#3301](https://github.com/EQEmu/Server/pull/3301)) @Kinglykrab 2023-04-30
### Crash
* Fix UCS crash that occurs during log reloading ([#3324](https://github.com/EQEmu/Server/pull/3324)) @Akkadius 2023-04-30
* Fix possible dereference of nullptr in Client::CalcHPRegen ([#3316](https://github.com/EQEmu/Server/pull/3316)) @Aeadoin 2023-04-23
* Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() ([#3317](https://github.com/EQEmu/Server/pull/3317)) @Kinglykrab 2023-04-23
### Discord
* Add Discord webhook callback processing to world ([#3322](https://github.com/EQEmu/Server/pull/3322)) @Akkadius 2023-04-30
### Fixes
* Fix issue with NPCs no longer using some armor. ([#3318](https://github.com/EQEmu/Server/pull/3318)) @noudess 2023-04-24
* Fix issue with spawning Mercs ([#3327](https://github.com/EQEmu/Server/pull/3327)) @Aeadoin 2023-04-29
* Possible issues with SummonItem in Client::QuestReward() methods ([#3325](https://github.com/EQEmu/Server/pull/3325)) @Kinglykrab 2023-04-27
### Maps
* Update download with faster releases link ([#3321](https://github.com/EQEmu/Server/pull/3321)) @Akkadius 2023-04-30
### Messages
* Remove duplicate you have lost a level message ([#3323](https://github.com/EQEmu/Server/pull/3323)) @noudess 2023-04-25
### Quest API
* Add GetDefaultRaceSize() overloads to Perl/Lua ([#3320](https://github.com/EQEmu/Server/pull/3320)) @Kinglykrab 2023-04-30
* Add HasSpellEffect() to Perl/Lua ([#3319](https://github.com/EQEmu/Server/pull/3319)) @Kinglykrab 2023-04-30
## [22.10.0] - 04/22/2023
### Backups
* Fix database dump error reporting ([#3175](https://github.com/EQEmu/Server/pull/3175)) @Akkadius 2023-04-04
### Bots
* Cleanup GetBotTables() ([#3270](https://github.com/EQEmu/Server/pull/3270)) @Aeadoin 2023-04-06
### Cleanuo
* Only define row if we have results in Database::GetCharacterID() ([#3199](https://github.com/EQEmu/Server/pull/3199)) @Kinglykrab 2023-04-05
### Code
* Add missing breaks and returns in bonuses.cpp ([#3231](https://github.com/EQEmu/Server/pull/3231)) @Kinglykrab 2023-04-05
* Breaks in wrong spot in cases in spell_effects.cpp ([#3297](https://github.com/EQEmu/Server/pull/3297)) @Kinglykrab 2023-04-22
* Cleanup always true/false statements in shareddb.cpp ([#3189](https://github.com/EQEmu/Server/pull/3189)) @Kinglykrab 2023-04-05
* Cleanup cheap-to-copy reference to use value instead in eq_stream_ident.cpp/eq_stream_ident.h ([#3209](https://github.com/EQEmu/Server/pull/3209)) @Kinglykrab 2023-04-05
* Cleanup discord.cpp and discord_manager.cpp ([#3205](https://github.com/EQEmu/Server/pull/3205)) @Kinglykrab 2023-04-05
* Cleanup duplicate conditions in negate bonuses in bonuses.cpp ([#3226](https://github.com/EQEmu/Server/pull/3226)) @Kinglykrab 2023-04-05
* Cleanup item_instance.cpp always true statements and reassigning of same values ([#3187](https://github.com/EQEmu/Server/pull/3187)) @Kinglykrab 2023-04-05
* Cleanup macros in features.h ([#3185](https://github.com/EQEmu/Server/pull/3185)) @Kinglykrab 2023-04-05
* Cleanup string -> char* -> string conversions in bot_command.cpp ([#3252](https://github.com/EQEmu/Server/pull/3252)) @Kinglykrab 2023-04-05
* Cleanup unnecessary condition in Client::SendAlternateCurrencyValue() ([#3266](https://github.com/EQEmu/Server/pull/3266)) @Kinglykrab 2023-04-05
* Cleanup zone/zoning.cpp ([#3289](https://github.com/EQEmu/Server/pull/3289)) @Kinglykrab 2023-04-14
* Combine similar cases in Client::InitInnates() ([#3260](https://github.com/EQEmu/Server/pull/3260)) @Kinglykrab 2023-04-05
* Convert equipable_slot_list to std::vector from std::list in bot_command.cpp ([#3253](https://github.com/EQEmu/Server/pull/3253)) @Kinglykrab 2023-04-05
* Delete embxs.cpp/embxs.h ([#3284](https://github.com/EQEmu/Server/pull/3284)) @Kinglykrab 2023-04-14
* Delete unused strings in bot_command.cpp ([#3251](https://github.com/EQEmu/Server/pull/3251)) @Kinglykrab 2023-04-05
* Fix GetLastName() length check in Client::SendWindow() ([#3263](https://github.com/EQEmu/Server/pull/3263)) @Kinglykrab 2023-04-05
* Fix always false conditions in Client::IncStats() ([#3256](https://github.com/EQEmu/Server/pull/3256)) @Kinglykrab 2023-04-05
* Fix check for !this in Client::SendHPUpdateMarquee() ([#3257](https://github.com/EQEmu/Server/pull/3257)) @Kinglykrab 2023-04-05
* Fix filter condition in attack.cpp ([#3218](https://github.com/EQEmu/Server/pull/3218)) @Kinglykrab 2023-04-05
* Fix ornamentation augment icons in inspect requests ([#3264](https://github.com/EQEmu/Server/pull/3264)) @Kinglykrab 2023-04-05
* Fix possible nullptr inst in GetSharedBank() ([#3190](https://github.com/EQEmu/Server/pull/3190)) @Kinglykrab 2023-04-08
* Fix possible overflows in Client::AddPlatinum() and Client::TakePlatinum() ([#3255](https://github.com/EQEmu/Server/pull/3255)) @Kinglykrab 2023-04-05
* Fix shared_tasks.cpp/shared_tasks.cpp variable named same as class member ([#3192](https://github.com/EQEmu/Server/pull/3192)) @Kinglykrab 2023-04-05
* Fix skill_used being used as boolean in Mob::CommonDamage() ([#3220](https://github.com/EQEmu/Server/pull/3220)) @Kinglykrab 2023-04-05
* Identical conditions right beside each other in aa.cpp ([#3213](https://github.com/EQEmu/Server/pull/3213)) @Kinglykrab 2023-04-05
* Move unreachable code in ApplySpellsBonuses() ([#3229](https://github.com/EQEmu/Server/pull/3229)) @Kinglykrab 2023-04-05
* Move variable definition to more relevant scope in DatabaseDumpService::Dump() ([#3200](https://github.com/EQEmu/Server/pull/3200)) @Kinglykrab 2023-04-05
* Multiple cases with same outcome in GetDiscordPayloadFromEvent() ([#3184](https://github.com/EQEmu/Server/pull/3184)) @Kinglykrab 2023-04-05
* Remove ExportVarComplex() from embparser.cpp/embparser.h ([#3282](https://github.com/EQEmu/Server/pull/3282)) @Kinglykrab 2023-04-14
* Remove GetQGlobal() from qglobals.cpp/qglobals.h ([#3285](https://github.com/EQEmu/Server/pull/3285)) @Kinglykrab 2023-04-14
* Remove IsFullHP from mob.cpp/mob.h ([#3277](https://github.com/EQEmu/Server/pull/3277)) @Kinglykrab 2023-04-14
* Remove IsMeleeDmg() from skills.cpp/skills.h ([#3279](https://github.com/EQEmu/Server/pull/3279)) @Kinglykrab 2023-04-14
* Remove _GetMovementSpeed() from mob.h ([#3276](https://github.com/EQEmu/Server/pull/3276)) @Kinglykrab 2023-04-14
* Remove always true condition in Strings::Commify() ([#3193](https://github.com/EQEmu/Server/pull/3193)) @Kinglykrab 2023-04-05
* Remove always true conditions and unreachable code in Client::SendMercPersonalInfo() ([#3258](https://github.com/EQEmu/Server/pull/3258)) @Kinglykrab 2023-04-05
* Remove always true statement in say_link.cpp ([#3188](https://github.com/EQEmu/Server/pull/3188)) @Kinglykrab 2023-04-05
* Remove always true statements in task_client_state.cpp ([#3292](https://github.com/EQEmu/Server/pull/3292)) @Kinglykrab 2023-04-14
* Remove always true/false conditions from bot.cpp ([#3237](https://github.com/EQEmu/Server/pull/3237)) @Kinglykrab 2023-04-05
* Remove bool return from GetSharedPlatinum() ([#3191](https://github.com/EQEmu/Server/pull/3191)) @Kinglykrab 2023-04-05
* Remove extra assignment of current_endurance in Client ctor ([#3261](https://github.com/EQEmu/Server/pull/3261)) @Kinglykrab 2023-04-05
* Remove extraneous check for NegateAttacks in SE_NegateAttacks ([#3228](https://github.com/EQEmu/Server/pull/3228)) @Kinglykrab 2023-04-05
* Remove extraneous parentheses around math in Mob::ApplySpellsBonuses() ([#3227](https://github.com/EQEmu/Server/pull/3227)) @Kinglykrab 2023-04-05
* Remove getd(), geti(), InUse(), lasterr(), my_get_sv(), and VarExists() in embperl.cpp/embperl.h ([#3283](https://github.com/EQEmu/Server/pull/3283)) @Kinglykrab 2023-04-15
* Remove item_timers from questmgr.cpp/questmgr.h ([#3286](https://github.com/EQEmu/Server/pull/3286)) @Kinglykrab 2023-04-14
* Remove pendinggroup from mob.h ([#3278](https://github.com/EQEmu/Server/pull/3278)) @Kinglykrab 2023-04-14
* Remove position_same_update_count from client.cpp/client.h ([#3280](https://github.com/EQEmu/Server/pull/3280)) @Kinglykrab 2023-04-14
* Remove unnecessary break in while loop in Mob::AddToHateList() ([#3219](https://github.com/EQEmu/Server/pull/3219)) @Kinglykrab 2023-04-05
* Remove unnecessary check for IsStackable() in DeleteItem() ([#3186](https://github.com/EQEmu/Server/pull/3186)) @Kinglykrab 2023-04-05
* Remove unnecessary condition and cleanup variable name in tasks.cpp ([#3293](https://github.com/EQEmu/Server/pull/3293)) @Kinglykrab 2023-04-14
* Remove unnecessary conditions in Client::Consume() ([#3265](https://github.com/EQEmu/Server/pull/3265)) @Kinglykrab 2023-04-05
* Remove unnecessary conditions in Client::FilteredMessageCheck() ([#3262](https://github.com/EQEmu/Server/pull/3262)) @Kinglykrab 2023-04-05
* Remove unnecessary conditions in Client::SendFactionMessage() ([#3267](https://github.com/EQEmu/Server/pull/3267)) @Kinglykrab 2023-04-05
* Remove unnecessary setting of reuse variable in Bot::DoClassAttacks() ([#3233](https://github.com/EQEmu/Server/pull/3233)) @Kinglykrab 2023-04-05
* Remove unused SetConfigFile in common/eqemu_config.h ([#3208](https://github.com/EQEmu/Server/pull/3208)) @Kinglykrab 2023-04-05
* Remove unused code in eq_packet.cpp/eq_packet.h ([#3183](https://github.com/EQEmu/Server/pull/3183)) @Kinglykrab 2023-04-05
* Remove unused ctor and use default dtor in xtargetautohaters.h ([#3290](https://github.com/EQEmu/Server/pull/3290)) @Kinglykrab 2023-04-14
* Remove unused macros in common/types.h ([#3194](https://github.com/EQEmu/Server/pull/3194)) @Kinglykrab 2023-04-05
* Remove unused variable in Database::CopyCharacter() ([#3197](https://github.com/EQEmu/Server/pull/3197)) @Kinglykrab 2023-04-05
* Remove unused variables and use reference in task_manager.cpp ([#3291](https://github.com/EQEmu/Server/pull/3291)) @Kinglykrab 2023-04-14
* SE_AttackSpeed3 effect_value is always less than 0 ([#3222](https://github.com/EQEmu/Server/pull/3222)) @Kinglykrab 2023-04-05
* SE_StrikeThrough and SE_StrikeThrough2 are the same in bonuses.cpp ([#3223](https://github.com/EQEmu/Server/pull/3223)) @Kinglykrab 2023-04-05
* Set bonuses to use spell ID instead of boolean ([#3230](https://github.com/EQEmu/Server/pull/3230)) @Kinglykrab 2023-04-05
* Use .clear() and .empty() instead of comparing to empty string or setting to empty string in CheckDatabaseConvertPPBlob() ([#3201](https://github.com/EQEmu/Server/pull/3201)) @Kinglykrab 2023-04-05
* Use .clear() instead of setting string to empty in eqemu_command_handler.cpp ([#3195](https://github.com/EQEmu/Server/pull/3195)) @Kinglykrab 2023-04-05
* Use .empty() in Client::ScribeSpells() and Client::LearnDisciplines() ([#3259](https://github.com/EQEmu/Server/pull/3259)) @Kinglykrab 2023-04-05
* Use constant reference and check for empty string properly in dbcore.cpp ([#3203](https://github.com/EQEmu/Server/pull/3203)) @Kinglykrab 2023-04-05
* Use default ctor instead of an empty ctor. ([#3206](https://github.com/EQEmu/Server/pull/3206)) @Kinglykrab 2023-04-05
* Use default dtor instead of empty dtor for EQTime in eqtime.cpp/eqtime.h ([#3210](https://github.com/EQEmu/Server/pull/3210)) @Kinglykrab 2023-04-05
* Use variable for c->GetTarget() instead of calling multiple times in bot_command.cpp ([#3254](https://github.com/EQEmu/Server/pull/3254)) @Kinglykrab 2023-04-05
* Use variable for character instead of a loop ([#3268](https://github.com/EQEmu/Server/pull/3268)) @Kinglykrab 2023-04-05
* Utilize .empty() instead of checking for an empty string in Database::ReserveName() ([#3198](https://github.com/EQEmu/Server/pull/3198)) @Kinglykrab 2023-04-05
* Utilize IsTaunting(), SetPetPower(), SetPetType(), and SetTaunting() ([#3275](https://github.com/EQEmu/Server/pull/3275)) @Kinglykrab 2023-04-15
* Validate for nullptrs in bot.cpp ([#3232](https://github.com/EQEmu/Server/pull/3232)) @Kinglykrab 2023-04-05
* other is always defined in these cases in attack.cpp ([#3217](https://github.com/EQEmu/Server/pull/3217)) @Kinglykrab 2023-04-05
* results variable is assigned but never used in SaveCharacterCreate() ([#3180](https://github.com/EQEmu/Server/pull/3180)) @Kinglykrab 2023-04-05
### Crash
* Add additional raid integrity checks on Bot Spawn. ([#3295](https://github.com/EQEmu/Server/pull/3295)) @Aeadoin 2023-04-16
* Fix crash with uninitialized item instance, and Bot timeout ([#3296](https://github.com/EQEmu/Server/pull/3296)) @Aeadoin 2023-04-15
* Resolve crash due to uninitialized pointer. ([#3271](https://github.com/EQEmu/Server/pull/3271)) @Aeadoin 2023-04-08
### Feature
* Make ornamentations work with any augment type ([#3281](https://github.com/EQEmu/Server/pull/3281)) @Kinglykrab 2023-04-16
### Fixes
* Camping was causing player to leave raid, causing unexpected behavior ([#3299](https://github.com/EQEmu/Server/pull/3299)) @Aeadoin 2023-04-22
* Resolve loading of inventory ([#3272](https://github.com/EQEmu/Server/pull/3272)) @Aeadoin 2023-04-08
### Quest API
* Add ApplySpellRaid() and SetSpellDurationRaid() to Bots in Perl/Lua ([#3274](https://github.com/EQEmu/Server/pull/3274)) @Kinglykrab 2023-04-09
* Add GetBuffSpellIDs() to Perl/Lua ([#3273](https://github.com/EQEmu/Server/pull/3273)) @Kinglykrab 2023-04-09
* Fix LDoN Methods in Perl/Lua ([#3287](https://github.com/EQEmu/Server/pull/3287)) @Kinglykrab 2023-04-10
### Rules
* Optional summoning when already in melee range ([#3204](https://github.com/EQEmu/Server/pull/3204)) @trentdm 2023-04-08
### Telnet
* Telnet encoding fix ([#3269](https://github.com/EQEmu/Server/pull/3269)) @Akkadius 2023-04-05
## [22.9.1] - 04/03/2023
### Code
* Add client pointer validation to Zone::GetClosestZonePoint() ([#3173](https://github.com/EQEmu/Server/pull/3173)) @Kinglykrab 2023-04-01
* Change level to bot_level in Bot::DoClassAttacks() to not overlap member variable ([#3239](https://github.com/EQEmu/Server/pull/3239)) @Kinglykrab 2023-04-03
* Cleanup unnecessary string -> char* -> string conversions in eqemu_config.cpp ([#3207](https://github.com/EQEmu/Server/pull/3207)) @Kinglykrab 2023-04-03
* Cleanup uses of insert/push_back when a temp object is used. ([#3170](https://github.com/EQEmu/Server/pull/3170)) @Aeadoin 2023-04-03
* Cleanup variable names in Bot::AddSpellToBotList() ([#3248](https://github.com/EQEmu/Server/pull/3248)) @Kinglykrab 2023-04-03
* Explicitly cast to float for more precision in Bot::GenerateBastHitPoints() ([#3238](https://github.com/EQEmu/Server/pull/3238)) @Kinglykrab 2023-04-03
* Fix SEResist array settings duplicate code ([#3225](https://github.com/EQEmu/Server/pull/3225)) @Kinglykrab 2023-04-03
* Fix loop and code duplication for SE_ProcOnKillShot ([#3224](https://github.com/EQEmu/Server/pull/3224)) @Kinglykrab 2023-04-03
* Fix possible dereferencing of invalid iterator in constants ([#3181](https://github.com/EQEmu/Server/pull/3181)) @Kinglykrab 2023-04-03
* Fix typo where itembonuses should have been used instead of spellbonuses ([#3221](https://github.com/EQEmu/Server/pull/3221)) @Kinglykrab 2023-04-03
* Further bot.cpp nullptr checks ([#3240](https://github.com/EQEmu/Server/pull/3240)) @Kinglykrab 2023-04-03
* Move cases in Bot::AICastSpell() ([#3247](https://github.com/EQEmu/Server/pull/3247)) @Kinglykrab 2023-04-03
* Multiple cases same outcome and set skip variable to same value ([#3216](https://github.com/EQEmu/Server/pull/3216)) @Kinglykrab 2023-04-03
* Multiple cases with same outcome in GetGMSayColorFromCategory() ([#3182](https://github.com/EQEmu/Server/pull/3182)) @Kinglykrab 2023-04-03
* Remove extraneous loottable_id setting in WakeTheDead in aa.cpp ([#3215](https://github.com/EQEmu/Server/pull/3215)) @Kinglykrab 2023-04-03
* Remove possible dereferenced nullptrs in bot.cpp ([#3241](https://github.com/EQEmu/Server/pull/3241)) @Kinglykrab 2023-04-03
* Remove unnecessary >= 0 checks for procs in botspellsai.cpp ([#3242](https://github.com/EQEmu/Server/pull/3242)) @Kinglykrab 2023-04-03
* Remove unnecessary botCaster check in Bot::GetDebuffBotSpell() ([#3246](https://github.com/EQEmu/Server/pull/3246)) @Kinglykrab 2023-04-03
* Remove unnecessary group validation in Bot::Death() ([#3235](https://github.com/EQEmu/Server/pull/3235)) @Kinglykrab 2023-04-03
* Remove unnecessary hpr checks in Bot::BotCastHeal() ([#3245](https://github.com/EQEmu/Server/pull/3245)) @Kinglykrab 2023-04-03
* Remove unnecessary setting of spell_type_index in Bot::GetChanceToCastBySpellType() ([#3243](https://github.com/EQEmu/Server/pull/3243)) @Kinglykrab 2023-04-03
* Remove unnecessary skill_to_use check in Bot::DoClassAttacks() ([#3236](https://github.com/EQEmu/Server/pull/3236)) @Kinglykrab 2023-04-03
* Remove unnecessary spell_list validation check in botspellsai.cpp ([#3244](https://github.com/EQEmu/Server/pull/3244)) @Kinglykrab 2023-04-03
* Remove unnecessary validation check in Zone::ClearBlockedSpells() ([#3172](https://github.com/EQEmu/Server/pull/3172)) @Kinglykrab 2023-04-01
* Remove unused Includes under zone files ([#3162](https://github.com/EQEmu/Server/pull/3162)) @Aeadoin 2023-04-02
* Remove unused query variable in Database::DeleteInstance() ([#3202](https://github.com/EQEmu/Server/pull/3202)) @Kinglykrab 2023-04-03
* Unconditional return in for loop in GetRaidByCharID() ([#3179](https://github.com/EQEmu/Server/pull/3179)) @Kinglykrab 2023-04-03
* Use a constant reference for content_flags in SetContentFlags() ([#3196](https://github.com/EQEmu/Server/pull/3196)) @Kinglykrab 2023-04-03
* Wake The Dead argument was named the same as a member variable in Mob ([#3214](https://github.com/EQEmu/Server/pull/3214)) @Kinglykrab 2023-04-03
* gid is assigned 2 values simultaneously in bot.cpp ([#3234](https://github.com/EQEmu/Server/pull/3234)) @Kinglykrab 2023-04-03
* summon_count > MAX_SWARM_PETS is always false in aa.cpp ([#3212](https://github.com/EQEmu/Server/pull/3212)) @Kinglykrab 2023-04-03
### Fixes
* Correct Forward Declaration compilation warning ([#3176](https://github.com/EQEmu/Server/pull/3176)) @Aeadoin 2023-04-02
* Fix issue with Bot Raid invites not working. ([#3249](https://github.com/EQEmu/Server/pull/3249)) @Aeadoin 2023-04-03
### Performance
* Change to use Pass by reference where valid. ([#3163](https://github.com/EQEmu/Server/pull/3163)) @Aeadoin 2023-04-02
## [22.9.0] - 04/01/2023
### Bots
* Remove Bot Groups Functionality ([#3165](https://github.com/EQEmu/Server/pull/3165)) @Aeadoin 2023-04-01
### Code
* Cleanup excessive type casting: string -> char * -> string ([#3169](https://github.com/EQEmu/Server/pull/3169)) @Aeadoin 2023-04-01
### Crash
* Add Checks for valid pointers or fix existing. ([#3164](https://github.com/EQEmu/Server/pull/3164)) @Aeadoin 2023-04-01
* Fix out of bound arrays, other potential crashes ([#3166](https://github.com/EQEmu/Server/pull/3166)) @Aeadoin 2023-04-01
### Fixes
* Correct SE_SlayUndead & SE_HeadShotLevel limit Value when applied. ([#3171](https://github.com/EQEmu/Server/pull/3171)) @Aeadoin 2023-04-01
* Prevent VerifyGroup from setting OOZ membername to Null character. ([#3168](https://github.com/EQEmu/Server/pull/3168)) @Aeadoin 2023-04-01
### Quest API
* Add missing Luabind definitions to lua_general.cpp ([#3167](https://github.com/EQEmu/Server/pull/3167)) @Kinglykrab 2023-04-01
## [22.8.2] - 03/30/2023
### Code
* "equipped" not "equiped", "dual" not "duel". ([#3149](https://github.com/EQEmu/Server/pull/3149)) @Kinglykrab 2023-03-27
### Crash
* Add Checks for out of bounds & dereferencing nullptrs ([#3151](https://github.com/EQEmu/Server/pull/3151)) @Aeadoin 2023-03-28
### Fixes
* Check Rule "Bots Enabled" to prevent bot database calls on connect ([#3154](https://github.com/EQEmu/Server/pull/3154)) @Aeadoin 2023-03-29
* Correct logic checks for Bot rule AllowOwnerOptionAltCombat ([#3158](https://github.com/EQEmu/Server/pull/3158)) @Aeadoin 2023-03-30
* Fix an issue with EVENT_DISCONNECT not firing on regular /camp ([#3153](https://github.com/EQEmu/Server/pull/3153)) @Kinglykrab 2023-03-28
* Fix bot_raid_members.sql for MYSQL. ([#3155](https://github.com/EQEmu/Server/pull/3155)) @Aeadoin 2023-03-28
* Fix for OOZ Group updates when removing/inviting Bots ([#3159](https://github.com/EQEmu/Server/pull/3159)) @Aeadoin 2023-03-30
* Fix issues with Lua tables not starting at index 1 ([#3160](https://github.com/EQEmu/Server/pull/3160)) @Kinglykrab 2023-03-30
* Fix strcpy-param-overlap ([#3157](https://github.com/EQEmu/Server/pull/3157)) @Aeadoin 2023-03-29
### Rules
* Remove Guild Bank Zone ID Rule ([#3156](https://github.com/EQEmu/Server/pull/3156)) @Kinglykrab 2023-03-29
## [22.8.1] - 03/27/2023
### Fixes
* Fix for NPCs having spells interrupted. ([#3150](https://github.com/EQEmu/Server/pull/3150)) @Aeadoin 2023-03-27
## [22.8.0] - 03/25/2023
### Code
* Cleanup Strings::ToInt uses. ([#3142](https://github.com/EQEmu/Server/pull/3142)) @Aeadoin 2023-03-26
* Remove extern bool Critical ([#3146](https://github.com/EQEmu/Server/pull/3146)) @Kinglykrab 2023-03-25
### Crash
* Fix for crash in Raid::QueuePacket ([#3145](https://github.com/EQEmu/Server/pull/3145)) @Aeadoin 2023-03-25
### Feature
* Add support for -1 extradmgskill to allow all skills to be scaled. ([#3136](https://github.com/EQEmu/Server/pull/3136)) @Kinglykrab 2023-03-26
### Fixes
* Fix for Items looted from corpses. ([#3147](https://github.com/EQEmu/Server/pull/3147)) @Aeadoin 2023-03-26
* Fix for SQL Query in npc_scale_global_base ([#3144](https://github.com/EQEmu/Server/pull/3144)) @Aeadoin 2023-03-26
## [22.7.0] - 03/24/2023
### Bots
* Place BOT_COMMAND_CHAR inside messages ([#3027](https://github.com/EQEmu/Server/pull/3027)) @trentdm 2023-03-05
* Prevent interrupt spam when OOM ([#3011](https://github.com/EQEmu/Server/pull/3011)) @nytmyr 2023-03-07
### Code
* Cleaning up Raid.cpp ([#3125](https://github.com/EQEmu/Server/pull/3125)) @Aeadoin 2023-03-20
* Cleanup unused methods and variables in world/main.cpp and world/main.h ([#3105](https://github.com/EQEmu/Server/pull/3105)) @Kinglykrab 2023-03-17
* Cleanup uses of Strings::ToInt to match correct type. ([#3054](https://github.com/EQEmu/Server/pull/3054)) @Aeadoin 2023-03-22
* Delete deprecated/perlxs folder ([#3110](https://github.com/EQEmu/Server/pull/3110)) @Kinglykrab 2023-03-17
* Delete queues.h ([#3089](https://github.com/EQEmu/Server/pull/3089)) @Kinglykrab 2023-03-17
* Delete world/console.old.cpp ([#3099](https://github.com/EQEmu/Server/pull/3099)) @Kinglykrab 2023-03-17
* Delete zone_numbers.h ([#3129](https://github.com/EQEmu/Server/pull/3129)) @Kinglykrab 2023-03-20
* Remove AllConnected(), CanUpdate(), and SendInfo() from login_server_list.cpp and login_server_list.h ([#3104](https://github.com/EQEmu/Server/pull/3104)) @Kinglykrab 2023-03-17
* Remove CLIENT_TIMEOUT from world/client.h and zone/client.h ([#3071](https://github.com/EQEmu/Server/pull/3071)) @Kinglykrab 2023-03-17
* Remove ChangeHP() from mob.h ([#3128](https://github.com/EQEmu/Server/pull/3128)) @Kinglykrab 2023-03-19
* Remove CheckAuth(), SetOnline(), and pMD5Pass from cliententry.h ([#3095](https://github.com/EQEmu/Server/pull/3095)) @Kinglykrab 2023-03-17
* Remove CommandRequirement() from zonedb.h ([#3094](https://github.com/EQEmu/Server/pull/3094)) @Kinglykrab 2023-03-17
* Remove CountZones() from launcher_link.h ([#3100](https://github.com/EQEmu/Server/pull/3100)) @Kinglykrab 2023-03-17
* Remove DBInitVars() and HandleMysqlError() from queryserv/database.h ([#3114](https://github.com/EQEmu/Server/pull/3114)) @Kinglykrab 2023-03-17
* Remove DBInitVars(), HandleMysqlError(), and IsChatChannelInDB() in ucs/database.h ([#3113](https://github.com/EQEmu/Server/pull/3113)) @Kinglykrab 2023-03-17
* Remove DisableStats(), EnableStats(), DisableLoginserver(), and EnableLoginserver() from world_config.h ([#3107](https://github.com/EQEmu/Server/pull/3107)) @Kinglykrab 2023-03-17
* Remove DoBuffWearOffEffect() from mob.h ([#3062](https://github.com/EQEmu/Server/pull/3062)) @Kinglykrab 2023-03-17
* Remove FindByName(charname) from clientlist.h ([#3096](https://github.com/EQEmu/Server/pull/3096)) @Kinglykrab 2023-03-17
* Remove FindCLEByLSID(), GetCLE(), GetCLEIPCount(), and RemoveCLEByLSID() from clientlist.h ([#3098](https://github.com/EQEmu/Server/pull/3098)) @Kinglykrab 2023-03-17
* Remove FindPatch() from struct_category.cpp and struct_category.h ([#3130](https://github.com/EQEmu/Server/pull/3130)) @Kinglykrab 2023-03-20
* Remove FlushLootStats() from npc.h ([#3079](https://github.com/EQEmu/Server/pull/3079)) @Kinglykrab 2023-03-17
* Remove GetAILevel() from npc.h ([#3080](https://github.com/EQEmu/Server/pull/3080)) @Kinglykrab 2023-03-17
* Remove GetDestination() from doors.h ([#3078](https://github.com/EQEmu/Server/pull/3078)) @Kinglykrab 2023-03-17
* Remove GetServerByAddress() from server_manager.h ([#3119](https://github.com/EQEmu/Server/pull/3119)) @Kinglykrab 2023-03-17
* Remove GetStartCount() and InitStartTimer() from zone_launch.cpp and zone_launch.h ([#3121](https://github.com/EQEmu/Server/pull/3121)) @Kinglykrab 2023-03-17
* Remove GetTransformation() and GetInvertedTransformation() from oriented_bounding_box.h ([#3084](https://github.com/EQEmu/Server/pull/3084)) @Kinglykrab 2023-03-17
* Remove IsAffectedByBuff() ([#3068](https://github.com/EQEmu/Server/pull/3068)) @Kinglykrab 2023-03-17
* Remove IsConnected() from loginserver/database.h ([#3117](https://github.com/EQEmu/Server/pull/3117)) @Kinglykrab 2023-03-17
* Remove IsOrigin(glm::vec2) from position.h ([#3088](https://github.com/EQEmu/Server/pull/3088)) @Kinglykrab 2023-03-17
* Remove MakeGuildMembers() from wguild_mgr.h ([#3106](https://github.com/EQEmu/Server/pull/3106)) @Kinglykrab 2023-03-17
* Remove PlayerLogin_Struct from login_types.h ([#3118](https://github.com/EQEmu/Server/pull/3118)) @Kinglykrab 2023-03-17
* Remove RemoveSpawnGroup() from spawngroup.h ([#3090](https://github.com/EQEmu/Server/pull/3090)) @Kinglykrab 2023-03-17
* Remove SendGuildPacket() from clientlist.cpp, clientlist.h, and wguild_mgr.cpp ([#3097](https://github.com/EQEmu/Server/pull/3097)) @Kinglykrab 2023-03-17
* Remove SetConnection() from loginserver/world_server.h ([#3120](https://github.com/EQEmu/Server/pull/3120)) @Kinglykrab 2023-03-17
* Remove SetDBID() from object.h ([#3082](https://github.com/EQEmu/Server/pull/3082)) @Kinglykrab 2023-03-17
* Remove SetSentTime2 in petitions.h ([#3086](https://github.com/EQEmu/Server/pull/3086)) @Kinglykrab 2023-03-17
* Remove StoreCharacter() from worlddb.h ([#3108](https://github.com/EQEmu/Server/pull/3108)) @Kinglykrab 2023-03-17
* Remove UpdateLoginserverWorldAdminAccountPasswordById() from account_management.cpp ([#3115](https://github.com/EQEmu/Server/pull/3115)) @Kinglykrab 2023-03-17
* Remove _baseBotStance from bot.h ([#3076](https://github.com/EQEmu/Server/pull/3076)) @Kinglykrab 2023-03-17
* Remove _botRole from bot.h ([#3075](https://github.com/EQEmu/Server/pull/3075)) @Kinglykrab 2023-03-17
* Remove _previousTarget from bot.h ([#3074](https://github.com/EQEmu/Server/pull/3074)) @Kinglykrab 2023-03-17
* Remove authenticated from launcher_link.cpp and launcher_link.h ([#3101](https://github.com/EQEmu/Server/pull/3101)) @Kinglykrab 2023-03-17
* Remove can_corpse_be_rezzed from corpse.h ([#3077](https://github.com/EQEmu/Server/pull/3077)) @Kinglykrab 2023-03-17
* Remove casting_spell_type from mob.h ([#3064](https://github.com/EQEmu/Server/pull/3064)) @Kinglykrab 2023-03-17
* Remove class EQStream from client.h ([#3070](https://github.com/EQEmu/Server/pull/3070)) @Kinglykrab 2023-03-17
* Remove current_buff_count ([#3067](https://github.com/EQEmu/Server/pull/3067)) @Kinglykrab 2023-03-17
* Remove firstlogin and realfirstlogin from world/client.h ([#3072](https://github.com/EQEmu/Server/pull/3072)) @Kinglykrab 2023-03-17
* Remove fixedZ from mob.h ([#3065](https://github.com/EQEmu/Server/pull/3065)) @Kinglykrab 2023-03-17
* Remove inWater from mob.h ([#3069](https://github.com/EQEmu/Server/pull/3069)) @Kinglykrab 2023-03-17
* Remove is_authenticatd, LSShutDownUpdate(), and SetInstanceID() from zoneserver.h ([#3109](https://github.com/EQEmu/Server/pull/3109)) @Kinglykrab 2023-03-17
* Remove last_insert_id from petitions.h ([#3087](https://github.com/EQEmu/Server/pull/3087)) @Kinglykrab 2023-03-17
* Remove last_max_hp from mob.h ([#3063](https://github.com/EQEmu/Server/pull/3063)) @Kinglykrab 2023-03-17
* Remove m_inuse, m_z, and m_heading from object.h ([#3083](https://github.com/EQEmu/Server/pull/3083)) @Kinglykrab 2023-03-17
* Remove npc_ai.cpp/npc_ai.cpp ([#3081](https://github.com/EQEmu/Server/pull/3081)) @Kinglykrab 2023-03-17
* Remove ownHiddenTrigger from trap.cpp and trap.h ([#3092](https://github.com/EQEmu/Server/pull/3092)) @Kinglykrab 2023-03-17
* Remove perlparser.h ([#3085](https://github.com/EQEmu/Server/pull/3085)) @Kinglykrab 2023-03-17
* Remove unused AbilityTimer variable in client.h ([#3035](https://github.com/EQEmu/Server/pull/3035)) @Kinglykrab 2023-03-05
* Remove unused BotAA struct in bot_structs.h ([#3038](https://github.com/EQEmu/Server/pull/3038)) @Kinglykrab 2023-03-05
* Remove unused HandleUpdateTasksOnKill in client.h ([#3032](https://github.com/EQEmu/Server/pull/3032)) @Kinglykrab 2023-03-05
* Remove unused SaveBackup in client.h ([#3030](https://github.com/EQEmu/Server/pull/3030)) @Kinglykrab 2023-03-05
* Remove unused ^evacuate and ^succor subcommands from bot_command.h ([#3039](https://github.com/EQEmu/Server/pull/3039)) @Kinglykrab 2023-03-05
* Remove unused bot structs in bot_structs.h ([#3037](https://github.com/EQEmu/Server/pull/3037)) @Kinglykrab 2023-03-05
* Remove unused client queued work variable in client.cpp/client.h ([#3034](https://github.com/EQEmu/Server/pull/3034)) @Kinglykrab 2023-03-05
* Remove unused command variables in client.cpp ([#3031](https://github.com/EQEmu/Server/pull/3031)) @Kinglykrab 2023-03-05
* Remove unused lua_hate_entry.cpp ([#3057](https://github.com/EQEmu/Server/pull/3057)) @Kinglykrab 2023-03-12
* Remove unused methods in eql_config.cpp, eql_config.h, launcher_list.cpp, and launcher_list.h ([#3103](https://github.com/EQEmu/Server/pull/3103)) @Kinglykrab 2023-03-17
* Remove unused methods in loginserver/client.h ([#3116](https://github.com/EQEmu/Server/pull/3116)) @Kinglykrab 2023-03-17
* Remove unused player update variables in client.cpp/client.h ([#3033](https://github.com/EQEmu/Server/pull/3033)) @Kinglykrab 2023-03-05
* Utilize GetPlayerState() in mob methods ([#3066](https://github.com/EQEmu/Server/pull/3066)) @Kinglykrab 2023-03-17
* Utilize GetScheduler() in zone/worldserver.cpp ([#3093](https://github.com/EQEmu/Server/pull/3093)) @Kinglykrab 2023-03-17
* Utilize SetFilter in client.cpp ([#3036](https://github.com/EQEmu/Server/pull/3036)) @Kinglykrab 2023-03-05
* Utilize SetHiddenTrigger in trap.cpp ([#3091](https://github.com/EQEmu/Server/pull/3091)) @Kinglykrab 2023-03-17
* remove _botOrderAttack from bot.h ([#3073](https://github.com/EQEmu/Server/pull/3073)) @Kinglykrab 2023-03-17
### Commands
* Cleanup #haste Command ([#3042](https://github.com/EQEmu/Server/pull/3042)) @Kinglykrab 2023-03-06
* Cleanup #hideme Command ([#3043](https://github.com/EQEmu/Server/pull/3043)) @Kinglykrab 2023-03-06
* Cleanup #interrupt Command ([#3044](https://github.com/EQEmu/Server/pull/3044)) @Kinglykrab 2023-03-06
* Cleanup #level Command ([#3045](https://github.com/EQEmu/Server/pull/3045)) @Kinglykrab 2023-03-06
* Cleanup #picklock Command ([#3046](https://github.com/EQEmu/Server/pull/3046)) @Kinglykrab 2023-03-06
* Cleanup #resetaa and #resetaa_timer ([#3047](https://github.com/EQEmu/Server/pull/3047)) @Kinglykrab 2023-03-06
* Cleanup #wc Command ([#3049](https://github.com/EQEmu/Server/pull/3049)) @Kinglykrab 2023-03-06
* Remove #equipitem Command ([#3040](https://github.com/EQEmu/Server/pull/3040)) @Kinglykrab 2023-03-06
### Console
* Add IS_TTY to force terminal coloring output ([#3021](https://github.com/EQEmu/Server/pull/3021)) @Akkadius 2023-03-04
### Crash
* Fix dangling Group member pointers for Bots. ([#3134](https://github.com/EQEmu/Server/pull/3134)) @Aeadoin 2023-03-21
* Fixes Crash when Zoning with XTarget when Bots are in group. ([#3126](https://github.com/EQEmu/Server/pull/3126)) @Aeadoin 2023-03-19
### Feature
* Add Basic Bot Raiding Functionality ([#2782](https://github.com/EQEmu/Server/pull/2782)) @neckkola 2023-03-17
* Add Data Bucket support for scaling of Heroic Stats. ([#3058](https://github.com/EQEmu/Server/pull/3058)) @Aeadoin 2023-03-24
* Add Item Extra Skill Damage Percent Modifier ([#3127](https://github.com/EQEmu/Server/pull/3127)) @Kinglykrab 2023-03-19
### Fixes
* Add Avoidance and HP Regen Per Second too NPC Scaling. ([#3050](https://github.com/EQEmu/Server/pull/3050)) @Aeadoin 2023-03-09
* Add Heroic Strikethrough & HP Regen Per Second to GM Entity Info ([#3055](https://github.com/EQEmu/Server/pull/3055)) @Aeadoin 2023-03-12
* Add Heroic Strikethrough to NPC Scaling ([#3028](https://github.com/EQEmu/Server/pull/3028)) @Kinglykrab 2023-03-06
* Change SPA 193 Weapon Damage to allow values over 65,535 ([#3138](https://github.com/EQEmu/Server/pull/3138)) @Aeadoin 2023-03-23
* Checkmarks and X characters in popup messages ([#3041](https://github.com/EQEmu/Server/pull/3041)) @Kinglykrab 2023-03-06
* Cursor Coin Upon Death ([#3020](https://github.com/EQEmu/Server/pull/3020)) @cybernine186 2023-03-04
* Ensure synchronization of pet taunt state with UI ([#3025](https://github.com/EQEmu/Server/pull/3025)) @catapultam-habeo 2023-03-04
* Fix Bard Bot Casting ([#3122](https://github.com/EQEmu/Server/pull/3122)) @Aeadoin 2023-03-17
* Fix Discovered Items with Alternate Currency and LDoN Adventure Merchants ([#3026](https://github.com/EQEmu/Server/pull/3026)) @Kinglykrab 2023-03-04
* Fix Heal Scale and Spell Scale in NPC Scaling ([#3051](https://github.com/EQEmu/Server/pull/3051)) @Kinglykrab 2023-03-10
* Fix Raid Invites causing client desync issues ([#3053](https://github.com/EQEmu/Server/pull/3053)) @Aeadoin 2023-03-11
* Fix Raid methods that could cause crashes with Bots in raid ([#3111](https://github.com/EQEmu/Server/pull/3111)) @Aeadoin 2023-03-17
* Fix edge cases where camped bots would be left in a raid ([#3139](https://github.com/EQEmu/Server/pull/3139)) @Aeadoin 2023-03-23
* Fix for Raid Disband if leader not in same zone. ([#3135](https://github.com/EQEmu/Server/pull/3135)) @Aeadoin 2023-03-21
* Fix for incorrect bindpoint x,y,z,headings ([#3141](https://github.com/EQEmu/Server/pull/3141)) @Aeadoin 2023-03-23
* Fix for transferring Raid Leader ([#3140](https://github.com/EQEmu/Server/pull/3140)) @Aeadoin 2023-03-23
* Fix issue with overflow on min/max hit dmg in npc scaling calculations ([#3052](https://github.com/EQEmu/Server/pull/3052)) @Aeadoin 2023-03-10
* Fix typo for bot_id raid_members column in db_update_manifest.txt ([#3132](https://github.com/EQEmu/Server/pull/3132)) @Kinglykrab 2023-03-20
* Fixes for corpses not properly saving some item instance data correctly. ([#3123](https://github.com/EQEmu/Server/pull/3123)) @KimLS 2023-03-23
### Illusions
* Fix bug where spells like Ignite Bones left NPC size incorrect. ([#3061](https://github.com/EQEmu/Server/pull/3061)) @noudess 2023-03-16
### Quest API
* Add SendIllusion overloads/parameters to Perl/Lua ([#3059](https://github.com/EQEmu/Server/pull/3059)) @Kinglykrab 2023-03-16
* Add Spell GetActX methods to Perl/Lua ([#3056](https://github.com/EQEmu/Server/pull/3056)) @Kinglykrab 2023-03-12
* Add Timer related methods to Mobs in Perl/Lua ([#3133](https://github.com/EQEmu/Server/pull/3133)) @Kinglykrab 2023-03-20
### Rules
* Add Multiplier for Heroic Stats. ([#3014](https://github.com/EQEmu/Server/pull/3014)) @Aeadoin 2023-03-04
* Add ResurrectionEffectsBlock ([#2990](https://github.com/EQEmu/Server/pull/2990)) @nytmyr 2023-03-04
* Add Rule to allow ExtraDmgSkill/SPA 220 to effect Spell Skills ([#3124](https://github.com/EQEmu/Server/pull/3124)) @Aeadoin 2023-03-19
* Add Task System Rule ExpRewardsIgnoreLevelBasedEXPMods ([#3112](https://github.com/EQEmu/Server/pull/3112)) @Aeadoin 2023-03-17
### Scaling
* Add support for pipe-separated zone IDs and versions ([#3015](https://github.com/EQEmu/Server/pull/3015)) @Kinglykrab 2023-03-04
### Strings
* Add exception handling to converters themselves ([#3029](https://github.com/EQEmu/Server/pull/3029)) @Akkadius 2023-03-05
* Add more number formatters ([#2873](https://github.com/EQEmu/Server/pull/2873)) @Kinglykrab 2023-03-04
## [22.4.5] - 03/03/2023
### Bots
+13
View File
@@ -16,6 +16,15 @@ SET(CMAKE_CXX_STANDARD 20)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
IF (EQEMU_BUILD_STATIC)
SET(BUILD_SHARED_LIBS OFF)
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
MESSAGE(STATUS "Building with static linking")
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
ENDIF(EQEMU_BUILD_STATIC)
IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX)
@@ -307,6 +316,10 @@ ELSE()
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ENDIF()
IF (EQEMU_BUILD_STATIC)
SET(ZLIB_LIBRARY_LIBS libz.a)
ENDIF(EQEMU_BUILD_STATIC)
MESSAGE(STATUS "")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Usage *")
+6 -2
View File
@@ -15,6 +15,9 @@ SET(common_sources
database.cpp
database_conversions.cpp
database_instances.cpp
database/database_update_manifest.cpp
database/database_update_manifest_bots.cpp
database/database_update.cpp
dbcore.cpp
deity.cpp
dynamic_zone_base.cpp
@@ -506,6 +509,7 @@ SET(common_headers
data_verification.h
database.h
database_schema.h
database/database_update.h
dbcore.h
deity.h
discord/discord.h
@@ -608,7 +612,6 @@ SET(common_headers
unix.h
useperl.h
version.h
zone_numbers.h
zone_store.h
event/event_loop.h
event/task.h
@@ -667,7 +670,8 @@ SET(common_headers
StackWalker/StackWalker.h
util/memory_stream.h
util/directory.h
util/uuid.h)
util/uuid.h
)
SOURCE_GROUP(Event FILES
event/event_loop.h
+78
View File
@@ -17,6 +17,7 @@
*/
#include "../common/global_define.h"
#include "../common/classes.h"
#include "data_verification.h"
const char *GetClassIDName(uint8 class_id, uint8 level)
{
@@ -630,6 +631,20 @@ bool IsINTCasterClass(uint8 class_id)
}
}
bool IsHeroicINTCasterClass(uint8 class_id)
{
switch (class_id) {
case NECROMANCER:
case WIZARD:
case MAGICIAN:
case ENCHANTER:
case SHADOWKNIGHT:
return true;
default:
return false;
}
}
bool IsWISCasterClass(uint8 class_id)
{
switch (class_id) {
@@ -642,6 +657,21 @@ bool IsWISCasterClass(uint8 class_id)
}
}
bool IsHeroicWISCasterClass(uint8 class_id)
{
switch (class_id) {
case CLERIC:
case DRUID:
case SHAMAN:
case PALADIN:
case BEASTLORD:
case RANGER:
return true;
default:
return false;
}
}
bool IsPlateClass(uint8 class_id)
{
switch (class_id) {
@@ -721,3 +751,51 @@ uint8 ClassArmorType(uint8 class_id)
return ARMOR_TYPE_UNKNOWN;
}
}
const std::string GetPlayerClassAbbreviation(uint8 class_id)
{
if (!EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) {
return std::string("UNK");
}
switch (class_id) {
case WARRIOR:
return "WAR";
case CLERIC:
return "CLR";
case PALADIN:
return "PAL";
case RANGER:
return "RNG";
case SHADOWKNIGHT:
return "SHD";
case DRUID:
return "DRU";
case MONK:
return "MNK";
case BARD:
return "BRD";
case ROGUE:
return "ROG";
case SHAMAN:
return "SHM";
case NECROMANCER:
return "NEC";
case WIZARD:
return "WIZ";
case MAGICIAN:
return "MAG";
case ENCHANTER:
return "ENC";
case BEASTLORD:
return "BST";
case BERSERKER:
return "BER";
}
return std::string("UNK");
}
bool IsPlayerClass(uint8 class_id) {
return EQ::ValueWithin(class_id, WARRIOR, BERSERKER);
}
+6 -1
View File
@@ -19,6 +19,7 @@
#define CLASSES_CH
#include "../common/types.h"
#include <string>
#define NO_CLASS 0
#define WARRIOR 1
@@ -127,6 +128,9 @@
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
bool IsPlayerClass(uint8 class_id);
const std::string GetPlayerClassAbbreviation(uint8 class_id);
uint32 GetPlayerClassValue(uint8 class_id);
uint32 GetPlayerClassBit(uint8 class_id);
@@ -140,7 +144,8 @@ bool IsHybridClass(uint8 class_id);
bool IsCasterClass(uint8 class_id);
bool IsINTCasterClass(uint8 class_id);
bool IsWISCasterClass(uint8 class_id);
bool IsHeroicINTCasterClass(uint8 class_id);
bool IsHeroicWISCasterClass(uint8 class_id);
bool IsPlateClass(uint8 class_id);
bool IsChainClass(uint8 class_id);
bool IsLeatherClass(uint8 class_id);
+2 -2
View File
@@ -77,7 +77,7 @@ namespace EQEmuCommand {
index++;
}
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
std::string arguments_string;
for (auto &arg : arguments) {
arguments_string += " " + arg;
@@ -160,7 +160,7 @@ namespace EQEmuCommand {
*/
std::string command_section;
for (auto &it: in_function_map) {
description = "";
description.clear();
(it.second)(argc, argv, cmd, description);
+1 -1
View File
@@ -120,7 +120,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
/**
* @param content_flags
*/
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags)
{
WorldContentService::content_flags = content_flags;
}
+1 -1
View File
@@ -167,7 +167,7 @@ public:
std::vector<std::string> GetContentFlagsDisabled();
bool IsContentFlagEnabled(const std::string& content_flag);
bool IsContentFlagDisabled(const std::string& content_flag);
void SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags);
void SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags);
void ReloadContentFlags();
WorldContentService * SetExpansionContext();
+1 -4
View File
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info
auto os = EQ::GetOS();
@@ -125,7 +122,7 @@ public:
StackWalker::OnOutput(szText);
}
const std::vector<std::string>& const GetLines() { return _lines; }
const std::vector<std::string>& GetLines() { return _lines; }
private:
std::vector<std::string> _lines;
};
+237 -166
View File
@@ -353,7 +353,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
results = QueryDatabase(query);
if (!results.Success() || results.ErrorMessage() != ""){ return false; }
if (!results.Success() || !results.ErrorMessage().empty()){ return false; }
// Put character into the default guild if rule is being used.
int guild_id = RuleI(Character, DefaultGuild);
@@ -363,7 +363,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
if (character_id > -1) {
query = StringFormat("INSERT INTO `guild_members` SET `char_id` = %i, `guild_id` = '%i'", character_id, guild_id);
results = QueryDatabase(query);
if (!results.Success() || results.ErrorMessage() != ""){
if (!results.Success() || !results.ErrorMessage().empty()){
LogInfo("Could not put character [{}] into default Guild", name);
}
}
@@ -387,7 +387,7 @@ bool Database::DeleteCharacter(char *character_name)
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
character_id = Strings::ToInt(row[0]);
character_id = Strings::ToUnsignedInt(row[0]);
}
if (character_id <= 0) {
@@ -449,7 +449,8 @@ bool Database::DeleteCharacter(char *character_name)
return true;
}
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp)
{
std::string query = StringFormat(
"REPLACE INTO `character_data` ("
"id,"
@@ -634,101 +635,102 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
"%u," // guild_auto_consent
"%u" // RestTimer
")",
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
character_id, // " id, "
account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, "
Strings::Escape(pp->last_name).c_str(), // " last_name, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
pp->level, // " `level`, "
pp->deity, // " deity, "
pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, "
pp->level2, // " level2, "
pp->anon, // " anon, "
pp->gm, // " gm, "
pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, "
pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
pp->gender, // " gender, "
pp->race, // " race, "
pp->class_, // " class, "
pp->level, // " `level`, "
pp->deity, // " deity, "
pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, "
pp->level2, // " level2, "
pp->anon, // " anon, "
pp->gm, // " gm, "
pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, "
pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, "
Strings::Escape(pp->title).c_str(), // " title, "
Strings::Escape(pp->suffix).c_str(), // " suffix, "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, "
pp->STR, // " str, "
pp->STA, // " sta, "
pp->CHA, // " cha, "
pp->DEX, // " dex, "
pp->INT, // " `int`, "
pp->AGI, // " agi, "
pp->WIS, // " wis, "
pp->face, // " face, "
pp->y, // " y, "
pp->x, // " x, "
pp->z, // " z, "
pp->heading, // " heading, "
pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, "
pp->guildAutoconsent, // " guild_auto_consent, "
pp->RestTimer // " RestTimer) "
pp->exp, // " exp, "
pp->points, // " points, "
pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, "
pp->STR, // " str, "
pp->STA, // " sta, "
pp->CHA, // " cha, "
pp->DEX, // " dex, "
pp->INT, // " `int`, "
pp->AGI, // " agi, "
pp->WIS, // " wis, "
pp->face, // " face, "
pp->y, // " y, "
pp->x, // " x, "
pp->z, // " z, "
pp->heading, // " heading, "
pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, "
pp->guildAutoconsent, // " guild_auto_consent, "
pp->RestTimer // " RestTimer) "
);
auto results = QueryDatabase(query);
QueryDatabase(query);
/* Save Bind Points */
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
query = StringFormat(
"REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
@@ -739,57 +741,73 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
character_id, pp->binds[2].zone_id, 0, pp->binds[2].x, pp->binds[2].y, pp->binds[2].z, pp->binds[2].heading, 2,
character_id, pp->binds[3].zone_id, 0, pp->binds[3].x, pp->binds[3].y, pp->binds[3].z, pp->binds[3].heading, 3,
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
); results = QueryDatabase(query);
);
QueryDatabase(query);
/* HoTT Ability */
if(RuleB(Character, GrantHoTTOnCreate))
{
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)", character_id, 14, 1);
results = QueryDatabase(query);
}
/* HoTT Ability */
if (RuleB(Character, GrantHoTTOnCreate)) {
query = StringFormat(
"INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)",
character_id,
14,
1
);
QueryDatabase(query);
}
/* Save Skills */
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++){
if (pp->skills[i] > 0){
if (firstquery != 1){
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++) {
if (pp->skills[i] > 0) {
if (firstquery != 1) {
firstquery = 1;
query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]);
}
else{
query = StringFormat(
"REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)",
character_id,
i,
pp->skills[i]
);
} else {
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]);
}
}
}
results = QueryDatabase(query);
QueryDatabase(query);
/* Save Language */
firstquery = 0;
for (int i = 0; i < MAX_PP_LANGUAGE; i++){
if (pp->languages[i] > 0){
if (firstquery != 1){
for (int i = 0; i < MAX_PP_LANGUAGE; i++) {
if (pp->languages[i] > 0) {
if (firstquery != 1) {
firstquery = 1;
query = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]);
}
else{
query = StringFormat(
"REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)",
character_id,
i,
pp->languages[i]
);
} else {
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]);
}
}
}
results = QueryDatabase(query);
QueryDatabase(query);
return true;
}
uint32 Database::GetCharacterID(const char *name) {
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
const auto query = fmt::format(
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
Strings::Escape(name)
);
auto results = QueryDatabase(query);
auto row = results.begin();
if (results.RowCount() == 1)
{
return Strings::ToInt(row[0]);
if (!results.Success() || !results.RowCount()) {
return 0;
}
return 0;
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
/*
@@ -812,10 +830,10 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
auto row = results.begin();
uint32 accountId = Strings::ToInt(row[0]);
uint32 accountId = Strings::ToUnsignedInt(row[0]);
if (oCharID)
*oCharID = Strings::ToInt(row[1]);
*oCharID = Strings::ToUnsignedInt(row[1]);
return accountId;
}
@@ -832,7 +850,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
return 0;
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
@@ -880,7 +898,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID
strcpy(name, row[0]);
if (row[1] && oLSAccountID) {
*oLSAccountID = Strings::ToInt(row[1]);
*oLSAccountID = Strings::ToUnsignedInt(row[1]);
}
}
@@ -968,7 +986,7 @@ bool Database::LoadVariables() {
std::string key, value;
for (auto row = results.begin(); row != results.end(); ++row) {
varcache.last_update = Strings::ToInt(row[2]); // ahh should we be comparing if this is newer?
varcache.last_update = Strings::ToUnsignedInt(row[2]); // ahh should we be comparing if this is newer?
key = row[0];
value = row[1];
std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be
@@ -999,7 +1017,7 @@ bool Database::GetVariable(std::string varname, std::string &varvalue)
return false;
}
bool Database::SetVariable(const std::string varname, const std::string &varvalue)
bool Database::SetVariable(const std::string& varname, const std::string &varvalue)
{
std::string escaped_name = Strings::Escape(varname);
std::string escaped_value = Strings::Escape(varvalue);
@@ -1052,7 +1070,7 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
auto row = results.begin();
if(graveyard_zoneid != nullptr)
*graveyard_zoneid = Strings::ToInt(row[0]);
*graveyard_zoneid = Strings::ToUnsignedInt(row[0]);
if(graveyard_x != nullptr)
*graveyard_x = Strings::ToFloat(row[1]);
if(graveyard_y != nullptr)
@@ -1168,7 +1186,7 @@ uint32 Database::GetAccountIDFromLSID(
}
for (auto row = results.begin(); row != results.end(); ++row) {
account_id = Strings::ToInt(row[0]);
account_id = Strings::ToUnsignedInt(row[0]);
if (in_account_name) {
strcpy(in_account_name, row[1]);
@@ -1244,7 +1262,7 @@ uint8 Database::GetServerType() {
return 0;
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id)
@@ -1296,7 +1314,7 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
return 0;
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
@@ -1312,12 +1330,12 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
if (results.Success() && results.RowsAffected() != 0)
{
auto row = results.begin();
skill_level = Strings::ToInt(row[0]);
skill_formula = Strings::ToInt(row[1]);
skill_cap = Strings::ToInt(row[2]);
if (Strings::ToInt(row[3]) > skill_cap)
skill_cap2 = (Strings::ToInt(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
skill_cap3 = Strings::ToInt(row[4]);
skill_level = Strings::ToUnsignedInt(row[0]);
skill_formula = Strings::ToUnsignedInt(row[1]);
skill_cap = Strings::ToUnsignedInt(row[2]);
if (Strings::ToUnsignedInt(row[3]) > skill_cap)
skill_cap2 = (Strings::ToUnsignedInt(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
skill_cap3 = Strings::ToUnsignedInt(row[4]);
}
int race_skill = GetRaceSkill(skillid,in_race);
@@ -1488,7 +1506,7 @@ uint32 Database::GetGroupID(const char* name){
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
@@ -1638,7 +1656,7 @@ uint8 Database::GetAgreementFlag(uint32 acctid) {
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
void Database::SetAgreementFlag(uint32 acctid) {
@@ -1724,7 +1742,7 @@ uint32 Database::GetRaidID(const char* name)
}
if (row[0]) // would it ever be possible to have a null here?
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
return 0;
}
@@ -1980,16 +1998,16 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
auto row = results.begin();
as->success.guk = Strings::ToInt(row[0]);
as->success.mir = Strings::ToInt(row[1]);
as->success.mmc = Strings::ToInt(row[2]);
as->success.ruj = Strings::ToInt(row[3]);
as->success.tak = Strings::ToInt(row[4]);
as->failure.guk = Strings::ToInt(row[5]);
as->failure.mir = Strings::ToInt(row[6]);
as->failure.mmc = Strings::ToInt(row[7]);
as->failure.ruj = Strings::ToInt(row[8]);
as->failure.tak = Strings::ToInt(row[9]);
as->success.guk = Strings::ToUnsignedInt(row[0]);
as->success.mir = Strings::ToUnsignedInt(row[1]);
as->success.mmc = Strings::ToUnsignedInt(row[2]);
as->success.ruj = Strings::ToUnsignedInt(row[3]);
as->success.tak = Strings::ToUnsignedInt(row[4]);
as->failure.guk = Strings::ToUnsignedInt(row[5]);
as->failure.mir = Strings::ToUnsignedInt(row[6]);
as->failure.mmc = Strings::ToUnsignedInt(row[7]);
as->failure.ruj = Strings::ToUnsignedInt(row[8]);
as->failure.tak = Strings::ToUnsignedInt(row[9]);
as->failure.total = as->failure.guk + as->failure.mir + as->failure.mmc + as->failure.ruj + as->failure.tak;
as->success.total = as->success.guk + as->success.mir + as->success.mmc + as->success.ruj + as->success.tak;
@@ -2008,7 +2026,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
return 0;
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
uint32 Database::GetGroupIDByCharID(uint32 character_id)
@@ -2030,7 +2048,7 @@ uint32 Database::GetGroupIDByCharID(uint32 character_id)
return 0;
auto row = results.begin();
return Strings::ToInt(row[0]);
return Strings::ToUnsignedInt(row[0]);
}
uint32 Database::GetRaidIDByCharID(uint32 character_id) {
@@ -2043,10 +2061,12 @@ uint32 Database::GetRaidIDByCharID(uint32 character_id) {
character_id
);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
return Strings::ToInt(row[0]);
if (!results.Success() || !results.RowCount()) {
return 0;
}
return 0;
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
int Database::CountInvSnapshots() {
@@ -2089,17 +2109,17 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
eqTime.day = 1;
eqTime.month = 1;
eqTime.year = 3100;
realtime = time(0);
realtime = time(nullptr);
}
else{
auto row = results.begin();
eqTime.minute = Strings::ToInt(row[0]);
eqTime.hour = Strings::ToInt(row[1]);
eqTime.day = Strings::ToInt(row[2]);
eqTime.month = Strings::ToInt(row[3]);
eqTime.year = Strings::ToInt(row[4]);
realtime = Strings::ToInt(row[5]);
eqTime.minute = Strings::ToUnsignedInt(row[0]);
eqTime.hour = Strings::ToUnsignedInt(row[1]);
eqTime.day = Strings::ToUnsignedInt(row[2]);
eqTime.month = Strings::ToUnsignedInt(row[3]);
eqTime.year = Strings::ToUnsignedInt(row[4]);
realtime = Strings::ToBigInt(row[5]);
}
return eqTime;
@@ -2272,7 +2292,6 @@ bool Database::CopyCharacter(
new_rows.emplace_back(new_values);
}
std::string insert_values;
std::vector<std::string> insert_rows;
for (auto &r: new_rows) {
@@ -2328,7 +2347,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
);
if (!DoesTableExist(table_name)) {
LogMySQLQuery("Table [{}] does not exist. Downloading from Github and installing...", table_name);
LogMySQLQuery("Table [{}] does not exist. Downloading and installing...", table_name);
// http get request
httplib::Client cli(
@@ -2336,7 +2355,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
"{}://{}",
request_uri.get_scheme(),
request_uri.get_host()
).c_str()
)
);
cli.set_connection_timeout(0, 60000000); // 60 sec
@@ -2345,7 +2364,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
int sourced_queries = 0;
if (auto res = cli.Get(request_uri.get_path().c_str())) {
if (auto res = cli.Get(request_uri.get_path())) {
if (res->status == 200) {
for (auto &s: Strings::Split(res->body, ';')) {
if (!Strings::Trim(s).empty()) {
@@ -2389,3 +2408,55 @@ uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
return !zones.empty() ? zones[0].min_status : 0;
}
void Database::SourceSqlFromUrl(std::string url)
{
try {
uri request_uri(url);
LogHTTPDetail(
"parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
url,
request_uri.get_path(),
request_uri.get_host(),
request_uri.get_query(),
request_uri.get_scheme(),
request_uri.get_port()
);
LogInfo("Downloading and installing from [{}]", url);
// http get request
httplib::Client cli(
fmt::format(
"{}://{}",
request_uri.get_scheme(),
request_uri.get_host()
)
);
cli.set_connection_timeout(0, 60000000); // 60 sec
cli.set_read_timeout(60, 0); // 60 seconds
cli.set_write_timeout(60, 0); // 60 seconds
if (auto res = cli.Get(request_uri.get_path())) {
if (res->status == 200) {
auto results = QueryDatabaseMulti(res->body);
if (!results.ErrorMessage().empty()) {
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
return;
}
}
if (res->status == 404) {
LogError("Error retrieving URL [{}]", url);
}
}
else {
LogError("Error retrieving URL [{}]", url);
}
}
catch (std::invalid_argument iae) {
LogError("URI parser error [{}]", iae.what());
}
}
+2 -2
View File
@@ -235,7 +235,7 @@ public:
/* Database Variables */
bool GetVariable(std::string varname, std::string &varvalue);
bool SetVariable(const std::string varname, const std::string &varvalue);
bool SetVariable(const std::string& varname, const std::string &varvalue);
bool LoadVariables();
/* General Queries */
@@ -263,7 +263,7 @@ public:
void ClearInvSnapshots(bool from_now = false);
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
void SourceSqlFromUrl(std::string url);
private:
+94 -23
View File
@@ -28,6 +28,7 @@
#include "../database_schema.h"
#include "../file.h"
#include "../process/process.h"
#include "../termcolor/rang.hpp"
#include <ctime>
@@ -36,6 +37,7 @@
#else
#include <sys/time.h>
#include <thread>
#endif
@@ -91,6 +93,8 @@ std::string DatabaseDumpService::GetMySQLVersion()
return Strings::Trim(version_output);
}
const std::string CREDENTIALS_FILE = "login.my.cnf";
/**
* @return
*/
@@ -99,21 +103,15 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
auto config = EQEmuConfig::get();
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
return fmt::format(
"mysqldump -u {} -p{} -h {} --port={} {}",
config->ContentDbUsername,
config->ContentDbPassword,
config->ContentDbHost,
config->ContentDbPort,
"mysqldump --defaults-extra-file={} {}",
CREDENTIALS_FILE,
config->ContentDbName
);
};
return fmt::format(
"mysqldump -u {} -p{} -h {} --port={} {}",
config->DatabaseUsername,
config->DatabasePassword,
config->DatabaseHost,
config->DatabasePort,
"mysqldump --defaults-extra-file={} {}",
CREDENTIALS_FILE,
config->DatabaseDB
);
}
@@ -145,7 +143,7 @@ std::string DatabaseDumpService::GetQueryServTables()
std::string DatabaseDumpService::GetSystemTablesList()
{
auto system_tables = DatabaseSchema::GetServerTables();
auto system_tables = DatabaseSchema::GetServerTables();
auto version_tables = DatabaseSchema::GetVersionTables();
system_tables.insert(
@@ -199,7 +197,7 @@ std::string DatabaseDumpService::GetDumpFileNameWithPath()
return GetSetDumpPath() + GetDumpFileName();
}
void DatabaseDumpService::Dump()
void DatabaseDumpService::DatabaseDump()
{
if (!IsMySQLInstalled()) {
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
@@ -293,14 +291,6 @@ void DatabaseDumpService::Dump()
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
}
std::string execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
File::Makedir(GetSetDumpPath());
}
@@ -308,30 +298,62 @@ void DatabaseDumpService::Dump()
if (IsDumpDropTableSyntaxOnly()) {
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
for (auto &table : tables) {
for (auto &table: tables) {
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
}
if (tables_to_dump.empty()) {
std::cerr << "No tables were specified" << std::endl;
}
return;
}
else {
const auto execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
BuildCredentialsFile();
std::string execution_result = Process::execute(execute_command);
if (!execution_result.empty() && IsDumpOutputToConsole()) {
std::cout << execution_result;
}
}
if (!IsDumpOutputToConsole()) {
LogSys.LoadLogSettingsDefaults();
}
if (!pipe_file.empty()) {
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
auto r = File::GetContents(file);
if (!r.error.empty()) {
LogError("{}", r.error);
}
for (auto &line: Strings::Split(r.contents, "\n")) {
if (Strings::Contains(line, "mysqldump:")) {
LogError("{}", line);
LogError("Database dump failed. Correct the error before continuing or trying again");
LogError("This is to prevent data loss on behalf of the server operator");
RemoveSqlBackup();
std::exit(1);
}
}
}
if (!tables_to_dump.empty()) {
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
}
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
if (HasCompressionBinary()) {
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
if (IsTarAvailable()) {
Process::execute(
@@ -343,6 +365,7 @@ void DatabaseDumpService::Dump()
)
);
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else if (Is7ZipAvailable()) {
Process::execute(
@@ -353,6 +376,7 @@ void DatabaseDumpService::Dump()
)
);
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else {
LogInfo("Compression requested, but no available compression binary was found");
@@ -363,6 +387,8 @@ void DatabaseDumpService::Dump()
}
}
RemoveCredentialsFile();
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
// LogDebug("[{}] dump-path", GetSetDumpPath());
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
@@ -535,3 +561,48 @@ void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
{
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
}
void DatabaseDumpService::RemoveSqlBackup()
{
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
if (File::Exists(file)) {
std::filesystem::remove(file);
}
RemoveCredentialsFile();
}
void DatabaseDumpService::BuildCredentialsFile()
{
auto config = EQEmuConfig::get();
std::ofstream out(CREDENTIALS_FILE);
if (out.is_open()) {
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
out << "[mysqldump]" << std::endl;
out << "user=" << config->ContentDbUsername << std::endl;
out << "password=" << config->ContentDbPassword << std::endl;
out << "host=" << config->ContentDbHost << std::endl;
out << "port=" << config->ContentDbPort << std::endl;
out << "default-character-set=utf8" << std::endl;
}
else {
out << "[mysqldump]" << std::endl;
out << "user=" << config->DatabaseUsername << std::endl;
out << "password=" << config->DatabasePassword << std::endl;
out << "host=" << config->DatabaseHost << std::endl;
out << "port=" << config->DatabasePort << std::endl;
out << "default-character-set=utf8" << std::endl;
}
out.close();
}
else {
LogError("Failed to open credentials file for writing");
}
}
void DatabaseDumpService::RemoveCredentialsFile()
{
if (File::Exists(CREDENTIALS_FILE)) {
std::filesystem::remove(CREDENTIALS_FILE);
}
}
+4 -1
View File
@@ -24,7 +24,7 @@
class DatabaseDumpService {
public:
void Dump();
void DatabaseDump();
bool IsDumpAllTables() const;
void SetDumpAllTables(bool dump_all_tables);
bool IsDumpWithNoData() const;
@@ -92,6 +92,9 @@ private:
std::string GetDumpFileNameWithPath();
std::string GetSetDumpPath();
std::string GetQueryServTables();
void RemoveSqlBackup();
void BuildCredentialsFile();
void RemoveCredentialsFile();
};
+300
View File
@@ -0,0 +1,300 @@
#include <filesystem>
#include "database_update.h"
#include "../eqemu_logsys.h"
#include "../database.h"
#include "../strings.h"
#include "../rulesys.h"
#include "../http/httplib.h"
#include "database_update_manifest.cpp"
#include "database_update_manifest_bots.cpp"
#include "database_dump_service.h"
constexpr int BREAK_LENGTH = 70;
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
{
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
if (!results.Success() || !results.RowCount()) {
LogError("Failed to read from [db_version] table!");
return DatabaseVersion{};
}
auto r = results.begin();
return DatabaseVersion{
.server_database_version = Strings::ToInt(r[0]),
.bots_database_version = Strings::ToInt(r[1]),
};
}
DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
{
return DatabaseVersion{
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
};
}
// the amount of versions we look-back to ensure we have all migrations
// we may not want to force these, but just warn about the look-backs
constexpr int LOOK_BACK_AMOUNT = 10;
// this check will take action
void DatabaseUpdate::CheckDbUpdates()
{
InjectBotsVersionColumn();
auto v = GetDatabaseVersions();
auto b = GetBinaryDatabaseVersions();
if (CheckVersionsUpToDate(v, b)) {
return;
}
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
LogInfo(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.server_database_version,
v.server_database_version
);
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
}
if (b.bots_database_version > 0) {
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
LogInfo(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.bots_database_version,
v.bots_database_version
);
m_database->QueryDatabase(
fmt::format(
"UPDATE `db_version` SET `bots_version` = {}",
b.bots_database_version
)
);
}
}
}
std::string DatabaseUpdate::GetQueryResult(std::string query)
{
auto results = m_database->QueryDatabase(query);
std::vector<std::string> result_lines = {};
for (auto row = results.begin(); row != results.end(); ++row) {
std::vector<std::string> cols;
int field_count = results.ColumnCount();
cols.reserve(field_count);
for (int i = 0; i < field_count; ++i) {
if (row[i] != nullptr) {
cols.emplace_back(row[i]);
}
}
result_lines.emplace_back(Strings::Join(cols, " "));
}
return Strings::Join(result_lines, "\n");
}
bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_result)
{
std::string r = Strings::Trim(query_result);
if (e.condition == "contains") {
return Strings::Contains(r, e.match);
}
else if (e.condition == "match") {
return r == e.match;
}
else if (e.condition == "missing") {
return !Strings::Contains(r, e.match);
}
else if (e.condition == "empty") {
return r.empty();
}
else if (e.condition == "not_empty") {
return !r.empty();
}
return false;
}
// return true if we ran updates
bool DatabaseUpdate::UpdateManifest(
std::vector<ManifestEntry> entries,
int version_low,
int version_high
)
{
std::vector<int> missing_migrations = {};
if (version_low != version_high) {
LogSys.DisableMySQLErrorLogs();
for (int version = version_low + 1; version <= version_high; ++version) {
for (auto &e: entries) {
if (e.version == version) {
bool has_migration = true;
std::string r = GetQueryResult(e.check);
if (ShouldRunMigration(e, r)) {
has_migration = false;
missing_migrations.emplace_back(e.version);
}
std::string prefix = fmt::format(
"[{}]",
has_migration ? "ok" : "missing"
);
LogInfo(
"[{}] {:>10} | [{}]",
e.version,
prefix,
e.description
);
}
}
}
LogSys.EnableMySQLErrorLogs();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
if (!missing_migrations.empty()) {
LogInfo("Automatically backing up database before applying updates");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
auto s = DatabaseDumpService();
s.SetDumpAllTables(true);
s.SetDumpWithCompression(true);
s.DatabaseDump();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
}
if (!missing_migrations.empty()) {
LogInfo("Running database migrations. Please wait...");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
}
for (auto &m: missing_migrations) {
for (auto &e: entries) {
if (e.version == m) {
bool errored_migration = false;
auto r = m_database->QueryDatabaseMulti(e.sql);
// ignore empty query result "errors"
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
LogError("(#{}) [{}]", r.ErrorNumber(), r.ErrorMessage());
errored_migration = true;
LogInfo("Required database update failed. This could be a problem");
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
// user input
std::string input;
bool gave_input = false;
time_t start_time = time(nullptr);
time_t wait_time_seconds = 60;
// spawn a concurrent thread that waits for input from std::cin
std::thread t1(
[&]() {
std::cin >> input;
gave_input = true;
}
);
t1.detach();
// check the inputReceived flag once every 50ms for 10 seconds
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// prompt for user skip
if (Strings::Trim(input) == "y") {
errored_migration = false;
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
}
}
LogInfo(
"[{}] [{}] [{}]",
e.version,
e.description,
(errored_migration ? "error" : "ok")
);
if (errored_migration) {
LogError("Fatal | Database migration [{}] failed to run", e.description);
LogError("Fatal | Shutting down");
std::exit(1);
}
}
}
}
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
return true;
}
return false;
}
DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
{
m_database = db;
return this;
}
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
{
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfo(
"{:>8} | database [{}] binary [{}] {}",
"Server",
v.server_database_version,
b.server_database_version,
(v.server_database_version == b.server_database_version) ? "up to date" : "checking updates"
);
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
LogInfo(
"{:>8} | database [{}] binary [{}] {}",
"Bots",
v.bots_database_version,
b.bots_database_version,
(v.bots_database_version == b.bots_database_version) ? "up to date" : "checking updates"
);
}
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
// server database version is required
bool server_up_to_date = v.server_database_version == b.server_database_version;
// bots database version is optional, if not enabled then it is always up-to-date
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
return server_up_to_date && bots_up_to_date;
}
// checks to see if there are pending updates
// used by zone to prevent launch or boot loop until updates are applied
bool DatabaseUpdate::HasPendingUpdates()
{
auto v = GetDatabaseVersions();
auto b = GetBinaryDatabaseVersions();
return !CheckVersionsUpToDate(v, b);
}
void DatabaseUpdate::InjectBotsVersionColumn()
{
auto r = m_database->QueryDatabase("show columns from db_version where Field like '%bots_version%'");
if (r.RowCount() == 0) {
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef EQEMU_DATABASE_UPDATE_H
#define EQEMU_DATABASE_UPDATE_H
#include "../database.h"
struct ManifestEntry {
int version{}; // database version of the migration
std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
std::string check{}; // query that checks against the condition
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
std::string sql{}; // the SQL DDL that gets ran when the condition is true
};
struct DatabaseVersion {
int server_database_version;
int bots_database_version;
};
class DatabaseUpdate {
public:
DatabaseVersion GetDatabaseVersions();
DatabaseVersion GetBinaryDatabaseVersions();
void CheckDbUpdates();
std::string GetQueryResult(std::string query);
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
DatabaseUpdate *SetDatabase(Database *db);
bool HasPendingUpdates();
private:
Database *m_database;
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
void InjectBotsVersionColumn();
};
#endif //EQEMU_DATABASE_UPDATE_H
File diff suppressed because one or more lines are too long
@@ -0,0 +1,84 @@
#include "database_update.h"
std::vector<ManifestEntry> bot_manifest_entries = {
ManifestEntry{
.version = 9035,
.description = "2022_12_04_bot_archery.sql",
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `bot_data`
ADD COLUMN `archery_setting` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `enforce_spell_settings`;
)",
},
ManifestEntry{
.version = 9036,
.description = "2023_01_19_drop_bot_views.sql",
.check = "SHOW TABLES LIKE 'vw_groups'",
.condition = "not_empty",
.match = "",
.sql = R"(
DROP VIEW vw_bot_groups;
DROP VIEW vw_bot_character_mobs;
DROP VIEW vw_groups;
DROP VIEW vw_guild_members;
DROP TABLE bot_guild_members;
)",
},
ManifestEntry{
.version = 9037,
.description = "2023_01_22_add_name_index.sql",
.check = "show index from bot_data WHERE key_name = 'name`",
.condition = "",
.match = "empty",
.sql = R"(
create index `name` on bot_data(`name`);
)",
},
ManifestEntry{
.version = 9038,
.description = "2023_02_16_add_caster_range.sql",
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'",
.condition = "",
.match = "empty",
.sql = R"(
ALTER TABLE `bot_data`
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
)",
},
ManifestEntry{
.version = 9039,
.description = "2023_03_31_remove_bot_groups.sql",
.check = "SHOW TABLES LIKE 'bot_groups'",
.condition = "",
.match = "not_empty",
.sql = R"(
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `bot_groups`;
DROP TABLE IF EXISTS `bot_group_members`;
SET FOREIGN_KEY_CHECKS = 1;
)",
},
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{
// .version = 9228,
// .description = "some_new_migration.sql",
// .check = "SHOW COLUMNS FROM `table_name` LIKE 'column_name'",
// .condition = "empty",
// .match = "",
// .sql = R"(
//
//)"
};
// see struct definitions for what each field does
// struct ManifestEntry {
// int version{}; // database version of the migration
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
// std::string check{}; // query that checks against the condition
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
// };
File diff suppressed because it is too large Load Diff
-2
View File
@@ -429,8 +429,6 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
void Database::DeleteInstance(uint16 instance_id)
{
std::string query;
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
+2 -4
View File
@@ -68,7 +68,7 @@ namespace DatabaseSchema {
{"character_spells", "id"},
{"character_task_timers", "character_id"},
{"character_tasks", "charid"},
{"character_tribute", "id"},
{"character_tribute", "character_id"},
{"completed_tasks", "charid"},
{"data_buckets", "id"},
{"faction_values", "char_id"},
@@ -256,6 +256,7 @@ namespace DatabaseSchema {
{
return {
"chatchannels",
"chatchannel_reserved_names",
"command_settings",
"content_flags",
"db_str",
@@ -392,9 +393,6 @@ namespace DatabaseSchema {
"bot_command_settings",
"bot_create_combinations",
"bot_data",
"bot_group_members",
"bot_groups",
"bot_guild_members",
"bot_heal_rotation_members",
"bot_heal_rotation_targets",
"bot_heal_rotations",
+135 -3
View File
@@ -13,6 +13,7 @@
#include <iostream>
#include <mysqld_error.h>
#include <string.h>
#include "strings.h"
#ifdef _WINDOWS
#define snprintf _snprintf
@@ -74,13 +75,13 @@ void DBcore::ping()
m_mutex->unlock();
}
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
MySQLRequestResult DBcore::QueryDatabase(const std::string& query, bool retryOnFailureOnce)
{
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
return r;
}
bool DBcore::DoesTableExist(std::string table_name)
bool DBcore::DoesTableExist(const std::string& table_name)
{
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
@@ -136,7 +137,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
/**
* Error logging
*/
if (mysql_errno(mysql) > 0 && strlen(query) > 0) {
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
}
@@ -305,3 +306,134 @@ void DBcore::SetMutex(Mutex *mutex)
DBcore::m_mutex = mutex;
}
// executes multiple statements in one query
// do not use this in application logic
// this was built and maintained for database migrations only
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
{
SetMultiStatementsOn();
BenchTimer timer;
timer.reset();
LockMutex lock(m_mutex);
// Reconnect if we are not connected before hand.
if (pStatus != Connected) {
Open();
}
auto r = MySQLRequestResult{};
int status = mysql_real_query(mysql, query.c_str(), query.length());
// process single result
if (status != 0) {
unsigned int error_number = mysql_errno(mysql);
if (error_number == CR_SERVER_GONE_ERROR) {
pStatus = Error;
}
// error logging
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
std::string error_raw = fmt::format("{}", mysql_error(mysql));
std::string mysql_err = Strings::Trim(error_raw);
std::string clean_query = Strings::Replace(query, "\n", "");
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
MYSQL_RES *res = mysql_store_result(mysql);
uint32 row_count = 0;
if (res) {
row_count = (uint32) mysql_num_rows(res);
}
r = MySQLRequestResult(
res,
(uint32) mysql_affected_rows(mysql),
row_count,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
);
std::string error_message = mysql_error(mysql);
r.SetErrorMessage(error_message);
r.SetErrorNumber(mysql_errno(mysql));
if (res) {
mysql_free_result(res);
}
SetMultiStatementsOff();
return r;
}
}
int index = 0;
// there could be a query with a semicolon in the actual data, this is best effort for
// logging / display purposes
// rare that we see this when this is only used in DDL statements
auto pieces = Strings::Split(query, ";");
// process each statement result
do {
uint32 row_count = 0;
MYSQL_RES *res = mysql_store_result(mysql);
r = MySQLRequestResult(
res,
(uint32) mysql_affected_rows(mysql),
row_count,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
);
if (pieces.size() >= index) {
auto piece = pieces[index];
LogMySQLQuery(
"{} -- ({} row{} affected) ({}s)",
piece,
r.RowsAffected(),
r.RowsAffected() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
}
if (res) {
row_count = (uint32) mysql_num_rows(res);
}
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
if ((status = mysql_next_result(mysql)) > 0) {
if (mysql_errno(mysql) > 0) {
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
}
mysql_free_result(res);
// error logging
std::string error_message = mysql_error(mysql);
r.SetErrorMessage(error_message);
r.SetErrorNumber(mysql_errno(mysql));
SetMultiStatementsOff();
// we handle errors elsewhere
return r;
}
if (res) {
mysql_free_result(res);
}
index++;
} while (status == 0);
SetMultiStatementsOff();
return r;
}
+16 -3
View File
@@ -24,7 +24,8 @@ public:
~DBcore();
eStatus GetStatus() { return pStatus; }
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
void TransactionBegin();
void TransactionCommit();
void TransactionRollback();
@@ -35,7 +36,7 @@ public:
const std::string &GetOriginHost() const;
void SetOriginHost(const std::string &origin_host);
bool DoesTableExist(std::string table_name);
bool DoesTableExist(const std::string& table_name);
void SetMySQL(const DBcore &o)
{
@@ -77,8 +78,20 @@ private:
uint32 pPort;
bool pSSL;
// allows multiple queries to be executed within the same query
// do not use this under normal operation
// we use this during database migrations only currently
void SetMultiStatementsOn()
{
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
}
// disables multiple statements to be executed in one query
void SetMultiStatementsOff()
{
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
}
};
#endif
+69 -119
View File
@@ -11,7 +11,7 @@
are required to give you total support for your newly bought product;
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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -19,131 +19,81 @@
#include "deity.h"
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
{
switch (deity_type) {
case DeityBertoxxulous:
return bit_DeityBertoxxulous;
case DeityBrellSirilis:
return bit_DeityBrellSirilis;
case DeityCazicThule:
return bit_DeityCazicThule;
case DeityErollisiMarr:
return bit_DeityErollisiMarr;
case DeityBristlebane:
return bit_DeityBristlebane;
case DeityInnoruuk:
return bit_DeityInnoruuk;
case DeityKarana:
return bit_DeityKarana;
case DeityMithanielMarr:
return bit_DeityMithanielMarr;
case DeityPrexus:
return bit_DeityPrexus;
case DeityQuellious:
return bit_DeityQuellious;
case DeityRallosZek:
return bit_DeityRallosZek;
case DeityRodcetNife:
return bit_DeityRodcetNife;
case DeitySolusekRo:
return bit_DeitySolusekRo;
case DeityTheTribunal:
return bit_DeityTheTribunal;
case DeityTunare:
return bit_DeityTunare;
case DeityVeeshan:
return bit_DeityVeeshan;
case DeityAgnostic_LB:
case DeityAgnostic:
return bit_DeityAgnostic;
default:
return bit_DeityAll;
};
case DeityBertoxxulous:
return bit_DeityBertoxxulous;
case DeityBrellSirilis:
return bit_DeityBrellSirilis;
case DeityCazicThule:
return bit_DeityCazicThule;
case DeityErollisiMarr:
return bit_DeityErollisiMarr;
case DeityBristlebane:
return bit_DeityBristlebane;
case DeityInnoruuk:
return bit_DeityInnoruuk;
case DeityKarana:
return bit_DeityKarana;
case DeityMithanielMarr:
return bit_DeityMithanielMarr;
case DeityPrexus:
return bit_DeityPrexus;
case DeityQuellious:
return bit_DeityQuellious;
case DeityRallosZek:
return bit_DeityRallosZek;
case DeityRodcetNife:
return bit_DeityRodcetNife;
case DeitySolusekRo:
return bit_DeitySolusekRo;
case DeityTheTribunal:
return bit_DeityTheTribunal;
case DeityTunare:
return bit_DeityTunare;
case DeityVeeshan:
return bit_DeityVeeshan;
case DeityAgnostic_LB:
case DeityAgnostic:
return bit_DeityAgnostic;
default:
return bit_DeityAll;
}
}
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
{
switch (deity_type_bit) {
case bit_DeityAgnostic:
return DeityAgnostic;
case bit_DeityBertoxxulous:
return DeityBertoxxulous;
case bit_DeityBrellSirilis:
return DeityBrellSirilis;
case bit_DeityCazicThule:
return DeityCazicThule;
case bit_DeityErollisiMarr:
return DeityErollisiMarr;
case bit_DeityBristlebane:
return DeityBristlebane;
case bit_DeityInnoruuk:
return DeityInnoruuk;
case bit_DeityKarana:
return DeityKarana;
case bit_DeityMithanielMarr:
return DeityMithanielMarr;
case bit_DeityPrexus:
return DeityPrexus;
case bit_DeityQuellious:
return DeityQuellious;
case bit_DeityRallosZek:
return DeityRallosZek;
case bit_DeityRodcetNife:
return DeityRodcetNife;
case bit_DeitySolusekRo:
return DeitySolusekRo;
case bit_DeityTheTribunal:
return DeityTheTribunal;
case bit_DeityTunare:
return DeityTunare;
case bit_DeityVeeshan:
return DeityVeeshan;
default:
return DeityUnknown;
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
{ DeityAgnostic, "Agnostic" },
{ DeityAgnostic_LB, "Agnostic" },
{ DeityBertoxxulous, "Bertoxxulous" },
{ DeityBrellSirilis, "Brell Serilis" },
{ DeityBristlebane, "Bristlebane" },
{ DeityCazicThule, "Cazic-Thule" },
{ DeityErollisiMarr, "Erollisi Marr" },
{ DeityInnoruuk, "Innoruuk" },
{ DeityKarana, "Karana" },
{ DeityMithanielMarr, "Mithaniel Marr" },
{ DeityPrexus, "Prexus" },
{ DeityQuellious, "Quellious" },
{ DeityRallosZek, "Rallos Zek" },
{ DeityRodcetNife, "Rodcet Nife" },
{ DeitySolusekRo, "Solusek Ro" },
{ DeityTheTribunal, "The Tribunal" },
{ DeityTunare, "Tunare" },
{ DeityVeeshan, "Veeshan" }
};
return deity_map;
}
const char* EQ::deity::DeityName(DeityType deity_type)
std::string EQ::deity::GetDeityName(DeityType deity_type)
{
switch (deity_type) {
case DeityBertoxxulous:
return "Bertoxxulous";
case DeityBrellSirilis:
return "Brell Serilis";
case DeityCazicThule:
return "Cazic-Thule";
case DeityErollisiMarr:
return "Erollisi Marr";
case DeityBristlebane:
return "Bristlebane";
case DeityInnoruuk:
return "Innoruuk";
case DeityKarana:
return "Karana";
case DeityMithanielMarr:
return "Mithaniel Marr";
case DeityPrexus:
return "Prexus";
case DeityQuellious:
return "Quellious";
case DeityRallosZek:
return "Rallos Zek";
case DeityRodcetNife:
return "Rodcet Nife";
case DeitySolusekRo:
return "Solusek Ro";
case DeityTheTribunal:
return "The Tribunal";
case DeityTunare:
return "Tunare";
case DeityVeeshan:
return "Veeshan";
case DeityAgnostic_LB:
case DeityAgnostic:
return "Agnostic";
default:
return "Unknown";
};
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
return EQ::deity::GetDeityMap().find(deity_type)->second;
}
return std::string();
}
+22 -21
View File
@@ -21,6 +21,8 @@
#define COMMON_DEITY_H
#include "types.h"
#include <map>
#include <string>
namespace EQ
@@ -49,30 +51,29 @@ namespace EQ
};
enum DeityTypeBit : uint32 {
bit_DeityNone = 0x00000000,
bit_DeityAgnostic = 0x00000001,
bit_DeityBertoxxulous = 0x00000002,
bit_DeityBrellSirilis = 0x00000004,
bit_DeityCazicThule = 0x00000008,
bit_DeityErollisiMarr = 0x00000010,
bit_DeityBristlebane = 0x00000020,
bit_DeityInnoruuk = 0x00000040,
bit_DeityKarana = 0x00000080,
bit_DeityAgnostic = 0x00000001,
bit_DeityBertoxxulous = 0x00000002,
bit_DeityBrellSirilis = 0x00000004,
bit_DeityCazicThule = 0x00000008,
bit_DeityErollisiMarr = 0x00000010,
bit_DeityBristlebane = 0x00000020,
bit_DeityInnoruuk = 0x00000040,
bit_DeityKarana = 0x00000080,
bit_DeityMithanielMarr = 0x00000100,
bit_DeityPrexus = 0x00000200,
bit_DeityQuellious = 0x00000400,
bit_DeityRallosZek = 0x00000800,
bit_DeityRodcetNife = 0x00001000,
bit_DeitySolusekRo = 0x00002000,
bit_DeityTheTribunal = 0x00004000,
bit_DeityTunare = 0x00008000,
bit_DeityVeeshan = 0x00010000,
bit_DeityAll = 0xFFFFFFFF
bit_DeityPrexus = 0x00000200,
bit_DeityQuellious = 0x00000400,
bit_DeityRallosZek = 0x00000800,
bit_DeityRodcetNife = 0x00001000,
bit_DeitySolusekRo = 0x00002000,
bit_DeityTheTribunal = 0x00004000,
bit_DeityTunare = 0x00008000,
bit_DeityVeeshan = 0x00010000,
bit_DeityAll = UINT32_MAX
};
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
extern const char* DeityName(DeityType deity_type);
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
extern std::string GetDeityName(DeityType deity_type);
extern const std::map<DeityType, std::string>& GetDeityMap();
} /*deity*/
-6
View File
@@ -27,9 +27,6 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// payload
Json::Value p;
@@ -96,9 +93,6 @@ void Discord::SendPlayerEventMessage(
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
if (payload.empty()) {
+2 -2
View File
@@ -37,7 +37,7 @@ void DiscordManager::ProcessMessageQueue()
message,
webhook.webhook_url
);
message = "";
message.clear();
}
message += m;
@@ -51,7 +51,7 @@ void DiscordManager::ProcessMessageQueue()
webhook.webhook_url
);
}
message = "";
message.clear();
}
}
// final flush
+34 -33
View File
@@ -197,11 +197,11 @@ const std::map<int, std::string>& EQ::constants::GetLanguageMap()
std::string EQ::constants::GetLanguageName(int language_id)
{
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
return EQ::constants::GetLanguageMap().find(language_id)->second;
if (!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
return std::string();
}
return std::string();
return EQ::constants::GetLanguageMap().find(language_id)->second;
}
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
@@ -220,11 +220,11 @@ const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
{
if (EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
if (!EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
return std::string();
}
return std::string();
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
}
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
@@ -243,11 +243,11 @@ const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
{
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
if (!EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
return std::string();
}
return std::string();
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
}
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
@@ -365,11 +365,11 @@ const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
{
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
if (!EQ::ValueWithin(faction_consider_level, ConsiderLevel::Ally, ConsiderLevel::Scowls)) {
return std::string();;
}
return std::string();
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
}
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
@@ -386,11 +386,11 @@ const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
{
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
if (!EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
return std::string();
}
return std::string();
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
}
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
@@ -407,11 +407,11 @@ const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
{
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
if (!EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
return std::string();
}
return std::string();
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
}
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
@@ -429,11 +429,11 @@ const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
{
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
if (!EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
return std::string();
}
return std::string();
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
}
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
@@ -507,11 +507,12 @@ const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
std::string EQ::constants::GetObjectTypeName(int object_type)
{
if (EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
return std::string();
}
return std::string();
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
@@ -527,11 +528,11 @@ const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
{
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
if (!EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
return std::string();
}
return std::string();
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
@@ -553,11 +554,11 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
{
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
if (!EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
return std::string();
}
return std::string();
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
@@ -573,9 +574,9 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
{
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
if (!EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
return std::string();
}
return std::string();
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
}
+25
View File
@@ -593,4 +593,29 @@ enum class ApplySpellType {
Raid
};
namespace HeroicBonusBucket
{
const std::string WisMaxMana = "HWIS-MaxMana";
const std::string WisManaRegen = "HWIS-ManaRegen";
const std::string WisHealAmt = "HWIS-HealAmt";
const std::string IntMaxMana = "HINT-MaxMana";
const std::string IntManaRegen = "HINT-ManaRegen";
const std::string IntSpellDmg = "HINT-SpellDmg";
const std::string StrMeleeDamage = "HSTR-MeleeDamage";
const std::string StrShieldAC = "HSTR-ShieldAC";
const std::string StrMaxEndurance = "HSTR-MaxEndurance";
const std::string StrEnduranceRegen = "HSTR-EnduranceRegen";
const std::string StaMaxHP = "HSTA-MaxHP";
const std::string StaHPRegen = "HSTA-HPRegen";
const std::string StaMaxEndurance = "HSTA-MaxEndurance";
const std::string StaEnduranceRegen = "HSTA-EnduranceRegen";
const std::string AgiAvoidance = "HAGI-Avoidance";
const std::string AgiMaxEndurance = "HAGI-MaxEndurance";
const std::string AgiEnduranceRegen = "HAGI-EnduranceRegen";
const std::string DexRangedDamage = "HDEX-RangedDamage";
const std::string DexMaxEndurance = "HDEX-MaxEndurance";
const std::string DexEnduranceRegen = "HDEX-EnduranceRegen";
}
#endif /*COMMON_EMU_CONSTANTS_H*/
+3
View File
@@ -316,6 +316,7 @@ N(OP_LootRequest),
N(OP_ManaChange),
N(OP_ManaUpdate),
N(OP_MarkNPC),
N(OP_MarkRaidNPC),
N(OP_Marquee),
N(OP_MemorizeSpell),
N(OP_Mend),
@@ -398,6 +399,8 @@ N(OP_PVPLeaderBoardRequest),
N(OP_PVPStats),
N(OP_QueryResponseThing),
N(OP_QueryUCSServerStatus),
N(OP_RaidDelegateAbility),
N(OP_RaidClearNPCMarks),
N(OP_RaidInvite),
N(OP_RaidJoin),
N(OP_RaidUpdate),
+7
View File
@@ -1045,4 +1045,11 @@ enum ResurrectionActions
Accept
};
enum ScribeSpellActions
{
Scribe,
Memorize,
Unmemorize
};
#endif /*COMMON_EQ_CONSTANTS_H*/
+1 -1
View File
@@ -129,7 +129,7 @@ namespace EQ
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
InventoryTypeSize_Struct InventoryTypeSize,
const InventoryTypeSize_Struct& InventoryTypeSize,
uint64 EquipmentBitmask,
uint64 GeneralBitmask,
uint64 CursorBitmask,
+1 -138
View File
@@ -236,26 +236,6 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
return size+OpCodeBytes;
}
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
opcode(op)
{
uint32 offset;
opcode=ntohs(*(const uint16 *)buf);
offset=2;
if (len-offset) {
pBuffer= new unsigned char[len-offset];
memcpy(pBuffer,buf+offset,len-offset);
size=len-offset;
} else {
pBuffer=nullptr;
size=0;
}
OpMgr=&RawOpcodeManager;
}*/
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
{
bool result=false;
@@ -287,74 +267,6 @@ bool result=false;
}
/*
this is the code to do app-layer combining, instead of protocol layer.
this was taken out due to complex interactions with the opcode manager,
and will require a bit more thinking (likely moving into EQStream) to
get running again... but might be a good thing some day.
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
{
uint32 newsize=0, offset=0;
unsigned char *tmpbuffer=nullptr;
if (opcode!=OP_AppCombined) {
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
offset=0;
if (size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(size);
offset+=1;
} else {
tmpbuffer[offset++]=size;
}
offset+=serialize(tmpbuffer+offset);
} else {
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
memcpy(tmpbuffer,pBuffer,size);
offset=size;
}
if (rhs->size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
offset+=1;
} else {
tmpbuffer[offset++]=rhs->size;
}
offset+=rhs->serialize(tmpbuffer+offset);
size=offset;
opcode=OP_AppCombined;
delete[] pBuffer;
pBuffer=tmpbuffer;
return true;
}
*/
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
{
bool valid=false;
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
valid=true;
} else {
uint16 comp_crc=CRC16(buffer,length-2,Key);
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
#ifdef EQN_DEBUG
if (packet_crc && comp_crc != packet_crc) {
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
}
#endif
valid = (!packet_crc || comp_crc == packet_crc);
}
return valid;
}
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
uint32 newlen=0;
@@ -403,55 +315,6 @@ uint32 flag_offset=1,newlength;
return newlength;
}
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
{
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=DecodeKey;
unsigned char *test=(unsigned char *)malloc(size);
buffer+=2;
size-=2;
int i;
for (i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = (*(int*)&buffer[i]);
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
{
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=EncodeKey;
char *test=(char*)malloc(size);
int i;
buffer+=2;
size-=2;
for ( i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = pt;
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
EQApplicationPacket *EQApplicationPacket::Copy() const {
return(new EQApplicationPacket(*this));
}
@@ -515,4 +378,4 @@ std::string DumpPacketToString(const EQApplicationPacket* app){
std::ostringstream out;
out << DumpPacketHexToString(app->pBuffer, app->size);
return out.str();
}
}
-3
View File
@@ -80,11 +80,8 @@ public:
protected:
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
uint16 GetRawOpcode() const { return(opcode); }
+23 -4
View File
@@ -1793,6 +1793,17 @@ struct GMSummon_Struct {
/*104*/ uint32 unknown2; // E0 E0 56 00
};
struct GMFind_Struct {
char charname[64];
char gmname[64];
uint32 success;
uint32 zoneID;
float x;
float y;
float z;
uint32 unknown2;
};
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
/* 0*/ char charname[64];
@@ -4094,7 +4105,9 @@ struct UpdateLeadershipAA_Struct {
enum
{
GroupLeadershipAbility_MarkNPC = 0
GroupLeadershipAbility_MarkNPC = 0,
RaidLeadershipAbility_MarkNPC = 16,
RaidLeadershipAbility_MainAssist = 19
};
struct DoGroupLeadershipAbility_Struct
@@ -4138,8 +4151,10 @@ struct InspectBuffs_Struct {
struct RaidGeneral_Struct {
/*00*/ uint32 action; //=10
/*04*/ char player_name[64]; //should both be the player's name
/*64*/ char leader_name[64];
/*132*/ uint32 parameter;
/*68*/ uint32 unknown1;
/*72*/ char leader_name[64];
/*136*/ uint32 parameter;
/*200*/ char note[64];
};
struct RaidAddMember_Struct {
@@ -5522,7 +5537,11 @@ struct ServerLootItem_Struct {
uint32 aug_4; // uint32 aug_4;
uint32 aug_5; // uint32 aug_5;
uint32 aug_6; // uint32 aug_5;
uint8 attuned;
bool attuned;
std::string custom_data;
uint32 ornamenticon {};
uint32 ornamentidfile {};
uint32 ornament_hero_model {};
uint16 trivial_min_level;
uint16 trivial_max_level;
uint16 npc_min_level;
+2 -2
View File
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
}
}
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
void EQStreamIdentifier::RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
auto p = new Patch;
p->signature = sig;
p->name = name;
@@ -145,7 +145,7 @@ void EQStreamIdentifier::Process() {
}
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
m_streams.push_back(Record(eqs));
m_streams.emplace_back(Record(eqs));
eqs = nullptr;
}
+1 -1
View File
@@ -18,7 +18,7 @@ public:
~EQStreamIdentifier();
//registration interface.
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
void RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
//main processing interface
void Process();
-3
View File
@@ -23,9 +23,6 @@
EQDB EQDB::s_EQDB;
EQDB::EQDB() {
}
unsigned int EQDB::field_count() {
return mysql_field_count(mysql_ref);
}
+1 -1
View File
@@ -27,7 +27,7 @@
//this is the main object exported to perl.
class EQDB {
EQDB();
EQDB() = default;
public:
static EQDB *Singleton() { return(&s_EQDB); }
+24 -18
View File
@@ -34,13 +34,13 @@ void EQEmuConfig::parse_config()
LongName = _root["server"]["world"].get("longname", "").asString();
WorldAddress = _root["server"]["world"].get("address", "").asString();
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString());
SharedKey = _root["server"]["world"].get("key", "").asString();
LoginCount = 0;
if (_root["server"]["world"]["loginserver"].isObject()) {
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
LoginPort = Strings::ToInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString());
LoginLegacy = false;
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
@@ -63,7 +63,7 @@ void EQEmuConfig::parse_config()
auto loginconfig = new LoginConfig;
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
loginconfig->LoginPort = Strings::ToInt(_root["server"]["world"][str].get("port", "5998").asString().c_str());
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString());
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
@@ -85,16 +85,22 @@ void EQEmuConfig::parse_config()
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
auto_database_updates = false;
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
auto_database_updates = true;
}
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = Strings::ToInt(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = Strings::ToInt(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString());
TelnetEnabled = false;
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
WorldHTTPPort = Strings::ToInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString());
WorldHTTPEnabled = false;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
@@ -109,9 +115,9 @@ void EQEmuConfig::parse_config()
* UCS
*/
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
ChatPort = Strings::ToInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
MailPort = Strings::ToInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
/**
* Database
@@ -119,7 +125,7 @@ void EQEmuConfig::parse_config()
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
DatabasePort = Strings::ToInt(_root["server"]["database"].get("port", "3306").asString().c_str());
DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString());
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
/**
@@ -128,14 +134,14 @@ void EQEmuConfig::parse_config()
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
ContentDbPort = Strings::ToInt(_root["server"]["content_database"].get("port", 0).asString().c_str());
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString());
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
/**
* QS
*/
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
QSDatabasePort = Strings::ToInt(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString());
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
@@ -143,9 +149,9 @@ void EQEmuConfig::parse_config()
/**
* Zones
*/
DefaultStatus = Strings::ToInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
ZonePortLow = Strings::ToInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
ZonePortHigh = Strings::ToInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString());
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString());
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString());
/**
* Files
@@ -175,10 +181,10 @@ void EQEmuConfig::parse_config()
/**
* Launcher
*/
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString());
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString());
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString());
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString());
#ifdef WIN32
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
#else
+2 -6
View File
@@ -120,6 +120,8 @@ class EQEmuConfig
uint16 ZonePortHigh;
uint8 DefaultStatus;
bool auto_database_updates;
// uint16 DynamicCount;
// map<string,uint16> StaticZones;
@@ -147,12 +149,6 @@ class EQEmuConfig
return (_config);
}
// Allow the use to set the conf file to be used.
static void SetConfigFile(std::string file)
{
EQEmuConfig::ConfigFile = file;
}
// Load the config
static bool LoadConfig(const std::string& path = "")
{
+94 -24
View File
@@ -104,9 +104,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* RFC 5424
*/
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
/**
* Set Category enabled status on defaults
@@ -187,9 +187,10 @@ void EQEmuLogSys::ProcessLogWrite(
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Crash:
case Logs::Error:
case Logs::MySQLError:
case Logs::QuestErrors:
case Logs::Error:
return Chat::Red;
case Logs::MySQLQuery:
case Logs::Debug:
@@ -199,8 +200,6 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
case Logs::Commands:
case Logs::Mercenaries:
return Chat::Magenta;
case Logs::Crash:
return Chat::Red;
default:
return Chat::Yellow;
}
@@ -220,7 +219,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
int line
)
{
bool is_error = (
bool is_error = (
log_category == Logs::LogCategory::Error ||
log_category == Logs::LogCategory::MySQLError ||
log_category == Logs::LogCategory::Crash ||
@@ -262,7 +261,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
}
if (log_category == Logs::LogCategory::MySQLQuery) {
auto s = Strings::Split(message, "--");
auto s = Strings::Split(message, "--");
if (s.size() > 1) {
std::string query = Strings::Trim(s[0]);
std::string meta = Strings::Trim(s[1]);
@@ -298,19 +297,76 @@ void EQEmuLogSys::ProcessConsoleMessage(
}
}
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::fgB::gray
<< "] "
;
// color matching in []
// ex: [<red>variable] would produce [variable] with red inside brackets
std::map<std::string, rang::fgB> colors = {
{"<black>", rang::fgB::black},
{"<green>", rang::fgB::green},
{"<yellow>", rang::fgB::yellow},
{"<blue>", rang::fgB::blue},
{"<magenta>", rang::fgB::magenta},
{"<cyan>", rang::fgB::cyan},
{"<gray>", rang::fgB::gray},
{"<red>", rang::fgB::red},
};
bool match_color = false;
for (auto &c: colors) {
if (Strings::Contains(e, c.first)) {
e = Strings::Replace(e, c.first, "");
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< c.second
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
match_color = true;
}
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
// string match to colors
std::map<std::string, rang::fgB> matches = {
{"missing", rang::fgB::red},
{"error", rang::fgB::red},
{"ok", rang::fgB::green},
};
for (auto &c: matches) {
if (Strings::Contains(e, c.first)) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< c.second
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
match_color = true;
}
}
// if we don't match a color in either the string matching or
// the color tag matching, we default to yellow inside brackets
// if uppercase, does not get colored
if (!match_color) {
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
}
}
}
else {
@@ -390,6 +446,8 @@ void EQEmuLogSys::Out(
// remove this when we remove all legacy logs
bool ignore_log_legacy_format = (
log_category == Logs::Netcode ||
log_category == Logs::MySQLQuery ||
log_category == Logs::MySQLError ||
log_category == Logs::PacketServerClient ||
log_category == Logs::PacketClientServer ||
log_category == Logs::PacketServerToServer
@@ -524,6 +582,8 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
*/
void EQEmuLogSys::SilenceConsoleLogging()
{
std::copy(std::begin(log_settings), std::end(log_settings), std::begin(pre_silence_settings));
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
log_settings[log_index].log_to_console = 0;
log_settings[log_index].is_category_enabled = 0;
@@ -537,10 +597,7 @@ void EQEmuLogSys::SilenceConsoleLogging()
*/
void EQEmuLogSys::EnableConsoleLogging()
{
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
log_settings[log_index].log_to_console = Logs::General;
log_settings[log_index].is_category_enabled = 1;
}
std::copy(std::begin(pre_silence_settings), std::end(pre_silence_settings), std::begin(log_settings));
}
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
@@ -742,3 +799,16 @@ EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
return this;
}
void EQEmuLogSys::DisableMySQLErrorLogs()
{
log_settings[Logs::MySQLError].log_to_file = 0;
log_settings[Logs::MySQLError].log_to_console = 0;
log_settings[Logs::MySQLError].log_to_gmsay = 0;
}
void EQEmuLogSys::EnableMySQLErrorLogs()
{
log_settings[Logs::MySQLError].log_to_file = 1;
log_settings[Logs::MySQLError].log_to_console = 1;
log_settings[Logs::MySQLError].log_to_gmsay = 1;
}
+8
View File
@@ -137,6 +137,7 @@ namespace Logs {
Bugs,
QuestErrors,
PlayerEvents,
DataBuckets,
MaxCategoryID /* Don't Remove this */
};
@@ -233,6 +234,7 @@ namespace Logs {
"Bugs",
"QuestErrors",
"PlayerEvents",
"DataBuckets",
};
}
@@ -324,6 +326,9 @@ public:
*/
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
// temporary bucket to re-load after silencing
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
struct LogEnabled {
bool log_to_file_enabled;
bool log_to_console_enabled;
@@ -374,6 +379,9 @@ public:
[[nodiscard]] const std::string &GetLogPath() const;
EQEmuLogSys * SetLogPath(const std::string &log_path);
void DisableMySQLErrorLogs();
void EnableMySQLErrorLogs();
private:
// reference to database
+10
View File
@@ -794,6 +794,16 @@
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDataBuckets(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::DataBuckets))\
OutF(LogSys, Logs::General, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDataBucketsDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DataBuckets))\
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.IsLogEnabled(debug_level, log_category))\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
+1 -5
View File
@@ -58,10 +58,6 @@ EQTime::EQTime()
SetCurrentEQTimeOfDay(start, time(0));
}
EQTime::~EQTime()
{
}
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
//This function was written by the ShowEQ Project.
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
@@ -203,4 +199,4 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
t->month, t->day, t->year, t->hour, t->minute);
buf[127] = '\0';
str = buf;
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ public:
//Constructor/destructor
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
EQTime();
~EQTime();
~EQTime() = default;
//Get functions
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
+1 -1
View File
@@ -38,7 +38,7 @@ namespace EQ
_running = true;
for (size_t i = 0; i < threads; ++i) {
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
_threads.emplace_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
}
}
+4 -10
View File
@@ -333,7 +333,10 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
break;
}
case PlayerEvent::FISH_FAILURE: {
case PlayerEvent::FISH_FAILURE:
case PlayerEvent::FORAGE_FAILURE:
case PlayerEvent::WENT_ONLINE:
case PlayerEvent::WENT_OFFLINE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
@@ -348,10 +351,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
break;
}
case PlayerEvent::FORAGE_FAILURE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::FORAGE_SUCCESS: {
PlayerEvent::ForageSuccessEvent n{};
std::stringstream ss;
@@ -550,11 +549,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
break;
}
case PlayerEvent::WENT_ONLINE:
case PlayerEvent::WENT_OFFLINE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::MERCHANT_PURCHASE: {
PlayerEvent::MerchantPurchaseEvent n{};
std::stringstream ss;
+1 -1
View File
@@ -384,7 +384,7 @@ namespace PlayerEvent {
};
struct AAPurchasedEvent {
int32 aa_id;
uint32 aa_id;
int32 aa_cost;
int32 aa_previous_id;
int32 aa_next_id;
+18 -32
View File
@@ -218,14 +218,14 @@ enum { //some random constants
#define HARD_LEVEL_CAP 127
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
#define USE_NPC_RANGE2 200*200 //arbitrary right now
#define USE_NPC_RANGE2 40000 //arbitrary right now
// Squared range for rampage 75.0 * 75.0 for now
#define NPC_RAMPAGE_RANGE2 5625.0f
//the formula for experience for killing a mob.
//level is the only valid variable to use
#define EXP_FORMULA level*level*75*35/10
#define EXP_FORMULA (level * level * 75 * 35 / 10)
#define HIGHEST_AA_VALUE 35
@@ -240,36 +240,22 @@ enum { //some random constants
//Some hard coded statuses from commands and other places:
enum {
minStatusToBeGM = 40,
minStatusToUseGMCommands = 80,
minStatusToKick = 150,
minStatusToAvoidFalling = 100,
minStatusToHaveInvalidSpells = 80,
minStatusToHaveInvalidSkills = 80,
minStatusToIgnoreZoneFlags = 80,
minStatusToBeGM = 40,
minStatusToUseGMCommands = 80,
minStatusToKick = 150,
minStatusToAvoidFalling = 100,
minStatusToIgnoreZoneFlags = 80,
minStatusToSeeOthersZoneFlags = 80,
minStatusToEditOtherGuilds = 80,
commandMovecharSelfOnly = 80, //below this == only self move allowed
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
commandZoneToSpecials = 80, //zone to cshome, out of load zones
commandToggleAI = 250, //can turn NPC AI on and off
commandCastSpecials = 100, //can cast special spells
commandInstacast = 100, //insta-cast all #casted spells
commandLevelAboveCap = 100, //can #level players above level cap
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
commandSetSkillsOther = 100, //ability to setskills on others
commandRaceOthers = 100, //ability to #race on others
commandGenderOthers = 100, //ability to #gender on others
commandTextureOthers = 100, //ability to #texture on others
commandDoAnimOthers = 100, //can #doanim on others
commandLockZones = 101, //can lock or unlock zones
commandEditPlayerCorpses = 150, //can Edit Player Corpses
commandChangeFlags = 200, //ability to set/refresh flags
commandBanPlayers = 100, //can set bans on players
commandChangeDatarate = 201, //edit client's data rate
commandZoneToCoords = 0, //can #zone with coords
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
commandInvSnapshot = 150 //ability to clear/restore snapshots
minStatusToEditOtherGuilds = 80,
commandMovecharSelfOnly = 80, //below this == only self move allowed
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
commandCastSpecials = 100, //can cast special spells
commandInstacast = 100, //insta-cast all #casted spells
commandDoAnimOthers = 100, //can #doanim on others
commandLockZones = 101, //can lock or unlock zones
commandEditPlayerCorpses = 150, //can Edit Player Corpses
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
commandInvSnapshot = 150 //ability to clear/restore snapshots
};
@@ -295,7 +281,7 @@ Developer configuration
#define COMMON_PROFILE
#define PROFILE_DUMP_TIME 3*60
#define PROFILE_DUMP_TIME 180
#endif //EQPROFILE
+24
View File
@@ -37,6 +37,7 @@
#include <fmt/format.h>
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
@@ -80,3 +81,26 @@ std::string File::GetCwd()
{
return fs::current_path().string();
}
FileContentsResult File::GetContents(const std::string &file_name)
{
std::string error;
std::ifstream f;
f.open(file_name);
std::string line;
std::string lines;
if (f.is_open()) {
while (f) {
std::getline(f, line);
lines += line + "\n";
}
}
else {
error = fmt::format("Couldn't open file [{}]", file_name);
}
return FileContentsResult{
.contents = lines,
.error = error,
};
}
+6
View File
@@ -25,10 +25,16 @@
namespace fs = std::filesystem;
struct FileContentsResult {
std::string contents;
std::string error;
};
class File {
public:
static bool Exists(const std::string &name);
static void Makedir(const std::string& directory_name);
static FileContentsResult GetContents(const std::string &file_name);
static std::string FindEqemuConfigPath();
static std::string GetCwd();
};
+14 -18
View File
@@ -61,7 +61,7 @@ bool BaseGuildManager::LoadGuilds() {
}
for (auto row=results.begin();row!=results.end();++row)
_CreateGuild(Strings::ToInt(row[0]), row[1], Strings::ToInt(row[2]), Strings::ToInt(row[3]), row[4], row[5], row[6], row[7]);
_CreateGuild(Strings::ToUnsignedInt(row[0]), row[1], Strings::ToUnsignedInt(row[2]), Strings::ToUnsignedInt(row[3]), row[4], row[5], row[6], row[7]);
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
@@ -75,8 +75,8 @@ bool BaseGuildManager::LoadGuilds() {
for (auto row=results.begin();row!=results.end();++row)
{
uint32 guild_id = Strings::ToInt(row[0]);
uint8 rankn = Strings::ToInt(row[1]);
uint32 guild_id = Strings::ToUnsignedInt(row[0]);
uint8 rankn = Strings::ToUnsignedInt(row[1]);
if(rankn > GUILD_MAX_RANK) {
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
@@ -131,7 +131,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
auto row = results.begin();
info = _CreateGuild(guild_id, row[0], Strings::ToInt(row[1]), Strings::ToInt(row[2]), row[3], row[4], row[5], row[6]);
info = _CreateGuild(guild_id, row[0], Strings::ToUnsignedInt(row[1]), Strings::ToUnsignedInt(row[2]), row[3], row[4], row[5], row[6]);
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
@@ -144,7 +144,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
for (auto row=results.begin();row!=results.end();++row)
{
uint8 rankn = Strings::ToInt(row[1]);
uint8 rankn = Strings::ToUnsignedInt(row[1]);
if(rankn > GUILD_MAX_RANK) {
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
@@ -787,9 +787,7 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
auto row = results.begin();
bool IsBanker = Strings::ToInt(row[0]);
return IsBanker;
return Strings::ToBool(row[0]);
}
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
@@ -817,9 +815,7 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
auto row = results.begin();
bool IsAlt = Strings::ToInt(row[0]);
return IsAlt;
return Strings::ToBool(row[0]);
}
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
@@ -873,18 +869,18 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
//fields from `characer_`
into.char_id = Strings::ToInt(row[0]);
into.char_id = Strings::ToUnsignedInt(row[0]);
into.char_name = row[1];
into.class_ = Strings::ToInt(row[2]);
into.level = Strings::ToInt(row[3]);
into.class_ = Strings::ToUnsignedInt(row[2]);
into.level = Strings::ToUnsignedInt(row[3]);
into.time_last_on = Strings::ToUnsignedInt(row[4]);
into.zone_id = Strings::ToInt(row[5]);
into.zone_id = Strings::ToUnsignedInt(row[5]);
//fields from `guild_members`, leave at defaults if missing
into.guild_id = row[6] ? Strings::ToInt(row[6]) : GUILD_NONE;
into.rank = row[7] ? Strings::ToInt(row[7]) : (GUILD_MAX_RANK+1);
into.guild_id = row[6] ? Strings::ToUnsignedInt(row[6]) : GUILD_NONE;
into.rank = row[7] ? Strings::ToUnsignedInt(row[7]) : (GUILD_MAX_RANK+1);
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
into.total_tribute = row[9] ? Strings::ToInt(row[9]) : 0;
into.total_tribute = row[9] ? Strings::ToUnsignedInt(row[9]) : 0;
into.last_tribute = row[10]? Strings::ToUnsignedInt(row[10]) : 0; //timestamp
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
into.public_note = row[12]? row[12] : "";
+4 -4
View File
@@ -6690,7 +6690,7 @@ static WSInit wsinit_;
if (params.empty()) { return Get(path, headers); }
std::string path_with_query = append_query_params(path, params);
return Get(path_with_query.c_str(), headers, progress);
return Get(path_with_query, headers, progress);
}
inline Result ClientImpl::Get(const std::string &path, const Params &params,
@@ -6710,7 +6710,7 @@ static WSInit wsinit_;
}
std::string path_with_query = append_query_params(path, params);
return Get(path_with_query.c_str(), headers, response_handler,
return Get(path_with_query, headers, response_handler,
content_receiver, progress);
}
@@ -6807,7 +6807,7 @@ static WSInit wsinit_;
std::string content_type;
const auto &body = detail::serialize_multipart_formdata(
items, detail::make_multipart_data_boundary(), content_type);
return Post(path, headers, body, content_type.c_str());
return Post(path, headers, body, content_type);
}
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
@@ -6820,7 +6820,7 @@ static WSInit wsinit_;
std::string content_type;
const auto &body =
detail::serialize_multipart_formdata(items, boundary, content_type);
return Post(path, headers, body, content_type.c_str());
return Post(path, headers, body, content_type);
}
inline Result ClientImpl::Put(const std::string &path) {
+9 -8
View File
@@ -353,7 +353,7 @@ bool EQ::InventoryProfile::SwapItem(
fail_state = swapRaceClass;
return false;
}
if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) {
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
fail_state = swapDeity;
return false;
}
@@ -379,7 +379,7 @@ bool EQ::InventoryProfile::SwapItem(
fail_state = swapRaceClass;
return false;
}
if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) {
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
fail_state = swapDeity;
return false;
}
@@ -412,11 +412,12 @@ bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
// If there are no charges left on the item,
if (item_to_delete->GetCharges() <= 0) {
// If the item is stackable (e.g arrows), or
// the item is not stackable, and is not a charged item, or is expendable, delete it
if (item_to_delete->IsStackable() ||
(!item_to_delete->IsStackable() &&
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
) {
// the item is not a charged item, or is expendable, delete it
if (
item_to_delete->IsStackable() ||
item_to_delete->GetItem()->MaxCharges == 0 ||
item_to_delete->IsExpendable()
) {
// Item can now be destroyed
InventoryProfile::MarkDirty(item_to_delete);
return true;
@@ -1443,7 +1444,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
}
if (result == INVALID_INDEX) {
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
LogError("Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
}
+6 -6
View File
@@ -203,12 +203,12 @@ namespace EQ
void dumpBankItems();
void dumpSharedBankItems();
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
std::string GetCustomItemData(int16 slot_id, std::string identifier);
static const int GetItemStatValue(uint32 item_id, std::string identifier);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
protected:
///////////////////////////////
// Protected Methods
+165 -160
View File
@@ -131,7 +131,7 @@ namespace EQ
Mounts?
Ornamentations?
GuildBanners?
Collectible?
Collectible?
Placeable?
(others?)
*/
@@ -355,181 +355,186 @@ namespace EQ
struct ItemData {
// Non packet based fields
uint8 MinStatus;
uint8 MinStatus {};
// Packet based fields
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
char Name[64]; // Name
char Lore[80]; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
char IDFile[30]; // Visible model
uint32 ID; // Unique ID (also PK for DB)
int32 Weight; // Item weight * 10
uint8 NoRent; // No Rent: 0=norent, 255=not norent
uint8 NoDrop; // No Drop: 0=nodrop, 255=not nodrop
uint8 Size; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
uint32 Slots; // Bitfield for which slots this item can be used in
uint32 Price; // Item cost (?)
uint32 Icon; // Icon Number
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag;
bool ArtifactFlag;
bool SummonedFlag;
uint8 FVNoDrop; // Firiona Vie nodrop flag
uint32 Favor; // Individual favor
uint32 GuildFavor; // Guild favor
uint32 PointType;
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
char Name[64] {}; // Name
char Lore[80] {}; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
char IDFile[30] {}; // Visible model
uint32 ID {}; // Unique ID (also PK for DB)
int32 Weight {}; // Item weight * 10
uint8 NoRent{} ; // No Rent: 0=norent, 255=not norent
uint8 NoDrop {}; // No Drop: 0=nodrop, 255=not nodrop
uint8 Size {}; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
uint32 Slots {}; // Bitfield for which slots this item can be used in
uint32 Price {}; // Item cost (?)
uint32 Icon {}; // Icon Number
int32 LoreGroup {}; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
bool LoreFlag {}; // This will be true if LoreGroup is non-zero
bool PendingLoreFlag {};
bool ArtifactFlag {};
bool SummonedFlag {};
uint8 FVNoDrop {}; // Firiona Vie nodrop flag
uint32 Favor {}; // Individual favor
uint32 GuildFavor {}; // Guild favor
uint32 PointType {};
//uint32 Unk117;
//uint32 Unk118;
//uint32 Unk121;
//uint32 Unk124;
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR; // 0->100
uint8 BagType {}; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
uint8 BagSlots {}; // Number of slots: can only be 2, 4, 6, 8, or 10
uint8 BagSize {}; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
uint8 BagWR {}; // 0->100
bool BenefitFlag;
bool Tradeskills; // Is this a tradeskill item?
int8 CR; // Save vs Cold
int8 DR; // Save vs Disease
int8 PR; // Save vs Poison
int8 MR; // Save vs Magic
int8 FR; // Save vs Fire
int8 AStr; // Strength
int8 ASta; // Stamina
int8 AAgi; // Agility
int8 ADex; // Dexterity
int8 ACha; // Charisma
int8 AInt; // Intelligence
int8 AWis; // Wisdom
int32 HP; // HP
int32 Mana; // Mana
int32 AC; // AC
uint32 Deity; // Bitmask of Deities that can equip this item
bool BenefitFlag {};
bool Tradeskills {}; // Is this a tradeskill item?
int8 CR {}; // Save vs Cold
int8 DR {}; // Save vs Disease
int8 PR {}; // Save vs Poison
int8 MR {}; // Save vs Magic
int8 FR {}; // Save vs Fire
int8 AStr {}; // Strength
int8 ASta {}; // Stamina
int8 AAgi {}; // Agility
int8 ADex {}; // Dexterity
int8 ACha {}; // Charisma
int8 AInt {}; // Intelligence
int8 AWis {}; // Wisdom
int32 HP {}; // HP
int32 Mana {}; // Mana
int32 AC {}; // AC
uint32 Deity {}; // Bitmask of Deities that can equip this item
//uint32 Unk033
int32 SkillModValue; // % Mod to skill specified in SkillModType
int32 SkillModMax; // Max skill point modification
uint32 SkillModType; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace; // Bane Damage Race
int32 BaneDmgAmt; // Bane Damage Body Amount
uint32 BaneDmgBody; // Bane Damage Body
bool Magic; // True=Magic Item, False=not
int32 CastTime_;
uint8 ReqLevel; // Required Level to use item
uint32 BardType; // Bard Skill Type
int32 BardValue; // Bard Skill Amount
int8 Light; // Light
uint8 Delay; // Delay * 10
uint8 RecLevel; // Recommended level to use item
uint8 RecSkill; // Recommended skill to use item (refers to primary skill of item)
uint8 ElemDmgType; // Elemental Damage Type (1=magic, 2=fire)
uint8 ElemDmgAmt; // Elemental Damage
uint8 Range; // Range of item
uint32 Damage; // Delay between item usage (in 0.1 sec increments)
uint32 Color; // RR GG BB 00 <-- as it appears in pc
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
uint32 Races; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054;
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType; // Item Type/Skill (itemClass* from above)
int32 SubType; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material; // Item material type
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
float SellRate; // Sell rate
//uint32 Unk059;
int32 SkillModValue {}; // % Mod to skill specified in SkillModType
int32 SkillModMax {}; // Max skill point modification
uint32 SkillModType {}; // Type of skill for SkillModValue to apply to
uint32 BaneDmgRace {}; // Bane Damage Race
int32 BaneDmgAmt {}; // Bane Damage Body Amount
uint32 BaneDmgBody {}; // Bane Damage Body
bool Magic {}; // True=Magic Item, False=not
int32 CastTime_ {};
uint8 ReqLevel {}; // Required Level to use item
uint32 BardType {}; // Bard Skill Type
int32 BardValue {}; // Bard Skill Amount
int8 Light {}; // Light
uint8 Delay {}; // Delay * 10
uint8 RecLevel {}; // Recommended level to use item
uint8 RecSkill {}; // Recommended skill to use item (refers to primary skill of item)
uint8 ElemDmgType {}; // Elemental Damage Type (1=magic, 2=fire)
uint8 ElemDmgAmt {}; // Elemental Damage
uint8 Range {}; // Range of item
uint32 Damage {}; // Delay between item usage (in 0.1 sec increments)
uint32 Color {}; // RR GG BB 00 <-- as it appears in pc
uint32 Classes {}; // Bitfield of classes that can equip item (1 << class#)
uint32 Races {}; // Bitfield of races that can equip item (1 << race#)
//uint32 Unk054 {};
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material {}; // Item material type
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
float SellRate {}; // Sell rate
//uint32 Unk059 {};
union {
uint32 Fulfilment; // Food fulfilment (How long it lasts)
uint32 CastTime; // Cast Time for clicky effects, in milliseconds
};
uint32 EliteMaterial;
int32 ProcRate;
int8 CombatEffects; // PoP: Combat Effects +
int8 Shielding; // PoP: Shielding %
int8 StunResist; // PoP: Stun Resist %
int8 StrikeThrough; // PoP: Strike Through %
uint32 ExtraDmgSkill;
uint32 ExtraDmgAmt;
int8 SpellShield; // PoP: Spell Shield %
int8 Avoidance; // PoP: Avoidance +
int8 Accuracy; // PoP: Accuracy +
uint32 CharmFileID;
int32 FactionMod1; // Faction Mod 1
int32 FactionMod2; // Faction Mod 2
int32 FactionMod3; // Faction Mod 3
int32 FactionMod4; // Faction Mod 4
int32 FactionAmt1; // Faction Amt 1
int32 FactionAmt2; // Faction Amt 2
int32 FactionAmt3; // Faction Amt 3
int32 FactionAmt4; // Faction Amt 4
char CharmFile[32]; // ?
uint32 AugType;
uint8 AugSlotType[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;
uint32 BaneDmgRaceAmt;
uint32 AugRestrict;
int32 Endur;
int32 DotShielding;
int32 Attack;
int32 Regen;
int32 ManaRegen;
int32 EnduranceRegen;
int32 Haste;
int32 DamageShield;
uint32 RecastDelay;
int RecastType;
uint32 AugDistiller;
bool Attuneable;
bool NoPet;
bool PotionBelt;
bool Stackable;
bool NoTransfer;
bool QuestItemFlag;
int16 StackSize;
uint8 PotionBeltSlots;
item::ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
uint32 EliteMaterial {};
int32 ProcRate {};
int8 CombatEffects {}; // PoP: Combat Effects +
int8 Shielding {}; // PoP: Shielding %
int8 StunResist {}; // PoP: Stun Resist %
int8 StrikeThrough {}; // PoP: Strike Through %
int32 ExtraDmgSkill {};
int32 ExtraDmgAmt {};
int8 SpellShield {}; // PoP: Spell Shield %
int8 Avoidance {}; // PoP: Avoidance +
int8 Accuracy {}; // PoP: Accuracy +
uint32 CharmFileID {};
int32 FactionMod1 {}; // Faction Mod 1
int32 FactionMod2 {}; // Faction Mod 2
int32 FactionMod3 {}; // Faction Mod 3
int32 FactionMod4 {}; // Faction Mod 4
int32 FactionAmt1 {}; // Faction Amt 1
int32 FactionAmt2 {}; // Faction Amt 2
int32 FactionAmt3 {}; // Faction Amt 3
int32 FactionAmt4 {}; // Faction Amt 4
char CharmFile[32] {}; // ?
uint32 AugType {};
uint8 AugSlotType[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme {};
uint32 LDoNPrice {};
uint32 LDoNSold {};
uint32 BaneDmgRaceAmt {};
uint32 AugRestrict {};
int32 Endur {};
int32 DotShielding {};
int32 Attack {};
int32 Regen {};
int32 ManaRegen {};
int32 EnduranceRegen {};
int32 Haste {};
int32 DamageShield {};
uint32 RecastDelay {};
int RecastType {};
uint32 AugDistiller {};
bool Attuneable {};
bool NoPet {};
bool PotionBelt {};
bool Stackable {};
bool NoTransfer {};
bool QuestItemFlag {};
int16 StackSize {};
uint8 PotionBeltSlots {};
item::ItemEffect_Struct Click {};
item::ItemEffect_Struct Proc {};
item::ItemEffect_Struct Worn {};
item::ItemEffect_Struct Focus {};
item::ItemEffect_Struct Scroll {};
item::ItemEffect_Struct Bard {};
uint8 Book; // 0=Not book, 1=Book
uint32 BookType;
char Filename[33]; // Filename for book data
uint8 Book {}; // 0=Not book, 1=Book
uint32 BookType {};
char Filename[33] {}; // Filename for book data
// Begin SoF Fields
int32 SVCorruption;
uint32 Purity;
uint8 EvolvingItem;
uint32 EvolvingID;
uint8 EvolvingLevel;
uint8 EvolvingMax;
uint32 BackstabDmg;
uint32 DSMitigation;
int32 HeroicStr;
int32 HeroicInt;
int32 HeroicWis;
int32 HeroicAgi;
int32 HeroicDex;
int32 HeroicSta;
int32 HeroicCha;
int32 HeroicMR;
int32 HeroicFR;
int32 HeroicCR;
int32 HeroicDR;
int32 HeroicPR;
int32 HeroicSVCorrup;
int32 HealAmt;
int32 SpellDmg;
uint32 LDoNSellBackRate;
uint32 ScriptFileID;
uint16 ExpendableArrow;
uint32 Clairvoyance;
char ClickName[65];
char ProcName[65];
char WornName[65];
char FocusName[65];
char ScrollName[65];
int32 SVCorruption {};
uint32 Purity {};
uint8 EvolvingItem {};
uint32 EvolvingID {};
uint8 EvolvingLevel {};
uint8 EvolvingMax {};
uint32 BackstabDmg {};
uint32 DSMitigation {};
int32 HeroicStr {};
int32 HeroicInt {};
int32 HeroicWis {};
int32 HeroicAgi {};
int32 HeroicDex {};
int32 HeroicSta {};
int32 HeroicCha {};
int32 HeroicMR {};
int32 HeroicFR {};
int32 HeroicCR {};
int32 HeroicDR {};
int32 HeroicPR {};
int32 HeroicSVCorrup {};
int32 HealAmt {};
int32 SpellDmg {};
uint32 LDoNSellBackRate {};
uint32 ScriptFileID {};
uint16 ExpendableArrow {};
uint32 Clairvoyance {};
char ClickName[65] {};
char ProcName[65] {};
char WornName[65] {};
char FocusName[65] {};
char ScrollName[65] {};
//BardName
bool IsEquipable(uint16 Race, uint16 Class) const;
+185 -197
View File
@@ -17,6 +17,7 @@
*/
#include "inventory_profile.h"
#include "../common/data_verification.h"
//#include "classes.h"
//#include "global_define.h"
//#include "item_instance.h"
@@ -24,16 +25,16 @@
#include "rulesys.h"
#include "shareddb.h"
#include "strings.h"
#include "util/uuid.h"
//#include "../common/light_source.h"
#include <limits.h>
//#include <iostream>
uint32 NextItemInstSerialNumber = 1;
int32 NextItemInstSerialNumber = 1;
static inline uint32 GetNextItemInstSerialNumber() {
static inline int32 GetNextItemInstSerialNumber() {
// The Bazaar relies on each item a client has up for Trade having a unique
// identifier. This 'SerialNumber' is sent in Serialized item packets and
@@ -45,7 +46,7 @@ static inline uint32 GetNextItemInstSerialNumber() {
// NextItemInstSerialNumber is the next one to hand out.
//
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
if(NextItemInstSerialNumber >= UINT_MAX)
if(NextItemInstSerialNumber >= INT_MAX)
NextItemInstSerialNumber = 1;
else
NextItemInstSerialNumber++;
@@ -56,131 +57,63 @@ static inline uint32 GetNextItemInstSerialNumber() {
//
// class EQ::ItemInstance
//
EQ::ItemInstance::ItemInstance(const ItemData* item, const std::string& guid, int16 charges) {
m_use_type = ItemInstNormal;
if(item) {
m_item = new ItemData(*item);
} else {
m_item = nullptr;
}
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
if (guid.empty()) {
m_guid = EQ::Util::UUID::Generate().ToString();
}
else {
m_guid = guid;
if (item) {
m_item = new ItemData(*item);
}
m_charges = charges;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color;
else
m_color = 0;
m_merchantcount = 1;
m_serial_number = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_currentslot = 0;
if (m_item && m_item->IsClassCommon()) {
m_color = m_item->Color;
}
m_SerialNumber = GetNextItemInstSerialNumber();
}
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, const std::string& guid, int16 charges) {
m_use_type = ItemInstNormal;
m_item = db->GetItem(item_id);
if(m_item) {
m_item = new ItemData(*m_item);
}
else {
m_item = nullptr;
}
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
if (guid.empty()) {
m_guid = EQ::Util::UUID::Generate().ToString();
}
else {
m_guid = guid;
m_item = db->GetItem(item_id);
if (m_item) {
m_item = new ItemData(*m_item);
}
m_charges = charges;
m_price = 0;
m_merchantslot = 0;
m_attuned=false;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color;
else
m_color = 0;
m_merchantcount = 1;
m_serial_number = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_currentslot = 0;
if (m_item && m_item->IsClassCommon()) {
m_color = m_item->Color;
} else {
m_color = 0;
}
m_SerialNumber = GetNextItemInstSerialNumber();
}
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
m_use_type = use_type;
m_guid = EQ::Util::UUID::Generate().ToString();
m_item = nullptr;
m_charges = 0;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
m_color = 0;
m_serial_number = 0;
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
m_scaledItem = nullptr;
m_evolveInfo = nullptr;
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_currentslot = 0;
m_merchantcount = 0;
m_use_type = use_type;
}
// Make a copy of an EQ::ItemInstance object
EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
{
m_use_type=copy.m_use_type;
if(copy.m_item)
m_item = new ItemData(*copy.m_item);
else
m_item = nullptr;
m_use_type = copy.m_use_type;
if (copy.m_item) {
m_item = new ItemData(*copy.m_item);
} else {
m_item = nullptr;
}
m_charges = copy.m_charges;
m_price = copy.m_price;
m_color = copy.m_color;
m_merchantslot = copy.m_merchantslot;
m_currentslot = copy.m_currentslot;
m_attuned = copy.m_attuned;
m_merchantcount = copy.m_merchantcount;
m_guid = copy.m_guid;
m_charges=copy.m_charges;
m_price=copy.m_price;
m_color=copy.m_color;
m_merchantslot=copy.m_merchantslot;
m_currentslot=copy.m_currentslot;
m_attuned=copy.m_attuned;
m_merchantcount=copy.m_merchantcount;
// Copy container contents
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
ItemInstance* inst_old = it->second;
@@ -190,37 +123,42 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
inst_new = inst_old->Clone();
}
if (inst_new != nullptr) {
if (inst_new) {
m_contents[it->first] = inst_new;
}
}
std::map<std::string, std::string>::const_iterator iter;
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
m_custom_data[iter->first] = iter->second;
}
m_serial_number = copy.m_serial_number;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;
m_exp = copy.m_exp;
m_SerialNumber = copy.m_SerialNumber;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;
m_exp = copy.m_exp;
m_evolveLvl = copy.m_evolveLvl;
m_activated = copy.m_activated;
if (copy.m_scaledItem)
if (copy.m_scaledItem) {
m_scaledItem = new ItemData(*copy.m_scaledItem);
else
} else {
m_scaledItem = nullptr;
}
if(copy.m_evolveInfo)
if (copy.m_evolveInfo) {
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
else
} else {
m_evolveInfo = nullptr;
}
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_ornament_hero_model = copy.m_ornament_hero_model;
m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file;
m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file;
}
// Clean up container contents
@@ -238,11 +176,13 @@ bool EQ::ItemInstance::IsType(item::ItemClass item_class) const
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
// Check usage type
if ((m_use_type == ItemInstWorldContainer) && (item_class == item::ItemClassBag))
if (m_use_type == ItemInstWorldContainer && item_class == item::ItemClassBag) {
return true;
}
if (!m_item)
if (!m_item) {
return false;
}
return (m_item->ItemClass == item_class);
}
@@ -265,21 +205,20 @@ bool EQ::ItemInstance::IsClassBook() const
// Is item stackable?
bool EQ::ItemInstance::IsStackable() const
{
if (!m_item)
return false;
return m_item->Stackable;
return (m_item && m_item->Stackable);
}
bool EQ::ItemInstance::IsCharged() const
{
if (!m_item)
if (!m_item) {
return false;
}
if (m_item->MaxCharges > 1)
if (m_item->MaxCharges > 1) {
return true;
else
} else {
return false;
}
}
// Can item be equipped?
@@ -328,26 +267,30 @@ bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
bool EQ::ItemInstance::IsAugmentable() const
{
if (!m_item)
if (!m_item) {
return false;
}
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (m_item->AugSlotType[index] != 0)
if (m_item->AugSlotType[index] != 0) {
return true;
}
}
return false;
}
bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
if (!m_item || !m_item->IsClassCommon())
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
int index = invslot::EQUIPMENT_BEGIN;
for (; index <= invslot::EQUIPMENT_END; ++index) {
if (m_item->Slots & (1 << index)) {
if (aug_wear_slots & (1 << index))
if (aug_wear_slots & (1 << index)) {
break;
}
}
}
@@ -416,9 +359,10 @@ EQ::ItemInstance* EQ::ItemInstance::GetItem(uint8 index) const
uint32 EQ::ItemInstance::GetItemID(uint8 slot) const
{
ItemInstance *item = GetItem(slot);
if (item)
const auto item = GetItem(slot);
if (item) {
return item->GetID();
}
return 0;
}
@@ -542,14 +486,21 @@ uint8 EQ::ItemInstance::FirstOpenSlot() const
uint8 EQ::ItemInstance::GetTotalItemCount() const
{
if (!m_item)
if (!m_item) {
return 0;
}
uint8 item_count = 1;
if (m_item && !m_item->IsClassBag()) { return item_count; }
if (!m_item->IsClassBag()) {
return item_count;
}
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } }
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) {
if (GetItem(index)) {
++item_count;
}
}
return item_count;
}
@@ -577,78 +528,99 @@ EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
return nullptr;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugtype) const
bool EQ::ItemInstance::IsOrnamentationAugment(EQ::ItemInstance* augment) const
{
if (!m_item || !m_item->IsClassCommon()) { return nullptr; }
if (ornamentationAugtype == 0) { return nullptr; }
if (!m_item || !m_item->IsClassCommon() || !augment) {
return false;
}
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++)
{
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
{
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
if (
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
|| strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
&& GetAugment(i)->GetItem()->HerosForgeModel == 0
)
{
continue;
}
return GetAugment(i);
const auto augment_item = augment->GetItem();
if (!augment_item) {
return false;
}
const std::string& idfile = augment_item->IDFile;
if (
EQ::ValueWithin(
augment->GetAugmentType(),
OrnamentationAugmentTypes::StandardOrnamentation,
OrnamentationAugmentTypes::SpecialOrnamentation
) ||
(
idfile != "IT63" &&
idfile != "IT64"
) ||
augment_item->HerosForgeModel
) {
return true;
}
return false;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
{
if (!m_item || !m_item->IsClassCommon()) {
return nullptr;
}
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
const auto augment = GetAugment(i);
if (augment && IsOrnamentationAugment(augment)) {
return augment;
}
}
return nullptr;
}
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
{
// Not a Hero Forge item.
if (m_ornament_hero_model == 0 || material_slot < 0)
if (m_ornament_hero_model == 0 || material_slot < 0) {
return 0;
}
// Item is using an explicit Hero Forge ID
if (m_ornament_hero_model >= 1000)
if (m_ornament_hero_model >= 1000) {
return m_ornament_hero_model;
}
// Item is using a shorthand ID
return (m_ornament_hero_model * 100) + material_slot;
}
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
if (!m_item || !m_item->IsClassCommon())
bool EQ::ItemInstance::UpdateOrnamentationInfo()
{
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
bool ornamentSet = false;
const auto augment = GetOrnamentationAugment();
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (GetOrnamentationAug(ornamentationAugtype))
{
const ItemData* ornamentItem;
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (ornamentItem != nullptr)
{
SetOrnamentIcon(ornamentItem->Icon);
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
if (strlen(ornamentItem->IDFile) > 2)
{
SetOrnamentationIDFile(Strings::ToInt(&ornamentItem->IDFile[2]));
}
else
{
if (augment) {
const auto augment_item = GetOrnamentationAugment()->GetItem();
if (augment_item) {
SetOrnamentIcon(augment_item->Icon);
SetOrnamentHeroModel(augment_item->HerosForgeModel);
if (strlen(augment_item->IDFile) > 2) {
SetOrnamentationIDFile(Strings::ToUnsignedInt(&augment_item->IDFile[2]));
} else {
SetOrnamentationIDFile(0);
}
ornamentSet = true;
return true;
}
}
else
{
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
}
return ornamentSet;
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
return false;
}
bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
@@ -748,12 +720,14 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
bool EQ::ItemInstance::IsAugmented()
{
if (!m_item || !m_item->IsClassCommon())
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (GetAugmentItemID(index))
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
if (GetAugmentItemID(slot_id)) {
return true;
}
}
return false;
@@ -862,7 +836,20 @@ std::string EQ::ItemInstance::GetCustomDataString() const {
return ret_val;
}
std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
void EQ::ItemInstance::SetCustomDataString(const std::string& str)
{
auto components = Strings::Split(str, "^");
auto value_count = components.size() / 2;
for (auto i = 0; i < value_count; i++) {
auto identifier = components[i * 2];
auto value = components[(i * 2) + 1];
SetCustomData(identifier, value);
}
}
std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) {
std::map<std::string, std::string>::const_iterator iter = m_custom_data.find(identifier);
if (iter != m_custom_data.end()) {
return iter->second;
@@ -871,33 +858,33 @@ std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
return "";
}
void EQ::ItemInstance::SetCustomData(std::string identifier, std::string value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, const std::string& value) {
DeleteCustomData(identifier);
m_custom_data[identifier] = value;
}
void EQ::ItemInstance::SetCustomData(std::string identifier, int value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, int value) {
DeleteCustomData(identifier);
std::stringstream ss;
ss << value;
m_custom_data[identifier] = ss.str();
}
void EQ::ItemInstance::SetCustomData(std::string identifier, float value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, float value) {
DeleteCustomData(identifier);
std::stringstream ss;
ss << value;
m_custom_data[identifier] = ss.str();
}
void EQ::ItemInstance::SetCustomData(std::string identifier, bool value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, bool value) {
DeleteCustomData(identifier);
std::stringstream ss;
ss << value;
m_custom_data[identifier] = ss.str();
}
void EQ::ItemInstance::DeleteCustomData(std::string identifier) {
void EQ::ItemInstance::DeleteCustomData(const std::string& identifier) {
auto iter = m_custom_data.find(identifier);
if (iter != m_custom_data.end()) {
m_custom_data.erase(iter);
@@ -949,8 +936,9 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
void EQ::ItemInstance::Initialize(SharedDatabase *db) {
// if there's no actual item, don't do anything
if (!m_item)
if (!m_item) {
return;
}
// initialize scaling items
if (m_item->CharmFileID != 0) {
@@ -959,7 +947,7 @@ void EQ::ItemInstance::Initialize(SharedDatabase *db) {
}
// initialize evolving items
else if ((db) && m_item->LoreGroup >= 1000 && m_item->LoreGroup != -1) {
else if (db && m_item->LoreGroup >= 1000) {
// not complete yet
}
}
+46 -42
View File
@@ -51,6 +51,11 @@ typedef enum {
byFlagNotSet //apply action if the flag is NOT set
} byFlagSetting;
enum OrnamentationAugmentTypes {
StandardOrnamentation = 20,
SpecialOrnamentation = 21
};
class SharedDatabase;
// ########################################
@@ -69,9 +74,9 @@ namespace EQ
/////////////////////////
// Constructors/Destructor
ItemInstance(const ItemData* item, const std::string& guid, int16 charges);
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
ItemInstance(SharedDatabase *db, uint32 item_id, const std::string &guid, int16 charges);
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
ItemInstance(ItemInstTypes use_type);
@@ -79,8 +84,6 @@ namespace EQ
~ItemInstance();
inline std::string GetGuid() const { return m_guid; }
// Query item type
bool IsType(item::ItemClass item_class) const;
@@ -105,7 +108,8 @@ namespace EQ
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augment_type) const;
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
inline int GetAugmentType() const { return m_item ? m_item->AugType : 0; }
inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
@@ -138,7 +142,8 @@ namespace EQ
bool IsAugmented();
bool ContainsAugmentByID(uint32 item_id);
int CountAugmentByID(uint32 item_id);
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool IsOrnamentationAugment(EQ::ItemInstance* augment) const;
ItemInstance* GetOrnamentationAugment() const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
@@ -177,12 +182,13 @@ namespace EQ
void SetAttuned(bool flag) { m_attuned = flag; }
std::string GetCustomDataString() const;
std::string GetCustomData(std::string identifier);
void SetCustomData(std::string identifier, std::string value);
void SetCustomData(std::string identifier, int value);
void SetCustomData(std::string identifier, float value);
void SetCustomData(std::string identifier, bool value);
void DeleteCustomData(std::string identifier);
std::string GetCustomData(const std::string &identifier);
void SetCustomDataString(const std::string& str);
void SetCustomData(const std::string &identifier, const std::string& value);
void SetCustomData(const std::string &identifier, int value);
void SetCustomData(const std::string &identifier, float value);
void SetCustomData(const std::string &identifier, bool value);
void DeleteCustomData(const std::string& identifier);
// Allows treatment of this object as though it were a pointer to m_item
operator bool() const { return (m_item != nullptr); }
@@ -227,8 +233,8 @@ namespace EQ
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
inline int32 GetSerialNumber() const { return m_serial_number; }
inline void SetSerialNumber(int32 id) { m_serial_number = id; }
inline int32 GetSerialNumber() const { return m_SerialNumber; }
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
void SetTimer(std::string name, uint32 time);
@@ -305,35 +311,33 @@ namespace EQ
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
std::string m_guid;
ItemInstTypes m_use_type; // Usage type for item
const ItemData* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
uint32 m_price; // Bazaar /trader price
uint32 m_color;
uint32 m_merchantslot;
int16 m_currentslot;
bool m_attuned;
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
uint32 m_serial_number; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;
ItemData* m_scaledItem;
::EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
uint32 m_new_id_file;
uint32 m_ornament_hero_model;
uint32 m_recast_timestamp;
int m_task_delivered_count = 0;
ItemInstTypes m_use_type {ItemInstNormal}; // Usage type for item
const ItemData* m_item {nullptr}; // Ptr to item data
int16 m_charges {0}; // # of charges for chargeable items
uint32 m_price {0}; // Bazaar /trader price
uint32 m_color {0};
uint32 m_merchantslot {0};
int16 m_currentslot {0};
bool m_attuned {false};
int32 m_merchantcount {1}; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber {0}; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp {0};
int8 m_evolveLvl {0};
bool m_activated {false};
ItemData* m_scaledItem {nullptr};
::EvolveInfo* m_evolveInfo {nullptr};
bool m_scaling {false};
uint32 m_ornamenticon {0};
uint32 m_ornamentidfile {0};
uint32 m_new_id_file {0};
uint32 m_ornament_hero_model {0};
uint32 m_recast_timestamp {0};
int m_task_delivered_count {0};
//
// Items inside of this item (augs or contents);
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data;
std::map<std::string, ::Timer> m_timers;
// Items inside of this item (augs or contents) {};
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data {};
std::map<std::string, ::Timer> m_timers {};
};
}
+2
View File
@@ -48,5 +48,7 @@
#define LANG_HADAL 26
#define LANG_UNKNOWN 27
#define MAX_LANGUAGE_SKILL 100
#endif
+1 -118
View File
@@ -151,7 +151,7 @@ static char *temp=nullptr;
return false;
}
ptr++;
uint32 id = Strings::ToInt(field[id_pos].c_str());
uint32 id = Strings::ToUnsignedInt(field[id_pos]);
items[id]=field;
for(i=0;i<10;i++) {
@@ -214,123 +214,6 @@ std::string x;
return i;
}
void LoadItemDBFieldNames() {
DBFieldNames[0]="N/A"; // Charges
DBFieldNames[1]="unknown002"; // ?
DBFieldNames[2]="N/A"; // Current Equip Slot
DBFieldNames[3]="unknown004";
DBFieldNames[4]="unknown005"; // ?
DBFieldNames[5]="itemclass"; // "Item Type (0=common, 1=container, 2=book)"
DBFieldNames[6]="name"; // Name
DBFieldNames[7]="lore"; // "Lore Name (*=lore, &=summoned, #=artifact)"
DBFieldNames[8]="idfile"; // IDFile
DBFieldNames[9]="id"; // ItemNumber
DBFieldNames[10]="weight"; // Weight
DBFieldNames[11]="norent"; // "NoRent (0=norent, 255=not norent)"
DBFieldNames[12]="nodrop"; // "NoDrop (0=nodrop, 255=not nodrop)"
DBFieldNames[13]="size"; // "Size (0=tiny, 1=small, 2=medium, 3=large, 4=giant)"
DBFieldNames[14]="slots"; // EquipSlots
DBFieldNames[15]="cost"; // Cost
DBFieldNames[16]="icon"; // IconNumber
DBFieldNames[17]="unknown018";
DBFieldNames[18]="unknown019";
DBFieldNames[19]="unknown020"; // ?
DBFieldNames[20]="tradeskills"; // "Tradeskill Item (1=is a tradeskill item, 0=not)"
DBFieldNames[21]="cr"; // SvCold
DBFieldNames[22]="dr"; // SvDisease
DBFieldNames[23]="pr"; // SvPoison
DBFieldNames[24]="mr"; // SvMagic
DBFieldNames[25]="fr"; // SvFire
DBFieldNames[26]="astr"; // STR
DBFieldNames[27]="asta"; // STA
DBFieldNames[28]="aagi"; // AGI
DBFieldNames[29]="adex"; // DEX
DBFieldNames[30]="acha"; // CHA
DBFieldNames[31]="aint"; // INT
DBFieldNames[32]="awis"; // WIS
DBFieldNames[33]="hp"; // HP
DBFieldNames[34]="mana"; // Mana
DBFieldNames[35]="ac"; // AC
DBFieldNames[36]="deity"; // Deity
DBFieldNames[37]="skillmodvalue"; // Skill Mod Value
DBFieldNames[38]="skillmodtype"; // Skill Mod Type
DBFieldNames[39]="banedmgrace"; // Bane Dmg Race
DBFieldNames[40]="banedmgamt"; // Band Dmg
DBFieldNames[41]="banedmgbody"; // Band Dmg Body
DBFieldNames[42]="magic"; // "Magic (0=not magic, 1=magic)"
DBFieldNames[43]="casttime2"; // Casttime appears twice
DBFieldNames[44]="hasteproclvl"; // "Level (Haste value, rather)"
DBFieldNames[45]="reqlevel"; // Required Level
DBFieldNames[46]="bardtype"; // Bard Type
DBFieldNames[47]="bardvalue"; // Bard Type Amount
DBFieldNames[48]="light"; // Light
DBFieldNames[49]="delay"; // Attack Delay
DBFieldNames[50]="reclevel"; // Recommended Level
DBFieldNames[51]="recskill"; // Recommended Skill
DBFieldNames[52]="elemdmgamt"; // "Elemental Dmg Type (1=magic, 2=fire, 3=cold, 4=poison, 5=disease)"
DBFieldNames[53]="elemdmgtype"; // Elemental Dmg
DBFieldNames[54]="effecttype"; // "Effect Type (0=combat, 1=clicky, 2=Worn, 3=Expendable charges, 4=Must Equip Clicky, 5=clicky)"
DBFieldNames[55]="range"; // Range
DBFieldNames[56]="damage"; // Damage
DBFieldNames[57]="color"; // Color
DBFieldNames[58]="classes"; // Classes
DBFieldNames[59]="races"; // Races
DBFieldNames[60]="unknown061";
DBFieldNames[61]="spellid"; // SpellId
DBFieldNames[62]="maxcharges"; // MaxCharges
DBFieldNames[63]="itemtype"; // "Skill (ItemType: 1hs, etc)"
DBFieldNames[64]="material"; // Material
DBFieldNames[65]="sellrate"; // ** Sell Rate
DBFieldNames[66]="unknown067";
DBFieldNames[67]="casttime"; // CastTime (milliseconds)
DBFieldNames[68]="unknown069";
DBFieldNames[69]="unknown070"; // ?
DBFieldNames[70]="focusid"; // Focus Effect Spell Id
DBFieldNames[71]="combateffects"; // CombatEffects
DBFieldNames[72]="shielding"; // Shielding
DBFieldNames[73]="stunresist"; // StunResist
DBFieldNames[74]="strikethrough"; // StrikeThrough
DBFieldNames[75]="unknown076";
DBFieldNames[76]="unknown077"; // ?
DBFieldNames[77]="spellshield"; // Spell Shield
DBFieldNames[78]="avoidance"; // Avoidance
DBFieldNames[79]="accuracy"; // Accuracy
DBFieldNames[80]="factionmod1"; // Faction Mod Index 1
DBFieldNames[81]="factionmod2"; // Faction Mod Index 2
DBFieldNames[82]="factionmod3"; // Faction Mod Index 3
DBFieldNames[83]="factionmod4"; // Faction Mod Index 4
DBFieldNames[84]="factionamt1"; // Faction Mod Value 1
DBFieldNames[85]="factionamt2"; // Faction Mod Value 2
DBFieldNames[86]="factionamt3"; // Faction Mod Value 3
DBFieldNames[87]="factionamt4"; // Faction Mod Value 4
DBFieldNames[88]="unknown089";
DBFieldNames[89]="charmfile"; // ** Charm File
DBFieldNames[90]="unknown091";
DBFieldNames[91]="augslot1type"; // Slot1Type
DBFieldNames[92]="augslot2type"; // Slot2Type
DBFieldNames[93]="augslot3type"; // Slot3Type
DBFieldNames[94]="augslot4type"; // Slot4Type
DBFieldNames[95]="augslot5type"; // Slot5Type
DBFieldNames[96]="ldonpointtheme";
DBFieldNames[97]="ldonpointcost"; // ?
DBFieldNames[98]="unknown099";
DBFieldNames[99]="bagtype"; // bag type
DBFieldNames[100]="bagslots"; // bag slots
DBFieldNames[101]="bagsize"; // bag size capacity
DBFieldNames[102]="bagwr"; // bag weight reduction
DBFieldNames[103]="booktype"; // "book type (0=rolled up note, 1=book)"
DBFieldNames[104]="unknown105";
DBFieldNames[105]="filename"; // Book Filename
DBFieldNames[106]="unknown107";
DBFieldNames[107]="unknown108";
DBFieldNames[108]="loreflag";
DBFieldNames[109]="unknown111";
DBFieldNames[110]="unknown112";
DBFieldNames[111]="unknown113";
DBFieldNames[112]="unknown114";
DBFieldNames[113]="unknown115"; // ? (end quote)
}
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
{
unsigned long i,j;
-2
View File
@@ -15,8 +15,6 @@ bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::stri
int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
void LoadItemDBFieldNames();
#ifndef WIN32
int print_stacktrace();
#endif
+1 -1
View File
@@ -131,7 +131,7 @@ bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf
if (*oIP == 0)
return false;
if (oPort)
*oPort = Strings::ToInt(sep.arg[1]);
*oPort = Strings::ToUnsignedInt(sep.arg[1]);
return true;
}
return false;
+21
View File
@@ -51,6 +51,7 @@ void MySQLRequestResult::ZeroOut()
m_RowCount = 0;
m_RowsAffected = 0;
m_LastInsertedID = 0;
m_error_message = "";
}
MySQLRequestResult::~MySQLRequestResult()
@@ -137,3 +138,23 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
other.ZeroOut();
return *this;
}
uint32 MySQLRequestResult::GetErrorNumber() const
{
return m_ErrorNumber;
}
void MySQLRequestResult::SetErrorNumber(uint32 m_error_number)
{
m_ErrorNumber = m_error_number;
}
const std::string &MySQLRequestResult::GetErrorMessage() const
{
return m_error_message;
}
void MySQLRequestResult::SetErrorMessage(const std::string &m_error_message)
{
MySQLRequestResult::m_error_message = m_error_message;
}
+15 -3
View File
@@ -33,30 +33,42 @@ private:
uint32 m_LastInsertedID;
uint32 m_ErrorNumber;
std::string m_error_message;
public:
MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected = 0, uint32 rowCount = 0, uint32 columnCount = 0, uint32 lastInsertedID = 0, uint32 errorNumber = 0, char *errorBuffer = nullptr);
MySQLRequestResult();
MySQLRequestResult();
MySQLRequestResult(MySQLRequestResult&& moveItem);
~MySQLRequestResult();
MySQLRequestResult& operator=(MySQLRequestResult&& other);
bool Success() const { return m_Success;}
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
std::string ErrorMessage() const {
if (!m_error_message.empty()) {
return m_error_message;
}
return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");
}
uint32 ErrorNumber() const {return m_ErrorNumber;}
uint32 RowsAffected() const {return m_RowsAffected;}
uint32 RowCount() const {return m_RowCount;}
uint32 ColumnCount() const {return m_ColumnCount;}
uint32 LastInsertedID() const {return m_LastInsertedID;}
// default to 0 index since we mostly use it that way anyways.
uint32 LengthOfColumn(int columnIndex = 0);
uint32 LengthOfColumn(int columnIndex = 0);
const std::string FieldName(int columnIndex);
MySQLRequestRow& begin() { return m_CurrentRow; }
MySQLRequestRow& end() { return m_OneBeyondRow; }
uint32 GetErrorNumber() const;
void SetErrorNumber(uint32 m_error_number);
const std::string &GetErrorMessage() const;
void SetErrorMessage(const std::string &m_error_message);
private:
void FreeInternals();
void ZeroOut();
+1 -1
View File
@@ -7,7 +7,7 @@ EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
m_server = std::make_unique<EQ::Net::TCPServer>();
m_server->Listen(addr, port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
ConsoleServerConnection *c = new ConsoleServerConnection(this, connection);
m_connections.insert(std::make_pair(c->GetUUID(), std::unique_ptr<ConsoleServerConnection>(c)));
m_connections.emplace(std::make_pair(c->GetUUID(), std::unique_ptr<ConsoleServerConnection>(c)));
});
}
+6 -6
View File
@@ -97,7 +97,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
m_on_new_connection(connection);
}
m_connections.insert(std::make_pair(std::make_pair(addr, port), connection));
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
}
void EQ::Net::DaybreakConnectionManager::Process()
@@ -234,7 +234,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
if (m_on_new_connection) {
m_on_new_connection(connection);
}
m_connections.insert(std::make_pair(std::make_pair(endpoint, port), connection));
m_connections.emplace(std::make_pair(std::make_pair(endpoint, port), connection));
connection->ProcessPacket(p);
}
else if (data[1] != OP_OutOfSession) {
@@ -527,7 +527,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
DynamicPacket *out = new DynamicPacket();
out->PutPacket(0, p);
s->packet_queue.insert(std::make_pair(seq, out));
s->packet_queue.emplace(std::make_pair(seq, out));
}
}
@@ -1427,7 +1427,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
InternalBufferedSend(first_packet);
@@ -1459,7 +1459,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
InternalBufferedSend(packet);
@@ -1483,7 +1483,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max);
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
stream->sequence_out++;
InternalBufferedSend(packet);
+1 -1
View File
@@ -22,7 +22,7 @@ void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
{
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
m_streams.insert(std::make_pair(connection, stream));
m_streams.emplace(std::make_pair(connection, stream));
if (m_on_new_connection) {
m_on_new_connection(stream);
}
+1 -1
View File
@@ -45,7 +45,7 @@ void EQ::Net::ServertalkClient::SendPacket(ServerPacket *p)
void EQ::Net::ServertalkClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
m_message_callbacks.emplace(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
@@ -41,7 +41,7 @@ void EQ::Net::ServertalkLegacyClient::SendPacket(ServerPacket *p)
void EQ::Net::ServertalkLegacyClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
m_message_callbacks.emplace(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkLegacyClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
+3 -3
View File
@@ -19,12 +19,12 @@ void EQ::Net::ServertalkServer::Listen(const ServertalkServerOptions& opts)
void EQ::Net::ServertalkServer::OnConnectionIdentified(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
{
m_on_ident.insert(std::make_pair(type, cb));
m_on_ident.emplace(std::make_pair(type, cb));
}
void EQ::Net::ServertalkServer::OnConnectionRemoved(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
{
m_on_disc.insert(std::make_pair(type, cb));
m_on_disc.emplace(std::make_pair(type, cb));
}
void EQ::Net::ServertalkServer::ConnectionDisconnected(ServertalkServerConnection *conn)
@@ -75,7 +75,7 @@ void EQ::Net::ServertalkServer::ConnectionIdentified(ServertalkServerConnection
else {
std::vector<std::shared_ptr<EQ::Net::ServertalkServerConnection>> vec;
vec.push_back(*iter);
m_ident_connections.insert(std::make_pair(conn->GetIdentifier(), vec));
m_ident_connections.emplace(std::make_pair(conn->GetIdentifier(), vec));
}
m_unident_connections.erase(iter);
+1 -1
View File
@@ -100,7 +100,7 @@ void EQ::Net::ServertalkServerConnection::SendPacket(ServerPacket *p)
void EQ::Net::ServertalkServerConnection::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
m_message_callbacks.emplace(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkServerConnection::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
+1 -1
View File
@@ -142,7 +142,7 @@ void EQ::Net::TCPConnection::Write(const char *data, size_t count)
WriteBaton *baton = new WriteBaton;
baton->connection = this;
baton->buffer = new char[count];;
baton->buffer = new char[count];
uv_write_t *write_req = new uv_write_t;
memset(write_req, 0, sizeof(uv_write_t));
+4 -5
View File
@@ -1050,7 +1050,7 @@ namespace RoF
{
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
@@ -1069,7 +1069,7 @@ namespace RoF
return;
}
//if(gjs->action == groupActLeave)
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
@@ -1099,7 +1099,7 @@ namespace RoF
for (int i = 0; i < 5; ++i)
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
if (gu2->membername[i][0] != '\0')
{
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
@@ -1169,7 +1169,7 @@ namespace RoF
return;
}
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
@@ -5218,7 +5218,6 @@ namespace RoF
/**
* Ornamentation
*/
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
uint32 hero_model = 0;
+18 -6
View File
@@ -35,6 +35,7 @@
#include "../path_manager.h"
#include "../classes.h"
#include "../races.h"
#include "../../zone/raids.h"
#include <iostream>
#include <sstream>
@@ -1101,7 +1102,7 @@ namespace RoF2
{
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
@@ -1120,7 +1121,7 @@ namespace RoF2
return;
}
//if(gjs->action == groupActLeave)
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
@@ -1150,7 +1151,7 @@ namespace RoF2
for (int i = 0; i < 5; ++i)
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
if (gu2->membername[i][0] != '\0')
{
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
@@ -1220,7 +1221,7 @@ namespace RoF2
return;
}
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
@@ -2737,7 +2738,7 @@ namespace RoF2
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
outlaa->action = inlaa->action;
@@ -2746,6 +2747,18 @@ namespace RoF2
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == raidSetNote)
{
auto in_note = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
auto note = (RaidGeneral_Struct*)outapp->pBuffer;
note->action = raidSetNote;
strn0cpy(note->leader_name, in_note->leader_name, sizeof(note->leader_name));
strn0cpy(note->player_name, in_note->player_name, sizeof(note->leader_name));
strn0cpy(note->note, in_note->note, sizeof(note->note));
dest->QueuePacket(outapp);
safe_delete(outapp);
}
else
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
@@ -5477,7 +5490,6 @@ namespace RoF2
/**
* Ornamentation
*/
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
uint32 hero_model = 0;
+2 -2
View File
@@ -2590,7 +2590,7 @@ struct GroupUpdate_Struct_Live { // New for Live
struct GroupMembers_Struct { // New for Live
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
/*0000*/ //char membername[0]; // Member Name Null Terminated
/*0000*/ //char member_name[0]; // Member Name Null Terminated
/*0000*/ uint8 unknown001[3]; // Seen 0
/*0000*/ uint32 memberlevel; // Guess
/*0000*/ uint8 unknown002[11]; // Seen 0
@@ -2600,7 +2600,7 @@ struct GroupJoin_Struct_Live { // New for Live
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
/*0004*/ uint32 action;
/*0008*/ uint8 unknown0008[5]; // Seen 0
/*0013*/ //char membername[0]; // Null Terminated?
/*0013*/ //char member_name[0]; // Null Terminated?
/*0000*/ uint8 unknown0013[3]; // Seen 0
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
/*0000*/ uint8 unknown0020[11]; // Seen 0
+2 -2
View File
@@ -2566,7 +2566,7 @@ struct GroupUpdate_Struct_Live { // New for Live
struct GroupMembers_Struct { // New for Live
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
/*0000*/ //char membername[0]; // Member Name Null Terminated
/*0000*/ //char member_name[0]; // Member Name Null Terminated
/*0000*/ uint8 unknown001[3]; // Seen 0
/*0000*/ uint32 memberlevel; // Guess
/*0000*/ uint8 unknown002[11]; // Seen 0
@@ -2576,7 +2576,7 @@ struct GroupJoin_Struct_Live { // New for Live
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
/*0004*/ uint32 action;
/*0008*/ uint8 unknown0008[5]; // Seen 0
/*0013*/ //char membername[0]; // Null Terminated?
/*0013*/ //char member_name[0]; // Null Terminated?
/*0000*/ uint8 unknown0013[3]; // Seen 0
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
/*0000*/ uint8 unknown0020[11]; // Seen 0
+4 -4
View File
@@ -785,7 +785,7 @@ namespace SoD
{
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
@@ -804,7 +804,7 @@ namespace SoD
return;
}
//if(gjs->action == groupActLeave)
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
@@ -834,7 +834,7 @@ namespace SoD
for (int i = 0; i < 5; ++i)
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
if (gu2->membername[i][0] != '\0')
{
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
@@ -902,7 +902,7 @@ namespace SoD
return;
}
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
+2 -2
View File
@@ -2085,7 +2085,7 @@ struct GroupUpdate_Struct_SoD { // New for SoD
struct GroupMembers_Struct { // New for SoD
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
/*0000*/ //char membername[0]; // Member Name Null Terminated
/*0000*/ //char member_name[0]; // Member Name Null Terminated
/*0000*/ uint8 unknown001[3]; // Seen 0
/*0000*/ uint32 memberlevel; // Guess
/*0000*/ uint8 unknown002[11]; // Seen 0
@@ -2095,7 +2095,7 @@ struct GroupJoin_Struct_SoD { // New for SoD
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
/*0004*/ uint32 action;
/*0008*/ uint8 unknown0008[5]; // Seen 0
/*0013*/ //char membername[0]; // Null Terminated?
/*0013*/ //char member_name[0]; // Null Terminated?
/*0000*/ uint8 unknown0013[3]; // Seen 0
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
/*0000*/ uint8 unknown0020[11]; // Seen 0
+13 -13
View File
@@ -927,7 +927,7 @@ namespace UF
{
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
@@ -947,7 +947,7 @@ namespace UF
return;
}
//if(gjs->action == groupActLeave)
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
auto outapp =
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
@@ -977,7 +977,7 @@ namespace UF
for (int i = 0; i < 5; ++i)
{
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
if (gu2->membername[i][0] != '\0')
{
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
@@ -1045,7 +1045,7 @@ namespace UF
delete in;
return;
}
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
@@ -3851,17 +3851,17 @@ namespace UF
ob.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
}
//ORNAMENT IDFILE / ICON -
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQ::ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
ornaIcon = aug_weap->Icon;
uint16 ornament_icon = 0;
const auto augment = inst->GetOrnamentationAugment();
ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
if (augment) {
const auto augment_item = augment->GetItem();
ornament_icon = augment_item->Icon;
ob.write(augment_item->IDFile, strlen(augment_item->IDFile));
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
ornaIcon = inst->GetOrnamentationIcon();
ornament_icon = inst->GetOrnamentationIcon();
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
ob.write(tmp, strlen(tmp));
@@ -3870,7 +3870,7 @@ namespace UF
UF::structs::ItemSerializationHeaderFinish hdrf;
hdrf.ornamentIcon = ornaIcon;
hdrf.ornamentIcon = ornament_icon;
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown061 = 0; //possibly ornament / special ornament
hdrf.isCopied = 0; //Flag for item to be 'Copied'
+2 -2
View File
@@ -2128,7 +2128,7 @@ struct GroupUpdate_Struct_Underfoot { // New for Underfoot
struct GroupMembers_Struct { // New for Underfoot
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
/*0000*/ //char membername[0]; // Member Name Null Terminated
/*0000*/ //char member_name[0]; // Member Name Null Terminated
/*0000*/ uint8 unknown001[3]; // Seen 0
/*0000*/ uint32 memberlevel; // Guess
/*0000*/ uint8 unknown002[11]; // Seen 0
@@ -2138,7 +2138,7 @@ struct GroupJoin_Struct_Underfoot { // New for Underfoot
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
/*0004*/ uint32 action;
/*0008*/ uint8 unknown0008[5]; // Seen 0
/*0013*/ //char membername[0]; // Null Terminated?
/*0013*/ //char member_name[0]; // Null Terminated?
/*0000*/ uint8 unknown0013[3]; // Seen 0
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
/*0000*/ uint8 unknown0020[11]; // Seen 0
+5 -5
View File
@@ -64,7 +64,7 @@ void ProcLauncher::Process() {
if(GetExitCodeProcess(cur->second->proc_info.hProcess, &res)) {
//got exit code, see if its still running...
if(res == STILL_ACTIVE) {
cur++;
++cur;
continue;
}
//else, it died, handle properly
@@ -76,7 +76,7 @@ void ProcLauncher::Process() {
//if we get here, the current process died.
tmp = cur;
tmp++;
++tmp;
ProcessTerminated(cur);
cur = tmp;
}
@@ -174,7 +174,7 @@ ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
std::vector<std::string>::iterator cur, end;
cur = it->args.begin();
end = it->args.end();
for(; cur != end; cur++) {
for(; cur != end; ++cur) {
args += " ";
args += *cur;
}
@@ -306,7 +306,7 @@ void ProcLauncher::TerminateAll(bool final) {
std::map<ProcRef, Spec *>::iterator cur, end;
cur = m_running.begin();
end = m_running.end();
for(; cur != end; cur++) {
for(; cur != end; ++cur) {
Terminate(cur->first, true);
}
} else {
@@ -317,7 +317,7 @@ void ProcLauncher::TerminateAll(bool final) {
std::map<ProcRef, Spec *>::iterator cur, end;
cur = running.begin();
end = running.end();
for(; cur != end; cur++) {
for(; cur != end; ++cur) {
Terminate(cur->first, true);
safe_delete(cur->second);
}
+2 -1
View File
@@ -4,7 +4,8 @@
std::string Process::execute(const std::string &cmd)
{
std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
std::string command = fmt::format("{} 2>&1", cmd);
std::shared_ptr<FILE> pipe(popen(command.c_str(), "r"), pclose);
if (!pipe) { return "ERROR"; }
char buffer[128];
std::string result;
+1 -1
View File
@@ -258,7 +258,7 @@ bool EQ::ProfanityManager::clear_database_entries(DBcore *db) {
return true;
}
bool EQ::ProfanityManager::check_for_existing_entry(std::string profanity) {
bool EQ::ProfanityManager::check_for_existing_entry(const std::string& profanity) {
if (profanity.empty()) {
return false;
}
+1 -1
View File
@@ -53,7 +53,7 @@ namespace EQ
private:
static bool load_database_entries(DBcore *db);
static bool clear_database_entries(DBcore *db);
static bool check_for_existing_entry(std::string profanity);
static bool check_for_existing_entry(const std::string& profanity);
};
+3 -3
View File
@@ -288,9 +288,9 @@ bool PTimerList::Load(Database *db) {
PersistentTimer *cur;
for (auto row = results.begin(); row != results.end(); ++row) {
type = Strings::ToInt(row[0]);
start_time = strtoul(row[1], nullptr, 10);
timer_time = strtoul(row[2], nullptr, 10);
type = Strings::ToUnsignedInt(row[0]);
start_time = Strings::ToUnsignedInt(row[1]);
timer_time = Strings::ToUnsignedInt(row[2]);
enabled = (row[3][0] == '1');
//if it expired allready, dont bother.
+60 -5
View File
@@ -17,6 +17,7 @@
*/
#include "../common/races.h"
#include "data_verification.h"
const char* GetRaceIDName(uint16 race_id)
{
@@ -67,7 +68,7 @@ const char* GetRaceIDName(uint16 race_id)
// return "Froglok";
//case DRAKKIN:
// return "Drakkin";
// RoF2 Race Labels
case RT_ABHORRENT:
return "Abhorrent";
@@ -1696,7 +1697,7 @@ bool PlayerAppearance::IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8
{
if (beard_color_value == 0xFF)
return true;
switch (BINDRG(race_id, gender_id)) {
case GNOME_MALE:
if (beard_color_value <= 24)
@@ -1783,7 +1784,7 @@ bool PlayerAppearance::IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 ey
case VAHSHIR_FEMALE:
if (eye_color_value <= 9)
return true;
break;
break;
case TROLL_MALE:
case TROLL_FEMALE:
if (eye_color_value <= 10)
@@ -2109,7 +2110,7 @@ bool PlayerAppearance::IsValidTexture(uint16 race_id, uint8 gender_id, uint8 tex
{
if (texture_value == 0xFF)
return true;
if (use_luclin) {
switch (BINDRG(race_id, gender_id)) {
case HUMAN_MALE:
@@ -2243,4 +2244,58 @@ const char* GetGenderName(uint32 gender_id) {
gender_name = "Neuter";
}
return gender_name;
}
}
const std::string GetPlayerRaceAbbreviation(uint16 race_id)
{
if (!IsPlayerRace(race_id)) {
return std::string("UNK");
}
switch (race_id) {
case RACE_HUMAN_1:
return "HUM";
case RACE_BARBARIAN_2:
return "BAR";
case RACE_ERUDITE_3:
return "ERU";
case RACE_WOOD_ELF_4:
return "ELF";
case RACE_HIGH_ELF_5:
return "HIE";
case RACE_DARK_ELF_6:
return "DEF";
case RACE_HALF_ELF_7:
return "HEF";
case RACE_DWARF_8:
return "DWF";
case RACE_TROLL_9:
return "TRL";
case RACE_OGRE_10:
return "OGR";
case RACE_HALFLING_11:
return "HFL";
case RACE_GNOME_12:
return "GNM";
case RACE_IKSAR_128:
return "IKS";
case RACE_VAH_SHIR_130:
return "VAH";
case RACE_FROGLOK_330:
return "FRG";
case RACE_DRAKKIN_522:
return "DRK";
}
return std::string("UNK");
}
bool IsPlayerRace(uint16 race_id) {
return (
EQ::ValueWithin(race_id, RACE_HUMAN_1, RACE_GNOME_12) ||
race_id == RACE_IKSAR_128 ||
race_id == RACE_VAH_SHIR_130 ||
race_id == RACE_FROGLOK_330 ||
race_id == RACE_DRAKKIN_522
);
}
+4
View File
@@ -19,6 +19,7 @@
#ifndef RACES_H
#define RACES_H
#include "../common/types.h"
#include <string>
#define MALE 0
#define FEMALE 1
@@ -853,6 +854,9 @@ const char* GetRaceIDName(uint16 race_id);
const char* GetPlayerRaceName(uint32 player_race_value);
const char* GetGenderName(uint32 gender_id);
bool IsPlayerRace(uint16 race_id);
const std::string GetPlayerRaceAbbreviation(uint16 race_id);
uint32 GetPlayerRaceValue(uint16 race_id);
uint32 GetPlayerRaceBit(uint16 race_id);
@@ -44,7 +44,35 @@ public:
*/
// Custom extended repository methods here
static void ClearFlag(
Database& db,
AccountFlagsRepository::AccountFlags e
) {
AccountFlagsRepository::DeleteWhere(
database,
fmt::format(
"p_accid = {} AND p_flag = '{}'",
e.p_accid,
Strings::Escape(e.p_flag)
)
);
}
static void ReplaceFlag(
Database& db,
AccountFlagsRepository::AccountFlags e
) {
db.QueryDatabase(
fmt::format(
"REPLACE INTO {} ({}) VALUES ({}, '{}', '{}')",
TableName(),
ColumnsRaw(),
e.p_accid,
Strings::Escape(e.p_flag),
Strings::Escape(e.p_value)
)
);
}
};
#endif //EQEMU_ACCOUNT_FLAGS_REPOSITORY_H
@@ -0,0 +1,354 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
#define EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseCharacterTributeRepository {
public:
struct CharacterTribute {
int32_t id;
uint32_t character_id;
uint8_t tier;
uint32_t tribute;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"character_id",
"tier",
"tribute",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"character_id",
"tier",
"tribute",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_tribute");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static CharacterTribute NewEntity()
{
CharacterTribute e{};
e.id = 0;
e.character_id = 0;
e.tier = 0;
e.tribute = 0;
return e;
}
static CharacterTribute GetCharacterTribute(
const std::vector<CharacterTribute> &character_tributes,
int character_tribute_id
)
{
for (auto &character_tribute : character_tributes) {
if (character_tribute.id == character_tribute_id) {
return character_tribute;
}
}
return NewEntity();
}
static CharacterTribute FindOne(
Database& db,
int character_tribute_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
character_tribute_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int character_tribute_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
character_tribute_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const CharacterTribute &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.character_id));
v.push_back(columns[2] + " = " + std::to_string(e.tier));
v.push_back(columns[3] + " = " + std::to_string(e.tribute));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static CharacterTribute InsertOne(
Database& db,
CharacterTribute e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.tier));
v.push_back(std::to_string(e.tribute));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<CharacterTribute> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.tier));
v.push_back(std::to_string(e.tribute));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<CharacterTribute> All(Database& db)
{
std::vector<CharacterTribute> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CharacterTribute> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CharacterTribute> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterTribute e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H
#define EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseCommandSubsettingsRepository {
public:
struct CommandSubsettings {
uint32_t id;
std::string parent_command;
std::string sub_command;
uint32_t access_level;
std::string top_level_aliases;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"parent_command",
"sub_command",
"access_level",
"top_level_aliases",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"parent_command",
"sub_command",
"access_level",
"top_level_aliases",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("command_subsettings");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static CommandSubsettings NewEntity()
{
CommandSubsettings e{};
e.id = 0;
e.parent_command = "";
e.sub_command = "";
e.access_level = 0;
e.top_level_aliases = "";
return e;
}
static CommandSubsettings GetCommandSubsettings(
const std::vector<CommandSubsettings> &command_subsettingss,
int command_subsettings_id
)
{
for (auto &command_subsettings : command_subsettingss) {
if (command_subsettings.id == command_subsettings_id) {
return command_subsettings;
}
}
return NewEntity();
}
static CommandSubsettings FindOne(
Database& db,
int command_subsettings_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
command_subsettings_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
CommandSubsettings e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.parent_command = row[1] ? row[1] : "";
e.sub_command = row[2] ? row[2] : "";
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.top_level_aliases = row[4] ? row[4] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int command_subsettings_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
command_subsettings_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const CommandSubsettings &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.parent_command) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.sub_command) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.access_level));
v.push_back(columns[4] + " = '" + Strings::Escape(e.top_level_aliases) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static CommandSubsettings InsertOne(
Database& db,
CommandSubsettings e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.parent_command) + "'");
v.push_back("'" + Strings::Escape(e.sub_command) + "'");
v.push_back(std::to_string(e.access_level));
v.push_back("'" + Strings::Escape(e.top_level_aliases) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<CommandSubsettings> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.parent_command) + "'");
v.push_back("'" + Strings::Escape(e.sub_command) + "'");
v.push_back(std::to_string(e.access_level));
v.push_back("'" + Strings::Escape(e.top_level_aliases) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<CommandSubsettings> All(Database& db)
{
std::vector<CommandSubsettings> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CommandSubsettings e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.parent_command = row[1] ? row[1] : "";
e.sub_command = row[2] ? row[2] : "";
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.top_level_aliases = row[4] ? row[4] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CommandSubsettings> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CommandSubsettings> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CommandSubsettings e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.parent_command = row[1] ? row[1] : "";
e.sub_command = row[2] ? row[2] : "";
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.top_level_aliases = row[4] ? row[4] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H
@@ -15,14 +15,33 @@
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
#include <cereal/cereal.hpp>
class BaseDataBucketsRepository {
public:
struct DataBuckets {
uint64_t id;
std::string key;
std::string key_;
std::string value;
uint32_t expires;
int64_t character_id;
int64_t npc_id;
int64_t bot_id;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(id),
CEREAL_NVP(key_),
CEREAL_NVP(value),
CEREAL_NVP(expires),
CEREAL_NVP(character_id),
CEREAL_NVP(npc_id),
CEREAL_NVP(bot_id)
);
}
};
static std::string PrimaryKey()
@@ -34,9 +53,12 @@ public:
{
return {
"id",
"key",
"`key`",
"value",
"expires",
"character_id",
"npc_id",
"bot_id",
};
}
@@ -44,9 +66,12 @@ public:
{
return {
"id",
"key",
"`key`",
"value",
"expires",
"character_id",
"npc_id",
"bot_id",
};
}
@@ -87,10 +112,13 @@ public:
{
DataBuckets e{};
e.id = 0;
e.key = "";
e.value = "";
e.expires = 0;
e.id = 0;
e.key_ = "";
e.value = "";
e.expires = 0;
e.character_id = 0;
e.npc_id = 0;
e.bot_id = 0;
return e;
}
@@ -116,8 +144,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
data_buckets_id
)
);
@@ -126,10 +155,13 @@ public:
if (results.RowCount() == 1) {
DataBuckets e{};
e.id = strtoull(row[0], nullptr, 10);
e.key = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.id = strtoull(row[0], nullptr, 10);
e.key_ = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.character_id = strtoll(row[4], nullptr, 10);
e.npc_id = strtoll(row[5], nullptr, 10);
e.bot_id = strtoll(row[6], nullptr, 10);
return e;
}
@@ -163,9 +195,12 @@ public:
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.key) + "'");
v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.expires));
v.push_back(columns[4] + " = " + std::to_string(e.character_id));
v.push_back(columns[5] + " = " + std::to_string(e.npc_id));
v.push_back(columns[6] + " = " + std::to_string(e.bot_id));
auto results = db.QueryDatabase(
fmt::format(
@@ -188,9 +223,12 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.key) + "'");
v.push_back("'" + Strings::Escape(e.key_) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'");
v.push_back(std::to_string(e.expires));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.bot_id));
auto results = db.QueryDatabase(
fmt::format(
@@ -221,9 +259,12 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.key) + "'");
v.push_back("'" + Strings::Escape(e.key_) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'");
v.push_back(std::to_string(e.expires));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.bot_id));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -257,10 +298,13 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
DataBuckets e{};
e.id = strtoull(row[0], nullptr, 10);
e.key = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.id = strtoull(row[0], nullptr, 10);
e.key_ = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.character_id = strtoll(row[4], nullptr, 10);
e.npc_id = strtoll(row[5], nullptr, 10);
e.bot_id = strtoll(row[6], nullptr, 10);
all_entries.push_back(e);
}
@@ -285,10 +329,13 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
DataBuckets e{};
e.id = strtoull(row[0], nullptr, 10);
e.key = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.id = strtoull(row[0], nullptr, 10);
e.key_ = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.character_id = strtoll(row[4], nullptr, 10);
e.npc_id = strtoll(row[5], nullptr, 10);
e.bot_id = strtoll(row[6], nullptr, 10);
all_entries.push_back(e);
}
@@ -16,6 +16,7 @@
#include "../../strings.h"
#include <ctime>
class BaseItemsRepository {
public:
struct Items {
@@ -122,7 +123,7 @@ public:
int32_t pr;
int32_t procrate;
int32_t races;
int32_t range;
int32_t range_;
int32_t reclevel;
int32_t recskill;
int32_t reqlevel;
@@ -417,7 +418,7 @@ public:
"pr",
"procrate",
"races",
"range",
"`range`",
"reclevel",
"recskill",
"reqlevel",
@@ -708,7 +709,7 @@ public:
"pr",
"procrate",
"races",
"range",
"`range`",
"reclevel",
"recskill",
"reqlevel",
@@ -1033,7 +1034,7 @@ public:
e.pr = 0;
e.procrate = 0;
e.races = 0;
e.range = 0;
e.range_ = 0;
e.reclevel = 0;
e.recskill = 0;
e.reqlevel = 0;
@@ -1240,8 +1241,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
items_id
)
);
@@ -1353,7 +1355,7 @@ public:
e.pr = static_cast<int32_t>(atoi(row[100]));
e.procrate = static_cast<int32_t>(atoi(row[101]));
e.races = static_cast<int32_t>(atoi(row[102]));
e.range = static_cast<int32_t>(atoi(row[103]));
e.range_ = static_cast<int32_t>(atoi(row[103]));
e.reclevel = static_cast<int32_t>(atoi(row[104]));
e.recskill = static_cast<int32_t>(atoi(row[105]));
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
@@ -1671,7 +1673,7 @@ public:
v.push_back(columns[100] + " = " + std::to_string(e.pr));
v.push_back(columns[101] + " = " + std::to_string(e.procrate));
v.push_back(columns[102] + " = " + std::to_string(e.races));
v.push_back(columns[103] + " = " + std::to_string(e.range));
v.push_back(columns[103] + " = " + std::to_string(e.range_));
v.push_back(columns[104] + " = " + std::to_string(e.reclevel));
v.push_back(columns[105] + " = " + std::to_string(e.recskill));
v.push_back(columns[106] + " = " + std::to_string(e.reqlevel));
@@ -1977,7 +1979,7 @@ public:
v.push_back(std::to_string(e.pr));
v.push_back(std::to_string(e.procrate));
v.push_back(std::to_string(e.races));
v.push_back(std::to_string(e.range));
v.push_back(std::to_string(e.range_));
v.push_back(std::to_string(e.reclevel));
v.push_back(std::to_string(e.recskill));
v.push_back(std::to_string(e.reqlevel));
@@ -2291,7 +2293,7 @@ public:
v.push_back(std::to_string(e.pr));
v.push_back(std::to_string(e.procrate));
v.push_back(std::to_string(e.races));
v.push_back(std::to_string(e.range));
v.push_back(std::to_string(e.range_));
v.push_back(std::to_string(e.reclevel));
v.push_back(std::to_string(e.recskill));
v.push_back(std::to_string(e.reqlevel));
@@ -2609,7 +2611,7 @@ public:
e.pr = static_cast<int32_t>(atoi(row[100]));
e.procrate = static_cast<int32_t>(atoi(row[101]));
e.races = static_cast<int32_t>(atoi(row[102]));
e.range = static_cast<int32_t>(atoi(row[103]));
e.range_ = static_cast<int32_t>(atoi(row[103]));
e.reclevel = static_cast<int32_t>(atoi(row[104]));
e.recskill = static_cast<int32_t>(atoi(row[105]));
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
@@ -2918,7 +2920,7 @@ public:
e.pr = static_cast<int32_t>(atoi(row[100]));
e.procrate = static_cast<int32_t>(atoi(row[101]));
e.races = static_cast<int32_t>(atoi(row[102]));
e.range = static_cast<int32_t>(atoi(row[103]));
e.range_ = static_cast<int32_t>(atoi(row[103]));
e.reclevel = static_cast<int32_t>(atoi(row[104]));
e.recskill = static_cast<int32_t>(atoi(row[105]));
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
@@ -25,7 +25,7 @@ public:
std::string zone_id_list;
std::string instance_version_list;
int32_t ac;
int32_t hp;
int64_t hp;
int32_t accuracy;
int32_t slow_mitigation;
int32_t attack;
@@ -45,10 +45,13 @@ public:
int32_t physical_resist;
int32_t min_dmg;
int32_t max_dmg;
int32_t hp_regen_rate;
int64_t hp_regen_rate;
int64_t hp_regen_per_second;
int32_t attack_delay;
int32_t spell_scale;
int32_t heal_scale;
uint32_t avoidance;
int32_t heroic_strikethrough;
std::string special_abilities;
};
@@ -86,9 +89,12 @@ public:
"min_dmg",
"max_dmg",
"hp_regen_rate",
"hp_regen_per_second",
"attack_delay",
"spell_scale",
"heal_scale",
"avoidance",
"heroic_strikethrough",
"special_abilities",
};
}
@@ -122,9 +128,12 @@ public:
"min_dmg",
"max_dmg",
"hp_regen_rate",
"hp_regen_per_second",
"attack_delay",
"spell_scale",
"heal_scale",
"avoidance",
"heroic_strikethrough",
"special_abilities",
};
}
@@ -192,9 +201,12 @@ public:
e.min_dmg = 0;
e.max_dmg = 0;
e.hp_regen_rate = 0;
e.hp_regen_per_second = 0;
e.attack_delay = 0;
e.spell_scale = 100;
e.heal_scale = 100;
e.avoidance = 0;
e.heroic_strikethrough = 0;
e.special_abilities = "";
return e;
@@ -237,7 +249,7 @@ public:
e.zone_id_list = row[2] ? row[2] : "";
e.instance_version_list = row[3] ? row[3] : "";
e.ac = static_cast<int32_t>(atoi(row[4]));
e.hp = static_cast<int32_t>(atoi(row[5]));
e.hp = strtoll(row[5], nullptr, 10);
e.accuracy = static_cast<int32_t>(atoi(row[6]));
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
e.attack = static_cast<int32_t>(atoi(row[8]));
@@ -257,11 +269,14 @@ public:
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
e.hp_regen_rate = static_cast<int32_t>(atoi(row[25]));
e.attack_delay = static_cast<int32_t>(atoi(row[26]));
e.spell_scale = static_cast<int32_t>(atoi(row[27]));
e.heal_scale = static_cast<int32_t>(atoi(row[28]));
e.special_abilities = row[29] ? row[29] : "";
e.hp_regen_rate = strtoll(row[25], nullptr, 10);
e.hp_regen_per_second = strtoll(row[26], nullptr, 10);
e.attack_delay = static_cast<int32_t>(atoi(row[27]));
e.spell_scale = static_cast<int32_t>(atoi(row[28]));
e.heal_scale = static_cast<int32_t>(atoi(row[29]));
e.avoidance = static_cast<uint32_t>(strtoul(row[30], nullptr, 10));
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[31]));
e.special_abilities = row[32] ? row[32] : "";
return e;
}
@@ -321,10 +336,13 @@ public:
v.push_back(columns[23] + " = " + std::to_string(e.min_dmg));
v.push_back(columns[24] + " = " + std::to_string(e.max_dmg));
v.push_back(columns[25] + " = " + std::to_string(e.hp_regen_rate));
v.push_back(columns[26] + " = " + std::to_string(e.attack_delay));
v.push_back(columns[27] + " = " + std::to_string(e.spell_scale));
v.push_back(columns[28] + " = " + std::to_string(e.heal_scale));
v.push_back(columns[29] + " = '" + Strings::Escape(e.special_abilities) + "'");
v.push_back(columns[26] + " = " + std::to_string(e.hp_regen_per_second));
v.push_back(columns[27] + " = " + std::to_string(e.attack_delay));
v.push_back(columns[28] + " = " + std::to_string(e.spell_scale));
v.push_back(columns[29] + " = " + std::to_string(e.heal_scale));
v.push_back(columns[30] + " = " + std::to_string(e.avoidance));
v.push_back(columns[31] + " = " + std::to_string(e.heroic_strikethrough));
v.push_back(columns[32] + " = '" + Strings::Escape(e.special_abilities) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -372,9 +390,12 @@ public:
v.push_back(std::to_string(e.min_dmg));
v.push_back(std::to_string(e.max_dmg));
v.push_back(std::to_string(e.hp_regen_rate));
v.push_back(std::to_string(e.hp_regen_per_second));
v.push_back(std::to_string(e.attack_delay));
v.push_back(std::to_string(e.spell_scale));
v.push_back(std::to_string(e.heal_scale));
v.push_back(std::to_string(e.avoidance));
v.push_back(std::to_string(e.heroic_strikethrough));
v.push_back("'" + Strings::Escape(e.special_abilities) + "'");
auto results = db.QueryDatabase(
@@ -431,9 +452,12 @@ public:
v.push_back(std::to_string(e.min_dmg));
v.push_back(std::to_string(e.max_dmg));
v.push_back(std::to_string(e.hp_regen_rate));
v.push_back(std::to_string(e.hp_regen_per_second));
v.push_back(std::to_string(e.attack_delay));
v.push_back(std::to_string(e.spell_scale));
v.push_back(std::to_string(e.heal_scale));
v.push_back(std::to_string(e.avoidance));
v.push_back(std::to_string(e.heroic_strikethrough));
v.push_back("'" + Strings::Escape(e.special_abilities) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
@@ -473,7 +497,7 @@ public:
e.zone_id_list = row[2] ? row[2] : "";
e.instance_version_list = row[3] ? row[3] : "";
e.ac = static_cast<int32_t>(atoi(row[4]));
e.hp = static_cast<int32_t>(atoi(row[5]));
e.hp = strtoll(row[5], nullptr, 10);
e.accuracy = static_cast<int32_t>(atoi(row[6]));
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
e.attack = static_cast<int32_t>(atoi(row[8]));
@@ -493,11 +517,14 @@ public:
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
e.hp_regen_rate = static_cast<int32_t>(atoi(row[25]));
e.attack_delay = static_cast<int32_t>(atoi(row[26]));
e.spell_scale = static_cast<int32_t>(atoi(row[27]));
e.heal_scale = static_cast<int32_t>(atoi(row[28]));
e.special_abilities = row[29] ? row[29] : "";
e.hp_regen_rate = strtoll(row[25], nullptr, 10);
e.hp_regen_per_second = strtoll(row[26], nullptr, 10);
e.attack_delay = static_cast<int32_t>(atoi(row[27]));
e.spell_scale = static_cast<int32_t>(atoi(row[28]));
e.heal_scale = static_cast<int32_t>(atoi(row[29]));
e.avoidance = static_cast<uint32_t>(strtoul(row[30], nullptr, 10));
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[31]));
e.special_abilities = row[32] ? row[32] : "";
all_entries.push_back(e);
}
@@ -527,7 +554,7 @@ public:
e.zone_id_list = row[2] ? row[2] : "";
e.instance_version_list = row[3] ? row[3] : "";
e.ac = static_cast<int32_t>(atoi(row[4]));
e.hp = static_cast<int32_t>(atoi(row[5]));
e.hp = strtoll(row[5], nullptr, 10);
e.accuracy = static_cast<int32_t>(atoi(row[6]));
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
e.attack = static_cast<int32_t>(atoi(row[8]));
@@ -547,11 +574,14 @@ public:
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
e.hp_regen_rate = static_cast<int32_t>(atoi(row[25]));
e.attack_delay = static_cast<int32_t>(atoi(row[26]));
e.spell_scale = static_cast<int32_t>(atoi(row[27]));
e.heal_scale = static_cast<int32_t>(atoi(row[28]));
e.special_abilities = row[29] ? row[29] : "";
e.hp_regen_rate = strtoll(row[25], nullptr, 10);
e.hp_regen_per_second = strtoll(row[26], nullptr, 10);
e.attack_delay = static_cast<int32_t>(atoi(row[27]));
e.spell_scale = static_cast<int32_t>(atoi(row[28]));
e.heal_scale = static_cast<int32_t>(atoi(row[29]));
e.avoidance = static_cast<uint32_t>(strtoul(row[30], nullptr, 10));
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[31]));
e.special_abilities = row[32] ? row[32] : "";
all_entries.push_back(e);
}
@@ -66,8 +66,8 @@ public:
uint8_t armortint_red;
uint8_t armortint_green;
uint8_t armortint_blue;
int32_t d_melee_texture1;
int32_t d_melee_texture2;
uint32_t d_melee_texture1;
uint32_t d_melee_texture2;
std::string ammo_idfile;
uint8_t prim_melee_type;
uint8_t sec_melee_type;
@@ -583,7 +583,7 @@ public:
e.exp_mod = 100;
e.heroic_strikethrough = 0;
e.faction_amount = 0;
e.keeps_sold_items = 0;
e.keeps_sold_items = 1;
return e;
}
@@ -666,8 +666,8 @@ public:
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
e.ammo_idfile = row[48] ? row[48] : "";
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
@@ -1289,8 +1289,8 @@ public:
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
e.ammo_idfile = row[48] ? row[48] : "";
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
@@ -1440,8 +1440,8 @@ public:
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
e.ammo_idfile = row[48] ? row[48] : "";
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
@@ -16,6 +16,7 @@
#include "../../strings.h"
#include <ctime>
class BaseRaidDetailsRepository {
public:
struct RaidDetails {
@@ -23,6 +24,9 @@ public:
int32_t loottype;
int8_t locked;
std::string motd;
uint16_t marked_npc_1;
uint16_t marked_npc_2;
uint16_t marked_npc_3;
};
static std::string PrimaryKey()
@@ -37,6 +41,9 @@ public:
"loottype",
"locked",
"motd",
"marked_npc_1",
"marked_npc_2",
"marked_npc_3",
};
}
@@ -47,6 +54,9 @@ public:
"loottype",
"locked",
"motd",
"marked_npc_1",
"marked_npc_2",
"marked_npc_3",
};
}
@@ -87,10 +97,13 @@ public:
{
RaidDetails e{};
e.raidid = 0;
e.loottype = 0;
e.locked = 0;
e.motd = "";
e.raidid = 0;
e.loottype = 0;
e.locked = 0;
e.motd = "";
e.marked_npc_1 = 0;
e.marked_npc_2 = 0;
e.marked_npc_3 = 0;
return e;
}
@@ -116,8 +129,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
raid_details_id
)
);
@@ -126,10 +140,13 @@ public:
if (results.RowCount() == 1) {
RaidDetails e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
return e;
}
@@ -167,6 +184,9 @@ public:
v.push_back(columns[1] + " = " + std::to_string(e.loottype));
v.push_back(columns[2] + " = " + std::to_string(e.locked));
v.push_back(columns[3] + " = '" + Strings::Escape(e.motd) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1));
v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_2));
v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_3));
auto results = db.QueryDatabase(
fmt::format(
@@ -192,6 +212,9 @@ public:
v.push_back(std::to_string(e.loottype));
v.push_back(std::to_string(e.locked));
v.push_back("'" + Strings::Escape(e.motd) + "'");
v.push_back(std::to_string(e.marked_npc_1));
v.push_back(std::to_string(e.marked_npc_2));
v.push_back(std::to_string(e.marked_npc_3));
auto results = db.QueryDatabase(
fmt::format(
@@ -225,6 +248,9 @@ public:
v.push_back(std::to_string(e.loottype));
v.push_back(std::to_string(e.locked));
v.push_back("'" + Strings::Escape(e.motd) + "'");
v.push_back(std::to_string(e.marked_npc_1));
v.push_back(std::to_string(e.marked_npc_2));
v.push_back(std::to_string(e.marked_npc_3));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -258,10 +284,13 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RaidDetails e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
all_entries.push_back(e);
}
@@ -286,10 +315,13 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RaidDetails e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
all_entries.push_back(e);
}
@@ -16,11 +16,14 @@
#include "../../strings.h"
#include <ctime>
class BaseRaidMembersRepository {
public:
struct RaidMembers {
uint64_t id;
int32_t raidid;
int32_t charid;
int32_t bot_id;
uint32_t groupid;
int8_t _class;
int8_t level;
@@ -28,18 +31,23 @@ public:
int8_t isgroupleader;
int8_t israidleader;
int8_t islooter;
uint8_t is_marker;
uint8_t is_assister;
std::string note;
};
static std::string PrimaryKey()
{
return std::string("charid");
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"raidid",
"charid",
"bot_id",
"groupid",
"_class",
"level",
@@ -47,14 +55,19 @@ public:
"isgroupleader",
"israidleader",
"islooter",
"is_marker",
"is_assister",
"note",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"raidid",
"charid",
"bot_id",
"groupid",
"_class",
"level",
@@ -62,6 +75,9 @@ public:
"isgroupleader",
"israidleader",
"islooter",
"is_marker",
"is_assister",
"note",
};
}
@@ -102,8 +118,10 @@ public:
{
RaidMembers e{};
e.id = 0;
e.raidid = 0;
e.charid = 0;
e.bot_id = 0;
e.groupid = 0;
e._class = 0;
e.level = 0;
@@ -111,6 +129,9 @@ public:
e.isgroupleader = 0;
e.israidleader = 0;
e.islooter = 0;
e.is_marker = 0;
e.is_assister = 0;
e.note = "";
return e;
}
@@ -121,7 +142,7 @@ public:
)
{
for (auto &raid_members : raid_memberss) {
if (raid_members.charid == raid_members_id) {
if (raid_members.id == raid_members_id) {
return raid_members;
}
}
@@ -136,8 +157,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
raid_members_id
)
);
@@ -146,15 +168,20 @@ public:
if (results.RowCount() == 1) {
RaidMembers e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.charid = static_cast<int32_t>(atoi(row[1]));
e.groupid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e._class = static_cast<int8_t>(atoi(row[3]));
e.level = static_cast<int8_t>(atoi(row[4]));
e.name = row[5] ? row[5] : "";
e.isgroupleader = static_cast<int8_t>(atoi(row[6]));
e.israidleader = static_cast<int8_t>(atoi(row[7]));
e.islooter = static_cast<int8_t>(atoi(row[8]));
e.id = strtoull(row[0], nullptr, 10);
e.raidid = static_cast<int32_t>(atoi(row[1]));
e.charid = static_cast<int32_t>(atoi(row[2]));
e.bot_id = static_cast<int32_t>(atoi(row[3]));
e.groupid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e._class = static_cast<int8_t>(atoi(row[5]));
e.level = static_cast<int8_t>(atoi(row[6]));
e.name = row[7] ? row[7] : "";
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
e.israidleader = static_cast<int8_t>(atoi(row[9]));
e.islooter = static_cast<int8_t>(atoi(row[10]));
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.note = row[13] ? row[13] : "";
return e;
}
@@ -188,15 +215,19 @@ public:
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.raidid));
v.push_back(columns[1] + " = " + std::to_string(e.charid));
v.push_back(columns[2] + " = " + std::to_string(e.groupid));
v.push_back(columns[3] + " = " + std::to_string(e._class));
v.push_back(columns[4] + " = " + std::to_string(e.level));
v.push_back(columns[5] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[6] + " = " + std::to_string(e.isgroupleader));
v.push_back(columns[7] + " = " + std::to_string(e.israidleader));
v.push_back(columns[8] + " = " + std::to_string(e.islooter));
v.push_back(columns[1] + " = " + std::to_string(e.raidid));
v.push_back(columns[2] + " = " + std::to_string(e.charid));
v.push_back(columns[3] + " = " + std::to_string(e.bot_id));
v.push_back(columns[4] + " = " + std::to_string(e.groupid));
v.push_back(columns[5] + " = " + std::to_string(e._class));
v.push_back(columns[6] + " = " + std::to_string(e.level));
v.push_back(columns[7] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[8] + " = " + std::to_string(e.isgroupleader));
v.push_back(columns[9] + " = " + std::to_string(e.israidleader));
v.push_back(columns[10] + " = " + std::to_string(e.islooter));
v.push_back(columns[11] + " = " + std::to_string(e.is_marker));
v.push_back(columns[12] + " = " + std::to_string(e.is_assister));
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -204,7 +235,7 @@ public:
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.charid
e.id
)
);
@@ -218,8 +249,10 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.raidid));
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.groupid));
v.push_back(std::to_string(e._class));
v.push_back(std::to_string(e.level));
@@ -227,6 +260,9 @@ public:
v.push_back(std::to_string(e.isgroupleader));
v.push_back(std::to_string(e.israidleader));
v.push_back(std::to_string(e.islooter));
v.push_back(std::to_string(e.is_marker));
v.push_back(std::to_string(e.is_assister));
v.push_back("'" + Strings::Escape(e.note) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -237,7 +273,7 @@ public:
);
if (results.Success()) {
e.charid = results.LastInsertedID();
e.id = results.LastInsertedID();
return e;
}
@@ -256,8 +292,10 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.raidid));
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.groupid));
v.push_back(std::to_string(e._class));
v.push_back(std::to_string(e.level));
@@ -265,6 +303,9 @@ public:
v.push_back(std::to_string(e.isgroupleader));
v.push_back(std::to_string(e.israidleader));
v.push_back(std::to_string(e.islooter));
v.push_back(std::to_string(e.is_marker));
v.push_back(std::to_string(e.is_assister));
v.push_back("'" + Strings::Escape(e.note) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -298,15 +339,20 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RaidMembers e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.charid = static_cast<int32_t>(atoi(row[1]));
e.groupid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e._class = static_cast<int8_t>(atoi(row[3]));
e.level = static_cast<int8_t>(atoi(row[4]));
e.name = row[5] ? row[5] : "";
e.isgroupleader = static_cast<int8_t>(atoi(row[6]));
e.israidleader = static_cast<int8_t>(atoi(row[7]));
e.islooter = static_cast<int8_t>(atoi(row[8]));
e.id = strtoull(row[0], nullptr, 10);
e.raidid = static_cast<int32_t>(atoi(row[1]));
e.charid = static_cast<int32_t>(atoi(row[2]));
e.bot_id = static_cast<int32_t>(atoi(row[3]));
e.groupid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e._class = static_cast<int8_t>(atoi(row[5]));
e.level = static_cast<int8_t>(atoi(row[6]));
e.name = row[7] ? row[7] : "";
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
e.israidleader = static_cast<int8_t>(atoi(row[9]));
e.islooter = static_cast<int8_t>(atoi(row[10]));
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.note = row[13] ? row[13] : "";
all_entries.push_back(e);
}
@@ -331,15 +377,20 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RaidMembers e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.charid = static_cast<int32_t>(atoi(row[1]));
e.groupid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e._class = static_cast<int8_t>(atoi(row[3]));
e.level = static_cast<int8_t>(atoi(row[4]));
e.name = row[5] ? row[5] : "";
e.isgroupleader = static_cast<int8_t>(atoi(row[6]));
e.israidleader = static_cast<int8_t>(atoi(row[7]));
e.islooter = static_cast<int8_t>(atoi(row[8]));
e.id = strtoull(row[0], nullptr, 10);
e.raidid = static_cast<int32_t>(atoi(row[1]));
e.charid = static_cast<int32_t>(atoi(row[2]));
e.bot_id = static_cast<int32_t>(atoi(row[3]));
e.groupid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e._class = static_cast<int8_t>(atoi(row[5]));
e.level = static_cast<int8_t>(atoi(row[6]));
e.name = row[7] ? row[7] : "";
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
e.israidleader = static_cast<int8_t>(atoi(row[9]));
e.islooter = static_cast<int8_t>(atoi(row[10]));
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.note = row[13] ? row[13] : "";
all_entries.push_back(e);
}
@@ -0,0 +1,50 @@
#ifndef EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
#define EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_character_tribute_repository.h"
class CharacterTributeRepository: public BaseCharacterTributeRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* CharacterTributeRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* CharacterTributeRepository::GetWhereNeverExpires()
* CharacterTributeRepository::GetWhereXAndY()
* CharacterTributeRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
};
#endif //EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
@@ -0,0 +1,221 @@
#ifndef EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H
#define EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_command_subsettings_repository.h"
class CommandSubsettingsRepository: public BaseCommandSubsettingsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* CommandSubsettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* CommandSubsettingsRepository::GetWhereNeverExpires()
* CommandSubsettingsRepository::GetWhereXAndY()
* CommandSubsettingsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
static std::vector<CommandSubsettingsRepository::CommandSubsettings> GetAll(Database& db)
{
// these are the base definitions for command_subsettings and can be over-ridden by the database
std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = {
{.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"},
{.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"},
{.parent_command = "find", .sub_command = "class", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findclass"},
{.parent_command = "find", .sub_command = "currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcurrency"},
{.parent_command = "find", .sub_command = "deity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "finddeity"},
{.parent_command = "find", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findemote"},
{.parent_command = "find", .sub_command = "faction", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findfaction"},
{.parent_command = "find", .sub_command = "item", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fi|finditem|itemsearch"},
{.parent_command = "find", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findlanguage"},
{.parent_command = "find", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fn|findnpc|findnpctype"},
{.parent_command = "find", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrace"},
{.parent_command = "find", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrecipe"},
{.parent_command = "find", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findskill"},
{.parent_command = "find", .sub_command = "spell", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fs|findspell"},
{.parent_command = "find", .sub_command = "task", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findtask"},
{.parent_command = "find", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fz|findzone"},
{.parent_command = "set", .sub_command = "aa_exp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaaxp|setaaexp"},
{.parent_command = "set", .sub_command = "aa_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaapts|setaapoints"},
{.parent_command = "set", .sub_command = "adventure_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setadventurepoints"},
{.parent_command = "set", .sub_command = "alternate_currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaltcurrency"},
{.parent_command = "set", .sub_command = "animation", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setanim"},
{.parent_command = "set", .sub_command = "anon", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setanon"},
{.parent_command = "set", .sub_command = "bind", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "bind"},
{.parent_command = "set", .sub_command = "checksum", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "updatechecksum"},
{.parent_command = "set", .sub_command = "class_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permaclass"},
{.parent_command = "set", .sub_command = "crystals", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setcrystals"},
{.parent_command = "set", .sub_command = "date", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "date"},
{.parent_command = "set", .sub_command = "endurance", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setendurance"},
{.parent_command = "set", .sub_command = "endurance_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "endurance"},
{.parent_command = "set", .sub_command = "exp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setxp|setexp"},
{.parent_command = "set", .sub_command = "faction", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setfaction"},
{.parent_command = "set", .sub_command = "flymode", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flymode"},
{.parent_command = "set", .sub_command = "freeze", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "freeze|unfreeze"},
{.parent_command = "set", .sub_command = "gender", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gender"},
{.parent_command = "set", .sub_command = "gender_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permagender"},
{.parent_command = "set", .sub_command = "gm", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gm"},
{.parent_command = "set", .sub_command = "gm_speed", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gmspeed"},
{.parent_command = "set", .sub_command = "gm_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flag"},
{.parent_command = "set", .sub_command = "god_mode", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "godmode"},
{.parent_command = "set", .sub_command = "haste", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "haste"},
{.parent_command = "set", .sub_command = "hero_model", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "heromodel"},
{.parent_command = "set", .sub_command = "hide_me", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hideme"},
{.parent_command = "set", .sub_command = "hp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "sethp"},
{.parent_command = "set", .sub_command = "hp_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "heal"},
{.parent_command = "set", .sub_command = "invulnerable", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "invul|invulnerable"},
{.parent_command = "set", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setlanguage"},
{.parent_command = "set", .sub_command = "last_name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "lastname"},
{.parent_command = "set", .sub_command = "level", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "level"},
{.parent_command = "set", .sub_command = "loginserver_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setlsinfo"},
{.parent_command = "set", .sub_command = "mana", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setmana"},
{.parent_command = "set", .sub_command = "mana_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "mana"},
{.parent_command = "set", .sub_command = "motd", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "motd"},
{.parent_command = "set", .sub_command = "name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "name"},
{.parent_command = "set", .sub_command = "ooc_mute", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "oocmute"},
{.parent_command = "set", .sub_command = "password", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setpass"},
{.parent_command = "set", .sub_command = "pvp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "pvp"},
{.parent_command = "set", .sub_command = "pvp_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setpvppoints"},
{.parent_command = "set", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "race"},
{.parent_command = "set", .sub_command = "race_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permarace"},
{.parent_command = "set", .sub_command = "server_locked", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "lock|serverlock|serverunlock|unlock"},
{.parent_command = "set", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setskill"},
{.parent_command = "set", .sub_command = "skill_all", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setallskill|setallskills|setskillall"},
{.parent_command = "set", .sub_command = "skill_all_max", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "maxskills"},
{.parent_command = "set", .sub_command = "start_zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setstartzone"},
{.parent_command = "set", .sub_command = "temporary_name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "tempname"},
{.parent_command = "set", .sub_command = "texture", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "texture"},
{.parent_command = "set", .sub_command = "time", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "time"},
{.parent_command = "set", .sub_command = "time_zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "timezone"},
{.parent_command = "set", .sub_command = "title", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "title"},
{.parent_command = "set", .sub_command = "title_suffix", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "titlesuffix"},
{.parent_command = "set", .sub_command = "weather", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "weather"},
{.parent_command = "set", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zclip|zcolor|zheader|zonelock|zsafecoords|zsky|zunderworld"},
{.parent_command = "show", .sub_command = "aggro", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "aggro"},
{.parent_command = "show", .sub_command = "buffs", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showbuffs"},
{.parent_command = "show", .sub_command = "buried_corpse_count", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getplayerburiedcorpsecount"},
{.parent_command = "show", .sub_command = "client_version_summary", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "cvs"},
{.parent_command = "show", .sub_command = "currencies", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewcurrencies"},
{.parent_command = "show", .sub_command = "distance", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "distance"},
{.parent_command = "show", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "emoteview"},
{.parent_command = "show", .sub_command = "field_of_view", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fov"},
{.parent_command = "show", .sub_command = "flags", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flags"},
{.parent_command = "show", .sub_command = "group_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "ginfo"},
{.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"},
{.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"},
{.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"},
{.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"},
{.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"},
{.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"},
{.parent_command = "show", .sub_command = "npc_global_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "shownpcgloballoot"},
{.parent_command = "show", .sub_command = "npc_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "npcstats"},
{.parent_command = "show", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewnpctype"},
{.parent_command = "show", .sub_command = "peqzone_flags", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peqzone_flags"},
{.parent_command = "show", .sub_command = "petition", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "listpetition|viewpetition"},
{.parent_command = "show", .sub_command = "petition_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "petitioninfo"},
{.parent_command = "show", .sub_command = "proximity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "proximity"},
{.parent_command = "show", .sub_command = "quest_errors", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "questerrors"},
{.parent_command = "show", .sub_command = "quest_globals", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "globalview"},
{.parent_command = "show", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewrecipe"},
{.parent_command = "show", .sub_command = "server_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "serverinfo"},
{.parent_command = "show", .sub_command = "skills", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showskills"},
{.parent_command = "show", .sub_command = "spawn_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "spawnstatus"},
{.parent_command = "show", .sub_command = "spells", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showspells"},
{.parent_command = "show", .sub_command = "spells_list", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showspellslist"},
{.parent_command = "show", .sub_command = "stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showstats"},
{.parent_command = "show", .sub_command = "timers", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "timers"},
{.parent_command = "show", .sub_command = "traps", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "trapinfo"},
{.parent_command = "show", .sub_command = "uptime", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "uptime"},
{.parent_command = "show", .sub_command = "variable", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getvariable"},
{.parent_command = "show", .sub_command = "version", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "version"},
{.parent_command = "show", .sub_command = "waypoints", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "wpinfo"},
{.parent_command = "show", .sub_command = "who", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "who"},
{.parent_command = "show", .sub_command = "xtargets", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "xtargets"},
{.parent_command = "show", .sub_command = "zone_global_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showzonegloballoot"},
{.parent_command = "show", .sub_command = "zone_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewzoneloot"},
{.parent_command = "show", .sub_command = "zone_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showzonepoints"},
{.parent_command = "show", .sub_command = "zone_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zstats"},
{.parent_command = "show", .sub_command = "zone_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zonestatus"},
};
auto db_sub_settings = All(db);
// inject commands in the database that are not already there
std::vector<CommandSubsettingsRepository::CommandSubsettings> new_records = {};
for (const auto &r: static_records) {
bool found = false;
for (const auto &db_r: db_sub_settings) {
if (r.parent_command == db_r.parent_command && r.sub_command == db_r.sub_command) {
found = true;
}
}
if (!found) {
LogInfo("New command [{}] sub-command [{}] added to database table [{}] !", r.parent_command, r.sub_command, TableName());
new_records.emplace_back(r);
}
}
if (!new_records.empty()) {
InsertMany(db, new_records);
// if any were added, we need to reload the list
db_sub_settings = All(db);
}
// remove commands from the database that are not in the static list
bool any_deleted = false;
for (const auto &db_r: db_sub_settings) {
bool found = false;
for (const auto &r: static_records) {
if (r.parent_command == db_r.parent_command && r.sub_command == db_r.sub_command) {
found = true;
}
}
if (!found) {
LogInfo("Command [{}] sub-command [{}] removed from database table [{}] !", db_r.parent_command, db_r.sub_command, TableName());
DeleteWhere(db, fmt::format("parent_command = '{}' AND sub_command = '{}'", db_r.parent_command, db_r.sub_command));
any_deleted = true;
}
}
// if any were deleted, re-read the database
if (any_deleted) {
db_sub_settings = All(db);
}
// return the final list of what's in the database
return db_sub_settings;
}
};
#endif //EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H
+28
View File
@@ -44,7 +44,35 @@ public:
*/
// Custom extended repository methods here
static std::vector<int32> GetItemIDsBySearchCriteria(
Database& db,
std::string search_string,
int query_limit = 0
)
{
auto query = fmt::format(
"SELECT `id` FROM {} WHERE LOWER(`name`) LIKE '%%{}%%' ORDER BY id ASC",
TableName(),
Strings::Escape(search_string)
);
if (query_limit >= 1) {
query += fmt::format(" LIMIT {}", query_limit);
}
std::vector<int32> item_id_list;
auto results = db.QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return item_id_list;
}
for (auto row : results) {
item_id_list.emplace_back(Strings::ToInt(row[0]));
}
return item_id_list;
}
};
#endif //EQEMU_ITEMS_REPOSITORY_H
@@ -44,7 +44,24 @@ public:
*/
// Custom extended repository methods here
static int UpdateRaidMarkedNPC(
Database& db,
int32_t raid_id,
uint8_t marked_npc_number,
uint8_t value
) {
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `marked_npc_{}` = '{}' WHERE raidid = '{}';",
TableName(),
marked_npc_number,
value,
raid_id
)
);
return results.Success() ? results.RowsAffected() : 0;
}
};
#endif //EQEMU_RAID_DETAILS_REPOSITORY_H

Some files were not shown because too many files have changed in this diff Show More