Compare commits

..

480 Commits

Author SHA1 Message Date
hg 4a66c3918a Convert perl apis to perlbind 2022-06-12 19:56:46 -04:00
hg a2c6252c58 Add perlbind library 2022-06-12 19:56:45 -04:00
Kinglykrab be00aa1b60 [Loot] Remove unnecessary loot error messages. (#2261)
* [Loot] Remove unnecessary loot error messages.
These messages are only sent when you loot a corpse that is mid-decay (i.e. no items and you go to loot it immediately) or if you try to loot a non-corpse entity.
The ent != 0 shows up a lot if you're trying to loot too quickly and really isn't an error, the server just hasn't caught up to decay the corpse before you try to loot.

* Use preexisting struct.

* Remove newline.

* Update client_packet.cpp
2022-06-12 18:44:16 -04:00
Akkadius b2658a6cbc [Hotfix] Correct database call to point to the content_db connection 2022-06-12 17:34:51 -05:00
Michael 026133f32a [Bug Fix] Tradeskill Item 0 Error (#2256)
When trying to fully script a combine so the tradeskill itself does not return an item (Item 0) and handling all items through quests, the source will provide an error regardless that "Item 0 does not exist". This change will move the item summon after the validity check thus preventing the error to the client.
2022-06-10 13:53:30 -04:00
Michael 6d4f22a1c0 [Bug Fix] Tradeskill Autocombine MinSkill (#2260)
* [Bug] Tradeskill Autocombine MinSkill

Require min tradeskill or above for autocombine.

* Syntax fixes
2022-06-10 13:52:31 -04:00
Michael e75f87a535 [Quest API] Expand SaveGuardSpot (#2258)
* Expand SaveGuardSpot

- Adds
-- mob:saveguardspot()
-- mob:saveguardspot(true)

* Perl Support
Thanks to KinglyKrab for the perl implementation.
2022-06-10 13:52:22 -04:00
Kinglykrab 83e066bffc [Bug Fix] Stop skill ups on Charmed NPCs. (#2249)
- Clients were capable of leveling up their melee skills on Charmed Mobs according to: https://github.com/EQEmu/Server/issues/2182
2022-06-09 21:08:50 -04:00
Chris Miles 4639405fdf [Discord Integration] Native Discord Integration (#2140)
* Start of discord integration work

* more testing

* Discord client work

* More discord work

* Cleanup

* Handle retry timer response and max retries

* Update base retry timer

* Move Discord queue handler to UCS, add queuer to own thread

* Post merge

* Send up Zone::SendDiscordMessage

* Start of discord integration work

* more testing

* Discord client work

* More discord work

* Cleanup

* Move Discord queue handler to UCS, add queuer to own thread

* Post merge

* Push up tables

* Quest API stuff.

* Update 2022_05_07_discord_webhooks.sql

* Post merge fixes

* Push up manifest

* Flip logging signs in logic from copy / paste of inverse logic before

* Make sure we add new line to quest api sourced messages

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2022-06-09 17:22:23 -05:00
hg 8ef3e87370 [Bug Fix] Fix stack leaks in Lua events #2254
EventItem was leaving the package table on the stack in successful
(non-encounter) calls and only popping the return. All events were
also leaking the full stack on lua_pcall errors. Lua mod callbacks
were popping error returns but leaking the table.
2022-06-09 17:20:35 -05:00
Akkadius bec28769aa [Hotfix] Flipped positive / negative values for legacy_combat.lua 2022-06-09 17:19:00 -05:00
Kinglykrab 8586cdc47e [Messages] Convert messages from Spells to FocusEffect where necessary. (#2243)
* [Messages] Convert messages from Spells to FocusEffect where necessary.
https://github.com/EQEmu/Server/issues/837 from 2019 notes a couple places that should use Focus Effect chat type instead of Spells chat type.

* Add rule for item cast messages.
2022-06-08 19:09:33 -04:00
Michael Cook (mackal) 63ba5dc3ab Fix memory leaks found by Quint (#2248) 2022-06-07 23:41:13 -04:00
Michael fcc7725ca3 [Bug Fix] Bazaar Search MYSQL Error (#2252)
Corrected fields that the bazaar search function is using to prevent mysql error due to non-existant field items.spellid.
2022-06-07 21:21:02 -04:00
Michael 5df6a61c96 [Bug Fix] Hacker_Str was causing sql errors - Non Escaped (#2251)
Processing the hacker_str through EscapeString().
2022-06-07 21:19:24 -04:00
Kinglykrab fc5105eed7 [Rules] Add Frontal Stun Immunity Rules. (#2217)
* [Rules] Add Frontal Stun Immunity Rules.
- Add Combat:FrontalStunImmunityClasses rule for determining Frontal Stun Immunity by class bitmasks
- Add Combat:FrontalStunImmunityRaces rule for determining Frontal Stun Immunity by race bitmasks
- Add Combat:NPCsUseFrontalStunImmunityClasses rule for determining if NPCs use Frontal Stun Immunity by class bitmasks
- Add Combat:NPCsUseFrontalStunImmunityRaces rule for determining if NPCs uses Frontal Stun Immunity by race bitmasks
- Cleanup GetDefaultGender() as best as possible with the globalload I have.
- Combat:NPCsUseFrontalStunImmunityRaces defaults to true as NPCs currently use Frontal Stun Immunity.
- Added **all** Ogre races to the check for Frontal Stun Immunity.

* Remove other Ogre races.
2022-06-06 22:29:06 -05:00
Quintinon 243fb781e8 [Bug Fix] Fix two invalid data accesses in zone/client.cpp (#2238)
* Correct potential read out of bounds on array in Client::Doppelganger

* Correct potential read out of bounds in Client::ChannelMessageSend

* Corrected logic to not read out of bounds on the lower end.
2022-06-06 22:26:36 -05:00
Kinglykrab ec4d228dd5 [Bug Fix] Fix issue where #advnpcspawn addspawn does not add spawn sometimes. (#2247)
* [Bug Fix] Fix issue where #advnpcspawn addspawn does not add spawn sometimes.
- Cleanup where std::stoi should be std::stoul.
- Cleanup ShowStats message to show NPC stats at bottom as well.

* Update advnpcspawn.cpp
2022-06-06 22:24:45 -05:00
Michael Cook (mackal) 2910073373 [Memory Leak] Fix leak of CommandRecords in commandlist (#2244)
* Fix leak of CommandRecords in commandlist

Quicker than porting to std::unique_ptr since we do fun stuff with
commandlist ...

* Fix leak so it won't double free

This is fine enough until we rewrite it to be better
2022-06-06 15:21:35 -04:00
Kinglykrab b4d5e807e3 [Commands] Add BestZ and Region Data to #loc (#2245) 2022-06-05 15:38:51 -04:00
Kinglykrab 8f729fe948 [Rules] Add Rule to Disable NPC Last Names. (#2227)
* [Rules] Add Rule to Disable NPC Last Names.
- Add NPC:DisableLastNames to disable NPC Last Names.
- Fix #npcedit lastname to allow you to use an empty string.

* Cleanup of classes in naming.

* Duplicate.

* Update classes.cpp
2022-06-04 14:01:00 -04:00
Kinglykrab 7160aa651e [Cleanup] Cleanup Haste references and Lua API calls for unsigned to signed. (#2240) 2022-06-04 14:00:21 -04:00
Kinglykrab 8414ce02e3 [Cleanup] Add Validation to varchar number item fields. (#2241)
- combateffects and charmfileid were varchar and have no default value, so if you passed '' shared memory would fail, default these to 0 to prevent this.
2022-06-04 14:00:16 -04:00
Kinglykrab 17034a6e47 [Commands] Cleanup #spawneditmass Command. (#2229)
* [Commands] Cleanup #spawneditmass Command.
- Cleanup messages and logic.
- Split command into its own file.

* Save querying database if they're not using the only supported option.

* Condense to one message.
2022-06-04 12:59:46 -05:00
Quintinon be1772d464 [Bug Fix] Correct (probably) unintended bitwise AND instead of logical AND (#2239) 2022-06-01 21:17:39 -04:00
Quintinon a00f086bb8 [Combat] Fix shield calculation (#2234)
* Fix max mitigation calculation

* Fix shield ability not receiving correct arguments from perl script.

* Correct shielder having wrong mitigation set.
2022-06-01 17:17:14 -04:00
Quintinon de830e5535 [Code Cleanup] Resharper Warnings (#2235)
* Remove unused local variable

* Remove another unused variable

* Correct typos and remove unused initialization

* Cleanup some code in OPCharCreate

* Remove unused function in client.cpp and undefined declaration.
Also the function potentially had a null pointer dereference according to Visual Studio.
2022-06-01 17:16:49 -04:00
Kinglykrab d1404a2d95 [Rules] Add Rules to disable various item functionalities and cleanup data types. (#2225)
- Noticed some data types were unsigned when they should be signed based on Live items having these stats as negatives.
- Loregroup was uint32 and should be int32 for Loregroup -1, fixed any references to -1 as 0xFFFFFFFF.
- Attack was uint32 and should be int32.
- DamageShield was uint32 and should be int32.
- DotShielding was uint32 and should be int32.
- Endurance was uint32 and should be int32.
- EnduranceRegen was uint32 and should be int32.
- Haste was uint32 and should be int32.
- ManaRegen was uint32 and should be int32.
- Regen was uint32 and should be int32.
- RULE_BOOL(Items, DisableAttuneable, false, "Enable this to disable Attuneable Items")
- RULE_BOOL(Items, DisableBardFocusEffects, false, "Enable this to disable Bard Focus Effects on Items")
- RULE_BOOL(Items, DisableLore, false, "Enable this to disable Lore Items")
- RULE_BOOL(Items, DisableNoDrop, false, "Enable this to disable No Drop Items")
- RULE_BOOL(Items, DisableNoPet, false, "Enable this to disable No Pet Items")
- RULE_BOOL(Items, DisableNoRent, false, "Enable this to disable No Rent Items")
- RULE_BOOL(Items, DisableNoTransfer, false, "Enable this to disable No Transfer Items")
- RULE_BOOL(Items, DisablePotionBelt, false, "Enable this to disable Potion Belt Items")
- RULE_BOOL(Items, DisableSpellFocusEffects, false, "Enable this to disable Spell Focus Effects on Items")
2022-06-01 17:12:31 -04:00
Kinglykrab 38da37755d [Bug Fix] Fix MovePC in #zone and #zoneinstance Commands. (#2236)
* [Bug Fix] Fix MovePC in #zone and #zoneinstance COmmands.

* #zone 0 Optional Functionality.
2022-06-01 17:05:43 -04:00
Kinglykrab 57ac46d090 [Commands] Cleanup #date Command. (#2228)
* [Commands] Cleanup #date Command.
- Cleanup messages and logic.

* Cleanup.
2022-06-01 15:31:31 -04:00
Chris Miles 59f32b8d34 [Loading] Zone Version Loading Fixes (#2233)
* Zone version loading fixes

* Remove errant code
2022-05-31 22:15:05 -05:00
Chris Miles a45117cd04 [Bug Fix] Adjustment for nullptr crash (#2232) 2022-05-31 22:24:12 -04:00
Chris Miles 291aaea581 [Bug Fix] Fix null pointer crash on zones that have not booted a zone yet with #reload commands or anything that calls GetZoneDescription (#2231) 2022-05-31 21:55:00 -04:00
Chris Miles 162d34e1d9 [Tasks] Fix validation loading (#2230) 2022-05-31 21:47:01 -04:00
titanium-forever 86c9be410d [Database Backup] Enable database dump of bot data (#2221)
* Add option to dump bot data

* Add player_bot_table dump suppor to command handler

* Add tableList getter to the dump_service

* Fix declaration in header file

* Include missed bot tables

* Rename player-bot to bot to be more descriptive

* Fix missed reference to player-bots

Co-authored-by: Kieren Hinch <khinch-github@nylonmoon.com>
2022-05-31 18:25:10 -05:00
Kinglykrab 30e34c67b4 [Quest API] Fix parameters in some Perl worldwide methods. (#2224) 2022-05-31 15:46:14 -04:00
Kinglykrab ce8b8da0d6 [Bug Fix] Fix Legacy Combat Lua Script (#2226) 2022-05-30 22:43:03 -04:00
Kinglykrab 02e8b125a4 [Hot Fix] Fix Linux compile due to missing include. (#2223)
- Not sure how Windows compiles, but Linux fails.
2022-05-30 22:10:49 -04:00
Kinglykrab 11369247b1 [INT64] Further int64 cleanup in Perl SetHP() and GetSpellHPBonuses() in Perl/Lua. (#2222) 2022-05-29 16:36:32 -05:00
Kinglykrab d493a6627b [Commands] Cleanup #nudge Command. (#2220)
* [Commands] Cleanup #nudge Command.
- Cleanup messages and logic.

* Update nudge.cpp

* Update nudge.cpp
2022-05-29 14:33:40 -04:00
Kinglykrab b07945f0be [Commands] Cleanup #emptyinventory Command. (#2219)
- Cleanup messages and logic.
- Breakout #emptyinventory into its own command file.
2022-05-29 14:33:35 -04:00
Kinglykrab 8f3ac74196 [INT64] Fix int64 for OOC Regen and GetHP(), GetMaxHP(), GetItemHPBonuses() in Perl/Lua. (#2218)
* [INT64] Fix int64 for OOC Regen and GetHP(), GetMaxHP(), GetItemHPBonuses() in Perl/Lua.
- These all had int64 values and were overflowing, returning garbage data.

* Update npc.cpp
2022-05-29 14:33:30 -04:00
Kinglykrab bcf7ccefcd [Money Messages] Cleanup quest::givecash(), split, and task reward messages. (#2205)
* [Money Messages] Cleanup quest::givecash(), split, and task reward messages.
- Cleans up all the money messages using ConvertMoneyToString().
- Allows quest::givecash() to have optional parameters other than copper.

* Commification.

* Corpse messages.

* String IDs and cleanup.
2022-05-29 14:33:18 -04:00
Kinglykrab 9e9ef6809b [Cleanup] Cleanup spell and max level bucket logic. (#2181)
* [Cleanup] Cleanup spell and max level bucket logic.
- Spell buckets will now allow new mob->SetBucket() buckets since most people use these now.
- Max level bucket will now allow new mob->SetBucket() bucket since most people use these now.
- Clean up GetScribeableSpells() and GetLearnableDisciplines() logic and magic numbers.
- Make GetClientMaxLevel() uint8 instead of int since it can only be 0-255.

* Fix typo from other commit.

* Lua setter.

* Update client.cpp
2022-05-28 14:35:17 -04:00
Kinglykrab c8f6dbb86d [Commands] Cleanup #npcedit, #lastname, #title, and #titlesuffix Commands. (#2215)
* [Commands] Cleanup #lastname, #npcedit, #title, and #titlesuffix Commands.
- Cleanup messages and logic.

* Update emu_constants.h

* Update command.cpp

* Update command.cpp

* Cleanup of GetXName methods to not define map unnecessarily.

* Update emu_constants.cpp

* Update npcedit.cpp
2022-05-28 14:35:05 -04:00
Kinglykrab 7de50d0e60 [Bug Fix] Fix IP Exemptions. (#2189)
* [Bug Fix] Fix IP Exemptions.
- IP Exemptions were broken due to GetAccountID() returning 0 in logic somehow, resolved this by setting a variable to GetAccountID() at the beginning of the method.
- Fixed weird IP messages where the long form of IP was displayed instead of the string form.
- Fixes edge case where IP rule may be set to -1 and this will make anyone get instantly kicked if IP Exemptions were enabled as their IP Count would always be greater than -1.

* Update client.cpp

* Update client.cpp

* Update clientlist.cpp

* Update clientlist.cpp
2022-05-27 23:57:55 -04:00
Paul Coene aaaee6c6a4 [Bug Fix] IsDamage test for lifetap was not complete. (#2213)
* [Bug Fix] IsDamage test for lifetap was not complete.

* Fix magic # and formatting as per Kingly

* Added #define
2022-05-27 15:30:38 -04:00
Kinglykrab d7f38361f2 [Commands] Cleanup #findaliases and #help Commands. (#2204)
- Cleanup messages and logic.
- Add saylinks to messages for ease of use when searching for commands as most have help messages when using them incorrectly or require no arguments and can be used immediately from the say link.
2022-05-27 15:28:36 -04:00
Kinglykrab 275995a374 [Commands] Cleanup #zone and #zoneinstance Commands. (#2202)
* [Commands] Cleanup #zone and #zoneinstance Commands.
- Cleanup messages and logic.
- Broke these commands out in to their own files.

* Update database.cpp

* Update database.cpp

* Update database.cpp
2022-05-27 15:26:30 -04:00
Kinglykrab 7072b5721b [Rules] Add Spells:BuffsFadeOnDeath. (#2200)
- Allows you to disable buffs fading on death.
2022-05-27 15:00:59 -04:00
Kinglykrab 123bc5f19a [Commands] Cleanup #findclass and #findrace Commands. (#2211)
- Cleanup messages and logic.
- Add bitmasks to player race messages.
2022-05-27 14:46:53 -04:00
Kinglykrab e6db71e31e [Commands] Cleanup #corpsefix Command. (#2197)
* [Commands] Cleanup #corpsefix Command.
- Cleanup messages and logic.

* Update entity.cpp
2022-05-27 14:46:26 -04:00
Kinglykrab 129a738072 [Commands] Cleanup #level Command. (#2203)
- Cleanup messages and logic.
- Breakout #level into its own command file.
2022-05-27 14:45:26 -04:00
Kinglykrab 0de90dc135 [Rules] Add Spells:IllusionsAlwaysPersist. (#2199)
- Allows illusions to always persist beyond death or zoning.
2022-05-27 14:39:35 -04:00
Kinglykrab 5bc4cff7a9 [Regen] Fix possible overflow in CalcHPRegenCap(). (#2185) 2022-05-27 14:39:25 -04:00
Kinglykrab f9191d4ef4 [Commands] Cleanup #oocmute Command. (#2191)
- Cleanup messages and logic.
- Add ServerOOCMute_Struct for cleanliness.
2022-05-27 14:38:40 -04:00
Michael Cook (mackal) 49d751b3d5 Revert "[Aggro] Rooted mobs will add other hated targets to Hate list (#2180)" (#2214)
This reverts commit 14f48fcc93.
2022-05-27 11:40:43 -04:00
Paul Coene 14f48fcc93 [Aggro] Rooted mobs will add other hated targets to Hate list (#2180) 2022-05-27 09:37:55 -04:00
titanium-forever 25addc3bd9 Create user directory during account creation to ensure default files are copied to profile from /etc/skel (#2176)
Co-authored-by: Kieren Hinch <khinch-github@nylonmoon.com>
2022-05-27 00:22:31 -05:00
Kinglykrab 7f12ad325a [Bug Fix] Fix bot compile locking client on server enter. (#2210) 2022-05-26 14:10:19 -04:00
Kinglykrab 6636c64c82 [Commands] Fix typos in #ban and #ipban Commands. (#2209) 2022-05-25 20:05:07 -04:00
Chris e2708af6f2 [Bug Fix] Blocked spells max spell id increased (#2207)
https://github.com/EQEmu/Server/pull/2073 broke blocking spells. There is another location in mob.h that needs to be updated to int32. Tested as fixed on my server.
2022-05-25 17:53:40 -04:00
Kinglykrab 1de0c27629 [Bug Fix] Fix HP Regen Per Second. (#2206)
`hp_regen_rate` was being used for `hp_regen_per_second` incorrectly.
2022-05-25 12:08:28 -05:00
Kinglykrab 9ccdb9eb84 [Bot Commands] Use Account Status Constants. (#2201)
- Convert bot_command_add calls to use constants instead of magic numbers.
2022-05-23 19:56:56 -04:00
Kinglykrab e69f7a6cf1 [Commands] Remove unused/broken #deletegraveyard and #setgraveyard Commands. (#2198)
- These commands don't function in their current state, and they probably haven't ever.
- Removing the commands and putting this in an editor makes more sense, as #setgraveyard uses the current zone XYZ coordinates of a target to set a graveyard for another zone. and they also only allow version 0 graveyards.
- Not sure of a better idea than just deleting, as setting data based on another zone using your current zone's data seems beyond the scope of a command.
2022-05-23 19:56:30 -04:00
Kinglykrab efd04f8324 [Commands] Cleanup #motd Command. (#2190) 2022-05-23 19:56:19 -04:00
Kinglykrab eeacc62a91 [Rules] Cleanup all unused rules. (#2184) 2022-05-23 19:56:03 -04:00
Kinglykrab a7a525ed0b [Commands] #bind Typo. (#2196) 2022-05-22 22:31:14 -04:00
Kinglykrab e43538cf73 [Commands] Cleanup #kill Command. (#2195)
- Cleanup messages and logic.
2022-05-22 22:31:08 -04:00
Kinglykrab 5b90d26a33 [Bug Fix] Fix bot guild removal. (#2194) 2022-05-22 22:31:03 -04:00
Kinglykrab 992e4ac59e [Commands] Consolidate #lock and #unlock Commands into #serverlock. (#2193)
- Convert the two commands into one command.
- Cleanup struct naming.
2022-05-22 22:30:56 -04:00
Chris Miles 6b85c914a5 Schema consistency fixes (#2192) 2022-05-21 23:44:04 -04:00
Kinglykrab 089246db53 [Cleanup] Move Client::Undye() to client.cpp from #path Command. (#2188)
- Client::Undye() was inside the #path command file.
2022-05-21 10:26:45 -04:00
Paul Coene f3e5423677 [Bug Fix] Fix duplicate and missing messages due to innate in spells (#2170)
* [Bug Fix] Fix duplicate and missing messages due to innate skill in spells.

* Seperate spell and melee damage range and skip

* Refine when innate messages are produced.

* Fix magic # (replace with constant)
2022-05-20 11:49:18 -04:00
Kinglykrab 0e96099b3d [Titles] Cleanup titles, title suffix, and last name methods. (#2174)
* [Titles] Cleanup titles, title suffix, and last name methods.
- Use strings instead of const chars*.
- Add optional parameter to SetAATitle in Lua so you can save to the database similar to Perl.
- Cleanup #lastname command.
- Cleanup #title command.
- Cleanup #titlesuffix command.

* Update npc.cpp
2022-05-19 20:15:44 -04:00
Kinglykrab 6398381c44 [Quest API] Add CheckNameFilter to Perl/Lua. (#2175)
- Add quest::checknamefilter(name) to Perl.
- Add eq.check_name_filter(name) to Lua.
- Allows operators to check strings against the name filter for stuff like setting custom pet names, titles, suffixes, etc in scripts.
2022-05-19 20:01:14 -04:00
Kinglykrab 7c1a139991 [Cleanup] Quest API push methods using invalid types. (#2172)
* [Cleanup] Quest API push methods using invalid types.
- Some push methods were pushing integers as unsigned integers or unsigned integer as integers, this fixes all of that.
- Also cleans up some lines that had multiple function calls on them.

* More cleanup of bools and one expansion name was wrong.
2022-05-15 22:14:16 -04:00
Kinglykrab 8554aab2ff [Cleanup] Remove unused methods. (#2171) 2022-05-15 19:12:33 -04:00
hg 77e72ba666 Save eyes in #npcedit featuresave (#2178) 2022-05-15 19:12:22 -04:00
Kinglykrab 8329760632 [Quest API] Add TaskSelector to Perl/Lua. (#2177)
- Add $client->TaskSelector(task_list) to Perl.
- Add client:TaskSelector({task_list}) to Lua.
- Allow $client->AssignTask(task_id) in Perl.
- Allow client:AssignTask(task_id) in Lua.
- Can now assign tasks in scripts without the NPC ID parameter.
2022-05-15 00:49:55 -04:00
hg d8aa8f7e7a [Opcode] Implement SetFace opcode (#2167)
* Implement SetFace opcode

This implements the opcode that's used to update zone clients when a
client updates their face

* Use SetFace in #feature command

Add check for valid number

This adds the #feature eyes command which isn't in the illusion struct
2022-05-11 19:57:20 -04:00
Kinglykrab 29cdd91ca0 [Quest API] Add GetHealAmount() and GetSpellDamage() to Perl/Lua. (#2165)
- Add $client->GetHealAmount() to Perl.
- Add $client->GetSpellDamage() to Perl.
- Add client:GetHealAmount() to Lua
- Add client:GetSpellDamage() to Lua.
2022-05-11 06:35:27 -04:00
Kinglykrab df99d97431 [Cleanup] Cleanup #kick message. (#2164) 2022-05-10 19:52:14 -04:00
Kinglykrab f314e05087 [Hot Fix] Off by on in Merchant Loading. (#2166) 2022-05-10 18:25:32 -04:00
Kinglykrab d120cf8a40 [Commands] #reload Command Overhaul. (#2162)
* [Commands] #reload Command Overhaul.
- Consolidated #reloadaa, #reloadallrules, #reloadcontentflags, #reloademote, #reloadlevelmods, #reloadmerchants, #reloadperlexportsettings, #reloadqst, #reloadstatic, #reloadtitles, #relaodtraps, #reloadworld, and #reloadzps in to one command.
- #reload has 15 different sub commands you may use, including Log Settings and Tasks reloading.
- All the reload commands are a part of the Developer Tools Menu messages now, as well as part of the documentation.
- Fixes the commands that weren't actually sending their packet to zone server to globally reload stuff.
- Added Variables table reloading to command.

* Consistency.

* Hot reload.

* Final big push.
2022-05-10 06:19:07 -04:00
Chris Miles 209b0eb273 [int64] Hate Fixes (#2163)
* Hate fixes

* Update perl_hateentry.cpp

* Update perl_hateentry.cpp
2022-05-09 20:49:43 -05:00
Kinglykrab 763fc82379 [Merchants] Add Merchant Data Bucket capability. (#2160)
* [Merchants] Add Merchant Data Bucket capability.
- Allows server operators to limit merchant items based on data bucket values and comparisons.
- Adds 3 columns, bucket_name, bucket_value, and bucket_comparison to merchantlist table.
- Bucket is checked based on GetBucketKey()-bucket_name.
- Buckets are mass loaded when using the merchant so it's not a database call per item, just a grouping of all their buckets from the start.
- This is a nearly year old pull request redone for master.
- bucket_comparison Values are as follows:
        - bucket_comparison 0: bucket_name == bucket_value
        - bucket_comparison 1: bucket_name != bucket_value
        - bucket_comparison 2: bucket_name >= bucket_value
        - bucket_comparison 3: bucket_name <= bucket_value
        - bucket_comparison 4: bucket_name > bucket_value
        - bucket_comparison 5: bucket_name < bucket_value
        - bucket_comparison 6: bucket_name is any of  pipe(|)-separated bucket_value
        - bucket_comparison 7: bucket_name is not any of  pipe(|)-separated bucket_value
        - bucket_comparison 8: bucket_name is between first and second value of pipe(|)-separated bucket_value
        - bucket_comparison 9: bucket_name is not between first and second value of pipe(|)-separated  bucket_value

* Revert query change.
2022-05-09 21:36:51 -04:00
Kinglykrab 6e0d101457 [Cleanup] Possible issues with variable/parameter name equality. (#2161) 2022-05-09 21:00:37 -04:00
Chris Miles a1a4f91ea6 [Hotfix] Fix regression caused by #2129 2022-05-09 01:18:10 -05:00
Michael Cook (mackal) 6cc845e05e Fix out of bounds issues with SPA 288 (#2157) 2022-05-08 18:18:24 -04:00
Kinglykrab 597e324319 [Bug FIx] Fix #repop Command. (#2159)
If you use no arguments, the command does not repop.
2022-05-08 17:01:50 -04:00
Kinglykrab f370a6048f [Bug Fix] Make Perl TakeMoneyFromPP int64 (#2158) 2022-05-08 13:17:46 -04:00
Kinglykrab 9d784d0d9b [Bug Fix] Fix possible issue where variables have the same name. (#2156)
* [Bug Fix] Fix possible issue where variables have the same name.

* Naming.
2022-05-08 01:43:28 -04:00
Chris Miles fd7b15abb1 [int64] Windows Compile Fixes (#2155)
* int64 windows aftermath

* Perl.

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2022-05-07 23:45:52 -05:00
Kinglykrab b27428a6d8 [Commands] Cleanup #cvs Command. (#2153)
* [Commands] Cleanup #cvs Command.
- Cleanup messages and logic.
- std::find was using .begin() in both comparisons, so it wasn't working and unique IPS always returned 1.

* Update cvs.cpp
2022-05-07 23:45:44 -04:00
Chris Miles f201d4c999 [int64] Support for HP / Mana / End / Damage / Hate (#2091)
* Initial int64 work

* Hate 64 bit

* Update special_attacks.cpp

* Aggro / Damage / Hate int64

* NPC edit adjustments

* Fix bot compile

* More int64 adjustments

* More int64 references

* npcedit references

* aggrozone

* More int64 changes

* More int64 changes for damage

* Many more damage int64 references

* More spell damage int64 conversions

* HealDamage

* Damage fully working

* Remove debug

* Add migration

* More int64 adjustments

* Much wow, many int64

* More int64

* PR adjustments
2022-05-07 22:32:02 -05:00
Kinglykrab d9c41526e8 [Commands] Cleanup #ban, #ipban, #flag, #kick, #setlsinfo, and #setpass Commands. (#2104)
* [Commands] Cleanup #ban, #ipban, #flag, and #kick Commands.
- Cleanup messages and logic.
- Add ServerFlagUpdate_Struct for flag updates.

* Add #setlsinfo and #setpass to cleanup.

* Update setlsinfo.cpp

* Update database.cpp

* Update database.cpp

* Update command.cpp
2022-05-07 23:28:45 -04:00
Chris Miles 07b46ed445 [UCS] Auto Client Reconnection (#2154) 2022-05-07 22:24:11 -05:00
Chris Miles 9f9eaed983 [Hotfix] Fix DB version merge 2022-05-07 21:19:21 -05:00
Chris Miles 862e1e33bf [Tasks] Implement Task Goal Match List (#2097)
* [Tasks] Implement Task Goal Match List

* Migration

* Add npc_type_id to match types for npc kill

* Flip str_tolower
2022-05-07 15:37:06 -05:00
Kinglykrab dca34cc2ff [Commands] Cleanup #time and #timezone Command. (#2147)
* [Commands] Cleanup #time and #timezone Command.
- Cleanup messages and logic.

* Cleanup.
2022-05-07 05:03:58 -05:00
Kinglykrab ccb316b11b [Bug Fix] NPC::GetNPCStat has no default return. (#2150)
```In member function 'float NPC::GetNPCStat(const char*)':
/drone/src/zone/npc.cpp:2810:1: warning: control reaches end of non-void function [-Wreturn-type]```
2022-05-07 05:01:36 -05:00
Kinglykrab 10ae4ea8f6 [Bug Fix] Lua GetBlockNextSpell() no return. (#2151)
- No return value.
2022-05-07 05:01:22 -05:00
Kinglykrab 7df9b2974b [Commands] Cleanup #reloadzps Command. (#2129)
* [Commands] Cleanup #reloadzps Command.
- Cleanup messages and logic.
- Make reloading of zone points global instead of zone specific.

* Further cleanup.
- Add zone->GetZoneDescription().
- Add mob->GetTargetDescription(mob).

* Final cleanup.

* Typo.
2022-05-07 03:23:15 -04:00
Kinglykrab 0b3065d7a9 [Commands] Cleanup #reloadtraps Command. (#2126)
* [Commands] Cleanup #reloadtraps Command.
- Cleanup messages and logic.
- Allow the option to reload/repop traps globally for this command.

* Typos.
2022-05-06 22:39:21 -04:00
Kinglykrab 7549fbbeea [Commands] Cleanup #reloadlevelmods Command. (#2122)
* [Commands] Cleanup #reloadlevelmods Command.
- Cleanup messages and logic.
- Make the reloading of modifiers global instead of zone-specific.

* Remove unnecessary message.

* Update worldserver.cpp

* Update worldserver.cpp

* Update worldserver.cpp
2022-05-06 22:31:17 -04:00
Kinglykrab e26eba8e03 [Commands] Cleanup #npctype_cache Command. (#2109)
* [Commands] Cleanup #npctype_cache Command.
- Cleanup messages and logic.
- Loop was returning as soon as it found first ID, so you couldn't use the spaced ID list functionality at all.

* Remove command.
2022-05-06 22:13:16 -04:00
Kinglykrab 02828a73b8 [Commands] Cleanup #npcspecialattk Command. (#2108)
* [Commands] Cleanup #npcspecialattk Command.
- Cleanup messages and logic.

* Remove command.
2022-05-06 22:06:12 -04:00
Kinglykrab 0e710fe5e7 [Commands] Cleanup #ucs Command. (#2149)
* [Commands] Cleanup #ucs Command.
- Cleanup messages and logic.

* Remove command.
2022-05-06 22:03:13 -04:00
Kinglykrab 86568e9292 [Commands] Cleanup #reloadaa Command. (#2120)
* [Commands] Cleanup #reloadaa Command.
- Cleanup messages.
- Remove unncessary file_exists command from file.
- Make reloading of Alternate Advancement data global instead of zone specific.

* Update worldserver.cpp

* Update worldserver.cpp
2022-05-06 21:57:19 -04:00
Kinglykrab bf1d05d639 [Commands] Cleanup #profanity Command. (#2113)
* [Commands] Cleanup #profanity Command.
- Cleanup messages and logic.

* Update profanity_manager.cpp

* Update profanity_manager.cpp

* Update profanity_manager.cpp

* Update profanity_manager.cpp
2022-05-06 21:36:23 -04:00
Kinglykrab 4eaf44fc33 [Commands] Remove unused #bestz and #pf Commands. (#2112)
- Remove unused commands.
2022-05-06 21:13:26 -04:00
Kinglykrab e62a283a79 [Commands] Cleanup #makepet Command. (#2105)
- Cleanup messages and logic.
2022-05-06 20:58:07 -04:00
Kinglykrab a847e461c1 [Commands] Cleanup #npcemote Command. (#2106)
* [Commands] Cleanup #npcemote Command.
- Cleanup messages and logic.

* Update npcemote.cpp
2022-05-06 20:58:01 -04:00
Kinglykrab 37fefad58e [Commands] Cleanup #npcsay and #npcshout Commands. (#2107)
* [Commands] Cleanup #npcsay and #npcshout Commands.
- Cleanup messages and logic.

* Update npcsay.cpp

* Update npcshout.cpp
2022-05-06 20:57:53 -04:00
Kinglykrab 26b26af8d7 [Commands] Cleanup #npctypespawn Command. (#2110)
- Cleanup messages and logic.
2022-05-06 20:50:02 -04:00
Kinglykrab ee86001132 [Commands] Cleanup #reloadmerchants Command. (#2123)
* [Commands] Cleanup #reloadmerchants Command.
- Cleanup messages and logic.
- Make the reloading of merchants global instead of zone specific.

* Update worldserver.cpp

* Update worldserver.cpp
2022-05-06 20:48:46 -04:00
Kinglykrab 7d89c05a48 [Commmands] Cleanup #questerrors Command. (#2116)
- Cleanup messages and logic.
2022-05-06 20:42:47 -04:00
Kinglykrab 6e15fae6a0 [Commands] Cleanup #randomizefeatures Command. (#2118)
- Cleanup messages and logic.
- Make #randomizefeatures function for Iksar and Vah Shir.
2022-05-06 20:42:34 -04:00
Kinglykrab 2f962c2c8a [Commands] Cleanup #refreshgroup Command. (#2119)
- Cleanup messages and logic.
2022-05-06 20:42:25 -04:00
Kinglykrab 6bbd1e94c3 [Commands] Cleanup #push Command. (#2114)
- Cleanup messages and logic.
2022-05-06 19:38:15 -05:00
Kinglykrab 78d44440eb [Commands] Cleanup #qglobal Command. (#2115)
- Cleanup messages and logic.
2022-05-06 19:37:45 -05:00
Kinglykrab 1e45ffa24d [Bug Fix] Resolve subroutine redefinition due to bot methods. (#2117)
* [Bug Fix] Resolve subroutine definition due to bot methods.

* Update perl_bot.cpp
2022-05-06 19:33:20 -05:00
Kinglykrab 37d5d96871 [Commands] Cleanup #resetaa_timer Command. (#2131)
* [Commands] Cleanup #resetaa_timer Command.
- Cleanup messages and logic.

* Typos.
2022-05-06 20:26:59 -04:00
Kinglykrab 90725f9fd9 [Commands] Cleanup #revoke Command. (#2134)
* [Commands] Cleanup #revoke Command.
- Cleanup messages and logic.

* Update revoke.cpp
2022-05-06 20:26:54 -04:00
Kinglykrab c1aa3e7056 [Commands] Cleanup #reloadallrules Command. (#2121)
* [Commands] Cleanup #reloadallrules Command.
- Cleanup messages.

* Typo.
2022-05-06 20:26:39 -04:00
Kinglykrab 1d59fff2bf [Commands] Cleanup #reloadperlexportsettings Command. (#2124)
* [Commands] Cleanup #reloadperlexportsettings Command.
- Cleanup messages and logic.
- Make reloading of Perl event export settings global instead of zone specific.

* Update worldserver.cpp
2022-05-06 20:22:58 -04:00
Kinglykrab 6beb220e93 [Commands] Cleanup #reloadtitles Command. (#2125)
* [Commands] Cleanup #reloadtitles Command.
- Cleanup messages;

* Update worldserver.cpp
2022-05-06 20:20:42 -04:00
Kinglykrab 3091a84540 [Commands] Cleanup #reloadworld and #repop Command. (#2127)
* [Commands] Cleanup #reloadworld Command.
- Cleanup messages and logic.

* [Commands] Cleanup #reloadworld and #repop Command.
- Cleanup messages and logic.
- Add #reloadworld 2 option to forcefully repop all mobs globally as well as reset quest timers and reload quests.
- Remove delay argument from #repop as it isn't used for anything.

* Typos.
2022-05-06 20:06:51 -04:00
Kinglykrab 9fbab76d40 [Commands] Cleanup #summonburiedplayercorpse Command. (#2146)
* [Commands] Cleanup #summonburiedplayercorpse Command.
- Cleanup messages and logic.

* Update summonburiedplayercorpse.cpp
2022-05-06 20:06:04 -04:00
Kinglykrab b03d47b9cd [Commands] Cleanup #trapinfo Command. (#2148)
* [Commands] Cleanup #trapinfo Command.
- Cleanup messages.
- Does not modify the command file, as it's only one line that calls the method in zones/trap.cpp.

* Cleanup.

* Update trap.cpp

* Update trap.cpp
2022-05-06 20:05:55 -04:00
Kinglykrab b583d95f09 [Commands] Cleanup #reloadrulesworld Command. (#2128)
- Cleanup messages and logic.
2022-05-06 20:05:40 -04:00
Kinglykrab 6846deb9c8 [Commands] Cleanup #reloadstatic Command. (#2130)
- Cleanup messages and logic.
- Make reloading of static zone data global instead of zone specific.
2022-05-06 20:03:22 -04:00
Kinglykrab adfec15893 [Commands] Cleanup #resetaa Command. (#2132)
* [Commands] Cleanup #resetaa Command.
- Cleanup messages and logic.

* Update resetaa.cpp
2022-05-06 20:02:32 -04:00
Kinglykrab 132c936c90 [Commands] Cleanup #sensetrap Command. (#2137)
* [Commands] Cleanup #sensetrap Command.
- Cleanup messages and logic.

* Update sensetrap.cpp
2022-05-06 20:01:29 -04:00
Kinglykrab a0ed0d57c5 [Commands] Cleanup #serverinfo Command. (#2138)
* [Commands] Cleanup #serverinfo Command.
- Cleanup message and logic.
- Use popup instead of messages.

* Update serverinfo.cpp
2022-05-06 20:01:21 -04:00
Kinglykrab 128e8ce08d [Commands] Cleanup #resetdisc_timer Command. (#2133)
- Cleanup messages and logic.
2022-05-06 19:50:58 -04:00
Kinglykrab 55629ce396 [Commands] Cleanup #roambox Command. (#2135)
- Cleanup messages and logic.
2022-05-06 19:50:26 -04:00
Kinglykrab bf7c1252f8 [Commands] Cleanup #save Command. (#2136)
- Cleanup messages and logic.
2022-05-06 19:50:19 -04:00
Kinglykrab e2bfa44df0 [Commands] Cleanup #serverrules Command. (#2139)
- Cleanup messages and logic.
- Change separator from new line to pipe separator, as new line was non-functional.
2022-05-06 19:50:09 -04:00
Kinglykrab e5acc7c322 [Commands] Cleanup #shownpcgloballoot and #showzonegloballoot Command. (#2141)
- Cleanup messages and logic.
2022-05-06 19:50:03 -04:00
Kinglykrab 5aaaaed6f1 [Commands] Add #feature Command. (#2142)
* [Commands] Add #feature Command.
- Removes #beard, #beardcolor, #details, #face, #hair, #haircolor, #helm, #heritage, #size, and #tattoo commands.
- Cleanup messages and logic.
- Consolidate 13 different feature settings to this one command.
- Unique commands including #gender, #race, and #texture were not removed.

* Add missing feature.cpp.

* Update feature.cpp
2022-05-06 19:49:56 -04:00
Kinglykrab 6d31786456 [Commands] Cleanup #spawnfix Command. (#2143)
- Cleanup messages and logic.
2022-05-06 19:49:51 -04:00
Kinglykrab 0aeab11408 [Commands] Cleanup #summon Command. (#2145)
* [Commands] Cleanup #summon Command.
- Cleanup messages and logic.
- Add glm::vec4 overload for GMMove.
- Remove unused parameter from GMMove.
- Remove unnecessary Lua GMMove now that parameter is gone.

* Update summon.cpp

* Cleanup.
2022-05-06 18:45:12 -05:00
Kinglykrab fc484d0b1c [Commands] Cleanup #gassign Command. (#2101)
* [Commands] Cleanup #gassign Command.
- Cleanup messages and logic.

* Update gassign.cpp

* Update gassign.cpp
2022-05-06 19:13:28 -04:00
Kinglykrab 8dcc810b43 [Commands] Cleanup #spawnstatus Command. (#2144)
* [Commands] Cleanup #spawnstatus Command.
- Cleanup messages and logic.

* Further cleanup and consolidation, add inline GetTimer() as timer is protected.
2022-05-06 18:12:29 -05:00
Kinglykrab 04f3d6286c [Commands] Cleanup #attack Command. (#2103)
- Cleanup messages and logic.
2022-05-03 23:05:16 -04:00
Kinglykrab 35044becc1 [Commands] Cleanup #freeze and #unfreeze Commands. (#2102)
- Cleanup messages and logic.
- Remove the ability to #freeze yourself.
2022-05-03 23:05:09 -04:00
Kinglykrab e08afb1234 [Commands] Cleanup #getvariable Command. (#2100)
- Cleanup messages and logic.
2022-05-03 23:05:02 -04:00
Kinglykrab b2b87ea4e0 [Quest API] Expand Bot quest API functionality. (#2096)
* [Quest API] Expand Bot quest API functionality.
- Add $bot->AddItem(slot_id, item_id, charges, attuned, augment_one, augment_two, augment_three, augment_four, augment_five, augment_six) to Perl.
- Add $bot->CountItem(item_id) to Perl.
- Add $bot->HasItem(item_id) to Perl.
- Add $bot->RemoveItem(item_id) to Perl.
- Add bot:AddItem(slot_id, item_id, charges, attuned, augment_one, augment_two, augment_three, augment_four, augment_five, augment_six) to Lua.
- Add bot:CountItem(item_id) to Lua.
- Add bot:GetOwner() to Lua.
- Add bot:HasItem(item_id) to Lua.
- Add bot:RemoveItem(item_id) to Lua.

* Fix possible crash.
2022-05-03 23:04:54 -04:00
Kinglykrab 837c0a4385 [Quest API] Perl Money Fixes. (#2098)
- Fixes `$client->GetAllMoney()` to use `uint64` and not overflow int value.
- Fixes `$client->GetCarriedMoney()` to use `uint64` and not overflow int value.
2022-05-03 22:55:56 -04:00
Kinglykrab 9b075c28b6 [Quest API] Add commify to Perl/Lua. (#2099)
- Add quest::commify(number) to Perl.
- Add eq.commify(number) to Lua.
2022-05-03 19:44:22 -04:00
Paul Coene c4f05c3864 [Combat] Fix Frenzy vs opponents immune to non-magic (#2095)
* [Combat] Fix Frenzy vs opponents immune to non-magic

* Fix naming.

* Use snake case for variable
2022-05-02 23:08:08 -04:00
hg 0c12ca8370 [Repository] Cast floats to avoid grid repository warnings (#2094)
This is in the custom repository method file so the generator doesn't
need modified for it
2022-05-01 21:53:37 -05:00
Chris Miles a450779c91 [Drone] Speed up drone builds (#2092)
* Speed up drone builds

* Add chown for ccache

* Add the cmake compiler launcher flag for ccache

* Update .drone.yml

* Don't optimize

* Don't optimize take 2
2022-05-01 20:17:43 -05:00
hg dc004c2a9d Remove already defined method (#2093)
CastRestrictedSpell is already defined in common/spdat

MSVC Debug builds caught this as an ODR violation, though Release
builds still allowed it (maybe because the methods were identical)
2022-05-01 20:54:50 -04:00
Kinglykrab d59dcb68ca [Commands] Add additional #peqzone functionality. (#2085)
* [Commands] Add additional #peqzone functionality.
- Add #peqzone flagging capabilities so operators don't have to blanket allow #peqzone access to zones.
- Allows you to set a zone's `peqzone` column to `2` and disallow use of `#peqzone` until they have been given the appropriate flag.
- Add #peqzone_flags command to list your #peqzone flags similar to #flags command.
- Add `character_peqzone_flags` table to database and database_schema.h.
- Required SQL update to add the new table.
- Add client:ClearPEQZoneFlag(zone_id) to Lua.
- Add client:HasPEQZoneFlag(zone_id) to Lua.
- Add client:LoadPEQZoneFlags() to Lua.
- Add client:LoadZoneFlags() to Lua.
- Add client:SendPEQZoneFlagInfo(client) to Lua.
- Add client:SetPEQZoneFlag(zone_id) to Lua.
- Add $client->ClearPEQZoneFlag(zone_id) to Perl.
- Add $client->HasPEQZoneFlag(zone_id) to Perl.
- Add $client->LoadPEQZoneFlags() to Perl.
- Add $client->SendPEQZoneFlagInfo(client) to Perl.
- Add $client->SetPEQZoneFlag(zone_id) to Perl.

* Fixes.
2022-05-01 19:39:52 -04:00
Chris Miles c7dbdfae58 [Combat] Basic Combat Recording (#2090)
* Basic combat recording

* Update combat_record.h
2022-05-01 18:08:12 -05:00
Kinglykrab 759f9bd007 [Bots] Bot::PerformTradeWithClient Cleanup. (#2084)
* [Bots] Bot::PerformTradeWithClient Cleanup.
- Cleanups message and logic.
- Initial cleanup to eventually allow easy use with Perl/Lua quest API.

* Duplicated comment.
2022-05-01 19:05:12 -04:00
Chris Miles 8f0b80097e [Refactor] Simplify NPC Loading (#2087)
* Refactor / simplify NPC loading

* Update spacing [skip ci]

* Update base_npc_types_repository.h
2022-05-01 17:04:38 -05:00
Chris Miles 71ae03d5bc [Compile] Decrease build times using unity build strategy (#2089) 2022-05-01 15:53:21 -05:00
KayenEQ 34dc081306 [Spells] Update to target types Beam and Cone to ignore invalid targets. (#2080) 2022-05-01 16:50:55 -04:00
Chris Miles 35b35f85cf [Logging] Update BUILD_LOGGING=false Blank Aliases (#2083) 2022-05-01 14:54:46 -05:00
Chris Miles 90da136b7a [Regen] Implement Per Second HP Regen for NPCs (#2086)
* Implement NPC per second regen

* Add hp_regen_per_second to ModifyNPCStat

* Take per second regen the rest of the way

* Add #npcedit hp_regen_per_second

* Add db migration
2022-05-01 10:26:16 -04:00
Chris Miles 5b4aeaa457 [Code Cleanup] Remove this-> in code where its implied (#2088) 2022-05-01 10:22:09 -04:00
Kinglykrab b02008ec53 [Bots] Remove unused methods. (#2082)
- Remove Bot::BotTradeSwapItem().
- Remove Bot::ApplySpecialAttackMod().
2022-04-30 18:13:34 -04:00
Kinglykrab c709a6aa8e [Quest API] Add multiple inventory method short hands to client. (#2078)
- Allows you to just directly use Client instead of having to grab reference to inventory.
- Add $client->CountAugmentEquippedByID(item_id) to Perl.
- Add $client->HasAugmentEquippedByID(item_id) to Perl.
- Add $client->CountItemEquippedByID(item_id) to Perl.
- Add $client->HasItemEquippedByID(item_id) to Perl.
- Add client:CountAugmentEquippedByID(item_id) to Lua.
- Add client:HasAugmentEquippedByID(item_id) to Lua
- Add client:CountItemEquippedByID(item_id) to Lua.
- Add client:HasItemEquippedByID(item_id) to Lua.
2022-04-30 11:47:05 -04:00
Kinglykrab 9113508269 [Bots] Fix ^dyearmor command math. (#2081)
* [Bots] Fix ^dyearmor command math.

* Typo.
2022-04-30 10:57:22 -04:00
Kinglykrab 1b7c12297d [Quest API] Add AddPlatinum(), GetCarriedPlatinum() and TakePlatinum() to Perl/Lua. (#2079)
* [Quest API] Add AddPlatinum(), GetCarriedPlatinum() and TakePlatinum() to Perl/Lua.
- Allows for easier NPC interactions.
- GetCarriedPlatinum() adds together all currencies in inventory based on conversion amounts so it works easily with removals/checks.
- Add $client->AddPlatinum(platinum, update_client) to Perl.
- Add $client->GetCarriedPlatinum() to Perl.
- Add $client->TakePlatinum(platinum, update_client) to Perl.
- Add client:AddPlatinum(platinum, update_client) to Lua.
- Add client:GetCarriedPlatinum() to Lua.
- Add client:TakePlatinum(platinum, update_client) to Lua.

* Formatting.
2022-04-30 10:57:05 -04:00
nytmyr b1311780a7 [Quest API] Add EVENT_SKILL_UP & EVENT_LANGUAGE_SKILL_UP to Perl/Lua (#2076)
Added EVENT_SKILL_UP to Perl/Lua

Adds sub EVENT_SKILL_UP output for use.
Exports:
$skill_id - ID of the skill being exported. Will export skill or language as the same so check below.
$skill_value - New skill level
$skill_max - Maximum value of skill
$is_tradeskill - 0 for non-tradeskill, 1 for tradeskill

Example usage:
sub EVENT_SKILL_UP {
if($is_tradeskill == 0) {
		quest::shout("Skill Increase! " . $client->GetCleanName() . " has increased their " . quest::getskillname($skill_id) . " to " . $skill_value . " of " . $skill_max . "!"); #deleteme
	}
	if ($is_tradeskill == 1) {
		quest::shout("Tradeskill Increase! " . $client->GetCleanName() . " has increased their " . quest::getskillname($skill_id) . " to " . $skill_value . " of " . $skill_max . "!"); #deleteme
	}
}

Adds sub EVENT_LANGUAGE_SKILL_UP output for use.
Exports:
$skill_id - ID of the skill being exported. Will export skill or language as the same so check below.
$skill_value - New skill level
$skill_max - Maximum value of skill

Example usage:
sub EVENT_LANGUAGE_SKILL_UP  {
		quest::shout("Language Increase! " . $client->GetCleanName() . " has increased their " . quest::getlanguagename($skill_id) . " to " . $skill_value . " of " . $skill_max . "!"); #deleteme
}

Co-authored-by: toxin06 <53322305+toxin06@users.noreply.github.com>
2022-04-25 11:18:52 -05:00
cybernine186 0d734a0837 Bug Fix for WorldServer::HandleMessage, CZUpdateType_NPC (#2074) 2022-04-21 08:17:29 -04:00
Paul Coene ee54a7eb5f [Bug Fix] Restore missing messages for lifetap and dmg spells. (#2057)
* [Bug Fix] Restore missing messages for lifetap and dmg spells.

* Fix unintended duplicate message for DD on clients.

* Improve performance and accuracy of IsDamageSpell()
2022-04-13 23:11:26 -04:00
Kinglykrab a6814d46de [Commands] Cleanup #task Command. (#2071)
* [Commands] Cleanup #task Command.
- Cleanup messages.
- Add #task uncomplete [Task ID] to uncomplete a completed task without having to go in the database manually.

* Message cleanup.
2022-04-13 23:11:20 -04:00
KayenEQ 9dba6a6680 [Bug Fix] Blocked spells max spell id increased (#2073)
Blocked spell id should be checking int32 not int16
2022-04-13 11:54:11 -04:00
KayenEQ bc875ae554 [API] Methods for getting more information on quest timers. (#2060)
* hastimer

* [API] Check quest timer duration, timer remaining and if timer exists.

* [API] Methods for getting more information on quest timers.

* [API] Methods for getting more information on quest timers.

* [API] Methods for getting more information on quest timers.
2022-04-13 11:20:03 -04:00
KayenEQ bb897b755f [Bug Fix] Instrument Mods should not affect spells that change model size. (#2072)
Instrument Mods should not affect spells that change model size.
2022-04-13 11:02:21 -04:00
Kinglykrab a39a825045 [Quest API] Add GetBotListByCharacterID() to Perl/Lua. (#2069) 2022-04-02 17:51:26 -04:00
Paul Coene ccd0713b33 [Bug Fix] Fix recipient sound (vtell) on non-player races (#2066)
* [Bug Fix] Fix recipient sound (vtell) on non-player races

* Fix to use BaseRace as intended
2022-04-02 11:18:10 -04:00
Kinglykrab 5d94c9844a [Bug Fix] Clear title/suffix bug fix. (#2068)
- Clearing uses title ID 0, so need to make sure title ID is valid when setting and based on that, either check and set, or just clear.
2022-04-02 11:09:48 -04:00
KayenEQ bbe2db7c0f [Bug Fix] Bard Invisible causing display issues. (#2067)
* [Bug Fix] Bard Invisible causing display issues.

Error occurring due to bard modifiers being applied to invisible spell effect value.

* [Bug Fix] Bard Invisible causing display issues.
2022-04-02 00:01:38 +02:00
Kinglykrab 5dc76e595b [Quest API] Add GetBotListByClientName(client_name) to Perl/Lua. (#2064)
* [Quest API] Add GetBotListByClientName(client_name) to Perl/Lua.
- Add $entity_list->GetBotListByClientName(client_name) to Perl.
- Add eq.get_entity_list():GetBotListByClientName(client_name) to Lua.
- Allows you to get a bot list comprised solely of a specific character's bots.

* Update lua_entity_list.cpp
2022-03-23 08:47:47 -04:00
Natedog2012 b6b662f1c7 [Bug Fix] #peqzone no longer bypass Handle_OP_ZoneChange (#2063)
* [Bug Fix] #peqzone no longer bypass Handle_OP_ZoneChange

* Force other quest functions to trigger EVENT_ZONE properly

* call MovePC

* Use MoveZone to keep things uniform
2022-03-19 19:25:14 -04:00
Paul Coene 5275201713 [Bug Fix] Fix for being able to skill up on corspe. (#2058)
* [Bug Fix] Fix for being able to skill up on corspe.

* Fix whitespace
2022-03-19 13:21:54 -05:00
Paul Coene 1e86e0c02f [Bug Fix] manifest for db version 9176 had incorrect field name(#2062)
Field name in version 9176 doesn't match field created.
2022-03-19 13:13:56 -05:00
Natedog2012 25c0416f1e [Bug Fix] Force NPCs to respect special ability 24 and 50 when set on player pets (#2059)
* Force NPCs to respect special ability 24 and 50 when set on player pets

* Fix error in logic

* Remove this
2022-03-15 19:28:36 -05:00
Paul Coene 326dba6aeb [Logging] Fix log messages to final damage values (#2056) 2022-03-14 12:05:39 -04:00
Kinglykrab b75741ff4e [Bug Fix] Fix possible crash with zone name methods. (#2055)
- ZoneLongName and ZoneName were returning nullptr in places that were then attempting to use that nullptr value, causing zone crashes.
2022-03-13 15:59:57 -04:00
Kinglykrab 8e62383997 [Quest API] Add AddItem() to Perl/Lua. (#2054)
- Add $client->AddItem(item_data) to Perl.
- Add client:AddItem(item_table) to Lua.
- This will allow server operators to add items without needless parameters.

Perl Example:
```pl
my %item_data = (
	"item_id" => 1200,
	"charges" => 1,
	"augment_one" => 49656,
	"augment_two" => 49656,
	"augment_three" => 49656,
	"augment_four" => 49656,
	"augment_five" => 49656,
	"augment_six" => 49656,
	"attuned" => 1,
	"slot_id" => quest::getinventoryslotid("general1")
);
$client->AddItem(\%item_data);
```
Lua Example:
```lua
local item_data = {
	item_id = 1200,
	charges = 1,
	augment_one = 49656,
	augment_two = 49656,
	augment_three = 49656,
	augment_four = 49656,
	augment_five = 49656,
	augment_six = 49656,
	attuned = true,
	slot_id = Slot.General1
};
e.self:AddItem(item_data);
```
2022-03-13 15:59:48 -04:00
KayenEQ 4296e2e39e [API] GetNPCStat default better naming (#2053) 2022-03-12 20:01:25 -05:00
Kinglykrab e5f924d1d5 [Quest API] Allow EVENT_ZONE to be parsed as non-zero to prevent zoning. (#2052)
- This will allow server operators to prevent zoning to or from a specific zone based on whatever criteria they want.
2022-03-12 16:11:27 -05:00
Kinglykrab fb2aee1827 [Quest API] Add EVENT_CAST_ON exports to EVENT_CAST and EVENT_CAST_BEGIN. (#2051)
- Export $caster_id and $caster_level to EVENT_CAST and EVENT_CAST_BEGIN in Perl.
- Export e.caster_id and e.caster_level to EVENT_CAST and EVENT_CAST_BEGIN in Lua.
2022-03-12 14:33:00 -05:00
Kinglykrab 791d8b329d [Quest API] Export killed XYZH to EVENT_DEATH_ZONE in Perl. (#2050)
- Export $killed_x, $killed_y, $killed_z, and $killed_h to EVENT_DEATH_ZONE in Perl.
- Cleanup export strings and unnecessary .c_str() calls on event exports.
2022-03-12 13:44:01 -05:00
catapultam-habeo abcf8cbce1 [Bots] Update Bot Heal & Damage methods to more closely match Clients + Bugfixes (#2045)
* - Fixed Bots Spell Damage being negative under some circumstances (heal target)
- Allow Bots to send non-melee damage reports in the same manner as Clients
- Refactor\Update Bots Spell Damage & Heal calculations to match current state of Clients.
- Allow Bots to actually utilize Spell Damage and Heal Amount stats

* Don't send packets to bots

* remove random tab

* align text lol
2022-03-11 18:28:00 -05:00
Chris Miles 3ed6663c4c [Repositories] Update repositories (#2040) 2022-03-11 18:27:36 -05:00
Chris Miles f22608a43a [Bug FIx] Saylink Collation Database Edge Case (#2039) 2022-03-11 18:27:15 -05:00
KayenEQ 0e5d578d71 [Bug Fix] #tune command various fixes (#2046)
* tune fixes

* [Bug Fix] #tune command various fixes

accuracy tune fix
2022-03-11 10:13:51 -05:00
KayenEQ 8107ed52e1 [API] GetNPCStat can now return default stat values. (#2048)
* [API] GetNPCStat return default stat values.

* [API] GetNPCStat can now return default stat values.
2022-03-11 09:10:52 -05:00
Kinglykrab d904db0e52 [Quest API] Add caster_id and caster_level export to EVENT_CAST_ON in Perl/Lua. (#2049)
- Add $caster_id and $caster_level to EVENT_CAST_ON in Perl.
- Add e.caster_id and e.caster_level to EVENT_CAST_ON in Perl.
2022-03-10 21:46:27 -05:00
Kinglykrab e6c8a38ffa [Bug Fix] Spell Buckets/Globals did not allow string-based values. (#2043) 2022-03-09 14:18:24 -05:00
KayenEQ dbe0591b09 [API] Perl functions to set invulnerable to and modify environmental damage. (#2044)
* invulnerable

* modifier

* fix

* fix

* fix

* [API] Perl functions to set invulnerable to and modify environmental damage.

* [API] Perl and Lua functions to set invulnerable to and modify environmental damage.

credit to kinglykrab for lua
2022-03-08 19:50:46 -05:00
KayenEQ 5b6f1d38be [Bug Fix] Invisible will display as dropped now on air pets when they attack. (#2042)
invisible display issue on pets
2022-03-07 16:41:43 -05:00
JJ ce85c70a07 [Database] Update 2022_01_10_checksum_verification.sql (#2041) 2022-03-07 14:30:24 -06:00
KayenEQ f814b5bec5 [Bug Fix] PR 2032 would lock client on casting fail as written (#2038) 2022-03-06 22:03:19 -06:00
Chris Miles 4e40d7eacc [Command] Fix #killallnpcs from crashing (#2037) 2022-03-06 22:03:10 -06:00
Randy Girard 31ad0da811 [Content Filtering] Updates contents flags to be checked at runtime. (#1940)
* Updates contents flags to be checked at runtime.

* Fix formatting

* Add expansion flags

* Tweaks to logic

* Logic tweaks

* Update world_content_service.cpp

* Inverse DoesPassContentFiltering logic

* Update world_content_service.cpp

* Update world_content_service.cpp

Co-authored-by: Akkadius <akkadius1@gmail.com>
2022-03-06 22:02:57 -06:00
Chris Miles 25a19a13dc [Database] Add Primary ID Keys to Tables (#2036) 2022-03-06 22:02:33 -06:00
Paul Coene 2a5ddde78a [Feature] Client Checksum Verification (Resubmit old 1678) (#1922)
* [Feature] Client Checksum Verification (Resubmit old 1678)

* Updated db version

* Add new updatechecksum to CmakeLists.txt

* Removed magic number and used constant

* Fix new command to have access to worldserver

* spacing, more venbose desc and remove unneeded check

* Cleanup, refactoring

Co-authored-by: Akkadius <akkadius1@gmail.com>
2022-03-06 20:26:29 -06:00
catapultam-habeo eca2ed0321 [Feature] EQ2-style implied targeting for spells. (#2032)
* Implemented EQ2-style implied targeting for spells.

* Fixed nullptr w\ target that has no target
2022-03-06 20:25:40 -06:00
Paul Coene afc32afb02 [AI] Spell Type (1024) InCombatBuff were spam casting (#2030) 2022-03-06 20:18:30 -06:00
catapultam-habeo 751db6fffb [Feature] Allow pets to zone with permanent (buffdurationformula 50) buffs to maintain them through zone transitions (#2035) 2022-03-06 20:17:25 -06:00
Paul Coene c4eb1f8439 [Bug Fix] Bandolier didn't recognize source weapon on cursor (#2026)
* [Bug Fix] Bandolier didn't recognize source weapon on cursor

* Add TODO comment
2022-03-06 20:15:22 -06:00
Paul Coene d6c03b54a1 [Bug Fix] Fixed several instances of incorrect comparision - & executes after == (#2025) 2022-03-06 18:42:23 -06:00
neckkola 261a9e6938 [Bots] Fix bot spawn when bot id = char_id (#1984)
* Fix for GENERIC_9_STRINGS

* Update .gitignore

* Fixed query for use case when char_id of owner equals a bot_id

* Update BotDatabase::LoadGroupedBotsByGroupID to not use a view though correct edge case where botid=charid
2022-03-06 18:41:53 -06:00
catapultam-habeo ac214f71d4 [Bots] Apply Spells:IgnoreSpellDmgLvlRestriction to bots (#2024)
* Correct bot spell damage and healing pathways to account for rule Spell:IgnoreSpellDmgLvlRestriction

* Corrected to be more consistent in regard to the 'spells[spell_id].no_heal_damage_item_mod' modifier. This modifier doesn't seem to actually exist on any content, and bots didn't use it to begin with.

This restriction is present on players - do we want it on bots also?
2022-03-06 18:40:21 -06:00
KayenEQ fd878e7b16 [Bug Fix] Missing break (#2031) 2022-03-04 18:35:59 -05:00
Michael Cook (mackal) 58cde58b45 Fix order of operations issues in worldshutdown command (#2029) 2022-03-04 12:24:13 -05:00
Kinglykrab cc2ef11158 [Bug Fix] Objects::GetTiltX() and Objects::GetTiltY() Perl Croak Typos. (#2028)
- Typo was causing GetIncline() to show three times on Spire and causing GetTiltX() and GetTiltY() not to show at all on Spire.
2022-03-03 22:06:25 -05:00
Kinglykrab 2dfb7614cc [Bug Fix] Doors::GetSize() Perl Croak Typo. (#2027)
- Typo was causing GetIncline() to show twice on Spire and causing GetSize() not to show at all on Spire.
2022-03-03 21:54:02 -05:00
KayenEQ 6dffeacc6e [Spells] Fixes for numhits type 7 counter incrementing incorrectly. (#2022)
* [Spells] Fix for numhits type 7 counter incrementing incorrectly.

* [Spells] Fixes for numhits type 7 counter incrementing incorrectly.

bot fix

* [Spells] Fixes for numhits type 7 counter incrementing incorrectly.

mercs

* [Spells] Fixes for numhits type 7 counter incrementing incorrectly.

remove old variable and related code.

* [Spells] Fixes for numhits type 7 counter incrementing incorrectly.

comments
2022-03-01 21:20:27 -05:00
Michael 2ec6dcbe24 Merge pull request #2023 from EQEmu/bug_fix/lua_argument_dispatch 2022-02-28 20:22:12 -05:00
Kinglykrab 39bc12b582 [Bug Fix] Removed Lua Event Argument Dispatch.
Fix accidentally removal of argument dispatch for EVENT_CONSIDER_CORPSE in https://github.com/EQEmu/Server/pull/2015
2022-02-28 19:59:34 -05:00
Kinglykrab 6d78f926c8 [Commands] Cleanup #worldwide command. (#2021)
- Cleanup messages and logic.
- Command usages would not display when using commands improperly, this will fix that.
2022-02-28 19:46:56 -05:00
catapultam-habeo 00af2903c3 Rule to apply Spell Dmg and Heal Amount stats as a percentage instead of flat value. (#2017)
* Apply Spell Dmg and Heal Amt stats as a percentage increase (1 SD\HA = 1% increase to spell effectiveness) instead of a flat addition.

* Corrected logic to allow for coexistence of FlatItemExtraSpellAmt rule and this.

* Adjusted rule name to be less ambiguous.
2022-02-28 15:24:16 -05:00
Kinglykrab 58fafd0f9c [Bug Fix] quest::MovePCInstance() Arguments Fix. (#2020)
- Logic made the method return an "error" when not using last parameter.
2022-02-27 16:39:45 -05:00
Kinglykrab 9f0989ee2d [Bug Fix] Spell Buckets/Globals SQL Escape. (#2019) 2022-02-26 10:17:05 -05:00
KayenEQ 14648b96c4 [Spells] SPA 79 SE_CurrentHPOnce now will check for focus, critical and partial resist checks, except for buffs. (#2018)
* [Spells] SPA 79 SE_CurrentHPOnce check for focus and related effects.

SPA 79 SE_CurrentHPOnce should have the damage checks as SPA 0 for heal/damage

* Update spell_effects.cpp

* [Spells] SPA 79 SE_CurrentHPOnce now will check for focus, critical and partial resist checks.
2022-02-24 13:47:54 -05:00
Kinglykrab bfd1cf9379 [Quest API] Add EVENT_EQUIP_ITEM_CLIENT and EVENT_UNEQUIP_ITEM_CLIENT to Perl/Lua. (#2015)
- These events allow more customization beyond forcing operators to use a script file for each and every item they want to have some sort of functionality for these events.
- Perl event exports $item_id, $item_quantity, and $slot_id.
- Lua event exports item_id, item_quantity, slot_id, and item.
2022-02-22 20:04:08 -05:00
Chris Miles 3c35e9bbc8 [GM Command] Fix Crash Issue and Validation with #zclip (#2014)
* Fix crash issue and validation with zclip

* Formatting.

Co-authored-by: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com>
2022-02-21 17:02:48 -05:00
Kinglykrab d86544ff60 [Bug Fix] Alleviate some lag with crosszone/worldwide spell casting. (#2016)
- Spell casting was using SpellFinished which casts the spell, and if the spell was a group spell each member of the group would cast it on all the other members, causing a chain reaction.
- This fix utilizes ApplySpellBuff(spell_id, duration) so that it only casts the spell on the target, as with the crosszone and worldwide methods you will be affecting your target based on identifiers regardless.
- This should alleviate some of the crosszone/worldwide casting crashes on larger servers such as Lazarus.
2022-02-20 21:59:46 -05:00
KayenEQ 70eed67e08 [Bug Fix] checking casting_spell_slot before its defined is bad (#2013) 2022-02-20 15:56:17 -05:00
KayenEQ 1c0524681e [API] perl added GetNPCStat(identifier) (#2012)
* [API] perl added GetNPCStat

Returns values of the modifiers from ModifyNPCStat

* https://github.com/EQEmu/Server/pull/2012
2022-02-20 14:00:28 -05:00
KayenEQ aa9320de3c [Spells] Bard songs from item clickies should not require components (#2011) 2022-02-18 09:37:09 -05:00
KayenEQ ad28f3c3f3 [Bug Fix] Fix for castspell command (#2010)
Fix for using castspell command with parameter 0
2022-02-17 20:44:11 -05:00
Kinglykrab 71dfa9acc0 [Commands] Bug fix for #logs command. (#2008)
* [Commands] Bug fix for #logs command.

* Update logs.cpp
2022-02-17 12:01:06 -05:00
KayenEQ 56d0478ab1 [API] Fix for SetBuffDuration function to check bard slots. (#2009) 2022-02-17 12:00:42 -05:00
Kinglykrab 0d02fadb60 [Quest API] Add GetRandomMob() and GetRandomNPC() to Perl/Lua. (#2006)
- Add $entity_list->GetRandomMob(x, y, z, distance, exclude_mob) to Perl.
- Add $entity_list->GetRandomNPC(x, y, z, distance, exclude_npc) to Perl.
- Add eq.get_entity_list():GetRandomMob(x, y, z, distance, exclude_mob) to Lua.
- Add eq.get_entity_list():GetRandomNPC(x, y, z, distance, exclude_npc) to Lua.
2022-02-17 08:57:02 -05:00
cybernine186 4de5a7b86d [Bug] Fixed trade items record log (#2003)
LogPlayerHandin was not recording the item details of the trade. It should be inserting the trade details into `qs_player_handin_record_entries` but it was not running the query because of missing QueryDatabase function.
2022-02-16 21:52:14 -06:00
KayenEQ ba3c19ad0b [Spells] AE Duration effect (Rains) will now work with Target Ring and PBAE spells. (#2000)
* done

* Update beacon.cpp

* [Spells] AE Duration effect (Rains) will now work with Target Ring and PBAE spells.

Mackals suggestions implemented.
2022-02-16 10:12:13 -05:00
Kinglykrab 8ec80644ee [Commands] Cleanup #unscribespell Command. (#1998)
* [Commands] Cleanup #unscribespell Command.
- Cleanup messages and logic.
- Add Client::UnscribeSpellBySpellID(spell_id, update_client).
- Add $client->UnscribeSpellBySpellID(spell_id, update_client) to Perl.
- Add client:UnscribeSpellBySpellID(spell_id, update_client) to Lua.

* Update unscribespell.cpp
2022-02-16 06:04:01 -05:00
Kinglykrab ed7e2b2652 [Commands] Cleanup #untraindisc Command. (#1996)
- Cleanup messages and logic.
2022-02-16 06:03:51 -05:00
KayenEQ a83ad7080a fix for meloday cast bar issue (#2005) 2022-02-15 14:01:01 -05:00
KayenEQ 677d595c9d invis updates (#2004) 2022-02-15 11:39:19 -05:00
KayenEQ 615f4a5304 [API] Apply spells with custom buff durations and adjust existing spell buff durations. (#1997)
* working

* Update spell_effects.cpp

* updates

* disable_buff_overwrite

* revert

* update

* working

* update

* updates

* Update spells.cpp

* getbuffstat done

* Update perl_mob.cpp

* [API] Apply spells with custom buff durations and adjust existing spell buff durations.

* [API] Apply spells with custom buff durations and adjust existing spell buff durations.

* [API] Apply spells with custom buff durations and adjust existing spell buff durations.

* [API] Apply spells with custom buff durations and adjust existing spell buff durations.

* https://github.com/EQEmu/Server/pull/1997

Lua added, thanks kinglykrab
2022-02-15 08:58:10 -05:00
KayenEQ 5fd62d82db Update bonuses.cpp (#2002) 2022-02-15 08:57:53 -05:00
KayenEQ b938e6223c [Spells] Invisibility updates and rework (#1991)
* updates pre merge

* update

* Update spell_effects.cpp

* Update mob.h

* test

* test

* updates

* updates

* save

* update

* working solid

* animal and undead start

* progress

* updates

* rename

* set invis appearance on bonus

* remove fade buff state check

* update IsViisble check

* optimizing

* don't break bots

* debug remover

* Update ruletypes.h

* perl adds

* Update client_packet.cpp

* update

* done

* remove debugs

* Update client_packet.cpp

* update

* [Spells] Invisibility updates and rework

lua support

* [Spells] Invisibility updates and rework

lua
2022-02-15 00:18:02 -05:00
KayenEQ 51c8771bd2 bug fix (#2001) 2022-02-15 00:17:23 -05:00
Kinglykrab cc9196bd65 [Commands] Cleanup #showskills Command. (#1994)
* [Commands] Cleanup #showskills Command.
- Utilize popup over messages.
- Usage: #showskills [Start Skill ID] [All] - shows skills starting from skill ID and if "all" is specified it will show skills the player does not have normally (no max/cannot have skill).

* Update showskills.cpp

* Update command.cpp
2022-02-14 19:49:14 -05:00
Kinglykrab 6303f129af [Commands] Cleanup #setskillall Command. (#1992)
- Cleanup messages and logic.
2022-02-14 19:02:27 -05:00
KayenEQ 3f0987ba55 [Combat] /shield command "too far away message" (#1999)
* live did something that makes sense

* [Combat] /shield command "too far away message

better chat

* [Combat] /shield command "too far away message

never mind that one was red.
2022-02-14 10:44:26 -05:00
KayenEQ 1d4438ae1f [Bug Fix] Edge case AA reset timer issue fixes (#1995)
* SendCastRestriction not displaying right on linux build

changed const char to string

* fail safe to prevent recast timer checks from triggered spells

* fixed

* Update spell_effects.cpp

* https://github.com/EQEmu/Server/pull/1995

better message code
2022-02-13 21:50:53 -05:00
KayenEQ 03adf20fe9 bot crash fix (#1993) 2022-02-13 12:09:32 -05:00
KimLS dd6cde68bb Small change to order of a couple of files in zone cmakefile, added the gm commands to their own source group so they are cleanly separated in any IDEs cmake supports 2022-02-12 23:31:51 -08:00
KimLS 95c8b60ec6 Extra extern c warning squash, XS macro expands to XS_EXTERNAL which under c++ expands to extern c 2022-02-12 22:04:30 -08:00
KimLS fa418172d6 What is this random semicoloned if, removed to silence warning 2022-02-12 22:04:30 -08:00
KimLS 7b106fc622 Handle default case of GetDynamicZoneTypeName to silence warning 2022-02-12 22:04:30 -08:00
KimLS 62a453f0d7 Remove obsolete register spec on int to silence warning 2022-02-12 22:04:30 -08:00
KayenEQ fa9314811e [Bug Fix] Fix for Bot command casting (#1990)
* missing return true in ApplyBardPulse

* Update bot.cpp

* [Bug Fix] Fix for Bot command casting

compile error

* [Bug Fix] Fix for Bot command casting

* Update bot.cpp
2022-02-12 15:12:35 -05:00
Kinglykrab d2d7b8108d [Commands] Cleanup #ai Command. (#1980)
- Cleanup messages and logic.
- Remove #ai start/#ai stop as they can crash zones and are mostly useless.
- Add EQ::constants::GetConsiderLevelMap() and EQ::constants::GetConsiderLevelName().
- Add quest::getconsiderlevelname(consider_level) to Perl.
- Add eq.get_consider_level_name(consider_level) to Lua.
2022-02-11 16:26:08 -05:00
KayenEQ 99793cab8b [Spells] Fix for AA recast timers not resetting properly (#1989)
* revert completed

Too many issues popping up that are difficult to track down. This was probably not best way to solve the problem.

* fixed for real

* Update aa.cpp

* Update aa.cpp

* Update aa.cpp

* should work

* remove spaces

* [Spells] Fix for AA recast timers not resetting properly
2022-02-11 16:25:59 -05:00
KayenEQ e2484997dd revert completed (#1988)
Too many issues popping up that are difficult to track down. This was probably not best way to solve the problem.
2022-02-11 10:58:43 -05:00
KimLS 66935fe21b Fix for passing std::string to vsprintf 2022-02-11 01:15:02 -08:00
KayenEQ db988e4261 group message (#1987) 2022-02-10 23:55:59 -05:00
Kinglykrab fdd260d5fa [Commands] Cleanup #npcloot Command. (#1974)
- Cleanup messages and logic.
- Utilize item links where helpful.
- Implement #npcloot remove all to remove all loot from an NPC using GetLootList().
- #npcloot money now supports 0 to 65,535 for the money types, clamped using EQ::Clamp.
2022-02-10 20:05:36 -05:00
Kinglykrab 9110bc863e [Commands] Cleanup #logs Command. (#1969)
- Cleanup messages and logic.
- Utilize popup for list and applying settings.
2022-02-10 16:52:15 -05:00
Kinglykrab 4a41583805 [Commands] Cleanup #flagedit Command. (#1968)
- Cleanup and fix messages and logic.
- Utilized popup for listing zones that have required flags.
2022-02-10 16:17:52 -05:00
Kinglykrab 5396c0c88b [Commands] Cleanup #name Command. (#1977)
- Cleanup messages and logic.
2022-02-10 16:14:40 -05:00
Kinglykrab 968ae26c99 [Commands] Cleanup #hatelist Command. (#1976)
- Cleanup messages and logic.
2022-02-10 16:14:17 -05:00
Kinglykrab 7bf466cf3f [Commands] Cleanup #netstats Command. (#1970)
- Utilize popup over chat messages.
2022-02-10 16:10:31 -05:00
Kinglykrab 49d7eb1402 [Commands] Cleanup #version Command. (#1967)
- Utilize popup over chat message.
2022-02-10 16:10:23 -05:00
Kinglykrab d83ced6f76 [Commands] Cleanup #undye and #undyeme Commands. (#1966)
- Fix #undye command as its method was not being used in command.cpp.
- Cleanup messages and logic for both #undye and #undyeme.
2022-02-10 16:10:16 -05:00
Kinglykrab 1ea8888607 [Commands] Cleanup #timers Command. (#1965)
- Cleanup message and logic.
- Utilize popup instead of chat messages.
- Utilize ConvertSecondsToTime() helper method.
2022-02-10 16:10:06 -05:00
Kinglykrab f9eb4603a3 [Quest API] Add GetEnvironmentalDamageName() to Perl/Lua. (#1964)
- Add EQ::constants::GetEnvironmentalDamageMap() and EQ::constants::GetEnvironmentalDamageName().
- Add quest::getenvironmentaldamagename(damage_type) to Perl.
- Add eq.get_environmental_damage_name(damage_type) to Lua.
- Cleanup GM messages for avoiding environmental damage.
2022-02-10 16:09:56 -05:00
KayenEQ d656be6be4 [Bug Fix] Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs (#1986)
* Update spells.cpp

* Update spells.cpp

* [Bug Fix] Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs

disc failure log

* [Bug Fix] Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs

improved HasItemRecastTimer check
2022-02-10 14:58:28 -05:00
KayenEQ fbbbd3b09d [Bug Fix] PR 1982 (#1985)
* Update spells.cpp

* [Bug Fix] PR 1982
2022-02-09 23:24:18 -05:00
KayenEQ a6d1652f44 fixed (#1983) 2022-02-09 18:02:45 -05:00
KayenEQ f0bf285836 [Spells] Support for SPA 194 SE_FadingMemories to use max level checks on aggroed mobs (#1979)
* escape fix for different target types

* implemented max level for fade

* test

* update

* update

* support modern limits

* Update ruletypes.h

* update

* [Spells] Support for SPA 194 SE_FadingMemories to use max level checks on aggroed mobs

not sure why this code got removed, maybe merge error.
2022-02-09 15:12:39 -05:00
KayenEQ 1f560529da [Bug Fix] Bard update fixes 1 (#1982)
* fix for bard item charge consumables

* [Bug Fix] Bards not consuming item click charges on instant cast items.

* [Bug Fix] Bard update fixes 1

bards not respecting deity/race/class restrictions on instant cast items
2022-02-09 15:07:38 -05:00
Kinglykrab f65a6d2761 [Quest API] Add AddAISpellEffect(spell_effect_id, base_value, limit_value, max_value) and RemoveAISpellEffect(spell_effect_id) to Lua. (#1981)
- Add npc:AddAISpellEffect(spell_effect_id, base_value, limit_value, max_value) to Lua.
- Add npc:RemoveAISpellEffect(spell_effect_id) to Lua.
2022-02-08 20:46:59 -05:00
KayenEQ 79f250da2d [API] Perl functions added to apply spell effects directly to NPCs without requiring buffs. (#1975)
* script functions working

* Update perl_npc.cpp

* [API] Perl functions added to apply spell effects directly to NPCs without requiring buffs.
2022-02-08 18:32:13 -05:00
KayenEQ 752e6c89f3 [Spells] Allow damage spells to heal if quest based spell mitigation is over 100 pct. (#1978)
* heal from nuke

* Update mob.cpp
2022-02-08 09:03:31 -05:00
KayenEQ e962ad3a35 procs silence (#1973) 2022-02-08 07:36:20 -05:00
KayenEQ 872d494bb6 [Bug Fix] Summon Companion causing pets to warps away. (#1972)
* Update spell_effects.cpp

* Update spell_effects.cpp
2022-02-08 07:36:04 -05:00
KayenEQ 8a48473dbc [Spells] Fix for AA and Discipline recast timers being set on spell casting failure. (#1971)
* recast timer updates

* reworked

* removed unneeded param

* fix expendible AA

* fixed

* Update spells.cpp

* [Spells] Fix for AA and Discipline recast timers being set on spell casting failure.

don't check recasts from triggered spells.
2022-02-08 07:35:47 -05:00
KayenEQ a208801d1f [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic. (#1954)
* test

* complete

* Update effects.cpp

* Update spells.cpp

* Update effects.cpp

* [Spells] Support for bards using Disciplines while casting or /melody.

Support for spell field 'cast not standing' not allow casting from divine aura

* [Spells] Support for bards using Disciplines while casting or /melody.

DA bypass logic for spells with field 'cast_not_standing'

* updates

* stun and mez bypass

* Update spdat.cpp

* Update spdat.cpp

* Update spells.cpp

* clean

* requirement messages

* update

* pct

* save work

* Reform code 1_22_22

* updated

* update id to pointer

* Update spells.cpp

* rework 2

* update 1_23_22

* Update spells.cpp

* updates

* msg string works

* fix disc timers not be set

* more optimization

* update 1_23_22 PM

moved stop casting out
charm and harmony moved in

* update 1_25_22

rework of functions

* updates 1_26_22

* remove old checks

* gm override added for some

* update bard AA casting checks

* updates

* addbuff exception for bard

* debugs

* charm working

* update

* moved skill check here

* cast from item while singing

* lets not attack mounts

* instant cast items click

* aug clicks working

* aug tests

Bug? Cast time not display on aug clicks for bards

* aug recast from items semi ok

* added item timer function

* unified setting item recast timer

* clean up time

* update

* bard AA cast updates

* debugs removed

* debugs removed

* clean up

* clean up

* better placement of bindsight and numhits fix

* move and rename function

* Update spells.cpp

* add logs

* delete old DoCastingChecks

* Removed old bard pulse functions

* remove AEBardPulse and GroupPulse

* removed Raid::GroupBardPulse

* Pulse Restriction: Divine Aura

* Pulse Restrictions : Fear behavior

* Update spells.cpp

* Update spells.cpp

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

bots...

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

added recommended isvalidspell check

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

merged

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

removed defines since we have them as constants
2022-02-07 07:48:52 -05:00
Kinglykrab a5d8a64792 [Quest API] Add inventory->CountItemEquippedByID(item_id) and inventory->HasItemEquippedByID(item_id) to Perl/Lua. (#1963)
- Add $inventory->CountItemEquippedByID(item_id) to Perl.
- Add $inventory->HasItemEquippedByID(item_id) to Perl.
- Add inventory:CountItemEquippedByID(item_id) to Lua.
- Add inventory:HasItemEquippedByID(item_id) to Lua
2022-02-06 13:21:48 -05:00
Chris Miles ee1f0ea91f [Maintenance Script] Pull from different maps mirror for now 2022-02-05 00:34:28 -06:00
KayenEQ 7c20a86f23 escape fix for different target types (#1962) 2022-02-04 21:14:53 -05:00
KayenEQ dbe6adbed0 [Spells] SPA 311 SE_LimitCombatSkills should prevent focusing of procs even if proc is a 'casted' spell. (#1961)
* proc limiter update

* Update spdat.h

* [Spells] SPA 311 SE_LimitCombatSkills should prevent focusing of procs even if proc is a 'casted' spell.
2022-02-04 21:14:40 -05:00
KayenEQ d300e78b39 [Spells] Illusions will now persist onto the corpse when mob is killed. (#1960)
* illusion applies to corpse

* Update spell_effects.cpp

* [Spells] Illusions will now persist onto the corpse when mob is killed.

addressed comments
2022-02-04 21:14:29 -05:00
Kinglykrab 0400504adc [Bug Fix] NPC::CountItem and Corpse::CountItem 0 Charge Item Fix. (#1959)
- Fixes an issue where 0 charged or out of charge items do not count towards the return value.
2022-02-04 06:07:46 -05:00
KayenEQ 5ce2889210 [Bug Fix] Illusions will now properly display armor to other clients when they zone in. (#1958)
* Fix for illusion wear change

On zone in, mobs with illusions were not displaying correct armor.

* [Bug Fix] Illusions will now properly display armor to other clients when they zone in

better looping
2022-02-03 22:04:15 -05:00
KayenEQ cc0371c16e [Spells] Swarm pet aggro logic fix (#1956)
* temp commit

* swarm pet logic fix

* [Spells] Swarm pet aggro logic fix
2022-02-03 22:00:52 -05:00
Kinglykrab 4e297f3d96 [Commands] #ginfo Cleanup. (#1955)
* [Commands] #ginfo Cleanup.
- Use popup over chat messages.

* Remove leader since GetLeaderName() is wrong.
2022-02-03 18:52:31 -05:00
Kinglykrab e9f48d5fba [Commands] Cleanup #npceditmass command. (#1957)
* [Commands] Cleanup #npceditmass command.
- Cleanup messages and logic.
- Fix crash with SQL format.

* Message change.
2022-02-03 15:25:37 -06:00
KayenEQ 00c41dda8c [Spells] Support for 'HateAdded' spell field to apply negative values to reduce hate. (#1953)
* HateAdded field can be negative

* [Spells] Support for 'HateAdded' spell field to apply negative values to reduce hate.
2022-02-02 21:43:17 -05:00
Kinglykrab 7b235a6ede [Bug Fix] Fix issue where you can set your title to titles you don't have. (#1917)
* [Bug Fix] Fix issue where you can set your title to titles you don't have.

* Fixes.

* Fix missing logic check for HasTitle

Co-authored-by: Natedog2012 <jwalters_06@yahoo.com>
2022-01-29 20:09:02 -06:00
mmcgarvey 58d5983ef1 [Skills] Configurable Exponential Decay Formula for Skill Up (#1887)
* [Skills] Exponential Decay Skill Up Formula

Added an exponential decay skill up formula option.
The current, linear, formula results in negative chances to skill up, which
have been mitigated via a multiplier and minimum of 1%

* [Skills]Configurable Exponential Decay Formala for Skill Up

What this fixes:
The existing formula for determining whether or not to skill up could result
in negative chances, and made an assumption around the number 252.
This would ultimately result in an override that would set the chance to 1.

My fix:
I created 2 new rules:
Character:SkillUpMaximumChancePercentage
Character:SkillUpMinimumChancePercentage

I changed the forumla to:
chance = ((max - min + skill_modification) * (.99^skill)) + min

This results in an exponential decay that starts at skill-modified maximum
and approaches minimum.

I decided that max-min+skill_modification should never be less than min
I also decided to continue to apply the Character:SkillUpModifier rule
post-calculation.  I do not really think this is necessary anymore, given
this new formula, but we can discuss removing it.
I chose 25 and 2 as default maximum and minimum based on feel.

Related method signature fix:

Client::mod_increase_skill_chance was changed to return a double and
accept a double as an input for chance.  This matches the actual data types
provided while calling the method and eliminates some type coersion and
resultant truncation.  Right now, this method doesn't do anything, but in the
future we could implement skill-specific training dummies that accelerate
skill ups.  I deduce that this is the purpose of this method call.

* [Skills]Configurable Exponential Decay Formula for Skill Up

What this fixes:
The existing formula for determining whether or not to skill up could result
in negative chances, and made an assumption around the number 252.
This would ultimately result in an override that would set the chance to 1.

My fix:
I created 2 new rules:
Character:SkillUpMaximumChancePercentage
Character:SkillUpMinimumChancePercentage

I changed the forumla to:
chance = ((max - min + skill_modification) * (.99^skill)) + min

This results in an exponential decay that starts at skill-modified maximum
and approaches minimum.

I decided that max-min+skill_modification should never be less than min
I also decided to continue to apply the Character:SkillUpModifier rule
post-calculation.  I do not really think this is necessary anymore, given
this new formula, but we can discuss removing it.
I chose 25 and 2 as default maximum and minimum based on feel.

Related method signature fix:

Client::mod_increase_skill_chance was changed to return a double and
accept a double as an input for chance.  This matches the actual data types
provided while calling the method and eliminates some type coersion and
resultant truncation.  Right now, this method doesn't do anything, but in the
future we could implement skill-specific training dummies that accelerate
skill ups.  I deduce that this is the purpose of this method call.

* fixup! [Skills]Configurable Exponential Decay Formula for Skill Up

* fixup! [Skills]Configurable Exponential Decay Formula for Skill Up
2022-01-29 20:01:58 -06:00
Paul Coene 7749c626f0 [Bug Fix] Fix issue with mobs summoning PCs into ceilings (#1921) 2022-01-29 19:55:40 -06:00
KayenEQ a6cd0bc33a [Bug Fix] Do not allow /open to be used on traps or auras, causes crash (#1951)
* Update client_packet.cpp

* [Bug Fix] Do not allow /open to be used on traps or auras, causes crash

* [Bug Fix] Do not allow /open to be used on traps or auras, causes crash
2022-01-29 19:54:26 -06:00
Chris Miles cba95851a2 [Combat] Legacy Combat Middleware Affected by PR #1858 (#1939) 2022-01-29 19:47:35 -06:00
KayenEQ 7f5706abcf bard throw while casting (#1937) 2022-01-28 22:07:23 -05:00
KayenEQ 44b8c9203a [Spells] Updates to spell field 'cast not stands' to ignore casting restrictions (#1938)
* test

* complete

* Update effects.cpp

* Update spells.cpp

* Update effects.cpp

* [Spells] Support for bards using Disciplines while casting or /melody.

Support for spell field 'cast not standing' not allow casting from divine aura

* [Spells] Support for bards using Disciplines while casting or /melody.

DA bypass logic for spells with field 'cast_not_standing'

* updates

* stun and mez bypass

* Update spdat.cpp

* Update spdat.cpp

* Update spells.cpp
2022-01-28 22:05:45 -05:00
KayenEQ afdbc0ce80 bug fix for push while rooted (#1949) 2022-01-28 22:05:29 -05:00
Paul Coene e850d80656 [Bug Fix (faction)] Do not award faction if NPC is charmed. (#1945)
* Do not award faction if npc is charmed.

* No faction on kill of charmed mob or questreward of same
2022-01-26 18:17:25 -05:00
Paul Coene b9722c6d28 [Bug Fix] Any use of TempName left old clean_name. (#1946)
* [Bug Fix] Any use of TempName left old clean_name.

* Dunsel change
2022-01-26 17:02:37 -05:00
Kinglykrab 5a7ee28740 [Bug Fix] Fix quest::updatespawntimer() Perl croak. (#1947) 2022-01-26 14:57:18 -06:00
mmcgarvey e4f2aec11e [XTarget] Revert All XTarget Corpse Changes (#1944) 2022-01-23 20:18:38 -06:00
KayenEQ e99c8dafc5 spellbar lock bug fix (#1943) 2022-01-23 20:27:45 -05:00
KayenEQ 936043a53c bind sight pets (#1942) 2022-01-23 20:27:32 -05:00
KayenEQ 3c09448e90 [Spells] NPC spell push should work on rooted mobs. (#1941)
* Update spells.cpp

* [Spells] NPC spell push should work on rooted mobs.

don't push perma or psuedorooted mobs
2022-01-20 12:13:14 -05:00
KayenEQ e09a8f8f8f [Spells] Support for bards using Disciplines while casting or /melody. (#1936)
* test

* complete

* Update effects.cpp

* Update spells.cpp

* Update effects.cpp

* [Spells] Support for bards using Disciplines while casting or /melody.

Support for spell field 'cast not standing' not allow casting from divine aura

* [Spells] Support for bards using Disciplines while casting or /melody.

DA bypass logic for spells with field 'cast_not_standing'
2022-01-19 22:44:17 -05:00
Randy Girard 804f0681a9 [Content Flags] Load the content flags before loading shared data. (#1935) 2022-01-19 12:58:15 -06:00
KayenEQ 71c53cb18b [Spells] Updates and fixes to Target Locked Pets (#1932)
* start of rework

* reworked v2 no timer

* fix

* more mechanics

* Update pets.cpp

* move to pet.cpp

* [Spells] Updates and fixes to Target Locked Pets

* [Spells] Updates and fixes to Target Locked Pets
2022-01-18 21:48:36 -05:00
Natedog2012 176bfc8524 [Bug Fix] Loading pets from database will make unique name to not overlap existing pets with same name in zone (#1933) 2022-01-18 16:43:58 -06:00
KayenEQ 28b1abe1a7 [Bug Fix] Fixes Enchanter AA Doppleganger crash issue (#1931)
* Fix crash bug

* [Bug Fix] Fixes Enchanter AA Doppleganger crash issue
2022-01-17 09:10:37 -05:00
Kinglykrab 3a94132749 [Quest API] Add multiple augment related methods to Perl/Lua. (#1930)
* [Quest API] Add multiple augment related methods to Perl/Lua.
- Add $inventory->CountAugmentEquippedByID(item_id) to Perl.
- Add $inventory->HasAugmentEquippedByID(item_id) to Perl.
- Add $item->ContainsAugmentByID(item_id) to Perl.
- Add $item->CountAugmentByID(item_id) to Perl.
- Add inventory:CountAugmentEquippedByID(item_id) to Perl.
- Add inventory:HasAugmentEquippedByID(item_id) to Perl.
- Add item:ContainsAugmentByID(item_id) to Perl.
- Add item:CountAugmentByID(item_id) to Perl.

* Update inventory_profile.cpp
2022-01-16 18:04:51 -05:00
KayenEQ 5ebbbf647b [Spells] SPA 299 Wake the Dead updates and crash fixes. SPA 306 Army of Dead implemented. (#1929)
* start

* wtd fix v1

* Update aa.cpp

* rework done, army of dead supported

* debugs

* Update aa.cpp

* Update spdat.h
2022-01-16 14:55:51 -05:00
KayenEQ 5f482a9b30 [Combat] Implemented rule for live like Riposte mechanics (#1927)
* Live like Riposte

* [Combat] Implemented rule for live like Riposte mechanics

bot fix
2022-01-15 19:37:47 -05:00
KayenEQ 91aa950304 fix for hasten AA (#1928) 2022-01-15 18:28:21 -05:00
JJ 613066976d [Bug Fix] Update to #1893 (#1926)
* Update to #1893

* Missed bonuses.cpp
2022-01-12 22:04:58 -05:00
mmcgarvey 1a556f4451 [XTarget] Performance Improvement After Corpse Change (#1918)
Removed a conditional that was rendered obsolete by moving the addition of a
mob to the auto haters list to fire after an IsValidXTarget check.  This
made an entity_list call unnecessary.  [zone/client.cpp]

Removed said unnecessary entity_list call.  [zone/client.cpp]

Removed a superfluous call to ProcessXTargetAutoHaters [zone/attack.cpp]
2022-01-12 16:04:18 -06:00
KayenEQ d10145fc6f [Bug Fix] Fix Tradeskill Salvage (#1925) 2022-01-11 18:24:47 -05:00
Kinglykrab f3002d9656 [Commands] Cleanup #who Command. (#1924)
* [Commands] Cleanup #who Command.
- Cleanup messages and logic.
- Add GetAccountStatusMap() and GetAccountStatusName() helpers for account status stuff.
- Use Chat::Who instead of Chat::Magenta so you can more easily see saylinks.
- Add a summon saylink to the list of saylinks so you can summon the player.

* New line.
2022-01-11 06:09:29 -05:00
KayenEQ 59c373bcff Update client_packet.cpp (#1923)
bug fix
2022-01-10 21:22:56 -05:00
Kinglykrab ae8273e0b1 [Commands] #guild create argument count bug fix. (#1920)
- Names with spaces were breaking command.
2022-01-10 17:33:28 -05:00
KayenEQ 10083387b6 [Spells] SPA 193 SE_SkillAttack will no longer trigger procs (#1919)
* fixed

* [Spells] SPA 193 SE_SkillAttack will no longer trigger procs
2022-01-09 08:32:09 -05:00
Chris Miles 7e065ad966 [Docs] Update Readme to reflect new docs 2022-01-08 13:57:31 -06:00
Kinglykrab ffa968f64f [Bug Fix] Disallow multiple augments in same item. (#1916)
- Disallows multiple augments via #augmentitem or otherwise.
- Added ItemInstance::ContainsAugmentByID(item_id) helper method for finding an augment in an item instance.
2022-01-04 17:18:17 -05:00
Natedog2012 6bf5608cf3 [Bug Fix] Add range check to OP_PickPocket (#1912)
* [Bug Fix] Add range check to OP_PickPocket

* Pickpocket distance is 15 constant according to Mackal

* Re-add wiggle room for distance check due to pathing
2022-01-03 22:26:37 -05:00
mmcgarvey 3853c4f150 [Bug Fix] XTarget Changes Causing Crashes (#1915)
* [Bugfix] XTarget Changes Causing Crashes

Added nullptr check when processing XTargetAutoHaters for pet owner.

* [Bugfix] XTarget Changes Causing Crashes

Added another needed sanity check after the nullptr check.

* [Bugfix] XTarget Changes Causing Crashes

Added another check against nullptr.

* [Bugfix] XTarget Changes Causing Crashes

Cleaned up nullptr checks per PR comments.
2022-01-03 22:22:21 -05:00
Chris Miles d6d4c458e7 [Database] Mark titles as a server table so it at least shows up in dumps (#1914) 2022-01-03 14:55:10 -06:00
Natedog2012 26b160c59b [Bug Fix] OP_Taunt checks if we have the skill (#1913) 2022-01-03 14:54:36 -06:00
Akkadius d107ff3069 [Hotfix] Add additional check to IsContentFlagEnabled given refactor from #1909 2022-01-03 01:06:17 -06:00
mmcgarvey 220d8497dd [XTarget] Disallow Corpses in XTarget Auto Slots (#1881)
* [XTarget] Disallow Corpses in XTarget Auto Slots

Why:
There exists an odd state where corpses will fill up your XTarget window.
This is reproducable using a combination of a pet to kill a mob
and timely feign death to wipe the owner's aggro.

What:
Added an IsCorpse check to IsXTarget.
Added a block to mark corpse XTargets as dirty to ProcessXTargetAutoHaters

* fixup! [XTarget] Disallow Corpses in XTarget Auto Slots

* fixup! [XTarget] Disallow Corpses in XTarget Auto Slots

* [XTarget] Disallow Corpses Code Cleanup

Added some safety, performance, and code readability changes per PR request.
2022-01-02 21:07:57 -06:00
Kinglykrab 645251992d [Bug Fix] Remove possible Duel exploit. (#1911)
* [Duels] Cleanup duel response/request logic.

* Fixes and function name cleanup.

* Patch file name changes.
2022-01-02 21:06:31 -06:00
Chris Miles 9815f50efa [Expansion] Content Filtering Adjustments (#1910)
* Change default expansion values for ALL to -1 from 0

* Adjust content_filter_criteria

* Refactor content filtering logic

* Allow flag strings to also just be empty instead of null

* Formatting

* Editor oops
2022-01-02 20:52:29 -06:00
Kinglykrab c0f57bed1f [Bug Fix] Cleanup Perl croaks for Spire parser. (#1908)
- Client::SendToInstance()
- Mob::DeleteBucket()
- Mob::GetBucket()
- Mob::GetBucketExpires()
- Mob::GetBucketRemaining()
- Mob::SetBucket()
2021-12-30 19:47:52 -06:00
j883376 d280d54446 [Spells] Allow GMs to remove buffs from any target (#1907) 2021-12-30 19:40:14 -06:00
Kinglykrab c99c5c1f1c [Bug Fix] Fix #guild rename, #killallnpcs, and #worldwide message errors. (#1904)
- #guild rename was checking argument count and not allowing you to rename guilds to names that had spaces.
- #killallnpcs was crashing zones when used sometimes due to getting a nullptr somewhere in the loop.
- #worldwide message was using just the first word of the message sent using the command, not all of them.
2021-12-29 12:06:51 -05:00
Natedog2012 e45f02af95 [Skills] RoF+ allows other classes to have feign death if set in skill_caps (#1902) 2021-12-29 11:17:31 -05:00
KayenEQ 323b35989c [Spells] Implemented SPA 281 SE_PetFeignMinion (#1900)
* start

* update

* debugs in

* test

* clean up

* debugs removed

* Update mob_ai.cpp

* Update spdat.h

* [Spells] Implemented SPA 281 SE_PetFeignMinion

debug remoevd

* [Spells] Implemented SPA 281 SE_PetFeignMinion

npc forget timer

* [Spells] Implemented SPA 281 SE_PetFeignMinion
2021-12-27 11:33:57 -05:00
Kinglykrab 7f23c93ce5 [Commands] Cleanup #setadventurepoints Command. (#1901)
- Cleanup message and logic.
2021-12-24 13:46:17 -05:00
Chris Miles 6a7782ab8d [Doors] Ignore Doors that Have Non-Zero Trigger or Door Param (#1899) 2021-12-23 14:47:24 -06:00
mmcgarvey 5457f30659 [Spells] Instant Heals honor IgnoreSpellDmgLvlRestriction (#1888)
Why:
Heal Over Time spells honor the Spells:IgnoreSpellDmgLvlRestriction rule,
shouldn't instant heals honor this rule too?

The fix:
Added a check for Spells:IgnoreSpellDmgLvlRestriction in the GetActSpellHealing
method.
2021-12-23 14:43:02 -06:00
KayenEQ 652ea89dea [Rule] Added rule to disable SPA 173 from making player immune to enrage. (#1897)
* immune enrage rule

* [Rule] Added rule to disable SPA 173 from making player immune to enrage.

spelling oops
2021-12-23 14:21:46 -06:00
mmcgarvey c79fbb99aa [Shared Tasks] Cross Zone Remove Fix (#1740)
* [Shared Tasks] Cross Zone Remove Fix

Why:
	The cross_zone_remove_task quest methods were not removing from
	shared_task_members database table and were not clearing shared task
	cache.  This resulted in a situation where a character could not
	request other shared tasks.

What:
	Shamelessly copied shared task logic from ClientTaskState::CancelTask
	into ClientTaskState::RemoveTaskByTaskID

* What:

Instead of copying code from CancelTask into RemoveTaskByTaskID, it is better
for code maintenance to simply call CancelTask from RemoveTaskByTaskID.
This is cleaner.

Note:  I chose to be explicit with the remove_from_db parameter, despite true
being the default.  I tend to do this to protect from the default value
changing in the future.

* [Shared Tasks] RemoveTaskByTaskID Cleanup

Removed unused variables.
Distinguished log messages for Shared Tasks from regular Tasks.
2021-12-23 14:20:15 -06:00
Paul Coene 4f0e9945c6 [Combat] Allow npcs/pets to kick vs opponents requiring magic weapons if wearing magic booties. (#1868)
* [Pets/NPC Kick] Allow pets/npcs kick vs mobs that req magic if using magic boots

* Backout accidental change to bash
2021-12-23 14:01:56 -06:00
mmcgarvey 4fbb98a5f7 [Skills] Make Tracking Skill Configurable (#1784)
Added 1 rule per class that defines tracking distance multiplier for that class
Kept the defaults of 12 for ranger, 10 for druid, and 7 for bard

Created 1 method for determining class tracking distance multiplier
Created 1 method for determining if a class can track, based on multiplier

Updated tracking logic to use these methods to determine whether a tracking
packet should and can be sent or not.
2021-12-23 13:57:53 -06:00
Paul Coene 8c78a19c95 [Bug Fix] Pick Lock was allowing skillups on doors above player skill (#1815)
* [Bux Fix] Pick Lock was allowing skillups on doors above player skill

* Fixed indentation

* Fix indentation #2 - I am not so bright :(

* Further refine messages for pick lock to match live

* sql to make pot pick locks book pickable by skill 1 and skillup
2021-12-23 13:56:06 -06:00
Kinglykrab 6a77764f8b [Commands] Cleanup #guild Command. (#1880)
- Cleanup messages and logic.
- Adds GetGuildNameByID, GetGuildRankName, GetGuildIDByCharacterID, and IsCharacterInGuild helper methods for guild stuff.
- Convert #guild info message to a popup display to tidy it up and make it more legible.
2021-12-23 13:04:26 -05:00
Natedog2012 d0ec0872b9 Client will give 1 second window to start casting at the end of DA effect but we interrupt it and need to allow spellbar active after (#1894) 2021-12-22 22:35:48 -06:00
Kinglykrab 724d47432b [Bug Fix] Fix Perl Croak for GetEnt() (#1898) 2021-12-22 15:27:25 -05:00
KayenEQ f26d56d6d5 validspell check (#1895) 2021-12-21 09:17:35 -05:00
KayenEQ 886b321e66 [Spells] Rework of SPA 288 SE_SkillAttackProc (#1893)
* start

* updated 288
2021-12-20 09:47:32 -05:00
Natedog2012 85971590c8 Re-enable spellbar and reset Discipline timer when stopping casts in EVENT_CAST_BEGIN (#1891) 2021-12-19 15:17:04 -06:00
KayenEQ 898b1ea4d1 Update attack.cpp (#1892) 2021-12-16 07:23:11 -05:00
KayenEQ d460fb3db8 [Spells] Update to SPA 440 SE_FinishingBlowMaxLevel limit value sets HP ratio for FB (#1890)
* fb max level update

* Update to SPA 440 SE_FinishingBlowMaxLevel limit value sets HP ratio for FB
2021-12-15 22:00:34 -05:00
Paul Coene fbc5d045de [Doors] Add new rule enabling classic "key on cursor" for pre keyring keys (#1869) 2021-12-15 13:26:31 -05:00
KayenEQ 3414d3a1ae fearstun update (#1889) 2021-12-15 13:17:15 -05:00
mmcgarvey feed584a41 [Database] Escape reserved mysql keyword rank w/ backticks (#1862)
Fixes #1567
2021-12-14 13:57:35 -05:00
KayenEQ 119b2d023f [Spells] Throwing procs fixed and other proc updates (#1871)
* first updating sbindex defines

* updates

* updates

* proctypes added for organization

* debug

* updates

* range procs cleaned up

* skill proc clean up

* fix

* remove debugs

* [Spells] Throwing procs fixed and other proc updates

* [Spells] Throwing procs fixed and other proc updates

bot fix

* [Spells] Throwing procs fixed and other proc updates

proctype updates
2021-12-14 12:34:51 -05:00
KayenEQ 73acc3310c [Spells] Updates and fixes to targeted focus effects (#1870) 2021-12-14 12:31:38 -05:00
KayenEQ 6da7116c66 [Bug Fix] Hero Forge armor graphics not displaying properly to other clients in zone. (#1883)
* fix part1

* updates

* Update inventory.cpp

* fixed

* Update inventory.cpp

* update

* [Bug Fix] Hero Forge armor graphics not displaying properly to other clients in zone.
2021-12-14 11:26:59 -05:00
KayenEQ 26b21673ad [Spells] Implemented SPA 245 SE_TrapCircumvention (#1885)
* implemented

* [Spells] Implemented SPA 245 SE_TrapCircumvention
2021-12-13 20:33:22 -05:00
KayenEQ ef1f6adf18 effective casting level update (#1886) 2021-12-13 20:32:25 -05:00
KayenEQ 1c2e1ea228 rampage updates (#1882) 2021-12-13 18:49:53 -05:00
KayenEQ 7cf66a2daa [Spells] Update SPA 238 SE_IllusionPersistence allow illusions to persist through deaths at higher AA ranks. (#1884)
* start

* working
2021-12-13 18:49:33 -05:00
KayenEQ 91c958ae63 Update spell_effects.cpp (#1877)
updated
2021-12-12 13:22:43 -05:00
KayenEQ 8de410ebb7 [Features] Appearance Effects will now be sent to clients upon zone in. GM commands. (#1874)
* start

* working

* Update perl_mob.cpp

* updates

* Update perl_mob.cpp

* illusion behavior

* rework start

* fix later

* Update mob.cpp

* rework

* updates

* Update mob.cpp

* update

* gm command updates

* updates

* Update CMakeLists.txt

* [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.

remove debugs

* [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.

perl fix

* [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.

space fix

* [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.

minor fix

* Update CMakeLists.txt

* [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.

cleaned up some inconsistency

* [Features] Appearance Effects will now be sent to clients upon zone in. GM commands.
2021-12-10 13:46:23 -05:00
KayenEQ 550485ba33 [Spells] Fixed issue with permanent Illusions not being consistent when zoning. (#1876)
* start of work

* updates

* [Spells] Fixed issue with permanent Illusions not being consistent when zoning.
2021-12-10 12:21:19 -05:00
KayenEQ eb2b4fd9e0 [Spells] Update to SPA 58 SE_Levitate to support limit value (#1875)
* [Spells] Update to SPA 58 SE_Levitate to support limit value

* [Spells] Update to SPA 58 SE_Levitate to support limit value

apply same on zone in
2021-12-10 12:20:25 -05:00
Natedog2012 42f439c4b7 [Quest API] Add ResetCastbarCooldownBySlot / ResetCastbarCooldownBySpellID / ResetAllCastbarCooldowns (#1873)
* New function to reset spellbar in perl/lua ResetCastbarCooldownsBySlot -1 for all slots and anything else to do it by slot number

* Add ResetCastbarCooldownsBySlot / ResetCastbarCooldownsBySpellID / ResetAllCastbarCooldowns
2021-12-08 21:39:35 -06:00
Kinglykrab 294e51fca7 [Commands] Add #setaltcurrency Command. (#1850)
* [Commands] Add #setaltcurrency Command.
- Add #setaltcurrency [Currency ID] [Amount] command to allow you to set a specific alternate currency to a value.
- Add Zone::GetCurrencyID() and Zone::GetCurrencyItemID() helper methods.
- Cleanup loops through zone->AlternateCurrencies.
- Utilize helper methods where necessary.
- Convert old methods parameters and return values from int to uint32 where necessary.

* Typo.
2021-12-08 18:58:06 -05:00
Kinglykrab 94166e0f95 [Commands] Add #unmemspell and #unmemspells Commands. (#1867)
- Add #unmemspell [Spell ID] command to unmemorize a spell by ID from you or your target.
- Add #unmemspells command to unmemorize all spells from you or your target.
- Cleanup #memspell command and change arguments from #memspell [Slot] [Spell ID] to #memspell [Spell ID] [Spell Gem] for easier use.
- Add #memspell [Spell ID] functionality to memorize to first open spell gem if there are any using FindEmptyMemSlot helper method.
- Rename client->FindMemmedSpellByID(spell_id) to FindMemmedSpellBySpellID(spell_id).
- Add client->FindEmptyMemSlot() helper method.
- Add $client->FindEmptyMemSlot() to Perl.
- Add client:FindEmptyMemSlot() to Lua.
- Add $client->FindMemmedSpellBySpellID(spell_id) to Perl.
- Add client:FindMemmedSpellBySpellID(spell_id) to Lua.
2021-12-08 18:18:14 -05:00
Kinglykrab 1a1c3abc24 [Commands] Cleanup #setstartzone Command. (#1853)
- Add a message when setting start zone.
- Cleanup logic.
2021-12-08 18:18:06 -05:00
Natedog2012 0f4f5d7046 RemoveAllAppearanceEffects sends all relevant data so NPC appearance doesn't get altered. (#1864) 2021-12-07 15:15:28 -05:00
Kinglykrab 8ec4afe721 [Commands] Cleanup #wpinfo Command. (#1866)
- Cleanup message and logic.
- Only display grid/waypoints if NPC has a grid.
2021-12-04 21:53:29 -05:00
Kinglykrab aa4536e1ef [Quest API] Add GetLDoNThemeName() to Perl/Lua. (#1861)
* [Quest API] Add GetLDoNThemeName() to Perl/Lua.
- Add quest::getldonthemename(theme_id) to Perl.
- Add eq.get_ldon_theme_name(theme_id) to Lua.

* Update embparser_api.cpp
2021-12-03 19:53:00 -05:00
Kinglykrab 01a671918a [Quest API] Add GetBodyTypeName() to Perl/Lua. (#1863)
* [Quest API] Add GetBodyTypeName() to Perl/Lua.
- Add GetBodyTypeName() and GetBodyTypeMap() helper methods.
- Add quest::getbodytypename(bodytype_id) to Perl.
- Add eq.get_body_type_name(bodytype_id) to Lua.

* ShowStats() cleanup.
2021-12-03 19:52:42 -05:00
KayenEQ e09f28c62c [Spells] Update to SPA 296 and 483 item and AA support (#1857)
[Spells] Update to SPA 296 and 483 item and AA support
2021-12-03 15:39:21 -05:00
KayenEQ 82000949e3 [Spells] Update to SPA 297 and 484 to support focus from AA and items. (#1858)
[Spells] Update to SPA 297 and 484 to support focus from  AA and items.
2021-12-03 15:39:06 -05:00
Kinglykrab 4a154686e1 [Quest API] Add GetFactionName() to Perl/Lua. (#1859)
* [Quest API] Add GetFactionName() to Perl/Lua.
- Add quest::getfactionname(faction_id) to Perl.
- Add eq.get_faction_name(faction_id) to Lua.

* Update embparser_api.cpp

* Update embparser_api.cpp

* Update embparser_api.cpp
2021-12-02 10:09:15 -05:00
Kinglykrab 29dfe9d404 [Quest API] Add GetLanguageName() to Perl/Lua. (#1860)
- Add quest::getlanguagename(language_id) to Perl.
- Add eq.get_language_name(language_id) to Lua.
2021-12-01 20:31:20 -05:00
Kinglykrab 9a0c98397e [Bug Fix] Charm Break Invisibility Fix. (#1855)
- Invisibility vs. Undead and Invisibility vs. Animals were not breaking charm.
- Add Invisibility enumerator.
- Add special identifier for Invisibility vs. Undead and Invisibility vs. Animals.
2021-12-01 12:01:19 -05:00
KayenEQ bc0795bb48 [Spells] SPA 310 SE_ReduceReuseTimer will now work on spell recast time (#1856)
* [Spells] SPA 310 SE_ReduceReuseTimer	will now work on spell recast time

[Spells] SPA 310 SE_ReduceReuseTimer	will now work on spell recast time

* [Spells] SPA 310 SE_ReduceReuseTimer will now work on spell recast time

[Spells] SPA 310 SE_ReduceReuseTimer will now work on spell recast time
2021-12-01 00:22:10 -06:00
JJ d972183a79 [Cleanup] holdzones not used. (#1852)
Fixes #1116.
2021-11-28 22:35:52 -05:00
Natedog2012 f70b4a79b2 SetPetID after we assign the new NPC an ID (#1851) 2021-11-28 15:42:42 -06:00
Kinglykrab 7cac2e2bc3 [Commands] Add #viewcurrencies Command. (#1844)
* [Commands] Add #viewcurrencies Command.
- Add #viewcurrencies command to view your or your target's currencies (Money, Crystals, Alternate Currency, LDoN, and PVP).
- Add GetLDoNThemeName() helper method.

* Update viewcurrencies.cpp

* Cleanup name of map method.

* Cleanup.
2021-11-28 00:09:07 -05:00
Kinglykrab 2be1321aa9 [Commands] Add #removeitem Command. (#1847)
- Add #removeitem [Item ID] [Amount] command to remove items by amount versus nuking them all, removes all if amount is greater than what you or your target have.
2021-11-27 21:41:54 -05:00
Kinglykrab ba5bb09af7 [Commands] Cleanup #flymode Command. (#1845)
- Cleanup message and logic.
- Add GetFlyModeName() and GetFlyModeMap() helper methods.
- Cleanup #npcedit flymode to use helper methods.
2021-11-27 21:39:54 -05:00
Kinglykrab 5ab9b941e2 [Commands] Cleanup #titlesuffix Command. (#1834)
- Cleanup message and logic.
2021-11-27 21:29:56 -05:00
Kinglykrab d28f902ecc [Commands] Add #countitem Command. (#1842)
* [Commands] Add #countitem Command.
- Add #countitem [Item ID] command to count an item by ID on yourself or your player/NPC target.

* Cleanup.
2021-11-27 20:52:09 -05:00
Kinglykrab fd862d16bb [Commands] Cleanup #mysql Command. (#1837)
* [Commands] Cleanup #mysql Command.
- Cleanup messages and logic.

* Update mysql.cpp
2021-11-27 20:32:21 -05:00
Kinglykrab a6e5534b64 [Commands] Cleanup #texture Command. (#1835)
* [Commands] Cleanup #texture Command.
- Cleanup message and logic.

* Update command.cpp
2021-11-27 20:21:58 -05:00
Kinglykrab 225497337c [Commands] Add #setendurance Command. (#1841)
- Add #setendurance [Endurance] command to set an NPC or player's endurance to a specified amount, or to max if the amount is greater than their max.
- Cleanup #endurance command message and logic.
2021-11-27 19:08:07 -05:00
Kinglykrab a5348e207b [Commands] Add #sethp Command. (#1840)
- Add #sethp [Health] command to set an NPC or player's health to a specified amount, or to max if the amount is greater than their max.
- Cleanup #heal command message and logic.
2021-11-27 19:08:00 -05:00
Kinglykrab c4c5256438 [Commands] Add #setmana Command. (#1839)
* [Commands] Add #setmana Command.
- Add #setmana [Mana] command to set an NPC or player's mana to a specified amount, or to max if the amount is greater than their max.
- Cleanup #mana command message and logic.

* Update mana.cpp
2021-11-27 19:07:47 -05:00
Kinglykrab b3b9899a23 [Commands] Cleanup #movechar Command. (#1838)
- Cleanup messages and logic.
- Add support for Zone ID versus Zone Short Name.
- Add support for Character ID versus Character Name.
2021-11-27 19:06:40 -05:00
Kinglykrab 7d1d385418 [Commands] Cleanup #gmzone Command. (#1836)
- Cleanup messages and logic.
- Add support for Zone ID.
2021-11-27 18:19:03 -05:00
Kinglykrab 96cdf1b076 [Commands] Cleanup #title Command. (#1833)
- Cleanup message and logic.
2021-11-27 18:18:27 -05:00
KayenEQ 8688e9c9fa [Spells] Eye of Zomm will now despawn and stack properly (#1849)
* [Spells] Eye of Zomm stop chain spawning

No more chain spawning.

* [Spells] Eye of Zomm stop chain spawning

* [Spells] Eye of Zomm update
2021-11-27 12:11:23 -05:00
KayenEQ 6a28828e08 [API] mob->AppearanceEffects improved functionality. (#1821)
* appearanceffectscript

* update

* debugged

* [API] SendAppearanceEffect update

* [API] SendAppearanceEffect update

* [API] SendAppearanceEffect Upates

perl method RemoveAppearanceEffect to remove the apperanceeffect

* [API} AppearanceEffects update

* [API] SendAppearanceEffects update
2021-11-27 12:10:08 -05:00
Natedog2012 8566662d56 [Bug Fix] SendSpellBarEnable sends correct slotid to fix spellbar on RoF2 (#1848)
* SendSpellBarEnable sends correct slotid to fix spellbar on RoF2

* Send correct data when using StopCasting() to re-enable spellbar
2021-11-27 09:45:57 -05:00
Kinglykrab 298ae3e3ba [Bug Fix] Fix possible crash with #killallnpcs. (#1846) 2021-11-27 09:45:13 -05:00
Michael Cook (mackal) 4507b063f5 Switch server to use new style ManaChange_Struct (#1843)
This will allow us to fix some bugs the current handling has.

Note: the decoder isn't needed since the client always sends it up as a
0 length packet.
2021-11-26 21:33:49 -05:00
Natedog2012 774e0c7faa Do not set teleport doors to Open (#1786) 2021-11-26 15:26:07 -06:00
Kinglykrab 8b54bb34e4 [Commands] Cleanup #gmspeed Command. (#1831)
* [Commands] Cleanup #gmspeed Command.
- Cleanup message and logic.

* Update gmspeed.cpp

* Update gmspeed.cpp
2021-11-26 13:56:45 -05:00
Kinglykrab e87b8e2682 [Commands] Cleanup #gender Command. (#1832)
- Cleanup message and logic.
- Cleanup other spots using similar logic so they're all uniform.
2021-11-26 10:01:35 -05:00
Kinglykrab 2dc3ca52db [Commands] Cleanup #gm Command. (#1830)
- Cleanup message and logic.
- Cleanup SetGM() message.
2021-11-26 10:01:13 -05:00
Kinglykrab 514029a6bb [Commands] Cleanup #bind Command. (#1829)
- Add message and cleanup logic.
2021-11-26 10:01:04 -05:00
Kinglykrab b29f398239 [Commands] Cleanup #getplayerburiedcorpsecount Command. (#1818)
* [Commands] Cleanup #getplayerburiedcorpsecount Command.
- Cleanup message and logic.

* Update command.cpp
2021-11-25 21:01:23 -05:00
Kinglykrab e474b2a280 [Commands] Add #petitems Command. (#1823)
- Add #petitems command to show a person's pet items if they have access to the command.
- Adds a default false parameter to QueryLoot for NPCs that keeps messages and logic from being ran on pets for no reason.
- Cleaned up message a bit for loot and stuff.
- Remove check for loottable ID when using #npcstats for NPCs that get items from a script or otherwise.
2021-11-25 14:50:05 -05:00
Kinglykrab d38b8a4867 [Bug Fix] Fix possible crash in #givemoney. (#1828) 2021-11-25 13:55:06 -05:00
KayenEQ 1a5f48521d [Bug Fix] Bind Sight will now function properly (#1825)
* start

* bind sight fixed

* Update spdat.h

* Update spells.cpp

* Search or jump to… Pull requests Issues Marketplace Explore   @KayenEQ  EQEmu / Server Public 60 338 290 Code Issues 106 Pull requests 11 Actions Projects 1 Wiki Security Insights [Bug Fix] Bind Sight will now function properly #1825  Open KayenEQ wants to merge 4 commits into EQEmu:master from KayenEQ:bindsightfix2  Open [Bug Fix] Bind Sight will now function properly
2021-11-25 10:16:28 -05:00
KayenEQ ba427c64ba [Bug Fix] Numhits now display instantly on cast. (#1826) 2021-11-25 08:33:39 -05:00
KayenEQ 9d59b3def4 [Spells] Bard AA clicks should not receive song modifiers. (#1824) 2021-11-25 08:32:46 -05:00
KayenEQ a6f5bf72be Update spell_effects.cpp (#1822) 2021-11-24 19:43:43 -05:00
KayenEQ 6ff7f7aa53 [API] mob->SpellEffect small perl fix (#1820)
* Update perl_mob.cpp

* Update perl_mob.cpp
2021-11-24 12:48:23 -05:00
Kinglykrab 1a2897c423 [Commands] Cleanup #disablerecipe Command. (#1816)
- Cleanup message and logic.
2021-11-23 21:45:59 -05:00
Kinglykrab 8b5b19ae2c [Commands] Cleanup #enablerecipe Command. (#1817)
- Cleanup message and logic.
2021-11-23 21:45:52 -05:00
Kinglykrab 6fa41a3b73 [Commands] Remove duplicate commands. (#1819) 2021-11-23 19:53:39 -05:00
Kinglykrab 6496690123 [Commands] Cleanup #zsafecoords Command. (#1806)
* [Commands] Cleanup #zsafecoords Command.
- Cleanup message and logic.
- Add parameter to allow data to be saved to database.

* Typo.

* Update zsafecoords.cpp

* Update zsafecoords.cpp
2021-11-23 18:25:12 -05:00
Kinglykrab a11482ff23 [Cleanup] Utilize ConvertSecondsToTime() method. (#1805)
* [Cleanup] Utilize ConvertSecondsToTime() method.

* Lowercase.
2021-11-23 18:25:02 -05:00
Kinglykrab 4672e48fbd [Commands] Cleanup #zcolor Command. (#1813)
* [Commands] Cleanup #zcolor Command.
- Cleanup message and logic.
- Add parameter to allow data to be saved to database.

* Update zcolor.cpp
2021-11-23 16:45:31 -05:00
KayenEQ 8f3cce6585 send graphic to target correctly (#1785) 2021-11-23 12:55:58 -05:00
Kinglykrab 8d3a179ecc [Commands] Remove #zuwcoords Command. (#1810)
- Remove duplicate command of #zunderworld
2021-11-23 06:03:09 -05:00
Kinglykrab 2cbcefd9a0 [Commands] Cleanup #zheader Command. (#1814)
* [Commands] Cleanup #zheader Command.
- Cleanup message and logic.
- Add parameter to allow versions to be loaded.
- Cleanup parameter name in CFG methods from instance_id to instance_version.

* Update zonedb.cpp
2021-11-23 05:49:11 -05:00
Kinglykrab ef06a0d0b6 [Commands] Cleanup #zclip Command. (#1812)
* [Commands] Cleanup #zclip Command.
- Cleanup message and logic.
- Add parameter to allow data to be saved to database.

* Cleanup.
2021-11-23 05:48:47 -05:00
Kinglykrab 1935ea60d0 [Commands] Remove #zonespawn Command. (#1811)
* [Commands] Remove #zonespawn Command.
- Remove unimplemented command.

* Remove from CMakeLists.txt.

* Fix.
2021-11-23 05:48:39 -05:00
Kinglykrab 8c7e1be344 [Commands] Cleanup #givemoney Command. (#1804)
- Cleanup money message to use new helper method.
2021-11-22 21:18:04 -05:00
Kinglykrab 9240497cbc [Commands] Cleanup #zsky Command. (#1808)
- Cleanup message and logic.
- Add parameter to allow data to be saved to database.
2021-11-22 21:17:13 -05:00
Kinglykrab 0da4610249 [Commands] Cleanup #zsave Command. (#1807)
* [Commands] Cleanup #zsave Command.
- Cleanup message and logic.

* White.
2021-11-22 21:17:03 -05:00
Kinglykrab 26c7287997 [Commands] Cleanup #zunderworld Command. (#1809)
* [Commands] Cleanup #zunderworld Command.
- Cleanup message and logic.
- Add parameter to allow data to be saved to database.

* Update zunderworld.cpp
2021-11-22 21:16:42 -05:00
Kinglykrab cece66adc6 [Commands] Cleanup #instance Command. (#1803)
* [Commands] Cleanup #instance Command.
- Cleanups message and logic.
- Cleanup ListAllInstances() method.
- Fix day calculation in ConvertSecondsToTime().

* Cleanup.

* Add return.
2021-11-21 19:02:01 -05:00
Kinglykrab d29993fafa [Commands] Cleanup #nukebuffs Command. (#1795)
* [Commands] Cleanup #nukebuffs Command.
- Cleanup messages and logic.
- #nukebuffs now allows you to nuke all, beneficial, or detrimental buffs, also added a help menu.
- Add BuffFadeBeneficial().
- Cleanup logic in some buff fade methods.
- Fix several spots where we were using CalcBonuses() when it was unnecessary, i.e when you fade no buffs you do not need to recalculate bonuses.

* Update spells.cpp
2021-11-21 15:20:16 -05:00
Kinglykrab 39c27c987d [Commands] Cleanup #peqzone Command. (#1794)
- Cleanup messages and logic.
- Add RULE_INT(Zone, PEQZoneHPRatio, 75, "Required HP Ratio to use #peqzone")
- Modify #peqzone Timer rule to allow it to be disabled.
2021-11-21 14:19:08 -05:00
Kinglykrab 5470ec6293 [Commands] Cleanup #corpse Command. (#1790)
- Cleanup message and logic.
- Add ConvertMoneyToString(platinum, gold, silver, copper) helper method.
- Cleanup NPC::QueryLoot() and Corpse::QueryLoot().
2021-11-21 14:02:03 -05:00
Kinglykrab 1acdc6034b [Commands] Cleanup #permagender Command. (#1779)
- Cleanup message and logic.
2021-11-21 14:01:15 -05:00
KayenEQ e9fc80815a [Spells] Support for SPA 161 and 450 to give percent spell or dot mitigation from Items or AA's. (#1793)
* spell dot shield item AA support

* Update spdat.h

* Update attack.cpp
2021-11-21 10:16:55 -05:00
splose a84536cd05 [Bug Fix] Autofire attacking yourself (#1776)
* Fix being able to attack yourself with autofire if Combat:MinRangedAttackDist == 0

* requested changes

* 2
2021-11-21 10:16:20 -05:00
splose 0a34809bb3 [Bug Fix] - Monk AA Spirit of Master Wu (#1775)
* Monk AA Spirit of Master Wu sends message even if it grants 0 extra attacks.

* fomatting + put if statement in wrong place.. oops.

* Need to push something to set up my Tortoise Github Auth

* test

* test

* test

* test

* test

* requested changes

* Update special_attacks.cpp

Co-authored-by: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com>
2021-11-21 10:15:36 -05:00
Kinglykrab 03847fb1ac [Commands] Cleanup #lastname Command. (#1802)
- Cleanup message and logic.
2021-11-21 10:12:47 -05:00
Kinglykrab 8a27fce3a8 [Commands] Cleanup #memspell Command. (#1801)
- Cleanup message and logic.
- Add support for memorizing spell to target if you have GM enabled.
2021-11-21 10:12:37 -05:00
Kinglykrab 6a42639386 [Commands] Cleanup #pvp Command. (#1800)
- Cleanup messages and logic.
2021-11-21 10:12:23 -05:00
Kinglykrab b9214bfdee [Commands] Cleanup #aggro Command. (#1799)
- Cleanup messages and logic.
- Cleanup constant names and references.
- Cleanup aggro description methods.
2021-11-21 10:12:12 -05:00
Kinglykrab 04fda24c8e [Commands] Cleanup #aggrozone Command. (#1798)
- Cleanup message and logic.
- Add the ability to aggro the zone on your target if you have one.
2021-11-21 10:12:02 -05:00
Kinglykrab 446c5d90ec [Commands] Cleanup #killallnpcs Command. (#1797)
- Cleanup message and logic.
2021-11-21 10:11:47 -05:00
Kinglykrab 80f15ed04a [Commands] Cleanup #myskills Command. (#1796)
- Cleanup popup window display and logic.
2021-11-21 10:11:29 -05:00
Kinglykrab 51fb46556d [Commands] Cleanup #setfaction Command. (#1792)
- Cleanup message and logic.
- Doesn't allow you to use invalid faction IDs anymore.
2021-11-21 10:11:03 -05:00
Kinglykrab d73194c1f6 [Commands] Cleanup #setanim Command. (#1791)
- Cleanup message and logic.
- SetAppearance was not sending to self, so if you modified your own appearance, you wouldn't be able to see it.
2021-11-21 10:10:52 -05:00
Kinglykrab ec1cf68ce2 [Commands] Cleanup #damage Command. (#1789)
- Cleanup logic.
2021-11-21 10:08:20 -05:00
Kinglykrab 39b39970f6 [Commands] Cleanup #ginfo Command. (#1788)
- Cleanup message and logic.
2021-11-21 10:03:31 -05:00
Kinglykrab 40edefa6f4 [Commands] Cleanup #camerashake Command. (#1787)
- Cleanup message and logic.
- Fix ConvertSecondsToTime logic for milliseconds.
- Add ConvertMillisecondsToTime inline function.
2021-11-21 10:03:20 -05:00
Kinglykrab 7154d5b841 [Commands] Cleanup #flags Command. (#1783)
- Cleanup message and logic.
2021-11-21 10:03:08 -05:00
Kinglykrab dfe43ce189 [Commands] Cleanup #nukeitem Command. (#1782)
* [Commands] Cleanup #nukeitem Command.
- Cleanup message and logic.

* Typo.
2021-11-21 09:59:07 -05:00
Kinglykrab 69d5fee471 [Commands] Cleanup #givemoney Command. (#1781)
* [Commands] Cleanup #givemoney Command.
- Cleanup message and logic.

* Update givemoney.cpp
2021-11-21 09:58:23 -05:00
Kinglykrab f1d9221b4c [Commands] Cleanup #invul Command. (#1780)
- Cleanup message and logic.
2021-11-21 09:58:13 -05:00
Kinglykrab fb2f901539 [Commands] Cleanup #permarace Command. (#1778)
- Cleanup message and logic.
2021-11-21 09:56:27 -05:00
Kinglykrab 7c12c5d5ef [Commands] Cleanup #permaclass Command. (#1777)
- Cleanup message and logic.
2021-11-21 09:56:10 -05:00
splose 7559732408 [Bug Fix] Frenzy is supposed to use 1H Animation. (#1774) 2021-11-21 01:19:04 -05:00
KayenEQ fac0d795f2 [Bug Fix] Melee Life tap overflowing and causing damage (#1773)
* Update mob.cpp

* Update mob.cpp
2021-11-18 09:10:02 -05:00
Kinglykrab 3efd9c7f60 [Cleanup] Convert DeleteItemInInventory quantity to int16. (#1767)
* [Cleanup] Convert DeleteItemInInventory quantity to int16.

* Type conversion.
2021-11-16 08:52:22 -05:00
Kinglykrab bf8a0328b3 [Cleanup] Add Entity ID to ShowStats() NPC display. (#1770) 2021-11-15 18:19:42 -05:00
Michael Cook (mackal) 0ebb1cc54c Fix linking tests due to ddcb18418 (#1769) 2021-11-15 13:27:01 -05:00
Akkadius a111668888 [Hotfix] Default PR #1758 to false 2021-11-15 04:07:55 -06:00
Chris Miles 0550fcfd3f [GM Commands] Split GM Commands Into Separate Files (#1766)
* Split GM commands into their own files

* Code cleanup
2021-11-14 22:48:47 -06:00
Kinglykrab 293361a1f7 [Cleanup] Make use of AccountStatus constants wherever status is checked or used. (#1764)
* [Cleanup] Make use of AccountStatus constants wherever status is checked or used.
- Cleanup all instances of SendEmoteMessage.
- Cleanup all instances of SendEmoteMessageRaw.
- Cleanup all instances of MessageStatus.
- Convert Quest API method defaults to use constants.

* Cleanup constant names.
2021-11-14 21:01:13 -06:00
Kinglykrab 5d75b7b365 [Commands] Cleanup #advnpcspawn and #npcspawn Commands. (#1754)
* [Commands] Cleanup #advnpcspawn and #npcspawn Commands.
- Cleanup messages and logic.
- Add enum for spawn types to remove magic numbers.
- Cleanup messages that were improper/unused.

* Cleanup.

* Cleanup.

* Cleanup.

* Typo.

* Update command.cpp
2021-11-14 19:58:55 -06:00
Natedog2012 6400e2f8bc [Rules] Add option rule to load AA based on CurrentExpansion rule (#1758)
* Add option rule to load AA based on CurrentExpansion rule

* Default UseCurrentExpansionAAOnly to true

* Only clear the PlayerAA when reloadingAA
2021-11-14 19:54:45 -06:00
JJ 76b0183a0f [Loginserver] Increase IP/hostname size a bit more (#1765) 2021-11-14 19:53:53 -06:00
JJ b3471c51df [Config] Delete extra versions (#1763)
* [Config] Delete extra versions [CI SKIP]

* Same
2021-11-14 19:53:14 -06:00
Kinglykrab b2c86f5571 [Commands] Cleanup #raidloot Command. (#1757)
- Cleanup message and logic.
- Add RaidLootTypes enum and map for names.
2021-11-14 19:50:51 -06:00
Kinglykrab 264c6cb019 [Commands] Cleanup #setcrystals Command. (#1745)
* [Commands] Cleanup #setcrystals Command.
- Add message.
- Increase cap from 100,000 to 2,000,000,000.

* Cleanup.

* Remove condition, ID is always defined.

* Cleanup.
2021-11-14 19:47:36 -06:00
Akkadius 9bcb617f90 [Hotfix] Line ending changes 2021-11-14 15:59:03 -06:00
Kinglykrab f5d37a9959 [Commands] Cleanup #setpvppoints Command. (#1755)
* [Commands] Cleanup #setpvppoints Command.
- Cleanup message and logic.

* Cleanup.
2021-11-14 14:47:25 -05:00
Kinglykrab c44b82500d [Commands] Cleanup #setaaxp Command. (#1751)
* [Commands] Cleanup #setaaxp Command.
- Add message.
- Cleanup logic.

* Update command.cpp

* Cleanup.
2021-11-14 14:47:17 -05:00
Kinglykrab 4f550fcbf3 [Commands] Cleanup #loc Command. (#1752)
- Cleanup message and logic.
2021-11-14 14:09:10 -05:00
Kinglykrab 1103d50733 [Commands] Cleanup #setaapts Command. (#1750)
* [Commands] Cleanup #setaapts Command.
- Cleanup message and logic.
- Increase cap from 5,000 to 2,000,000,000.

* Update command.cpp

* Update command.cpp

* Cleanup.

* Cleanup.
2021-11-14 14:06:57 -05:00
Kinglykrab ddcb184183 [Commands] Cleanup #stun Command. (#1749)
* [Commands] Cleanup #stun Command.
- Cleanup message.
- Add ConvertSecondsToTime() to string_util.h and convert Quest API Methods to use helper.

* Add days to ConvertSecondsToTime() and cleanup logic.

* Cleanup.

* Typo.

* Cleanup.

* Cleanup.
2021-11-14 14:05:44 -05:00
Kinglykrab 90bcc5f03c [Commands] Cleanup #zonelock Command. (#1711)
* [Commands] Cleanup #zonelock Command.
- Add support for Zone IDs.
- Cleanup messages and display.
- Fix dangling pointer in ZoneLongName() helper method so name is displayed properly.

* Add account status enum.

* Typo.

* Typo.

* Convert list to constants.

* Cleanup.

* Update command.cpp

* Fix compile.
2021-11-14 11:32:08 -05:00
767 changed files with 69478 additions and 63964 deletions
+10 -1
View File
@@ -7,10 +7,19 @@ name: EQEmulator Server Linux CI
concurrency:
limit: 1
volumes:
- name: cache
host:
path: /var/lib/cache
steps:
- name: server-build
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
image: akkadius/eqemu-server:latest
commands:
- sudo chown eqemu:eqemu /drone/src/ * -R
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
- sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O0 -g -DNDEBUG" -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
volumes:
- name: cache
path: /home/eqemu/.ccache/
+2
View File
@@ -54,3 +54,5 @@ bin/
/Win32
/x64
/client_files/**/CMakeFiles/
.idea
+1 -2
View File
@@ -9,8 +9,7 @@
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"configurationProvider": "ms-vscode.cmake-tools"
"cppStandard": "c++17"
}
],
"version": 4
-8
View File
@@ -1,8 +0,0 @@
{
"files.associations": {
"chrono": "cpp",
"xutility": "cpp",
"iterator": "cpp",
"*.ipp": "cpp"
}
}
+14 -14
View File
@@ -6,7 +6,7 @@
{
"label": "make",
"type": "shell",
"command": "mkdir -p build && cd build && make",
"command": "cd bin && make",
"group": {
"kind": "build",
"isDefault": true
@@ -18,7 +18,7 @@
{
"label": "make clean",
"type": "shell",
"command": "mkdir -p build && cd build && make clean",
"command": "cd bin && make clean",
"group": {
"kind": "build",
"isDefault": true
@@ -30,7 +30,7 @@
{
"label": "cmake",
"type": "shell",
"command": "mkdir -p build && cd build && rm CMakeCache.txt && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' ..",
"command": "mkdir -p bin && cd bin && rm CMakeCache.txt && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' ..",
"group": {
"kind": "build",
"isDefault": true
@@ -52,7 +52,7 @@
{
"label": "download maps",
"type": "shell",
"command": "mkdir -p build && cd build/bin && wget https://codeload.github.com/Akkadius/EQEmuMaps/zip/master -O maps.zip && unzip -o maps.zip && rm ./maps -rf && mv EQEmuMaps-master maps && rm maps.zip",
"command": "mkdir -p bin && cd bin && wget https://codeload.github.com/Akkadius/EQEmuMaps/zip/master -O maps.zip && unzip -o maps.zip && rm ./maps -rf && mv EQEmuMaps-master maps && rm maps.zip",
"group": {
"kind": "build",
"isDefault": true
@@ -64,7 +64,7 @@
{
"label": "download quests",
"type": "shell",
"command": "mkdir -p build && cd build/bin && cd server && git -C ./quests pull 2> /dev/null || git clone https://github.com/ProjectEQ/projecteqquests.git quests",
"command": "mkdir -p bin && cd bin && cd server && git -C ./quests pull 2> /dev/null || git clone https://github.com/ProjectEQ/projecteqquests.git quests",
"group": {
"kind": "build",
"isDefault": true
@@ -76,7 +76,7 @@
{
"label": "download eqemu_config",
"type": "shell",
"command": "mkdir -p build && cd build/bin && wget --no-check-certificate https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/eqemu_config_docker.json -O eqemu_config.json",
"command": "mkdir -p bin && cd bin && wget --no-check-certificate https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/eqemu_config_docker.json -O eqemu_config.json",
"group": {
"kind": "build",
"isDefault": true
@@ -88,7 +88,7 @@
{
"label": "rebuild database (mariadb must be started)",
"type": "shell",
"command": "mkdir -p build && cd build/bin && docker run -i --rm --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --network=eqemu -it eqemu/server:0.0.3 bash -c './eqemu_server.pl source_peq_db && ./eqemu_server.pl check_db_updates && ./eqemu_server.pl assets && ./eqemu_server.pl lua_modules && ./eqemu_server.pl opcodes && ./eqemu_server.pl linux_login_server_setup'",
"command": "mkdir -p bin && cd bin && docker run -i --rm --privileged -v ${HOST_PROJECT_PATH}/bin:/src --network=eqemu -it eqemu/server:0.0.3 bash -c './eqemu_server.pl source_peq_db && ./eqemu_server.pl check_db_updates && ./eqemu_server.pl linux_login_server_setup'",
"group": {
"kind": "build",
"isDefault": true
@@ -100,7 +100,7 @@
{
"label": "zone 7000",
"type": "shell",
"command": "docker stop zone7000 | true && docker network create eqemu | true && docker run -i --rm --name zone7000 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu -p 7000:7000/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7000:7000",
"command": "docker stop zone7000 | true && docker network create eqemu | true && docker run -i --rm --name zone7000 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu -p 7000:7000/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7000:7000",
"group": {
"kind": "test",
"isDefault": true
@@ -109,7 +109,7 @@
{
"label": "zone 7001",
"type": "shell",
"command": "docker stop zone7001 | true && docker network create eqemu | true && docker run -i --rm --name zone7001 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu -p 7001:7001/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7001:7001",
"command": "docker stop zone7001 | true && docker network create eqemu | true && docker run -i --rm --name zone7001 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu -p 7001:7001/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7001:7001",
"group": {
"kind": "test",
"isDefault": true
@@ -118,7 +118,7 @@
{
"label": "loginserver",
"type": "shell",
"command": "docker stop loginserver | true && docker network create eqemu | true && docker run -i --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu --name loginserver -p 5999:5999/udp -p 5998:5998/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./loginserver",
"command": "docker stop loginserver | true && docker network create eqemu | true && docker run -i --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu --name loginserver -p 5999:5999/udp -p 5998:5998/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./loginserver",
"group": {
"kind": "test",
"isDefault": true
@@ -127,7 +127,7 @@
{
"label": "shared_memory, world",
"type": "shell",
"command": "docker stop sharedmemory | true && docker stop world | true && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --network=eqemu --name sharedmemory eqemu/server:0.0.3 ./shared_memory && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name world -p 9000:9000 -p 9000:9000/udp -p 9001:9001 -p 9080:9080 eqemu/server:0.0.3 gdb -ex run ./world",
"command": "docker stop sharedmemory | true && docker stop world | true && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --network=eqemu --name sharedmemory eqemu/server:0.0.3 ./shared_memory && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name world -p 9000:9000 -p 9000:9000/udp -p 9001:9001 -p 9080:9080 eqemu/server:0.0.3 gdb -ex run ./world",
"group": {
"kind": "test",
"isDefault": true
@@ -136,7 +136,7 @@
{
"label": "queryserv",
"type": "shell",
"command": "docker stop queryserv | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name queryserv eqemu/server:0.0.3 gdb -ex run ./queryserv",
"command": "docker stop queryserv | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name queryserv eqemu/server:0.0.3 gdb -ex run ./queryserv",
"group": {
"kind": "test",
"isDefault": true
@@ -145,7 +145,7 @@
{
"label": "mariadb",
"type": "shell",
"command": "docker stop mariadb | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin/db:/bitnami/mariadb -p 3306:3306 -e MARIADB_DATABASE=peq -e MARIADB_USER=eqemu -e MARIADB_PASSWORD=eqemupass -e ALLOW_EMPTY_PASSWORD=yes --name mariadb --network=eqemu bitnami/mariadb:latest",
"command": "docker stop mariadb | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin/db:/bitnami/mariadb -p 3306:3306 -e MARIADB_DATABASE=peq -e MARIADB_USER=eqemu -e MARIADB_PASSWORD=eqemupass -e ALLOW_EMPTY_PASSWORD=yes --name mariadb --network=eqemu bitnami/mariadb:latest",
"group": {
"kind": "test",
"isDefault": true
@@ -154,7 +154,7 @@
{
"label": "ucs",
"type": "shell",
"command": "docker stop ucs | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src -p 7778:7778 --name ucs --network=eqemu eqemu/server:0.0.3 gdb -ex run ./ucs",
"command": "docker stop ucs | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src -p 7778:7778 --name ucs --network=eqemu eqemu/server:0.0.3 gdb -ex run ./ucs",
"group": {
"kind": "test",
"isDefault": true
+1 -1
View File
@@ -373,7 +373,7 @@ ENDIF()
IF(PERL_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
IF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
+4 -4
View File
@@ -18,16 +18,16 @@
|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)|
### > Windows
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-windows)
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
### > Debian/Ubuntu/CentOS/Fedora
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-linux)
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
* You can use curl or wget to kick off the installer (whichever your OS has)
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
## Supported Clients
@@ -56,7 +56,7 @@ forum, although pull requests will be much quicker and easier on all parties.
## Resources
- [EQEmulator Forums](http://www.eqemulator.org/forums)
- [EQEmulator Wiki](https://eqemu.gitbook.io/)
- [EQEmulator Wiki](https://docs.eqemu.io/)
## Related Repositories
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
+4
View File
@@ -7,6 +7,7 @@ SET(common_sources
compression.cpp
condition.cpp
content/world_content_service.cpp
discord/discord.cpp
crash.cpp
crc16.cpp
crc32.cpp
@@ -34,6 +35,7 @@ SET(common_sources
event_sub.cpp
expedition_lockout_timer.cpp
extprofile.cpp
discord_manager.cpp
faction.cpp
file_util.cpp
guild_base.cpp
@@ -491,6 +493,8 @@ SET(common_headers
database_schema.h
dbcore.h
deity.h
discord/discord.h
discord_manager.h
dynamic_zone_base.h
emu_constants.h
emu_limits.h
+8 -8
View File
@@ -23,18 +23,18 @@
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
{
this->pBuffer=nullptr;
this->size=0;
this->_wpos = 0;
this->_rpos = 0;
this->timestamp.tv_sec = 0;
pBuffer=nullptr;
size=0;
_wpos = 0;
_rpos = 0;
timestamp.tv_sec = 0;
if (len>0) {
this->size=len;
size=len;
pBuffer= new unsigned char[len];
if (buf) {
memcpy(this->pBuffer,buf,len);
memcpy(pBuffer,buf,len);
} else {
memset(this->pBuffer,0,len);
memset(pBuffer,0,len);
}
}
}
+5 -5
View File
@@ -380,12 +380,12 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
return "Merchant";
case DISCORD_MERCHANT:
return "Discord Merchant";
case ADVENTURERECRUITER:
case ADVENTURE_RECRUITER:
return "Adventure Recruiter";
case ADVENTUREMERCHANT:
case ADVENTURE_MERCHANT:
return "Adventure Merchant";
case CORPSE_CLASS:
return "Corpse Class";
case LDON_TREASURE:
return "LDoN Treasure";
case TRIBUTE_MASTER:
return "Tribute Master";
case GUILD_TRIBUTE_MASTER:
@@ -400,7 +400,7 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
return "Fellowship Master";
case ALT_CURRENCY_MERCHANT:
return "Alternate Currency Merchant";
case MERCERNARY_MASTER:
case MERCENARY_MASTER:
return "Mercenary Liaison";
default:
return "Unknown";
+4 -5
View File
@@ -55,10 +55,9 @@
#define BANKER 40
#define MERCHANT 41
#define DISCORD_MERCHANT 59
#define ADVENTURERECRUITER 60
#define ADVENTUREMERCHANT 61
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
#define ADVENTURE_RECRUITER 60
#define ADVENTURE_MERCHANT 61
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
#define TRIBUTE_MASTER 63
#define GUILD_TRIBUTE_MASTER 64 // not sure
#define GUILD_BANKER 66
@@ -66,7 +65,7 @@
#define DARK_REIGN_MERCHANT 68
#define FELLOWSHIP_MASTER 69
#define ALT_CURRENCY_MERCHANT 70
#define MERCERNARY_MASTER 71
#define MERCENARY_MASTER 71
// player class values
+138 -17
View File
@@ -22,6 +22,7 @@
#include "../database.h"
#include "../rulesys.h"
#include "../eqemu_logsys.h"
#include "../loottable.h"
#include "../repositories/content_flags_repository.h"
@@ -35,8 +36,12 @@ int WorldContentService::GetCurrentExpansion() const
return current_expansion;
}
void WorldContentService::SetExpansionContext()
WorldContentService *WorldContentService::SetExpansionContext()
{
// do a rule manager reload until where we store expansion is changed to somewhere else
RuleManager::Instance()->LoadRules(GetDatabase(), "default", true);
// pull expansion from rules
int expansion = RuleI(Expansion, CurrentExpansion);
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
content_service.SetCurrentExpansion(expansion);
@@ -47,6 +52,8 @@ void WorldContentService::SetExpansionContext()
GetCurrentExpansion(),
GetCurrentExpansionName()
);
return this;
}
std::string WorldContentService::GetCurrentExpansionName()
@@ -73,15 +80,47 @@ void WorldContentService::SetCurrentExpansion(int current_expansion)
/**
* @return
*/
const std::vector<std::string> &WorldContentService::GetContentFlags() const
const std::vector<ContentFlagsRepository::ContentFlags> &WorldContentService::GetContentFlags() const
{
return content_flags;
}
/**
* @return
*/
std::vector<std::string> WorldContentService::GetContentFlagsEnabled()
{
std::vector<std::string> enabled_flags;
for (auto &f: GetContentFlags()) {
if (f.enabled) {
enabled_flags.emplace_back(f.flag_name);
}
}
return enabled_flags;
}
/**
* @return
*/
std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
{
std::vector<std::string> disabled_flags;
for (auto &f: GetContentFlags()) {
if (!f.enabled) {
disabled_flags.emplace_back(f.flag_name);
}
}
return disabled_flags;
}
/**
* @param content_flags
*/
void WorldContentService::SetContentFlags(std::vector<std::string> content_flags)
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
{
WorldContentService::content_flags = content_flags;
}
@@ -90,10 +129,10 @@ void WorldContentService::SetContentFlags(std::vector<std::string> content_flags
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagEnabled(const std::string& content_flag)
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
{
for (auto &flag : GetContentFlags()) {
if (flag == content_flag) {
for (auto &f: GetContentFlags()) {
if (f.flag_name == content_flag && f.enabled == true) {
return true;
}
}
@@ -101,20 +140,102 @@ bool WorldContentService::IsContentFlagEnabled(const std::string& content_flag)
return false;
}
void WorldContentService::ReloadContentFlags(Database &db)
/**
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
{
std::vector<std::string> set_content_flags;
auto content_flags = ContentFlagsRepository::GetWhere(db, "enabled = 1");
set_content_flags.reserve(content_flags.size());
for (auto &flags: content_flags) {
set_content_flags.push_back(flags.flag_name);
for (auto &f: GetContentFlags()) {
if (f.flag_name == content_flag && f.enabled == false) {
return true;
}
}
LogInfo(
"Enabled content flags [{}]",
implode(", ", set_content_flags)
);
return false;
}
bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
{
// if we're not set to (-1 All) then fail when we aren't within minimum expansion
if (f.min_expansion > Expansion::EXPANSION_ALL && current_expansion < f.min_expansion) {
return false;
}
// if we're not set to (-1 All) then fail when we aren't within max expansion
if (f.max_expansion > Expansion::EXPANSION_ALL && current_expansion > f.max_expansion) {
return false;
}
// if we don't have any enabled flag in enabled flags, we fail
for (const auto& flag: SplitString(f.content_flags)) {
if (!contains(GetContentFlagsEnabled(), flag)) {
return false;
}
}
// if we don't have any disabled flag in disabled flags, we fail
for (const auto& flag: SplitString(f.content_flags_disabled)) {
if (!contains(GetContentFlagsDisabled(), flag)) {
return false;
}
}
return true;
}
void WorldContentService::ReloadContentFlags()
{
std::vector<ContentFlagsRepository::ContentFlags> set_content_flags;
auto flags = ContentFlagsRepository::All(*GetDatabase());
set_content_flags.reserve(flags.size());
for (auto &f: flags) {
set_content_flags.push_back(f);
LogInfo(
"Loaded content flag [{}] [{}]",
f.flag_name,
(f.enabled ? "Enabled" : "Disabled")
);
}
SetContentFlags(set_content_flags);
}
Database *WorldContentService::GetDatabase() const
{
return m_database;
}
WorldContentService *WorldContentService::SetDatabase(Database *database)
{
WorldContentService::m_database = database;
return this;
}
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
{
auto flags = ContentFlagsRepository::GetWhere(
*GetDatabase(),
fmt::format("flag_name = '{}'", content_flag_name)
);
auto f = ContentFlagsRepository::NewEntity();
if (!flags.empty()) {
f = flags.front();
}
f.enabled = enabled ? 1 : 0;
f.flag_name = content_flag_name;
if (!flags.empty()) {
ContentFlagsRepository::UpdateOne(*GetDatabase(), f);
}
else {
ContentFlagsRepository::InsertOne(*GetDatabase(), f);
}
ReloadContentFlags();
}
+25 -10
View File
@@ -23,6 +23,8 @@
#include <string>
#include <vector>
#include "../loottable.h"
#include "../repositories/content_flags_repository.h"
class Database;
@@ -52,7 +54,7 @@ namespace Expansion {
VeilOfAlaris,
RainOfFear,
CallOfTheForsaken,
TheDarkendSea,
TheDarkenedSea,
TheBrokenMirror,
EmpiresOfKunark,
RingOfScale,
@@ -125,7 +127,7 @@ public:
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheDarkendSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkendSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheDarkenedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkenedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
@@ -153,22 +155,35 @@ public:
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
bool IsCurrentExpansionTheDarkendSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkendSea; }
bool IsCurrentExpansionTheDarkenedSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkenedSea; }
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
bool IsCurrentExpansionTormentOfVelious() { return current_expansion == Expansion::ExpansionNumber::TormentOfVelious; }
const std::vector<ContentFlagsRepository::ContentFlags> &GetContentFlags() const;
std::vector<std::string> GetContentFlagsEnabled();
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 ReloadContentFlags();
WorldContentService * SetExpansionContext();
bool DoesPassContentFiltering(const ContentFlags& f);
WorldContentService * SetDatabase(Database *database);
Database *GetDatabase() const;
void SetContentFlag(const std::string &content_flag_name, bool enabled);
private:
int current_expansion{};
std::vector<std::string> content_flags;
public:
const std::vector<std::string> &GetContentFlags() const;
bool IsContentFlagEnabled(const std::string& content_flag);
void SetContentFlags(std::vector<std::string> content_flags);
void ReloadContentFlags(Database &db);
void SetExpansionContext();
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
// reference to database
Database *m_database;
};
extern WorldContentService content_service;
+201 -210
View File
@@ -50,6 +50,8 @@
#include "http/httplib.h"
#include "http/uri.h"
#include "repositories/zone_repository.h"
extern Client client;
Database::Database () {
@@ -92,112 +94,123 @@ Database::~Database()
*/
uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) {
if(strlen(name) >= 50 || strlen(password) >= 50)
if (strlen(name) >= 50 || strlen(password) >= 50)
return(0);
char tmpUN[100];
char tmpPW[100];
char temporary_username[100];
char temporary_password[100];
DoEscapeString(tmpUN, name, strlen(name));
DoEscapeString(tmpPW, password, strlen(password));
DoEscapeString(temporary_username, name, strlen(name));
DoEscapeString(temporary_password, password, strlen(password));
std::string query = StringFormat("SELECT id, status FROM account WHERE `name`='%s' AND ls_id='%s' AND password is not null "
"and length(password) > 0 and (password='%s' or password=MD5('%s'))",
tmpUN, EscapeString(loginserver).c_str(), tmpPW, tmpPW);
std::string query = fmt::format(
"SELECT id, status FROM account WHERE `name` = '{}' AND ls_id = '{}' AND password is NOT NULL "
"AND length(password) > 0 AND (password = '{}' OR password = MD5('{}'))",
temporary_username,
EscapeString(loginserver),
temporary_password,
temporary_password
);
auto results = QueryDatabase(query);
if (!results.Success())
{
if (!results.Success() || !results.RowCount()) {
return 0;
}
if(results.RowCount() == 0)
return 0;
auto row = results.begin();
uint32 id = atoi(row[0]);
auto id = std::stoul(row[0]);
if (oStatus)
*oStatus = atoi(row[1]);
if (oStatus) {
*oStatus = std::stoi(row[1]);
}
return id;
}
//Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table.
bool Database::CheckBannedIPs(const char* loginIP)
bool Database::CheckBannedIPs(std::string login_ip)
{
std::string query = StringFormat("SELECT ip_address FROM banned_ips WHERE ip_address='%s'", loginIP);
auto query = fmt::format(
"SELECT ip_address FROM banned_ips WHERE ip_address = '{}'",
login_ip
);
auto results = QueryDatabase(query);
if (!results.Success())
{
if (!results.Success() || results.RowCount() != 0) {
return true;
}
if (results.RowCount() != 0)
return true;
return false;
}
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
std::string query = StringFormat("INSERT into banned_ips SET ip_address='%s', notes='%s'", bannedIP, notes);
bool Database::AddBannedIP(std::string banned_ip, std::string notes) {
auto query = fmt::format(
"INSERT into banned_ips SET ip_address = '{}', notes = '{}'",
EscapeString(banned_ip),
EscapeString(notes)
);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
return true;
}
bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) {
std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id);
bool Database::CheckGMIPs(std::string login_ip, uint32 account_id) {
auto query = fmt::format(
"SELECT * FROM `gm_ips` WHERE `ip_address` = '{}' AND `account_id` = {}",
login_ip,
account_id
);
auto results = QueryDatabase(query);
if (!results.Success())
if (!results.Success()) {
return false;
}
if (results.RowCount() == 1)
if (results.RowCount() == 1) {
return true;
}
return false;
}
bool Database::AddGMIP(char* ip_address, char* name) {
std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name);
auto results = QueryDatabase(query);
return results.Success();
}
void Database::LoginIP(uint32 AccountID, const char* LoginIP) {
std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP);
void Database::LoginIP(uint32 account_id, std::string login_ip) {
auto query = fmt::format(
"INSERT INTO account_ip SET accid = {}, ip = '{}' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()",
account_id,
login_ip
);
QueryDatabase(query);
}
int16 Database::CheckStatus(uint32 account_id)
{
std::string query = StringFormat(
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = %i",
account_id);
auto query = fmt::format(
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = {}",
account_id
);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() != 1)
if (!results.Success() || results.RowCount() != 1) {
return 0;
}
auto row = results.begin();
int16 status = atoi(row[0]);
int16 status = std::stoi(row[0]);
int32 date_diff = 0;
if (row[1] != nullptr)
date_diff = atoi(row[1]);
if (row[1]) {
date_diff = std::stoi(row[1]);
}
if (date_diff > 0)
if (date_diff > 0) {
return -1;
}
return status;
}
@@ -307,9 +320,7 @@ bool Database::SetAccountStatus(const std::string& account_name, int16 status)
LogInfo("Account [{}] is attempting to be set to status [{}]", account_name, status);
std::string query = fmt::format(
SQL(
UPDATE account SET status = {} WHERE name = '{}'
),
"UPDATE account SET status = {} WHERE name = '{}'",
status,
account_name
);
@@ -716,7 +727,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
/* HoTT Ability */
if(RuleB(Character, GrantHoTTOnCreate))
{
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, rank) VALUES (%u, %i, %i)", character_id, 14, 1);
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)", character_id, 14, 1);
results = QueryDatabase(query);
}
@@ -807,36 +818,34 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
return atoi(row[0]);
}
uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver, int16* status, uint32* lsid) {
if (!isAlphaNumeric(accname))
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
if (!isAlphaNumeric(account_name.c_str())) {
return 0;
}
std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1",
EscapeString(accname).c_str(), EscapeString(loginserver).c_str());
auto query = fmt::format(
"SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '{}' AND `ls_id` = '{}' LIMIT 1",
EscapeString(account_name),
EscapeString(loginserver)
);
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success() || !results.RowCount()) {
return 0;
}
if (results.RowCount() != 1)
return 0;
auto row = results.begin();
auto account_id = std::stoul(row[0]);
uint32 id = atoi(row[0]);
if (status)
*status = atoi(row[1]);
if (lsid) {
if (row[2])
*lsid = atoi(row[2]);
else
*lsid = 0;
if (status) {
*status = static_cast<int16>(std::stoi(row[1]));
}
return id;
if (lsid) {
*lsid = row[2] ? std::stoul(row[2]) : 0;
}
return account_id;
}
void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) {
@@ -997,6 +1006,18 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
return true;
}
void Database::SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum)
{
QueryDatabase(
fmt::format(
"UPDATE `account` SET `{}` = '{}' WHERE `id` = {}",
field_name,
checksum,
account_id
)
);
}
// Get zone starting points from DB
bool Database::GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x, float* safe_y, float* safe_z, float* safe_heading, int16* min_status, uint8* min_level, char *flag_needed) {
@@ -1088,21 +1109,6 @@ bool Database::GetZoneLongName(const char* short_name, char** long_name, char* f
return true;
}
uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
std::string query = StringFormat("SELECT graveyard_id FROM zone WHERE zoneidnumber='%u' AND (version=%i OR version=0) ORDER BY version DESC", zone_id, version);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) {
std::string query = StringFormat("SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id);
@@ -1131,108 +1137,84 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
return true;
}
uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version);
uint8 Database::GetPEQZone(uint32 zone_id, uint32 version){
std::string query = fmt::format(
"SELECT peqzone FROM zone WHERE zoneidnumber = {} AND (version = {} OR version = 0) ORDER BY version DESC LIMIT 1",
zone_id,
version
);
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success() || !results.RowCount()) {
return 0;
}
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
return static_cast<uint8>(std::stoi(row[0]));
}
bool Database::CheckNameFilter(const char* name, bool surname)
bool Database::CheckNameFilter(std::string name, bool surname)
{
std::string str_name = name;
name = str_tolower(name);
// the minimum 4 is enforced by the client too
if (!name || strlen(name) < 4)
{
if (name.empty() || name.size() < 4) {
return false;
}
// Given name length is enforced by the client too
if (!surname && strlen(name) > 15)
{
if (!surname && name.size() > 15) {
return false;
}
for (size_t i = 0; i < str_name.size(); i++)
{
if(!isalpha(str_name[i]))
{
for (size_t i = 0; i < name.size(); i++) {
if (!isalpha(name[i])) {
return false;
}
}
for(size_t x = 0; x < str_name.size(); ++x)
{
str_name[x] = tolower(str_name[x]);
}
char c = '\0';
uint8 num_c = 0;
for(size_t x = 0; x < str_name.size(); ++x)
{
if(str_name[x] == c)
{
for (size_t x = 0; x < name.size(); ++x) {
if (name[x] == c) {
num_c++;
}
else
{
} else {
num_c = 1;
c = str_name[x];
c = name[x];
}
if(num_c > 2)
{
if (num_c > 2) {
return false;
}
}
std::string query("SELECT name FROM name_filter");
std::string query = "SELECT name FROM name_filter";
auto results = QueryDatabase(query);
if (!results.Success())
{
// false through to true? shouldn't it be falls through to false?
if (!results.Success()) {
return true;
}
for (auto row = results.begin();row != results.end();++row)
{
std::string current_row = row[0];
for(size_t x = 0; x < current_row.size(); ++x)
current_row[x] = tolower(current_row[x]);
if(str_name.find(current_row) != std::string::npos)
for (auto row : results) {
std::string current_row = str_tolower(row[0]);
if (name.find(current_row) != std::string::npos) {
return false;
}
}
return true;
}
bool Database::AddToNameFilter(const char* name) {
std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name);
bool Database::AddToNameFilter(std::string name) {
auto query = fmt::format(
"INSERT INTO name_filter (name) values ('{}')",
name
);
auto results = QueryDatabase(query);
if (!results.Success())
{
if (!results.Success() || !results.RowsAffected()) {
return false;
}
if (results.RowsAffected() == 0)
return false;
return true;
}
@@ -1320,16 +1302,16 @@ bool Database::UpdateName(const char* oldname, const char* newname) {
}
// If the name is used or an error occurs, it returns false, otherwise it returns true
bool Database::CheckUsedName(const char* name) {
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
bool Database::CheckUsedName(std::string name) {
auto query = fmt::format(
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
name
);
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success() || results.RowCount()) {
return false;
}
if (results.RowCount() > 0)
return false;
return true;
}
@@ -1487,41 +1469,25 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
return base_cap;
}
uint32 Database::GetCharacterInfo(
const char *iName,
uint32 *oAccID,
uint32 *oZoneID,
uint32 *oInstanceID,
float *oX,
float *oY,
float *oZ
)
uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id)
{
std::string query = StringFormat(
"SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'",
EscapeString(iName).c_str()
auto query = fmt::format(
"SELECT `id`, `account_id`, `zone_id`, `zone_instance` FROM `character_data` WHERE `name` = '{}'",
EscapeString(character_name)
);
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success() || !results.RowCount()) {
return 0;
}
if (results.RowCount() != 1) {
return 0;
}
auto row = results.begin();
auto character_id = std::stoul(row[0]);
*account_id = std::stoul(row[1]);
*zone_id = std::stoul(row[2]);
*instance_id = std::stoul(row[3]);
auto row = results.begin();
uint32 charid = atoi(row[0]);
if (oAccID) { *oAccID = atoi(row[1]); }
if (oZoneID) { *oZoneID = atoi(row[2]); }
if (oInstanceID) { *oInstanceID = atoi(row[3]); }
if (oX) { *oX = atof(row[4]); }
if (oY) { *oY = atof(row[5]); }
if (oZ) { *oZ = atof(row[6]); }
return charid;
return character_id;
}
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
@@ -1645,29 +1611,36 @@ uint32 Database::GetGroupID(const char* name){
return atoi(row[0]);
}
/* Is this really getting used properly... A half implementation ? Akkadius */
char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
strcpy(leaderbuf, "");
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
uint32 group_id = 0;
std::string query = StringFormat("SELECT `groupid` FROM `group_id` WHERE `name` = '%s'", name);
auto query = fmt::format(
"SELECT `groupid` FROM `group_id` WHERE `name` = '{}'",
character_name
);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row)
if (row[0])
group_id = atoi(row[0]);
if (results.Success() && results.RowCount()) {
auto row = results.begin();
group_id = std::stoul(row[0]);
}
if (group_id == 0)
return leaderbuf;
if (!group_id) {
return std::string();
}
query = StringFormat("SELECT `leadername` FROM `group_leaders` WHERE `gid` = '%u' LIMIT 1", group_id);
query = fmt::format(
"SELECT `leadername` FROM `group_leaders` WHERE `gid` = {} LIMIT 1",
group_id
);
results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row)
if (row[0])
strcpy(leaderbuf, row[0]);
if (results.Success() && results.RowCount()) {
auto row = results.begin();
return row[0];
}
return leaderbuf;
return std::string();
}
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
@@ -2262,43 +2235,48 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year
}
int Database::GetIPExemption(std::string account_ip) {
std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str());
auto results = QueryDatabase(query);
if (results.Success() && results.RowCount() > 0) {
auto row = results.begin();
return atoi(row[0]);
}
return RuleI(World, MaxClientsPerIP);
}
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
std::string query = fmt::format(
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
auto query = fmt::format(
"SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
account_ip
);
auto results = QueryDatabase(query);
uint32 exemption_id = 0;
if (results.Success() && results.RowCount() > 0) {
auto row = results.begin();
exemption_id = atoi(row[0]);
if (!results.Success() || !results.RowCount()) {
return RuleI(World, MaxClientsPerIP);
}
auto row = results.begin();
return std::stoi(row[0]);
}
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
auto query = fmt::format(
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
account_ip
);
uint32 exemption_id = 0;
auto results = QueryDatabase(query);
if (results.Success() && results.RowCount()) {
auto row = results.begin();
exemption_id = std::stoul(row[0]);
}
query = fmt::format(
"INSERT INTO `ip_exemptions` (`exemption_ip`, `exemption_amount`) VALUES ('{}', {})",
account_ip,
exemption_amount
);
if (exemption_id != 0) {
if (exemption_id) {
query = fmt::format(
"UPDATE `ip_exemptions` SET `exemption_amount` = {} WHERE `exemption_ip` = '{}'",
exemption_amount,
account_ip
);
}
QueryDatabase(query);
}
@@ -2516,3 +2494,16 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
}
}
uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
{
auto zones = ZoneRepository::GetWhere(
*this,
fmt::format(
"zoneidnumber = {} AND (version = {} OR version = 0) ORDER BY version DESC LIMIT 1",
zone_id,
instance_version
)
);
return !zones.empty() ? zones[0].min_status : 0;
}
+15 -15
View File
@@ -88,7 +88,6 @@ public:
/* Character Creation */
bool AddToNameFilter(const char *name);
bool CreateCharacter(
uint32 account_id,
char *name,
@@ -121,18 +120,18 @@ public:
/* General Information Queries */
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
bool AddGMIP(char* ip_address, char* name);
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
bool CheckGMIPs(const char* loginIP, uint32 account_id);
bool CheckNameFilter(const char* name, bool surname = false);
bool CheckUsedName(const char* name);
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
bool AddToNameFilter(std::string name);
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
bool CheckGMIPs(std::string login_ip, uint32 account_id);
bool CheckNameFilter(std::string name, bool surname = false);
bool CheckUsedName(std::string name);
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const char *name);
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
uint32 GetGuildIDByCharID(uint32 char_id);
uint32 GetGroupIDByCharID(uint32 char_id);
uint32 GetRaidIDByCharID(uint32 char_id);
@@ -142,7 +141,7 @@ public:
std::string GetCharNameByID(uint32 char_id);
std::string GetNPCNameByID(uint32 npc_id);
std::string GetCleanNPCNameByID(uint32 npc_id);
void LoginIP(uint32 AccountID, const char* LoginIP);
void LoginIP(uint32 account_id, std::string login_ip);
/* Instancing */
@@ -190,6 +189,8 @@ public:
int16 CheckStatus(uint32 account_id);
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
@@ -206,8 +207,8 @@ public:
/* Groups */
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
std::string GetGroupLeaderForLogin(std::string character_name);
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
uint32 GetGroupID(const char* name);
@@ -250,9 +251,8 @@ public:
bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0);
bool LoadPTimers(uint32 charid, PTimerList &into);
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
uint8 GetPEQZone(uint32 zoneID, uint32 version);
uint8 GetPEQZone(uint32 zone_id, uint32 version);
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
uint8 GetServerType();
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
+30
View File
@@ -163,6 +163,20 @@ std::string DatabaseDumpService::GetPlayerTablesList()
return trim(tables_list);
}
/**
* @return
*/
std::string DatabaseDumpService::GetBotTablesList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetBotTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return trim(tables_list);
}
/**
* @return
*/
@@ -317,6 +331,11 @@ void DatabaseDumpService::Dump()
tables_to_dump += GetPlayerTablesList() + " ";
dump_descriptor += "-player";
}
if (IsDumpBotTables()) {
tables_to_dump += GetBotTablesList() + " ";
dump_descriptor += "-bots";
}
if (IsDumpSystemTables()) {
tables_to_dump += GetSystemTablesList() + " ";
@@ -436,6 +455,7 @@ void DatabaseDumpService::Dump()
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
// LogDebug("[{}] bot", (IsDumpBotTables() ? "true" : "false"));
}
bool DatabaseDumpService::IsDumpSystemTables() const
@@ -577,3 +597,13 @@ void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
{
DatabaseDumpService::dump_state_tables = dump_state_tables;
}
bool DatabaseDumpService::IsDumpBotTables() const
{
return dump_bot_tables;
}
void DatabaseDumpService::SetDumpBotTables(bool dump_bot_tables)
{
DatabaseDumpService::dump_bot_tables = dump_bot_tables;
}
+4
View File
@@ -53,6 +53,8 @@ public:
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
bool IsDumpStateTables() const;
void SetDumpStateTables(bool dump_state_tables);
bool IsDumpBotTables() const;
void SetDumpBotTables(bool dump_bot_tables);
private:
bool dump_all_tables = false;
@@ -67,6 +69,7 @@ private:
bool dump_with_compression = false;
bool dump_output_to_console = false;
bool dump_drop_table_syntax_only = false;
bool dump_bot_tables = false;
std::string dump_path;
std::string dump_file_name;
@@ -75,6 +78,7 @@ private:
std::string GetMySQLVersion();
std::string GetBaseMySQLDumpCommand();
std::string GetPlayerTablesList();
std::string GetBotTablesList();
std::string GetSystemTablesList();
std::string GetStateTablesList();
std::string GetContentTablesList();
+2 -2
View File
@@ -476,7 +476,7 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertCorpseDeblob();
/* Run EQEmu Server script (Checks for database updates) */
if(system("perl eqemu_server.pl ran_from_world"));
system("perl eqemu_server.pl ran_from_world");
return true;
}
@@ -1452,7 +1452,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){
if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
first_entry = 1;
}
rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
+37 -2
View File
@@ -62,6 +62,7 @@ namespace DatabaseSchema {
{"character_pet_buffs", "char_id"},
{"character_pet_info", "char_id"},
{"character_pet_inventory", "char_id"},
{"character_peqzone_flags", "id"},
{"character_potionbelt", "id"},
{"character_skills", "id"},
{"character_spells", "id"},
@@ -82,7 +83,6 @@ namespace DatabaseSchema {
{"player_titlesets", "char_id"},
{"quest_globals", "charid"},
{"timers", "char_id"},
{"titles", "char_id"},
{"trader", "char_id"},
{"zone_flags", "charID"}
};
@@ -130,6 +130,7 @@ namespace DatabaseSchema {
"character_pet_buffs",
"character_pet_info",
"character_pet_inventory",
"character_peqzone_flags",
"character_potionbelt",
"character_skills",
"character_spells",
@@ -158,7 +159,6 @@ namespace DatabaseSchema {
"spell_buckets",
"spell_globals",
"timers",
"titles",
"trader",
"trader_audit",
"zone_flags"
@@ -270,6 +270,7 @@ namespace DatabaseSchema {
"perl_event_export_settings",
"profanity_list",
"rule_sets",
"titles",
"rule_values",
"variables",
};
@@ -374,6 +375,40 @@ namespace DatabaseSchema {
"inventory_versions",
};
}
/**
* @description Gets all player bot tables
* @note These tables have no content in the PEQ daily dump
*
* @return
*/
static std::vector<std::string> GetBotTables()
{
return {
"bot_buffs",
"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",
"bot_inspect_messages",
"bot_inventories",
"bot_owner_options",
"bot_pet_buffs",
"bot_pet_inventories",
"bot_pets",
"bot_spell_casting_chances",
"bot_spells_entries",
"bot_stances",
"bot_timers",
"vw_bot_character_mobs",
"vw_bot_groups"
};
}
}
+2 -2
View File
@@ -167,7 +167,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if ((strncasecmp(query, "select", 6) == 0)) {
LogMySQLQuery(
"{0} ({1} row{2} returned) ({3}s)",
"{0}; -- ({1} row{2} returned) ({3}s)",
query,
requestResult.RowCount(),
requestResult.RowCount() == 1 ? "" : "s",
@@ -176,7 +176,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
}
else {
LogMySQLQuery(
"{0} ({1} row{2} affected) ({3}s)",
"{0}; -- ({1} row{2} affected) ({3}s)",
query,
requestResult.RowsAffected(),
requestResult.RowsAffected() == 1 ? "" : "s",
+91
View File
@@ -0,0 +1,91 @@
#include "discord.h"
#include "../http/httplib.h"
#include "../json/json.h"
#include "../string_util.h"
#include "../eqemu_logsys.h"
constexpr int MAX_RETRIES = 10;
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
{
// validate
if (webhook_url.empty()) {
LogDiscord("[webhook_url] is empty");
return;
}
// validate
if (webhook_url.find("http://") == std::string::npos && webhook_url.find("https://") == std::string::npos) {
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
return;
}
// split
auto s = SplitString(webhook_url, '/');
// url
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
std::string endpoint = replace_string(webhook_url, base_url, "");
// client
httplib::Client cli(base_url.c_str());
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;
p["content"] = message;
std::stringstream payload;
payload << p;
bool retry = true;
int retries = 0;
int retry_timer = 1000;
while (retry) {
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
if (res->status != 200 && res->status != 204) {
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
}
if (res->status == 429) {
if (!res->body.empty()) {
std::stringstream ss(res->body);
Json::Value response;
try {
ss >> response;
}
catch (std::exception const &ex) {
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
}
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
}
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
}
if (res->status == 204) {
retry = false;
}
if (retries > MAX_RETRIES) {
LogDiscord("Retries exceeded for message [{}]", message);
retry = false;
}
retries++;
}
}
}
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
{
if (category_id == Logs::LogCategory::MySQLQuery) {
return fmt::format("```sql\n{}\n```", message);
}
return message + "\n";
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef EQEMU_DISCORD_H
#define EQEMU_DISCORD_H
#include <string>
#include "../types.h"
class Discord {
public:
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
};
#endif //EQEMU_DISCORD_H
+65
View File
@@ -0,0 +1,65 @@
#include "discord_manager.h"
#include "../common/discord/discord.h"
#include "../common/eqemu_logsys.h"
#include "../common/string_util.h"
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
{
webhook_queue_lock.lock();
webhook_message_queue[webhook_id].emplace_back(message);
webhook_queue_lock.unlock();
}
constexpr int MAX_MESSAGE_LENGTH = 1900;
void DiscordManager::ProcessMessageQueue()
{
if (webhook_message_queue.empty()) {
return;
}
webhook_queue_lock.lock();
for (auto &q: webhook_message_queue) {
LogDiscord("Processing [{}] messages in queue for webhook ID [{}]...", q.second.size(), q.first);
auto webhook = LogSys.discord_webhooks[q.first];
std::string message;
for (auto &m: q.second) {
// next message would become too large
bool next_message_too_large = ((int) m.length() + (int) message.length()) > MAX_MESSAGE_LENGTH;
if (next_message_too_large) {
Discord::SendWebhookMessage(
message,
webhook.webhook_url
);
message = "";
}
message += m;
// one single message was too large
// this should rarely happen but the message will need to be split
if ((int) message.length() > MAX_MESSAGE_LENGTH) {
for (unsigned mi = 0; mi < message.length(); mi += MAX_MESSAGE_LENGTH) {
Discord::SendWebhookMessage(
message.substr(mi, MAX_MESSAGE_LENGTH),
webhook.webhook_url
);
}
message = "";
}
}
// final flush
if (!message.empty()) {
Discord::SendWebhookMessage(
message,
webhook.webhook_url
);
}
webhook_message_queue.erase(q.first);
}
webhook_queue_lock.unlock();
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef EQEMU_DISCORD_MANAGER_H
#define EQEMU_DISCORD_MANAGER_H
#include <mutex>
#include <map>
#include <vector>
#include "../common/types.h"
class DiscordManager {
public:
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
void ProcessMessageQueue();
private:
std::mutex webhook_queue_lock{};
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
};
#endif
+2 -1
View File
@@ -561,8 +561,9 @@ std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
return "Mission";
case DynamicZoneType::Quest:
return "Quest";
default:
return "Unknown";
}
return "Unknown";
}
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
+240 -5
View File
@@ -19,7 +19,8 @@
#include "emu_constants.h"
#include "languages.h"
#include "data_verification.h"
#include "bodytypes.h"
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
static const int16 local_array[] = {
@@ -148,8 +149,9 @@ const char *EQ::constants::GetStanceName(StanceType stance_type) {
}
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
if (stance_type >= EQ::constants::stancePassive && stance_type <= EQ::constants::stanceBurnAE)
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
return (stance_type - EQ::constants::stancePassive);
}
return 0;
}
@@ -186,14 +188,247 @@ const std::map<int, std::string>& EQ::constants::GetLanguageMap()
{ LANG_HADAL, "Hadal" },
{ LANG_UNKNOWN, "Unknown" }
};
return language_map;
}
std::string EQ::constants::GetLanguageName(int language_id)
{
if (language_id >= LANG_COMMON_TONGUE && language_id <= LANG_UNKNOWN) {
auto languages = EQ::constants::GetLanguageMap();
return languages[language_id];
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
return EQ::constants::GetLanguageMap().find(language_id)->second;
}
return std::string();
}
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
{
static const std::map<uint32, std::string> ldon_theme_map = {
{ LDoNThemes::Unused, "Unused" },
{ LDoNThemes::GUK, "Deepest Guk" },
{ LDoNThemes::MIR, "Miragul's Menagerie" },
{ LDoNThemes::MMC, "Mistmoore Catacombs" },
{ LDoNThemes::RUJ, "Rujarkian Hills" },
{ LDoNThemes::TAK, "Takish-Hiz" },
};
return ldon_theme_map;
}
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;
}
return std::string();
}
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
{
static const std::map<int8, std::string> flymode_map = {
{ GravityBehavior::Ground, "Ground" },
{ GravityBehavior::Flying, "Flying" },
{ GravityBehavior::Levitating, "Levitating" },
{ GravityBehavior::Water, "Water" },
{ GravityBehavior::Floating, "Floating" },
{ GravityBehavior::LevitateWhileRunning, "Levitating While Running" },
};
return flymode_map;
}
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;
}
return std::string();
}
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
{
static const std::map<bodyType, std::string> bodytype_map = {
{ BT_Humanoid, "Humanoid" },
{ BT_Lycanthrope, "Lycanthrope" },
{ BT_Undead, "Undead" },
{ BT_Giant, "Giant" },
{ BT_Construct, "Construct" },
{ BT_Extraplanar, "Extraplanar" },
{ BT_Magical, "Magical" },
{ BT_SummonedUndead, "Summoned Undead" },
{ BT_RaidGiant, "Raid Giant" },
{ BT_RaidColdain, "Raid Coldain" },
{ BT_NoTarget, "Untargetable" },
{ BT_Vampire, "Vampire" },
{ BT_Atenha_Ra, "Aten Ha Ra" },
{ BT_Greater_Akheva, "Greater Akheva" },
{ BT_Khati_Sha, "Khati Sha" },
{ BT_Seru, "Seru" },
{ BT_Grieg_Veneficus, "Grieg Veneficus" },
{ BT_Draz_Nurakk, "Draz Nurakk" },
{ BT_Zek, "Zek" },
{ BT_Luggald, "Luggald" },
{ BT_Animal, "Animal" },
{ BT_Insect, "Insect" },
{ BT_Monster, "Monster" },
{ BT_Summoned, "Summoned" },
{ BT_Plant, "Plant" },
{ BT_Dragon, "Dragon" },
{ BT_Summoned2, "Summoned 2" },
{ BT_Summoned3, "Summoned 3" },
{ BT_Dragon2, "Dragon 2" },
{ BT_VeliousDragon, "Velious Dragon" },
{ BT_Familiar, "Familiar" },
{ BT_Dragon3, "Dragon 3" },
{ BT_Boxes, "Boxes" },
{ BT_Muramite, "Muramite" },
{ BT_NoTarget2, "Untargetable 2" },
{ BT_SwarmPet, "Swarm Pet" },
{ BT_MonsterSummon, "Monster Summon" },
{ BT_InvisMan, "Invisible Man" },
{ BT_Special, "Special" },
};
return bodytype_map;
}
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
{
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
{
static const std::map<uint8, std::string> account_status_map = {
{ AccountStatus::Player, "Player" },
{ AccountStatus::Steward, "Steward" },
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
{ AccountStatus::Guide, "Guide" },
{ AccountStatus::QuestTroupe, "Quest Troupe" },
{ AccountStatus::SeniorGuide, "Senior Guide" },
{ AccountStatus::GMTester, "GM Tester" },
{ AccountStatus::EQSupport, "EQ Support" },
{ AccountStatus::GMStaff, "GM Staff" },
{ AccountStatus::GMAdmin, "GM Admin" },
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
{ AccountStatus::QuestMaster, "Quest Master" },
{ AccountStatus::GMAreas, "GM Areas" },
{ AccountStatus::GMCoder, "GM Coder" },
{ AccountStatus::GMMgmt, "GM Mgmt" },
{ AccountStatus::GMImpossible, "GM Impossible" },
{ AccountStatus::Max, "GM Max" }
};
return account_status_map;
}
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
{
for (
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
status_level != EQ::constants::GetAccountStatusMap().rend();
++status_level
) {
if (account_status >= status_level->first) {
return status_level->second;
}
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
{
static const std::map<uint8, std::string> consider_level_map = {
{ ConsiderLevel::Ally, "Ally" },
{ ConsiderLevel::Warmly, "Warmly" },
{ ConsiderLevel::Kindly, "Kindly" },
{ ConsiderLevel::Amiably, "Amiably" },
{ ConsiderLevel::Indifferently, "Indifferently" },
{ ConsiderLevel::Apprehensively, "Apprehensively" },
{ ConsiderLevel::Dubiously, "Dubiously" },
{ ConsiderLevel::Threateningly, "Threateningly" },
{ ConsiderLevel::Scowls, "Scowls" }
};
return consider_level_map;
}
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;
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
{
static const std::map<uint8, std::string> damage_type_map = {
{ EnvironmentalDamage::Lava, "Lava" },
{ EnvironmentalDamage::Drowning, "Drowning" },
{ EnvironmentalDamage::Falling, "Falling" },
{ EnvironmentalDamage::Trap, "Trap" }
};
return damage_type_map;
}
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;
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
{
static const std::map<uint8, std::string> stuck_behavior_map = {
{ StuckBehavior::RunToTarget, "Run To Target" },
{ StuckBehavior::WarpToTarget, "Warp To Target" },
{ StuckBehavior::TakeNoAction, "Take No Action" },
{ StuckBehavior::EvadeCombat, "Evade Combat" }
};
return stuck_behavior_map;
}
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;
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
{
static const std::map<uint8, std::string> spawn_animation_map = {
{ SpawnAnimations::Standing, "Standing" },
{ SpawnAnimations::Sitting, "Sitting" },
{ SpawnAnimations::Crouching, "Crouching" },
{ SpawnAnimations::Laying, "Laying" },
{ SpawnAnimations::Looting, "Looting" }
};
return spawn_animation_map;
}
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;
}
return std::string();
}
+135 -7
View File
@@ -22,6 +22,7 @@
#include "eq_limits.h"
#include "emu_versions.h"
#include "bodytypes.h"
#include <string.h>
@@ -220,12 +221,67 @@ namespace EQ
stanceBurnAE
};
enum GravityBehavior : int8 {
Ground,
Flying,
Levitating,
Water,
Floating,
LevitateWhileRunning
};
enum EnvironmentalDamage : uint8 {
Lava = 250,
Drowning,
Falling,
Trap
};
enum StuckBehavior : uint8 {
RunToTarget,
WarpToTarget,
TakeNoAction,
EvadeCombat
};
enum SpawnAnimations : uint8 {
Standing,
Sitting,
Crouching,
Laying,
Looting
};
const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type);
extern const std::map<int, std::string>& GetLanguageMap();
std::string GetLanguageName(int language_id);
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
std::string GetLDoNThemeName(uint32 theme_id);
extern const std::map<int8, std::string>& GetFlyModeMap();
std::string GetFlyModeName(int8 flymode_id);
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
std::string GetBodyTypeName(bodyType bodytype_id);
extern const std::map<uint8, std::string>& GetAccountStatusMap();
std::string GetAccountStatusName(uint8 account_status);
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
std::string GetConsiderLevelName(uint8 consider_level);
extern const std::map<uint8, std::string>& GetEnvironmentalDamageMap();
std::string GetEnvironmentalDamageName(uint8 damage_type);
extern const std::map<uint8, std::string>& GetStuckBehaviorMap();
std::string GetStuckBehaviorName(uint8 behavior_id);
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
std::string GetSpawnAnimationName(uint8 animation_id);
const int STANCE_TYPE_FIRST = stancePassive;
const int STANCE_TYPE_LAST = stanceBurnAE;
const int STANCE_TYPE_COUNT = stanceBurnAE;
@@ -328,13 +384,85 @@ namespace EQ
Guild
};
}; // namespace consent
} /*EQEmu*/
enum ServerLockType : int {
List,
Lock,
Unlock
};
enum AccountStatus : uint8 {
Player = 0,
Steward = 10,
ApprenticeGuide = 20,
Guide = 50,
QuestTroupe = 80,
SeniorGuide = 81,
GMTester = 85,
EQSupport = 90,
GMStaff = 95,
GMAdmin = 100,
GMLeadAdmin = 150,
QuestMaster = 160,
GMAreas = 170,
GMCoder = 180,
GMMgmt = 200,
GMImpossible = 250,
Max = 255
};
enum Invisibility : uint8 {
Visible,
Invisible,
Special = 255
};
enum AugmentActions : int {
Insert,
Remove,
Swap,
Destroy
};
enum ConsiderLevel : uint8 {
Ally = 1,
Warmly,
Kindly,
Amiably,
Indifferently,
Apprehensively,
Dubiously,
Threateningly,
Scowls
};
enum TargetDescriptionType : uint8 {
LCSelf,
UCSelf,
LCYou,
UCYou,
LCYour,
UCYour
};
enum ReloadWorld : uint8 {
NoRepop = 0,
Repop,
ForceRepop
};
enum MerchantBucketComparison : uint8 {
BucketEqualTo = 0,
BucketNotEqualTo,
BucketGreaterThanOrEqualTo,
BucketLesserThanOrEqualTo,
BucketGreaterThan,
BucketLesserThan,
BucketIsAny,
BucketIsNotAny,
BucketIsBetween,
BucketIsNotBetween
};
#endif /*COMMON_EMU_CONSTANTS_H*/
/* hack list to prevent circular references
eq_limits.h:EQ::inventory::LookupEntry::InventoryTypeSize[n];
*/
+4 -2
View File
@@ -129,8 +129,8 @@ N(OP_DisciplineTimer),
N(OP_DisciplineUpdate),
N(OP_DiscordMerchantInventory),
N(OP_DoGroupLeadershipAbility),
N(OP_DuelResponse),
N(OP_DuelResponse2),
N(OP_DuelDecline),
N(OP_DuelAccept),
N(OP_DumpName),
N(OP_Dye),
N(OP_DynamicWall),
@@ -455,6 +455,7 @@ N(OP_ServerListResponse),
N(OP_SessionReady),
N(OP_SetChatServer),
N(OP_SetChatServer2),
N(OP_SetFace),
N(OP_SetGroupTarget),
N(OP_SetGuildMOTD),
N(OP_SetGuildRank),
@@ -558,6 +559,7 @@ N(OP_WhoAllRequest),
N(OP_WhoAllResponse),
N(OP_World_Client_CRC1),
N(OP_World_Client_CRC2),
N(OP_World_Client_CRC3),
N(OP_WorldClientReady),
N(OP_WorldComplete),
N(OP_WorldLogout),
+24 -12
View File
@@ -448,6 +448,7 @@ struct ManaChange_Struct
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 normal, otherwise clear ETA and GCD
};
struct SwapSpell_Struct
@@ -2315,9 +2316,12 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint32 drakkin_heritage;
/*011*/ uint32 drakkin_tattoo;
/*015*/ uint32 drakkin_details;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*024*/
//there are only 10 faces for barbs changing woad just
//increase the face value by ten so if there were 8 woad
//designs then there would be 80 barb faces
@@ -2761,7 +2765,7 @@ struct EnvDamage2_Struct {
/*0004*/ uint16 unknown4;
/*0006*/ uint32 damage;
/*0010*/ uint8 unknown10[12];
/*0022*/ uint8 dmgtype; //FA = Lava; FC = Falling
/*0022*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
/*0023*/ uint8 unknown2[4];
/*0027*/ uint16 constant; //Always FFFF
/*0029*/ uint16 unknown29;
@@ -3620,14 +3624,17 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
};
struct MerchantList {
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
std::string bucket_name;
std::string bucket_value;
uint8 bucket_comparison;
};
struct TempMerchantList {
@@ -5581,6 +5588,11 @@ struct SayLinkBodyFrame_Struct {
/*056*/
};
struct Checksum_Struct {
uint64 checksum;
uint8 data[2048];
};
struct UpdateMovementEntry {
/* 00 */ float Y;
/* 04 */ float X;
+71 -75
View File
@@ -23,6 +23,8 @@
#include "platform.h"
#include "string_util.h"
#include "misc.h"
#include "discord/discord.h"
#include "repositories/discord_webhooks_repository.h"
#include "repositories/logsys_categories_repository.h"
#include <iostream>
@@ -46,6 +48,7 @@ std::ofstream process_log;
#include <unistd.h>
#include <sys/stat.h>
#include <thread>
#endif
@@ -89,7 +92,7 @@ namespace Console {
EQEmuLogSys::EQEmuLogSys()
{
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
on_log_console_hook = [](uint16 log_type, const std::string &) {};
}
/**
@@ -108,6 +111,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
log_settings[log_category_id].log_to_console = 0;
log_settings[log_category_id].log_to_file = 0;
log_settings[log_category_id].log_to_gmsay = 0;
log_settings[log_category_id].log_to_discord = 0;
log_settings[log_category_id].is_category_enabled = 0;
}
@@ -116,22 +120,26 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* Set Defaults
*/
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::CombatRecord].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
/**
* RFC 5424
@@ -151,7 +159,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
const bool log_to_console = log_settings[log_category_id].log_to_console > 0;
const bool log_to_file = log_settings[log_category_id].log_to_file > 0;
const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
const bool log_to_discord = log_settings[log_category_id].log_to_discord > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
if (is_category_enabled) {
log_settings[log_category_id].is_category_enabled = 1;
}
@@ -218,41 +227,12 @@ std::string EQEmuLogSys::FormatOutMessageString(
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessGMSay(
uint16 debug_level,
uint16 log_category,
const std::string &message
)
{
/**
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
*/
if (log_category == Logs::LogCategory::Netcode) {
return;
}
/**
* Processes that actually support hooks
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone ||
EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld
) {
on_log_gmsay_hook(log_category, message);
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessLogWrite(
uint16 debug_level,
uint16 log_category,
const std::string &message
)
@@ -270,10 +250,9 @@ void EQEmuLogSys::ProcessLogWrite(
crash_log.close();
}
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
if (process_log) {
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
process_log << time_stamp << " " << message << std::endl;
}
}
@@ -369,7 +348,7 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
void EQEmuLogSys::ProcessConsoleMessage(uint16 log_category, const std::string &message)
{
#ifdef _WINDOWS
HANDLE console_handle;
@@ -387,7 +366,7 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
on_log_console_hook(debug_level, log_category, message);
on_log_console_hook(log_category, message);
}
/**
@@ -444,28 +423,28 @@ void EQEmuLogSys::Out(
...
)
{
bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) {
log_to_console = false;
}
bool log_to_console = log_settings[log_category].log_to_console > 0 &&
log_settings[log_category].log_to_console >= debug_level;
bool log_to_file = log_settings[log_category].log_to_file > 0 &&
log_settings[log_category].log_to_file >= debug_level;
bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0 &&
log_settings[log_category].log_to_gmsay >= debug_level &&
log_category != Logs::LogCategory::Netcode &&
(EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone ||
EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld);
bool log_to_discord = EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone &&
log_settings[log_category].log_to_discord > 0 &&
log_settings[log_category].log_to_discord >= debug_level &&
log_settings[log_category].discord_webhook_id > 0 &&
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
bool log_to_file = true;
if (log_settings[log_category].log_to_file < debug_level) {
log_to_file = false;
}
bool log_to_gmsay = true;
if (log_settings[log_category].log_to_gmsay < debug_level) {
log_to_gmsay = false;
}
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
// bail out if nothing to log
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay && !log_to_discord;
if (nothing_to_log) {
return;
}
std::string prefix;
if (RuleB(Logging, PrintFileFunctionAndLine)) {
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
}
@@ -478,13 +457,16 @@ void EQEmuLogSys::Out(
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
if (log_to_console) {
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
EQEmuLogSys::ProcessConsoleMessage(log_category, output_debug_message);
}
if (log_to_gmsay) {
EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
on_log_gmsay_hook(log_category, message);
}
if (log_to_file) {
EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
EQEmuLogSys::ProcessLogWrite(log_category, output_debug_message);
}
if (log_to_discord && on_log_discord_hook) {
on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message);
}
}
@@ -627,16 +609,20 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
continue;
}
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
log_settings[c.log_category_id].log_to_discord = static_cast<uint8>(c.log_to_discord);
log_settings[c.log_category_id].discord_webhook_id = c.discord_webhook_id;
// Determine if any output method is enabled for the category
// and set it to 1 so it can used to check if category is enabled
const bool log_to_console = log_settings[c.log_category_id].log_to_console > 0;
const bool log_to_file = log_settings[c.log_category_id].log_to_file > 0;
const bool log_to_gmsay = log_settings[c.log_category_id].log_to_gmsay > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
const bool log_to_discord = log_settings[c.log_category_id].log_to_discord > 0 &&
log_settings[c.log_category_id].discord_webhook_id > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
if (is_category_enabled) {
log_settings[c.log_category_id].is_category_enabled = 1;
@@ -666,6 +652,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
new_category.log_to_console = log_settings[i].log_to_console;
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
new_category.log_to_file = log_settings[i].log_to_file;
new_category.log_to_discord = log_settings[i].log_to_discord;
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
}
@@ -673,6 +660,14 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
LogInfo("Loaded [{}] log categories", categories.size());
auto webhooks = DiscordWebhooksRepository::All(*m_database);
if (!webhooks.empty()) {
for (auto &w: webhooks) {
discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url};
}
LogInfo("Loaded [{}] Discord webhooks", webhooks.size());
}
return this;
}
@@ -682,3 +677,4 @@ EQEmuLogSys *EQEmuLogSys::SetDatabase(Database *db)
return this;
}
+44 -11
View File
@@ -127,6 +127,10 @@ namespace Logs {
DiaWind,
HTTP,
Saylink,
ChecksumVerification,
CombatRecord,
Hate,
Discord,
MaxCategoryID /* Don't Remove this */
};
@@ -212,6 +216,10 @@ namespace Logs {
"DialogueWindow",
"HTTP",
"Saylink",
"ChecksumVerification",
"CombatRecord",
"Hate",
"Discord",
};
}
@@ -219,6 +227,8 @@ namespace Logs {
class Database;
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
class EQEmuLogSys {
public:
EQEmuLogSys();
@@ -281,9 +291,19 @@ public:
uint8 log_to_file;
uint8 log_to_console;
uint8 log_to_gmsay;
uint8 log_to_discord;
int discord_webhook_id;
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
};
struct OriginationInfo {
std::string zone_short_name;
std::string zone_long_name;
int instance_id;
};
OriginationInfo origination_info{};
/**
* Internally used memory reference for all log settings per category
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
@@ -291,24 +311,38 @@ public:
*/
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
struct DiscordWebhooks {
int id;
std::string webhook_name;
std::string webhook_url;
};
DiscordWebhooks discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
bool file_logs_enabled = false;
int log_platform = 0;
std::string platform_file_name;
int log_platform = 0;
std::string platform_file_name;
// gmsay
uint16 GetGMSayColorFromCategory(uint16 log_category);
EQEmuLogSys * SetGMSayHandler(std::function<void(uint16 log_type, const std::string &)> f) {
EQEmuLogSys *SetGMSayHandler(std::function<void(uint16 log_type, const std::string &)> f)
{
on_log_gmsay_hook = f;
return this;
}
EQEmuLogSys *SetDiscordHandler(std::function<void(uint16 log_category, int webhook_id, const std::string &)> f)
{
on_log_discord_hook = f;
return this;
}
// console
void SetConsoleHandler(
std::function<void(
uint16 debug_level,
uint16 log_type,
const std::string &
)> f
@@ -322,18 +356,17 @@ public:
private:
// reference to database
Database *m_database;
std::function<void(uint16 log_category, const std::string &)> on_log_gmsay_hook;
std::function<void(uint16 debug_level, uint16 log_category, const std::string &)> on_log_console_hook;
Database *m_database;
std::function<void(uint16 log_category, const std::string &)> on_log_gmsay_hook;
std::function<void(uint16 log_category, int webhook_id, const std::string &)> on_log_discord_hook;
std::function<void(uint16 log_category, const std::string &)> on_log_console_hook;
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
void ProcessConsoleMessage(uint16 log_category, const std::string &message);
void ProcessLogWrite(uint16 log_category, const std::string &message);
bool IsRfc5424LogCategory(uint16 log_category);
};
+88
View File
@@ -696,6 +696,46 @@
OutF(LogSys, Logs::Detail, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogChecksumVerification(message, ...) do {\
if (LogSys.log_settings[Logs::ChecksumVerification].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogChecksumVerificationDetail(message, ...) do {\
if (LogSys.log_settings[Logs::ChecksumVerification].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCombatRecord(message, ...) do {\
if (LogSys.log_settings[Logs::CombatRecord].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::CombatRecord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCombatRecordDetail(message, ...) do {\
if (LogSys.log_settings[Logs::CombatRecord].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::CombatRecord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHate(message, ...) do {\
if (LogSys.log_settings[Logs::Hate].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Hate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHateDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Hate].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Hate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDiscord(message, ...) do {\
if (LogSys.log_settings[Logs::Discord].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Discord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDiscordDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Discord].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Discord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -1092,6 +1132,54 @@
#define LogHTTPDetail(message, ...) do {\
} while (0)
#define LogSaylink(message, ...) do {\
} while (0)
#define LogSaylinkDetail(message, ...) do {\
} while (0)
#define LogScheduler(message, ...) do {\
} while (0)
#define LogSchedulerDetail(message, ...) do {\
} while (0)
#define LogCheat(message, ...) do {\
} while (0)
#define LogCheatDetail(message, ...) do {\
} while (0)
#define LogLoot(message, ...) do {\
} while (0)
#define LogLootDetail(message, ...) do {\
} while (0)
#define LogFood(message, ...) do {\
} while (0)
#define LogFoodDetail(message, ...) do {\
} while (0)
#define LogChecksumVerification(message, ...) do {\
} while (0)
#define LogChecksumVerificationDetail(message, ...) do {\
} while (0)
#define LogCombatRecord(message, ...) do {\
} while (0)
#define LogCombatRecordDetail(message, ...) do {\
} while (0)
#define LogHate(message, ...) do {\
} while (0)
#define LogHateDetail(message, ...) do {\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
} while (0)
+22 -22
View File
@@ -20,31 +20,31 @@
#include "races.h"
#include "rulesys.h"
const char *FactionValueToString(FACTION_VALUE fv)
const char *FactionValueToString(FACTION_VALUE faction_value)
{
switch (fv) {
switch (faction_value) {
case FACTION_ALLY:
return ("Ally");
return "Ally";
case FACTION_WARMLY:
return ("Warmly");
return "Warmly";
case FACTION_KINDLY:
return ("Kindly");
case FACTION_AMIABLE:
return ("Amiable");
case FACTION_INDIFFERENT:
return ("Indifferent");
case FACTION_APPREHENSIVE:
return ("Apprehensive");
case FACTION_DUBIOUS:
return ("Dubious");
case FACTION_THREATENLY:
return ("Threatenly");
return "Kindly";
case FACTION_AMIABLY:
return "Amiably";
case FACTION_INDIFFERENTLY:
return "Indifferently";
case FACTION_APPREHENSIVELY:
return "Apprehensively";
case FACTION_DUBIOUSLY:
return "Dubiously";
case FACTION_THREATENINGLY:
return "Threateningly";
case FACTION_SCOWLS:
return ("Scowls, ready to attack.");
return "Scowls";
default:
break;
}
return ("Unknown Faction Con");
return "Unknown";
}
@@ -70,19 +70,19 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
return FACTION_KINDLY;
}
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
return FACTION_AMIABLE;
return FACTION_AMIABLY;
}
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
return FACTION_INDIFFERENT;
return FACTION_INDIFFERENTLY;
}
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
return FACTION_APPREHENSIVE;
return FACTION_APPREHENSIVELY;
}
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
return FACTION_DUBIOUS;
return FACTION_DUBIOUSLY;
}
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
return FACTION_THREATENLY;
return FACTION_THREATENINGLY;
}
return FACTION_SCOWLS;
}
+6 -6
View File
@@ -27,13 +27,13 @@ enum FACTION_VALUE {
FACTION_ALLY = 1,
FACTION_WARMLY = 2,
FACTION_KINDLY = 3,
FACTION_AMIABLE = 4,
FACTION_AMIABLY = 4,
FACTION_INDIFFERENT = 5,
FACTION_INDIFFERENTLY = 5,
FACTION_APPREHENSIVE = 6,
FACTION_DUBIOUS = 7,
FACTION_THREATENLY = 8,
FACTION_APPREHENSIVELY = 6,
FACTION_DUBIOUSLY = 7,
FACTION_THREATENINGLY = 8,
FACTION_SCOWLS = 9
};
@@ -75,6 +75,6 @@ struct NPCFaction
uint8 temp;
};
const char *FactionValueToString(FACTION_VALUE fv);
const char *FactionValueToString(FACTION_VALUE faction_value);
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
#endif
+1 -1
View File
@@ -204,7 +204,7 @@ enum { //some random constants
#define MIN_LEVEL_ALCHEMY 25
//chance ratio that a
#define THREATENLY_ARRGO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
#define THREATENINGLY_AGGRO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
//max factions per npc faction list
#define MAX_NPC_FACTIONS 20
+6 -1
View File
@@ -64,4 +64,9 @@ void FileUtil::mkdir(const std::string& directory_name)
}
::mkdir(directory_name.c_str(), 0755);
#endif
}
}
bool file_exists(const std::string& name) {
std::ifstream f(name.c_str());
return f.good();
}
+1
View File
@@ -28,5 +28,6 @@ public:
static void mkdir(const std::string& directory_name);
};
bool file_exists(const std::string& name);
#endif //EQEMU_FILE_UTIL_H
+66 -6
View File
@@ -63,7 +63,7 @@ bool BaseGuildManager::LoadGuilds() {
for (auto row=results.begin();row!=results.end();++row)
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
query = "SELECT guild_id,rank,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
query = "SELECT guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
results = m_db->QueryDatabase(query);
if (!results.Success())
@@ -131,7 +131,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(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 "
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);
results = m_db->QueryDatabase(query);
@@ -268,7 +268,7 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
m_db->DoEscapeString(title_esc, rankInfo.name.c_str(), rankInfo.name.length());
query = StringFormat("INSERT INTO guild_ranks "
"(guild_id,rank,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace)"
"(guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace)"
" VALUES(%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%d)",
guild_id, rank, title_esc,
rankInfo.permissions[GUILD_HEAR],
@@ -738,7 +738,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
std::string query;
if(guild_id != GUILD_NONE) {
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,`rank`,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
auto results = m_db->QueryDatabase(query);
if (!results.Success()) {
@@ -758,7 +758,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
}
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
std::string query = StringFormat("UPDATE guild_members SET rank=%d WHERE char_id=%d", rank, charid);
std::string query = StringFormat("UPDATE guild_members SET `rank`=%d WHERE char_id=%d", rank, charid);
return(QueryWithLogging(query, "setting a guild member's rank"));
}
@@ -1208,7 +1208,7 @@ BaseGuildManager::RankInfo::RankInfo() {
BaseGuildManager::GuildInfo::GuildInfo() {
leader_char_id = 0;
minstatus = 0;
minstatus = AccountStatus::Player;
}
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
@@ -1225,6 +1225,66 @@ uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
return results.RowCount();
}
std::string BaseGuildManager::GetGuildNameByID(uint32 guild_id) const {
if(guild_id == GUILD_NONE) {
return std::string();
}
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end()) {
return "Invalid Guild";
}
return res->second->name;
}
std::string BaseGuildManager::GetGuildRankName(uint32 guild_id, uint8 rank) const
{
if(rank > GUILD_MAX_RANK) {
return "Invalid Rank";
}
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end()) {
return "Invalid Guild Rank";
}
return res->second->ranks[rank].name;
}
uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id)
{
if(!m_db) {
return GUILD_NONE;
}
std::string query = fmt::format(
"SELECT `guild_id` FROM `guild_members` WHERE char_id = {} LIMIT 1",
character_id
);
auto results = m_db->QueryDatabase(query);
if(!results.Success() || !results.RowCount()) {
return GUILD_NONE;
}
auto row = results.begin();
auto guild_id = std::stoul(row[0]);
return guild_id;
}
bool BaseGuildManager::IsCharacterInGuild(uint32 character_id, uint32 guild_id)
{
auto current_guild_id = GetGuildIDByCharacterID(character_id);
if (current_guild_id == GUILD_NONE) {
return false;
}
if (guild_id && current_guild_id != guild_id) {
return false;
}
return true;
}
+4
View File
@@ -76,8 +76,12 @@ class BaseGuildManager
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
const char *GetRankName(uint32 guild_id, uint8 rank) const;
const char *GetGuildName(uint32 guild_id) const;
std::string GetGuildNameByID(uint32 guild_id) const;
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
uint32 GetGuildIDByName(const char *GuildName);
uint32 GetGuildIDByCharacterID(uint32 character_id);
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
+63 -1
View File
@@ -399,7 +399,7 @@ bool EQ::InventoryProfile::SwapItem(
}
// Remove item from inventory (with memory delete)
bool EQ::InventoryProfile::DeleteItem(int16 slot_id, uint8 quantity) {
bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
// Pop item out of inventory map (or queue)
ItemInstance *item_to_delete = PopItem(slot_id);
@@ -590,6 +590,68 @@ bool EQ::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Quan
// Checks that user has at least 'quantity' number of items in a given inventory slot
// Returns first slot it was found in, or SLOT_INVALID if not found
bool EQ::InventoryProfile::HasAugmentEquippedByID(uint32 item_id)
{
bool has_equipped = false;
ItemInstance* item = nullptr;
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
item = GetItem(slot_id);
if (item && item->ContainsAugmentByID(item_id)) {
has_equipped = true;
break;
}
}
return has_equipped;
}
int EQ::InventoryProfile::CountAugmentEquippedByID(uint32 item_id)
{
int quantity = 0;
ItemInstance* item = nullptr;
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
item = GetItem(slot_id);
if (item && item->ContainsAugmentByID(item_id)) {
quantity += item->CountAugmentByID(item_id);
}
}
return quantity;
}
bool EQ::InventoryProfile::HasItemEquippedByID(uint32 item_id)
{
bool has_equipped = false;
ItemInstance* item = nullptr;
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
item = GetItem(slot_id);
if (item && item->GetID() == item_id) {
has_equipped = true;
break;
}
}
return has_equipped;
}
int EQ::InventoryProfile::CountItemEquippedByID(uint32 item_id)
{
int quantity = 0;
ItemInstance* item = nullptr;
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
item = GetItem(slot_id);
if (item && item->GetID() == item_id) {
quantity += item->IsStackable() ? item->GetCharges() : 1;
}
}
return quantity;
}
//This function has a flaw in that it only returns the last stack that it looked at
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
int16 EQ::InventoryProfile::HasItem(uint32 item_id, uint8 quantity, uint8 where)
+13 -1
View File
@@ -132,7 +132,7 @@ namespace EQ
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = 0, uint8 class_id = 0, uint16 deity_id = 0, uint8 level = 0);
// Remove item from inventory
bool DeleteItem(int16 slot_id, uint8 quantity = 0);
bool DeleteItem(int16 slot_id, int16 quantity = 0);
// Checks All items in a bag for No Drop
bool CheckNoDrop(int16 slot_id, bool recurse = true);
@@ -140,6 +140,18 @@ namespace EQ
// Remove item from inventory (and take control of memory)
ItemInstance* PopItem(int16 slot_id);
// Check if player has a specific item equipped by Item ID
bool HasItemEquippedByID(uint32 item_id);
// Check how many of a specific item the player has equipped by Item ID
int CountItemEquippedByID(uint32 item_id);
// Check if player has a specific augment equipped by Item ID
bool HasAugmentEquippedByID(uint32 item_id);
// Check how many of a specific augment the player has equipped by Item ID
int CountAugmentEquippedByID(uint32 item_id);
// Check whether there is space for the specified number of the specified item.
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
+9 -9
View File
@@ -370,7 +370,7 @@ namespace EQ
uint32 Slots; // Bitfield for which slots this item can be used in
uint32 Price; // Item cost (?)
uint32 Icon; // Icon Number
uint32 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)
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;
@@ -473,14 +473,14 @@ namespace EQ
uint32 LDoNSold;
uint32 BaneDmgRaceAmt;
uint32 AugRestrict;
uint32 Endur;
uint32 DotShielding;
uint32 Attack;
uint32 Regen;
uint32 ManaRegen;
uint32 EnduranceRegen;
uint32 Haste;
uint32 DamageShield;
int32 Endur;
int32 DotShielding;
int32 Attack;
int32 Regen;
int32 ManaRegen;
int32 EnduranceRegen;
int32 Haste;
int32 DamageShield;
uint32 RecastDelay;
int RecastType;
uint32 AugDistiller;
+57 -18
View File
@@ -214,7 +214,7 @@ EQ::ItemInstance::~ItemInstance()
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))
return true;
@@ -245,7 +245,7 @@ bool EQ::ItemInstance::IsStackable() const
{
if (!m_item)
return false;
return m_item->Stackable;
}
@@ -253,7 +253,7 @@ bool EQ::ItemInstance::IsCharged() const
{
if (!m_item)
return false;
if (m_item->MaxCharges > 1)
return true;
else
@@ -381,7 +381,7 @@ EQ::ItemInstance* EQ::ItemInstance::PopItem(uint8 index)
m_contents.erase(index);
return inst; // Return pointer that needs to be deleted (or otherwise managed)
}
return nullptr;
}
@@ -476,7 +476,7 @@ uint8 EQ::ItemInstance::GetTotalItemCount() const
{
if (!m_item)
return 0;
uint8 item_count = 1;
if (m_item && !m_item->IsClassBag()) { return item_count; }
@@ -526,7 +526,7 @@ EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugty
{
continue;
}
return this->GetAugment(i);
return GetAugment(i);
}
}
@@ -549,7 +549,7 @@ uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
if (!m_item || !m_item->IsClassCommon())
return false;
bool ornamentSet = false;
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
@@ -642,7 +642,7 @@ void EQ::ItemInstance::PutAugment(uint8 slot, const ItemInstance& augment)
{
if (!m_item || !m_item->IsClassCommon())
return;
PutItem(slot, augment);
}
@@ -655,7 +655,7 @@ void EQ::ItemInstance::PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id
if (aug) {
PutAugment(slot, *aug);
safe_delete(aug);
}
}
}
// Remove augment from item and destroy it
@@ -663,7 +663,7 @@ void EQ::ItemInstance::DeleteAugment(uint8 index)
{
if (!m_item || !m_item->IsClassCommon())
return;
DeleteItem(index);
}
@@ -672,7 +672,7 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
{
if (!m_item || !m_item->IsClassCommon())
return nullptr;
return PopItem(index);
}
@@ -680,7 +680,7 @@ bool EQ::ItemInstance::IsAugmented()
{
if (!m_item || !m_item->IsClassCommon())
return false;
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (GetAugmentItemID(index))
return true;
@@ -689,6 +689,45 @@ bool EQ::ItemInstance::IsAugmented()
return false;
}
bool EQ::ItemInstance::ContainsAugmentByID(uint32 item_id)
{
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
if (!item_id) {
return false;
}
for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) {
if (GetAugmentItemID(augment_slot) == item_id) {
return true;
}
}
return false;
}
int EQ::ItemInstance::CountAugmentByID(uint32 item_id)
{
int quantity = 0;
if (!m_item || !m_item->IsClassCommon()) {
return quantity;
}
if (!item_id) {
return quantity;
}
for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) {
if (GetAugmentItemID(augment_slot) == item_id) {
quantity++;
}
}
return quantity;
}
// Has attack/delay?
bool EQ::ItemInstance::IsWeapon() const
{
@@ -834,7 +873,7 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
return false;
}
}
return true;
}
@@ -1058,7 +1097,7 @@ int EQ::ItemInstance::GetItemElementalFlag(bool augments) const
int EQ::ItemInstance::GetItemElementalDamage(bool augments) const
{
int damage = 0;
int64 damage = 0;
const auto item = GetItem();
if (item) {
damage = item->ElemDmgAmt;
@@ -1123,7 +1162,7 @@ int EQ::ItemInstance::GetItemRequiredLevel(bool augments) const
int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
{
int damage = 0;
int64 damage = 0;
const auto item = GetItem();
if (item) {
damage = item->Damage;
@@ -1139,7 +1178,7 @@ int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
int EQ::ItemInstance::GetItemBackstabDamage(bool augments) const
{
int damage = 0;
int64 damage = 0;
const auto item = GetItem();
if (item) {
damage = item->BackstabDmg;
@@ -1197,7 +1236,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
{
int damage = 0;
int64 damage = 0;
const auto item = GetItem();
if (item) {
if (item->BaneDmgBody == against)
@@ -1214,7 +1253,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) con
int EQ::ItemInstance::GetItemBaneDamageRace(uint16 against, bool augments) const
{
int damage = 0;
int64 damage = 0;
const auto item = GetItem();
if (item) {
if (item->BaneDmgRace == against)
+2
View File
@@ -132,6 +132,8 @@ namespace EQ
void DeleteAugment(uint8 slot);
ItemInstance* RemoveAugment(uint8 index);
bool IsAugmented();
bool ContainsAugmentByID(uint32 item_id);
int CountAugmentByID(uint32 item_id);
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
+14 -5
View File
@@ -30,11 +30,19 @@ struct LootTableEntries_Struct {
float probability;
};
struct ContentFlags {
int16 min_expansion;
int16 max_expansion;
char content_flags[100];
char content_flags_disabled[100];
};
struct LootTable_Struct {
uint32 mincash;
uint32 maxcash;
uint32 avgcoin;
uint32 NumEntries;
uint32 mincash;
uint32 maxcash;
uint32 avgcoin;
uint32 NumEntries;
ContentFlags content_flags;
LootTableEntries_Struct Entries[0];
};
@@ -51,7 +59,8 @@ struct LootDropEntries_Struct {
};
struct LootDrop_Struct {
uint32 NumEntries;
uint32 NumEntries;
ContentFlags content_flags;
LootDropEntries_Struct Entries[0];
};
#pragma pack()
+1 -1
View File
@@ -194,7 +194,7 @@ void MD5::Final(uint8 digest[16], MD5Context *ctx) {
/* The heart of the MD5 algorithm. */
void MD5::Transform(uint32 hash[4], const uint32 input[16]) {
register uint32 a = hash[0], b = hash[1], c = hash[2], d = hash[3];
uint32 a = hash[0], b = hash[1], c = hash[2], d = hash[3];
MD5STEP(F1, a, b, c, d, input[ 0]+0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, input[ 1]+0xe8c7b756, 12);
+2 -2
View File
@@ -15,7 +15,7 @@ EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent,
memset(m_line, 0, MaxConsoleLineLength);
m_accept_messages = false;
m_user_id = 0;
m_admin = 0;
m_admin = AccountStatus::Player;
m_connection->OnRead(std::bind(&ConsoleServerConnection::OnRead, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_connection->OnDisconnect(std::bind(&ConsoleServerConnection::OnDisconnect, this, std::placeholders::_1));
@@ -29,7 +29,7 @@ EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent,
if (addr.find("127.0.0.1") != std::string::npos || addr.find("::0") != std::string::npos) {
SendLine("Connection established from localhost, assuming admin");
m_status = ConsoleStatusLoggedIn;
m_admin = 255;
m_admin = AccountStatus::Max;
SendPrompt();
}
else {
+3 -2
View File
@@ -5,6 +5,7 @@
#include <map>
#include <unordered_set>
#include <array>
#include "../emu_constants.h"
struct MethodHandlerEntry
{
@@ -174,13 +175,13 @@ Json::Value EQ::Net::WebsocketServer::Login(WebsocketServerConnection *connectio
auto r = _impl->login_handler(connection, user, pass);
if (r.logged_in) {
connection->SetAuthorized(true, r.account_name, r.account_id, 255);
connection->SetAuthorized(true, r.account_name, r.account_id, AccountStatus::Max);
ret["status"] = "Ok";
}
else if (user == "admin" && (connection->RemoteIP() == "127.0.0.1" || connection->RemoteIP() == "::")) {
r.logged_in = true;
r.account_id = 0;
connection->SetAuthorized(true, r.account_name, r.account_id, 255);
connection->SetAuthorized(true, r.account_name, r.account_id, AccountStatus::Max);
ret["status"] = "Ok";
}
else {
+2 -2
View File
@@ -115,8 +115,8 @@ IN(OP_GMTraining, GMTrainee_Struct);
IN(OP_GMEndTraining, GMTrainEnd_Struct);
IN(OP_GMTrainSkill, GMSkillChange_Struct);
IN(OP_RequestDuel, Duel_Struct);
IN(OP_DuelResponse, DuelResponse_Struct);
IN(OP_DuelResponse2, Duel_Struct);
IN(OP_DuelDecline, DuelResponse_Struct);
IN(OP_DuelAccept, Duel_Struct);
IN(OP_SpawnAppearance, SpawnAppearance_Struct);
IN(OP_BazaarInspect, BazaarInspect_Struct);
IN(OP_Death, Death_Struct);
+2 -2
View File
@@ -240,8 +240,8 @@ void load_opcode_names()
opcode_map[0x00a1] = "LiveOP_SaveOnZoneReq";
opcode_map[0x0185] = "LiveOP_Logout";
opcode_map[0x0298] = "LiveOP_RequestDuel";
opcode_map[0x0a5d] = "LiveOP_DuelResponse";
opcode_map[0x016e] = "LiveOP_DuelResponse2";
opcode_map[0x0a5d] = "LiveOP_DuelDecline";
opcode_map[0x016e] = "LiveOP_DuelAccept";
opcode_map[0x007c] = "LiveOP_InstillDoubt";
opcode_map[0x00ac] = "LiveOP_SafeFallSuccess";
opcode_map[0x02fb] = "LiveOP_DisciplineUpdate";
-14
View File
@@ -1634,20 +1634,6 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_ManaChange)
{
ENCODE_LENGTH_EXACT(ManaChange_Struct);
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
ENCODE(OP_MercenaryDataResponse)
{
//consume the packet
-14
View File
@@ -1683,20 +1683,6 @@ namespace RoF2
FINISH_ENCODE();
}
ENCODE(OP_ManaChange)
{
ENCODE_LENGTH_EXACT(ManaChange_Struct);
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
ENCODE(OP_MercenaryDataResponse)
{
//consume the packet
-1
View File
@@ -93,7 +93,6 @@ E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
E(OP_MoveItem)
+8 -3
View File
@@ -2649,11 +2649,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unknown007;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 unknown020;
/*020*/ uint32 entity_id;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -3061,7 +3061,7 @@ struct EnvDamage2_Struct {
/*0006*/ uint32 damage;
/*0010*/ float unknown10; // New to Underfoot - Seen 1
/*0014*/ uint8 unknown14[12];
/*0026*/ uint8 dmgtype; // FA = Lava; FC = Falling
/*0026*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
/*0027*/ uint8 unknown27[4];
/*0031*/ uint16 unknown31; // New to Underfoot - Seen 66
/*0033*/ uint16 constant; // Always FFFF
@@ -5218,6 +5218,11 @@ struct SayLinkBodyFrame_Struct {
/*056*/
};
struct Checksum_Struct {
uint64_t checksum;
uint8_t data[2048];
};
}; /*structs*/
}; /*RoF2*/
-1
View File
@@ -79,7 +79,6 @@ E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
E(OP_MoveItem)
+3 -3
View File
@@ -2622,11 +2622,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unknown007;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 unknown020;
/*020*/ uint32 entity_id;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -3032,7 +3032,7 @@ struct EnvDamage2_Struct {
/*0006*/ uint32 damage;
/*0010*/ float unknown10; // New to Underfoot - Seen 1
/*0014*/ uint8 unknown14[12];
/*0026*/ uint8 dmgtype; // FA = Lava; FC = Falling
/*0026*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
/*0027*/ uint8 unknown27[4];
/*0031*/ uint16 unknown31; // New to Underfoot - Seen 66
/*0033*/ uint16 constant; // Always FFFF
-14
View File
@@ -1170,20 +1170,6 @@ namespace SoD
FINISH_ENCODE();
}
ENCODE(OP_ManaChange)
{
ENCODE_LENGTH_EXACT(ManaChange_Struct);
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
ENCODE(OP_MercenaryDataResponse)
{
//consume the packet
-1
View File
@@ -63,7 +63,6 @@ E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
E(OP_MoveItem)
+3 -3
View File
@@ -2136,11 +2136,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unknown007;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 unknown020;
/*020*/ uint32 entity_id;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -2539,7 +2539,7 @@ struct EnvDamage2_Struct {
/*0004*/ uint16 unknown4;
/*0006*/ uint32 damage;
/*0010*/ uint8 unknown10[12];
/*0022*/ uint8 dmgtype; //FA = Lava; FC = Falling
/*0022*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
/*0023*/ uint8 unknown2[4];
/*0027*/ uint16 constant; //Always FFFF
/*0029*/ uint16 unknown29;
-14
View File
@@ -966,20 +966,6 @@ namespace SoF
FINISH_ENCODE();
}
ENCODE(OP_ManaChange)
{
ENCODE_LENGTH_EXACT(ManaChange_Struct);
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
ENCODE(OP_MemorizeSpell)
{
ENCODE_LENGTH_EXACT(MemorizeSpell_Struct);
-1
View File
@@ -59,7 +59,6 @@ E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MemorizeSpell)
E(OP_MoveItem)
E(OP_NewSpawn)
+3 -3
View File
@@ -2106,11 +2106,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unknown007;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 unknown020;
/*020*/ uint32 entity_id;
/*024*/
};
//there are only 10 faces for barbs changing woad just
@@ -2509,7 +2509,7 @@ struct EnvDamage2_Struct {
/*0004*/ uint16 unknown4;
/*0006*/ uint32 damage;
/*0010*/ uint8 unknown10[12];
/*0022*/ uint8 dmgtype; //FA = Lava; FC = Falling
/*0022*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
/*0023*/ uint8 unknown2[4];
/*0027*/ uint16 constant; //Always FFFF
/*0029*/ uint16 unknown29;
+37
View File
@@ -932,6 +932,19 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_ManaChange)
{
ENCODE_LENGTH_EXACT(ManaChange_Struct);
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
OUT(keepcasting);
FINISH_ENCODE();
}
ENCODE(OP_MemorizeSpell)
{
ENCODE_LENGTH_EXACT(MemorizeSpell_Struct);
@@ -1451,6 +1464,30 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_SetFace)
{
auto emu = reinterpret_cast<FaceChange_Struct*>((*p)->pBuffer);
EQApplicationPacket outapp(OP_Illusion, sizeof(structs::Illusion_Struct));
auto buf = reinterpret_cast<structs::Illusion_Struct*>(outapp.pBuffer);
buf->spawnid = emu->entity_id;
buf->race = -1; // unchanged
buf->gender = -1; // unchanged
buf->texture = -1; // unchanged
buf->helmtexture = -1; // unchanged
buf->face = emu->face;
buf->hairstyle = emu->hairstyle;
buf->haircolor = emu->haircolor;
buf->beard = emu->beard;
buf->beardcolor = emu->beardcolor;
buf->size = 0.0f; // unchanged
safe_delete(*p); // not using the original packet
dest->QueuePacket(&outapp, ack_req);
}
ENCODE(OP_ShopPlayerSell)
{
ENCODE_LENGTH_EXACT(Merchant_Purchase_Struct);
+2
View File
@@ -55,6 +55,7 @@ E(OP_ItemPacket)
E(OP_LeadershipExpUpdate)
E(OP_LFGuild)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MemorizeSpell)
E(OP_MoveItem)
E(OP_OnLevelMessage)
@@ -65,6 +66,7 @@ E(OP_ReadBook)
E(OP_RespondAA)
E(OP_SendCharInfo)
E(OP_SendAATable)
E(OP_SetFace)
E(OP_ShopPlayerSell)
E(OP_SpecialMesg)
E(OP_TaskDescription)
+1 -2
View File
@@ -1761,8 +1761,7 @@ struct AdventureRequestResponse_Struct{
struct Illusion_Struct {
/*000*/ uint32 spawnid;
/*004*/ char charname[64];
/*068*/ uint16 race;
/*070*/ char unknown070[2];
/*068*/ int race;
/*072*/ uint8 gender;
/*073*/ uint8 texture;
/*074*/ uint8 helmtexture;
-14
View File
@@ -1390,20 +1390,6 @@ namespace UF
FINISH_ENCODE();
}
ENCODE(OP_ManaChange)
{
ENCODE_LENGTH_EXACT(ManaChange_Struct);
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
ENCODE(OP_MercenaryDataResponse)
{
//consume the packet
-1
View File
@@ -68,7 +68,6 @@ E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
E(OP_MoveItem)
+2 -2
View File
@@ -2185,11 +2185,11 @@ struct FaceChange_Struct {
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unknown007;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 unknown020;
/*020*/ uint32 entity_id;
/*024*/
};
//there are only 10 faces for barbs changing woad just
+8 -7
View File
@@ -58,7 +58,8 @@ XS(XS_EQDB_field_count)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->field_count();
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
@@ -84,7 +85,8 @@ XS(XS_EQDB_affected_rows)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->affected_rows();
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
@@ -110,7 +112,8 @@ XS(XS_EQDB_insert_id)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->insert_id();
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
@@ -136,7 +139,8 @@ XS(XS_EQDB_get_errno)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->get_errno();
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
@@ -221,9 +225,6 @@ XS(XS_EQDB_escape_string)
XSRETURN(1);
}
#ifdef __cplusplus
extern "C"
#endif
XS(boot_EQDB); /* prototype to pass -Wmissing-prototypes */
XS(boot_EQDB)
{
+4 -5
View File
@@ -54,7 +54,8 @@ XS(XS_EQDBRes_num_rows)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->num_rows();
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
@@ -80,7 +81,8 @@ XS(XS_EQDBRes_num_fields)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->num_fields();
XSprePUSH; PUSHu((UV)RETVAL);
XSprePUSH;
PUSHu((UV) RETVAL);
}
XSRETURN(1);
}
@@ -260,9 +262,6 @@ XS(XS_EQDBRes_fetch_lengths)
XSRETURN(1);
}
#ifdef __cplusplus
extern "C"
#endif
XS(boot_EQDBRes); /* prototype to pass -Wmissing-prototypes */
XS(boot_EQDBRes)
{
+84 -64
View File
@@ -19,6 +19,7 @@
#include "profanity_manager.h"
#include "dbcore.h"
#include "string_util.h"
#include <ctype.h>
#include <cstring>
@@ -34,15 +35,17 @@ bool EQ::ProfanityManager::LoadProfanityList(DBcore *db) {
return true;
}
if (!load_database_entries(db))
if (!load_database_entries(db)) {
return false;
}
return true;
}
bool EQ::ProfanityManager::UpdateProfanityList(DBcore *db) {
if (!load_database_entries(db))
if (!load_database_entries(db)) {
return false;
}
update_originator_flag = true;
@@ -58,53 +61,60 @@ bool EQ::ProfanityManager::DeleteProfanityList(DBcore *db) {
return true;
}
bool EQ::ProfanityManager::AddProfanity(DBcore *db, const char *profanity) {
if (!db || !profanity)
bool EQ::ProfanityManager::AddProfanity(DBcore *db, std::string profanity) {
if (!db || profanity.empty()) {
return false;
}
std::string entry(profanity);
std::string entry = str_tolower(profanity);
std::transform(entry.begin(), entry.end(), entry.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
if (check_for_existing_entry(entry.c_str()))
if (check_for_existing_entry(entry)) {
return true;
}
if (entry.length() < REDACTION_LENGTH_MIN)
if (entry.length() < REDACTION_LENGTH_MIN) {
return false;
}
profanity_list.push_back(entry);
std::string query = "REPLACE INTO `profanity_list` (`word`) VALUES ('";
query.append(entry);
query.append("')");
auto query = fmt::format(
"REPLACE INTO `profanity_list` (`word`) VALUES ('{}')",
profanity
);
auto results = db->QueryDatabase(query);
if (!results.Success())
if (!results.Success()) {
return false;
}
update_originator_flag = true;
return true;
}
bool EQ::ProfanityManager::RemoveProfanity(DBcore *db, const char *profanity) {
if (!db || !profanity)
bool EQ::ProfanityManager::RemoveProfanity(DBcore *db, std::string profanity) {
if (!db || profanity.empty()) {
return false;
}
std::string entry(profanity);
std::string entry = str_tolower(profanity);
std::transform(entry.begin(), entry.end(), entry.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
if (!check_for_existing_entry(entry.c_str()))
if (!check_for_existing_entry(entry)) {
return true;
}
profanity_list.remove(entry);
std::string query = "DELETE FROM `profanity_list` WHERE `word` LIKE '";
query.append(entry);
query.append("'");
auto query = fmt::format(
"DELETE FROM `profanity_list` WHERE `word` = '{}'",
entry
);
auto results = db->QueryDatabase(query);
if (!results.Success())
if (!results.Success()) {
return false;
}
update_originator_flag = true;
@@ -112,16 +122,16 @@ bool EQ::ProfanityManager::RemoveProfanity(DBcore *db, const char *profanity) {
}
void EQ::ProfanityManager::RedactMessage(char *message) {
if (!message)
if (!message) {
return;
}
std::string test_message(message);
std::string test_message = str_tolower(message);
// hard-coded max length based on channel message buffer size (4096 bytes)..
// ..will need to change or remove if other sources are used for redaction
if (test_message.length() < REDACTION_LENGTH_MIN || test_message.length() >= 4096)
if (test_message.length() < REDACTION_LENGTH_MIN || test_message.length() >= 4096) {
return;
std::transform(test_message.begin(), test_message.end(), test_message.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
}
for (const auto &iter : profanity_list) { // consider adding textlink checks if it becomes an issue
size_t pos = 0;
@@ -129,12 +139,17 @@ void EQ::ProfanityManager::RedactMessage(char *message) {
while (pos != std::string::npos) {
pos = test_message.find(iter, start_pos);
if (pos == std::string::npos)
if (pos == std::string::npos) {
continue;
}
if ((pos + iter.length()) == test_message.length() || !isalpha(test_message.at(pos + iter.length()))) {
if (pos == 0 || !isalpha(test_message.at(pos - 1)))
if (
(pos + iter.length()) == test_message.length() ||
!isalpha(test_message.at(pos + iter.length()))
) {
if (pos == 0 || !isalpha(test_message.at(pos - 1))) {
memset((message + pos), REDACTION_CHARACTER, iter.length());
}
}
start_pos = (pos + iter.length());
@@ -143,25 +158,29 @@ void EQ::ProfanityManager::RedactMessage(char *message) {
}
void EQ::ProfanityManager::RedactMessage(std::string &message) {
if (message.length() < REDACTION_LENGTH_MIN || message.length() >= 4096)
if (message.length() < REDACTION_LENGTH_MIN || message.length() >= 4096) {
return;
}
std::string test_message(const_cast<const std::string&>(message));
std::string test_message = str_tolower(message);
std::transform(test_message.begin(), test_message.end(), test_message.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
for (const auto &iter : profanity_list) { // consider adding textlink checks if it becomes an issue
for (const auto &iter : profanity_list) {
size_t pos = 0;
size_t start_pos = 0;
while (pos != std::string::npos) {
pos = test_message.find(iter, start_pos);
if (pos == std::string::npos)
if (pos == std::string::npos) {
continue;
}
if ((pos + iter.length()) == test_message.length() || !isalpha(test_message.at(pos + iter.length()))) {
if (pos == 0 || !isalpha(test_message.at(pos - 1)))
if (
(pos + iter.length()) == test_message.length() ||
!isalpha(test_message.at(pos + iter.length()))
) {
if (pos == 0 || !isalpha(test_message.at(pos - 1))) {
message.replace(pos, iter.length(), iter.length(), REDACTION_CHARACTER);
}
}
start_pos = (pos + iter.length());
@@ -169,24 +188,18 @@ void EQ::ProfanityManager::RedactMessage(std::string &message) {
}
}
bool EQ::ProfanityManager::ContainsCensoredLanguage(const char *message) {
if (!message)
return false;
return ContainsCensoredLanguage(std::string(message));
}
bool EQ::ProfanityManager::ContainsCensoredLanguage(const std::string &message) {
if (message.length() < REDACTION_LENGTH_MIN || message.length() >= 4096)
if (message.length() < REDACTION_LENGTH_MIN || message.length() >= 4096) {
return false;
}
std::string test_message(message);
std::transform(test_message.begin(), test_message.end(), test_message.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
std::string test_message = str_tolower(message);
for (const auto &iter : profanity_list) {
if (test_message.find(iter) != std::string::npos)
if (test_message.find(iter) != std::string::npos) {
return true;
}
}
return false;
@@ -197,26 +210,28 @@ const std::list<std::string> &EQ::ProfanityManager::GetProfanityList() {
}
bool EQ::ProfanityManager::IsCensorshipActive() {
return (profanity_list.size() != 0);
return profanity_list.size() != 0;
}
bool EQ::ProfanityManager::load_database_entries(DBcore *db) {
if (!db)
if (!db) {
return false;
}
profanity_list.clear();
std::string query = "SELECT `word` FROM `profanity_list`";
auto results = db->QueryDatabase(query);
if (!results.Success())
if (!results.Success()) {
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
if (std::strlen(row[0]) >= REDACTION_LENGTH_MIN) {
std::string entry(row[0]);
std::transform(entry.begin(), entry.end(), entry.begin(), [](unsigned char c) -> unsigned char { return tolower(c); });
if (!check_for_existing_entry(entry.c_str()))
profanity_list.push_back((std::string)entry);
for (auto row : results) {
std::string entry = str_tolower(row[0]);
if (entry.length() >= REDACTION_LENGTH_MIN) {
if (!check_for_existing_entry(entry)) {
profanity_list.push_back(entry);
}
}
}
@@ -224,26 +239,31 @@ bool EQ::ProfanityManager::load_database_entries(DBcore *db) {
}
bool EQ::ProfanityManager::clear_database_entries(DBcore *db) {
if (!db)
if (!db) {
return false;
}
profanity_list.clear();
std::string query = "DELETE FROM `profanity_list`";
auto results = db->QueryDatabase(query);
if (!results.Success())
if (!results.Success()) {
return false;
}
return true;
}
bool EQ::ProfanityManager::check_for_existing_entry(const char *profanity) {
if (!profanity)
bool EQ::ProfanityManager::check_for_existing_entry(std::string profanity) {
if (profanity.empty()) {
return false;
}
for (const auto &iter : profanity_list) {
if (iter.compare(profanity) == 0)
if (!iter.compare(profanity)) {
return true;
}
}
return false;
+4 -4
View File
@@ -22,6 +22,7 @@
#include <string>
#include <list>
#include <fmt/format.h>
class DBcore;
@@ -34,13 +35,12 @@ namespace EQ
static bool UpdateProfanityList(DBcore *db);
static bool DeleteProfanityList(DBcore *db);
static bool AddProfanity(DBcore *db, const char *profanity);
static bool RemoveProfanity(DBcore *db, const char *profanity);
static bool AddProfanity(DBcore *db, std::string profanity);
static bool RemoveProfanity(DBcore *db, std::string profanity);
static void RedactMessage(char *message);
static void RedactMessage(std::string &message);
static bool ContainsCensoredLanguage(const char *message);
static bool ContainsCensoredLanguage(const std::string &message);
static const std::list<std::string> &GetProfanityList();
@@ -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(const char *profanity);
static bool check_for_existing_entry(std::string profanity);
};
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAaAbilityRepository {
public:
@@ -59,11 +60,36 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"name",
"category",
"classes",
"races",
"drakkin_heritage",
"deities",
"status",
"type",
"charges",
"grant_only",
"first_rank_id",
"enabled",
"reset_on_death",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("aa_ability");
@@ -73,7 +99,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAaRankEffectsRepository {
public:
@@ -41,11 +42,27 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"rank_id",
"slot",
"effect_id",
"base1",
"base2",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("aa_rank_effects");
@@ -55,7 +72,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAaRankPrereqsRepository {
public:
@@ -37,11 +38,25 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"rank_id",
"aa_id",
"points",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("aa_rank_prereqs");
@@ -51,7 +66,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAaRanksRepository {
public:
@@ -57,11 +58,35 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"upper_hotkey_sid",
"lower_hotkey_sid",
"title_sid",
"desc_sid",
"cost",
"level_req",
"spell",
"spell_type",
"recast_time",
"expansion",
"prev_id",
"next_id",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("aa_ranks");
@@ -71,7 +96,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAccountFlagsRepository {
public:
@@ -37,11 +38,25 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"p_accid",
"p_flag",
"p_value",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("account_flags");
@@ -51,7 +66,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAccountIpRepository {
public:
@@ -39,11 +40,26 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"accid",
"ip",
"count",
"lastused",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("account_ip");
@@ -53,7 +69,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -74,7 +90,7 @@ public:
entry.accid = 0;
entry.ip = "";
entry.count = 1;
entry.lastused = "";
entry.lastused = std::time(nullptr);
return entry;
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAccountRepository {
public:
@@ -32,11 +33,14 @@ public:
std::string minilogin_ip;
int hideme;
int rulesflag;
std::string suspendeduntil;
time_t suspendeduntil;
int time_creation;
int expansion;
std::string ban_reason;
std::string suspend_reason;
std::string crc_eqgame;
std::string crc_skillcaps;
std::string crc_basedata;
};
static std::string PrimaryKey()
@@ -66,6 +70,37 @@ public:
"expansion",
"ban_reason",
"suspend_reason",
"crc_eqgame",
"crc_skillcaps",
"crc_basedata",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"name",
"charname",
"sharedplat",
"password",
"status",
"ls_id",
"lsaccount_id",
"gmspeed",
"revoked",
"karma",
"minilogin_ip",
"hideme",
"rulesflag",
"UNIX_TIMESTAMP(suspendeduntil)",
"time_creation",
"expansion",
"ban_reason",
"suspend_reason",
"crc_eqgame",
"crc_skillcaps",
"crc_basedata",
};
}
@@ -74,6 +109,11 @@ public:
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("account");
@@ -83,7 +123,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -115,11 +155,14 @@ public:
entry.minilogin_ip = "";
entry.hideme = 0;
entry.rulesflag = 0;
entry.suspendeduntil = "0000-00-00 00:00:00";
entry.suspendeduntil = 0;
entry.time_creation = 0;
entry.expansion = 0;
entry.ban_reason = "";
entry.suspend_reason = "";
entry.crc_eqgame = "";
entry.crc_skillcaps = "";
entry.crc_basedata = "";
return entry;
}
@@ -169,11 +212,14 @@ public:
entry.minilogin_ip = row[11] ? row[11] : "";
entry.hideme = atoi(row[12]);
entry.rulesflag = atoi(row[13]);
entry.suspendeduntil = row[14] ? row[14] : "";
entry.suspendeduntil = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
entry.time_creation = atoi(row[15]);
entry.expansion = atoi(row[16]);
entry.ban_reason = row[17] ? row[17] : "";
entry.suspend_reason = row[18] ? row[18] : "";
entry.crc_eqgame = row[19] ? row[19] : "";
entry.crc_skillcaps = row[20] ? row[20] : "";
entry.crc_basedata = row[21] ? row[21] : "";
return entry;
}
@@ -220,11 +266,14 @@ public:
update_values.push_back(columns[11] + " = '" + EscapeString(account_entry.minilogin_ip) + "'");
update_values.push_back(columns[12] + " = " + std::to_string(account_entry.hideme));
update_values.push_back(columns[13] + " = " + std::to_string(account_entry.rulesflag));
update_values.push_back(columns[14] + " = '" + EscapeString(account_entry.suspendeduntil) + "'");
update_values.push_back(columns[14] + " = FROM_UNIXTIME(" + (account_entry.suspendeduntil > 0 ? std::to_string(account_entry.suspendeduntil) : "null") + ")");
update_values.push_back(columns[15] + " = " + std::to_string(account_entry.time_creation));
update_values.push_back(columns[16] + " = " + std::to_string(account_entry.expansion));
update_values.push_back(columns[17] + " = '" + EscapeString(account_entry.ban_reason) + "'");
update_values.push_back(columns[18] + " = '" + EscapeString(account_entry.suspend_reason) + "'");
update_values.push_back(columns[19] + " = '" + EscapeString(account_entry.crc_eqgame) + "'");
update_values.push_back(columns[20] + " = '" + EscapeString(account_entry.crc_skillcaps) + "'");
update_values.push_back(columns[21] + " = '" + EscapeString(account_entry.crc_basedata) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -260,11 +309,14 @@ public:
insert_values.push_back("'" + EscapeString(account_entry.minilogin_ip) + "'");
insert_values.push_back(std::to_string(account_entry.hideme));
insert_values.push_back(std::to_string(account_entry.rulesflag));
insert_values.push_back("'" + EscapeString(account_entry.suspendeduntil) + "'");
insert_values.push_back("FROM_UNIXTIME(" + (account_entry.suspendeduntil > 0 ? std::to_string(account_entry.suspendeduntil) : "null") + ")");
insert_values.push_back(std::to_string(account_entry.time_creation));
insert_values.push_back(std::to_string(account_entry.expansion));
insert_values.push_back("'" + EscapeString(account_entry.ban_reason) + "'");
insert_values.push_back("'" + EscapeString(account_entry.suspend_reason) + "'");
insert_values.push_back("'" + EscapeString(account_entry.crc_eqgame) + "'");
insert_values.push_back("'" + EscapeString(account_entry.crc_skillcaps) + "'");
insert_values.push_back("'" + EscapeString(account_entry.crc_basedata) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -308,11 +360,14 @@ public:
insert_values.push_back("'" + EscapeString(account_entry.minilogin_ip) + "'");
insert_values.push_back(std::to_string(account_entry.hideme));
insert_values.push_back(std::to_string(account_entry.rulesflag));
insert_values.push_back("'" + EscapeString(account_entry.suspendeduntil) + "'");
insert_values.push_back("FROM_UNIXTIME(" + (account_entry.suspendeduntil > 0 ? std::to_string(account_entry.suspendeduntil) : "null") + ")");
insert_values.push_back(std::to_string(account_entry.time_creation));
insert_values.push_back(std::to_string(account_entry.expansion));
insert_values.push_back("'" + EscapeString(account_entry.ban_reason) + "'");
insert_values.push_back("'" + EscapeString(account_entry.suspend_reason) + "'");
insert_values.push_back("'" + EscapeString(account_entry.crc_eqgame) + "'");
insert_values.push_back("'" + EscapeString(account_entry.crc_skillcaps) + "'");
insert_values.push_back("'" + EscapeString(account_entry.crc_basedata) + "'");
insert_chunks.push_back("(" + implode(",", insert_values) + ")");
}
@@ -360,11 +415,14 @@ public:
entry.minilogin_ip = row[11] ? row[11] : "";
entry.hideme = atoi(row[12]);
entry.rulesflag = atoi(row[13]);
entry.suspendeduntil = row[14] ? row[14] : "";
entry.suspendeduntil = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
entry.time_creation = atoi(row[15]);
entry.expansion = atoi(row[16]);
entry.ban_reason = row[17] ? row[17] : "";
entry.suspend_reason = row[18] ? row[18] : "";
entry.crc_eqgame = row[19] ? row[19] : "";
entry.crc_skillcaps = row[20] ? row[20] : "";
entry.crc_basedata = row[21] ? row[21] : "";
all_entries.push_back(entry);
}
@@ -403,11 +461,14 @@ public:
entry.minilogin_ip = row[11] ? row[11] : "";
entry.hideme = atoi(row[12]);
entry.rulesflag = atoi(row[13]);
entry.suspendeduntil = row[14] ? row[14] : "";
entry.suspendeduntil = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
entry.time_creation = atoi(row[15]);
entry.expansion = atoi(row[16]);
entry.ban_reason = row[17] ? row[17] : "";
entry.suspend_reason = row[18] ? row[18] : "";
entry.crc_eqgame = row[19] ? row[19] : "";
entry.crc_skillcaps = row[20] ? row[20] : "";
entry.crc_basedata = row[21] ? row[21] : "";
all_entries.push_back(entry);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAccountRewardsRepository {
public:
@@ -37,11 +38,25 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"account_id",
"reward_id",
"amount",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("account_rewards");
@@ -51,7 +66,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAdventureDetailsRepository {
public:
@@ -49,11 +50,31 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"adventure_id",
"instance_id",
"count",
"assassinate_count",
"status",
"time_created",
"time_zoned",
"time_completed",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("adventure_details");
@@ -63,7 +84,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAdventureMembersRepository {
public:
@@ -35,11 +36,24 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"charid",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("adventure_members");
@@ -49,7 +63,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAdventureStatsRepository {
public:
@@ -53,11 +54,33 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"player_id",
"guk_wins",
"mir_wins",
"mmc_wins",
"ruj_wins",
"tak_wins",
"guk_losses",
"mir_losses",
"mmc_losses",
"ruj_losses",
"tak_losses",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("adventure_stats");
@@ -67,7 +90,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAdventureTemplateEntryFlavorRepository {
public:
@@ -35,11 +36,24 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"text",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("adventure_template_entry_flavor");
@@ -49,7 +63,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAdventureTemplateEntryRepository {
public:
@@ -35,11 +36,24 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"template_id",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("adventure_template_entry");
@@ -49,7 +63,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAdventureTemplateRepository {
public:
@@ -97,11 +98,55 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"zone",
"zone_version",
"is_hard",
"is_raid",
"min_level",
"max_level",
"type",
"type_data",
"type_count",
"assa_x",
"assa_y",
"assa_z",
"assa_h",
"text",
"duration",
"zone_in_time",
"win_points",
"lose_points",
"theme",
"zone_in_zone_id",
"zone_in_x",
"zone_in_y",
"zone_in_object_id",
"dest_x",
"dest_y",
"dest_z",
"dest_h",
"graveyard_zone_id",
"graveyard_x",
"graveyard_y",
"graveyard_z",
"graveyard_radius",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("adventure_template");
@@ -111,7 +156,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -148,7 +193,7 @@ public:
entry.zone_in_time = 1800;
entry.win_points = 0;
entry.lose_points = 0;
entry.theme = LDoNThemes::GUK;
entry.theme = 1;
entry.zone_in_zone_id = 0;
entry.zone_in_x = 0;
entry.zone_in_y = 0;
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAlternateCurrencyRepository {
public:
@@ -35,11 +36,24 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"item_id",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("alternate_currency");
@@ -49,7 +63,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseAurasRepository {
public:
@@ -53,11 +54,33 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"type",
"npc_type",
"name",
"spell_id",
"distance",
"aura_type",
"spawn_type",
"movement",
"duration",
"icon",
"cast_time",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("auras");
@@ -67,7 +90,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseBaseDataRepository {
public:
@@ -51,11 +52,32 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"level",
"`class`",
"hp",
"mana",
"end",
"unk1",
"unk2",
"hp_fac",
"mana_fac",
"end_fac",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("base_data");
@@ -65,7 +87,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseBlockedSpellsRepository {
public:
@@ -55,11 +56,34 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"spellid",
"type",
"zoneid",
"x",
"y",
"z",
"x_diff",
"y_diff",
"z_diff",
"message",
"description",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("blocked_spells");
@@ -69,7 +93,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -0,0 +1,326 @@
/**
* 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_BOOKS_REPOSITORY_H
#define EQEMU_BASE_BOOKS_REPOSITORY_H
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseBooksRepository {
public:
struct Books {
int id;
std::string name;
std::string txtfile;
int language;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"name",
"txtfile",
"language",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"name",
"txtfile",
"language",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("books");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static Books NewEntity()
{
Books entry{};
entry.id = 0;
entry.name = "";
entry.txtfile = "";
entry.language = 0;
return entry;
}
static Books GetBooksEntry(
const std::vector<Books> &bookss,
int books_id
)
{
for (auto &books : bookss) {
if (books.id == books_id) {
return books;
}
}
return NewEntity();
}
static Books FindOne(
Database& db,
int books_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
BaseSelect(),
books_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Books entry{};
entry.id = atoi(row[0]);
entry.name = row[1] ? row[1] : "";
entry.txtfile = row[2] ? row[2] : "";
entry.language = atoi(row[3]);
return entry;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int books_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
books_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
Books books_entry
)
{
std::vector<std::string> update_values;
auto columns = Columns();
update_values.push_back(columns[1] + " = '" + EscapeString(books_entry.name) + "'");
update_values.push_back(columns[2] + " = '" + EscapeString(books_entry.txtfile) + "'");
update_values.push_back(columns[3] + " = " + std::to_string(books_entry.language));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
implode(", ", update_values),
PrimaryKey(),
books_entry.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static Books InsertOne(
Database& db,
Books books_entry
)
{
std::vector<std::string> insert_values;
insert_values.push_back(std::to_string(books_entry.id));
insert_values.push_back("'" + EscapeString(books_entry.name) + "'");
insert_values.push_back("'" + EscapeString(books_entry.txtfile) + "'");
insert_values.push_back(std::to_string(books_entry.language));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
implode(",", insert_values)
)
);
if (results.Success()) {
books_entry.id = results.LastInsertedID();
return books_entry;
}
books_entry = NewEntity();
return books_entry;
}
static int InsertMany(
Database& db,
std::vector<Books> books_entries
)
{
std::vector<std::string> insert_chunks;
for (auto &books_entry: books_entries) {
std::vector<std::string> insert_values;
insert_values.push_back(std::to_string(books_entry.id));
insert_values.push_back("'" + EscapeString(books_entry.name) + "'");
insert_values.push_back("'" + EscapeString(books_entry.txtfile) + "'");
insert_values.push_back(std::to_string(books_entry.language));
insert_chunks.push_back("(" + implode(",", insert_values) + ")");
}
std::vector<std::string> insert_values;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<Books> All(Database& db)
{
std::vector<Books> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Books entry{};
entry.id = atoi(row[0]);
entry.name = row[1] ? row[1] : "";
entry.txtfile = row[2] ? row[2] : "";
entry.language = atoi(row[3]);
all_entries.push_back(entry);
}
return all_entries;
}
static std::vector<Books> GetWhere(Database& db, std::string where_filter)
{
std::vector<Books> 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) {
Books entry{};
entry.id = atoi(row[0]);
entry.name = row[1] ? row[1] : "";
entry.txtfile = row[2] ? row[2] : "";
entry.language = atoi(row[3]);
all_entries.push_back(entry);
}
return all_entries;
}
static int DeleteWhere(Database& db, 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);
}
};
#endif //EQEMU_BASE_BOOKS_REPOSITORY_H
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseBugReportsRepository {
public:
@@ -45,9 +46,9 @@ public:
int _unknown_value;
std::string bug_report;
std::string system_info;
std::string report_datetime;
time_t report_datetime;
int bug_status;
std::string last_review;
time_t last_review;
std::string last_reviewer;
std::string reviewer_notes;
};
@@ -95,11 +96,54 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"zone",
"client_version_id",
"client_version_name",
"account_id",
"character_id",
"character_name",
"reporter_spoof",
"category_id",
"category_name",
"reporter_name",
"ui_path",
"pos_x",
"pos_y",
"pos_z",
"heading",
"time_played",
"target_id",
"target_name",
"optional_info_mask",
"_can_duplicate",
"_crash_bug",
"_target_info",
"_character_flags",
"_unknown_value",
"bug_report",
"system_info",
"UNIX_TIMESTAMP(report_datetime)",
"bug_status",
"UNIX_TIMESTAMP(last_review)",
"last_reviewer",
"reviewer_notes",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("bug_reports");
@@ -109,7 +153,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -154,9 +198,9 @@ public:
entry._unknown_value = 0;
entry.bug_report = "";
entry.system_info = "";
entry.report_datetime = "";
entry.report_datetime = std::time(nullptr);
entry.bug_status = 0;
entry.last_review = "";
entry.last_review = std::time(nullptr);
entry.last_reviewer = "None";
entry.reviewer_notes = "";
@@ -221,9 +265,9 @@ public:
entry._unknown_value = atoi(row[24]);
entry.bug_report = row[25] ? row[25] : "";
entry.system_info = row[26] ? row[26] : "";
entry.report_datetime = row[27] ? row[27] : "";
entry.report_datetime = strtoll(row[27] ? row[27] : "-1", nullptr, 10);
entry.bug_status = atoi(row[28]);
entry.last_review = row[29] ? row[29] : "";
entry.last_review = strtoll(row[29] ? row[29] : "-1", nullptr, 10);
entry.last_reviewer = row[30] ? row[30] : "";
entry.reviewer_notes = row[31] ? row[31] : "";
@@ -285,9 +329,9 @@ public:
update_values.push_back(columns[24] + " = " + std::to_string(bug_reports_entry._unknown_value));
update_values.push_back(columns[25] + " = '" + EscapeString(bug_reports_entry.bug_report) + "'");
update_values.push_back(columns[26] + " = '" + EscapeString(bug_reports_entry.system_info) + "'");
update_values.push_back(columns[27] + " = '" + EscapeString(bug_reports_entry.report_datetime) + "'");
update_values.push_back(columns[27] + " = FROM_UNIXTIME(" + (bug_reports_entry.report_datetime > 0 ? std::to_string(bug_reports_entry.report_datetime) : "null") + ")");
update_values.push_back(columns[28] + " = " + std::to_string(bug_reports_entry.bug_status));
update_values.push_back(columns[29] + " = '" + EscapeString(bug_reports_entry.last_review) + "'");
update_values.push_back(columns[29] + " = FROM_UNIXTIME(" + (bug_reports_entry.last_review > 0 ? std::to_string(bug_reports_entry.last_review) : "null") + ")");
update_values.push_back(columns[30] + " = '" + EscapeString(bug_reports_entry.last_reviewer) + "'");
update_values.push_back(columns[31] + " = '" + EscapeString(bug_reports_entry.reviewer_notes) + "'");
@@ -338,9 +382,9 @@ public:
insert_values.push_back(std::to_string(bug_reports_entry._unknown_value));
insert_values.push_back("'" + EscapeString(bug_reports_entry.bug_report) + "'");
insert_values.push_back("'" + EscapeString(bug_reports_entry.system_info) + "'");
insert_values.push_back("'" + EscapeString(bug_reports_entry.report_datetime) + "'");
insert_values.push_back("FROM_UNIXTIME(" + (bug_reports_entry.report_datetime > 0 ? std::to_string(bug_reports_entry.report_datetime) : "null") + ")");
insert_values.push_back(std::to_string(bug_reports_entry.bug_status));
insert_values.push_back("'" + EscapeString(bug_reports_entry.last_review) + "'");
insert_values.push_back("FROM_UNIXTIME(" + (bug_reports_entry.last_review > 0 ? std::to_string(bug_reports_entry.last_review) : "null") + ")");
insert_values.push_back("'" + EscapeString(bug_reports_entry.last_reviewer) + "'");
insert_values.push_back("'" + EscapeString(bug_reports_entry.reviewer_notes) + "'");
@@ -399,9 +443,9 @@ public:
insert_values.push_back(std::to_string(bug_reports_entry._unknown_value));
insert_values.push_back("'" + EscapeString(bug_reports_entry.bug_report) + "'");
insert_values.push_back("'" + EscapeString(bug_reports_entry.system_info) + "'");
insert_values.push_back("'" + EscapeString(bug_reports_entry.report_datetime) + "'");
insert_values.push_back("FROM_UNIXTIME(" + (bug_reports_entry.report_datetime > 0 ? std::to_string(bug_reports_entry.report_datetime) : "null") + ")");
insert_values.push_back(std::to_string(bug_reports_entry.bug_status));
insert_values.push_back("'" + EscapeString(bug_reports_entry.last_review) + "'");
insert_values.push_back("FROM_UNIXTIME(" + (bug_reports_entry.last_review > 0 ? std::to_string(bug_reports_entry.last_review) : "null") + ")");
insert_values.push_back("'" + EscapeString(bug_reports_entry.last_reviewer) + "'");
insert_values.push_back("'" + EscapeString(bug_reports_entry.reviewer_notes) + "'");
@@ -464,9 +508,9 @@ public:
entry._unknown_value = atoi(row[24]);
entry.bug_report = row[25] ? row[25] : "";
entry.system_info = row[26] ? row[26] : "";
entry.report_datetime = row[27] ? row[27] : "";
entry.report_datetime = strtoll(row[27] ? row[27] : "-1", nullptr, 10);
entry.bug_status = atoi(row[28]);
entry.last_review = row[29] ? row[29] : "";
entry.last_review = strtoll(row[29] ? row[29] : "-1", nullptr, 10);
entry.last_reviewer = row[30] ? row[30] : "";
entry.reviewer_notes = row[31] ? row[31] : "";
@@ -520,9 +564,9 @@ public:
entry._unknown_value = atoi(row[24]);
entry.bug_report = row[25] ? row[25] : "";
entry.system_info = row[26] ? row[26] : "";
entry.report_datetime = row[27] ? row[27] : "";
entry.report_datetime = strtoll(row[27] ? row[27] : "-1", nullptr, 10);
entry.bug_status = atoi(row[28]);
entry.last_review = row[29] ? row[29] : "";
entry.last_review = strtoll(row[29] ? row[29] : "-1", nullptr, 10);
entry.last_reviewer = row[30] ? row[30] : "";
entry.reviewer_notes = row[31] ? row[31] : "";
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseBugsRepository {
public:
@@ -57,11 +58,35 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"zone",
"name",
"ui",
"x",
"y",
"z",
"type",
"flag",
"target",
"bug",
"date",
"status",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("bugs");
@@ -71,7 +96,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseBuyerRepository {
public:
@@ -43,11 +44,28 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"charid",
"buyslot",
"itemid",
"itemname",
"quantity",
"price",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("buyer");
@@ -57,7 +75,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseCharCreateCombinationsRepository {
public:
@@ -43,11 +44,28 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"allocation_id",
"race",
"`class`",
"deity",
"start_zone",
"expansions_req",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("char_create_combinations");
@@ -57,7 +75,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseCharCreatePointAllocationsRepository {
public:
@@ -61,11 +62,37 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"base_str",
"base_sta",
"base_dex",
"base_agi",
"base_int",
"base_wis",
"base_cha",
"alloc_str",
"alloc_sta",
"alloc_dex",
"alloc_agi",
"alloc_int",
"alloc_wis",
"alloc_cha",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("char_create_point_allocations");
@@ -75,7 +102,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseCharRecipeListRepository {
public:
@@ -37,11 +38,25 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"char_id",
"recipe_id",
"madecount",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("char_recipe_list");
@@ -51,7 +66,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseCharacterActivitiesRepository {
public:
@@ -41,11 +42,27 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"charid",
"taskid",
"activityid",
"donecount",
"completed",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_activities");
@@ -55,7 +72,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseCharacterAltCurrencyRepository {
public:
@@ -37,11 +38,25 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"char_id",
"currency_id",
"amount",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_alt_currency");
@@ -51,7 +66,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}
@@ -14,6 +14,7 @@
#include "../../database.h"
#include "../../string_util.h"
#include <ctime>
class BaseCharacterAlternateAbilitiesRepository {
public:
@@ -39,11 +40,26 @@ public:
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"aa_id",
"aa_value",
"charges",
};
}
static std::string ColumnsRaw()
{
return std::string(implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_alternate_abilities");
@@ -53,7 +69,7 @@ public:
{
return fmt::format(
"SELECT {} FROM {}",
ColumnsRaw(),
SelectColumnsRaw(),
TableName()
);
}

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