Compare commits

...

123 Commits

Author SHA1 Message Date
Chris Miles 2b79a36014 [Release] 23.1.0 (#4736)
* [Release] 23.1.0

* Version

* Pet table last minute add in
2025-03-01 19:23:50 -06:00
Akkadius 8cf52294e9 [Hotfix] Add character_pet_name to player tables schema 2025-03-01 18:56:38 -06:00
Chris Miles 0ef79903f8 [Crash] Validate item in SE_SummonItemIntoBag (#4734) 2025-03-01 18:32:43 -06:00
Chris Miles ab14458f9e [Crash] Fix large file size crash in File::GetContents for windows (#4735) 2025-03-01 18:32:35 -06:00
Chris Miles 5b94e736b3 [Crash] Fix reload concurrency crash when ran from Spire (#4733) 2025-03-01 18:05:28 -06:00
Chris Miles c3b8cc9744 [Crash] Check for directory existence before traversing in CheckForCompatibleQuestPlugins (#4730) 2025-03-01 20:01:37 -04:00
Mitch Freeman 89e3b2c72e [Fix] Add client packets to questmanager:setguild (#4732) 2025-03-01 17:55:44 -06:00
Chris Miles 23c4aa241b [Crash] World CLI validation (#4728)
* [Crash] World CLI validation

* Clean
2025-03-01 19:52:51 -04:00
Chris Miles acb7584e26 [Loginserver] Minor cleanup (#4729) 2025-03-01 19:52:21 -04:00
Chris Miles a885bd9322 [Crash] Fix filesystem crash / exception in DatabaseDumpService::RemoveCredentialsFile() (#4731) 2025-03-01 19:51:41 -04:00
Chris Miles 20fe1926e0 [Database] Remove force_interactive from big bag updates (#4727) 2025-03-01 16:55:57 -06:00
Chris Miles eb7118754b [Zone State] Wrap all serialization/deserialization in try/catch (#4726) 2025-03-01 16:46:08 -06:00
Mitch Freeman 3611b49f68 [Feature] Evolving items Additions (#4725)
* Implement multi-value for evolving sub_types

- Added ability for evolving sub_types to contain multiple values
- Implemented EvolvingItems::Types::NUMBER_OF_KILLS with level for sub_type

* Repair a timer issue preventing proper evolution of items

* Simplify

* Remove extra level of nesting

* Update client_evolving_items.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-03-01 16:38:59 -06:00
catapultam-habeo 511d8a8bb3 [Bug Fix] Refactor ApplyItemBonuses to fix double-counting of ATK and recommended levels not correctly applying (#4713)
* refactor AddItemBonuses

* typo

* simplify some syntax

* fix indents

* Revert "fix indents"

This reverts commit 8e660707a9.

* fix indents without blowing up entire file

* Revert "fix indents without blowing up entire file"

This reverts commit 6b21d1bcc9.

* ok for real though

* Undo spaces in formatting, source uses tabs

* Spaces to tabs take 2

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-28 21:04:42 -06:00
catapultam-habeo 1598d2e17b [Feature] Add a rule for spells to bypass stacking rules (#4716)
* define rule that allows for spells which always stack

* Update spells.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-28 16:49:20 -06:00
nytmyr 805757ba87 [Bots] Fix unresponsive bots in groups upon group wipe (#4712)
- Bots were failing to recall their group after dying due to the way it was grabbing the group from entity list.
2025-02-28 16:10:46 -06:00
Chris Miles eb6ac25540 [Code Cleanup] More login <-> world code cleanup (#4724)
* More cleanup

* More cleanup
2025-02-28 16:08:06 -06:00
MortimerGreenwald cb634cf57d [Bug Fix] Fix Trading Items to Bot Pets (#4721)
Small change using IsPetOwnerOfClientBot() instead of just IsPetOwnerClient

Can bot pet take item?

not before, but hopefully now?
2025-02-28 15:54:38 -06:00
Chris Miles 2f7ca2cdc8 [Zone] Implement Zone State Saving on Shutdown (#4715)
* Save spawns

* Update base_zone_state_spawns_repository.h

* Zone state save work

* Code cleanup

* More cleanup

* Database migration

* Update database_update_manifest.cpp

* Revert decay at storage model

* Code cleanup

* More cleanup

* More cleanup

* More cleanup

* Entity variables

* Add entity variables to the schema

* Post rebase

* Checkpoint

* Serialize / deserialize buffs

* Current hp / mana / end save / load

* Save / load current_waypoint

* Add zone spawn protection

* Finishing touches

* Cleanup

* Update zone_save_state.cpp

* Cleanup

* Update zone_save_state.cpp

* Update npc.cpp

* Update npc.cpp

* More

* Update perl_npc.cpp

* Update zone_loot.cpp
2025-02-28 15:31:06 -06:00
Chris Miles 425d24c1f4 [Quest API] Implement eq.handin() and quest::handin() (#4718)
* [Quest API] Implement eq.handin() and quest::handin()

* Fix MQ using new API style
2025-02-28 15:22:39 -06:00
Alex King 875df8e64a [Quest API] Add Key Ring Methods to Perl and Lua (#4719) 2025-02-28 15:08:57 -06:00
Alex King 7a2d2a0c51 [Bug Fix] Fix AA Reset Error Message (#4720)
* [Bug Fix] Fix AA Reset Error Message

* Update client.cpp

* Update client.cpp
2025-02-28 15:06:49 -06:00
Alex King 5296202e56 [Bug Fix] Fix Issue with Suffixes/Prefixes (#4723) 2025-02-28 15:05:57 -06:00
Akkadius e2db8ffea8 [Hotfix] Clear m_completed_shared_tasks before reloading 2025-02-24 17:24:18 -06:00
Chris Miles fa2ab11676 [Tasks] Extend IsTaskCompleted to also be aware of shared task completion (#4714)
* [Tasks] Extend IsTaskCompleted to also be aware of shared task completion

* Fix my stupidity

* Update client.h
2025-02-24 16:31:35 -06:00
Chris Miles 80e8634a48 [Release] 23.0.2 (#4711) 2025-02-21 23:18:29 -06:00
zimp-wow 98c2fa5127 [Bug Fix] Fix bad Mob reference in QuestManager::resumetimer() (#4710) 2025-02-21 23:14:50 -06:00
nytmyr 8b8b41dab3 [Bots] Add checks to ensure bots and pets do not engage on ^pull (#4708) 2025-02-21 23:13:54 -06:00
nytmyr 63b1e6b4b4 [Bots] Improve positioning (#4709)
- Prevent bots not set to ^behindmob from finding positions behind their target.
- Backs up a bot if they're too close and have target reflection, not just taunting bots.
- Backs up bots if the target is rooting and they are not taunting to the appropriate position.
- This will particularly help with casters running around.
2025-02-21 23:12:50 -06:00
nytmyr 21b7b6e7ab [Bots] Prevent medding in combat if any mob has bot targeted (#4707)
- Previously this only checked the bots target to med. It will now check the hatelist of the bot to ensure no mobs have the bot targeted before medding.
2025-02-21 23:12:29 -06:00
Alex King 878a5377ae [Bug Fix] Fix Lua Zone ID Exports (#4700) 2025-02-21 23:12:04 -06:00
Alex King 486c7c44be [Quest API] Add GetSpawn() to Perl and Lua (#4702)
* [Quest API] Add GetSpawn() to Perl and Lua

* Push

* Update npc.h
2025-02-21 22:57:41 -06:00
nytmyr aa4869c6e9 [Hotfix] Fix cursor load on zone (#4704)
* [Hotfix] Fix cursor load on zone

- Corrects an issue where the item on your cursor would become invisible upon trying to place it anywhere in your inventory.

* Remove general to prevent duplicate loads
2025-02-21 22:54:35 -06:00
zimp-wow 94e1b4edfa [Bug Fix] Fix infinite loop in QuestManager::stoptimer() (#4703) 2025-02-20 19:52:08 -05:00
Akkadius 4d73b7d641 [Release] 23.0.1 2025-02-20 02:48:01 -06:00
Chris Miles ed4f9b0d30 [Fix] Player event ordering merge fix (#4699) 2025-02-20 02:46:24 -06:00
Alex King f8837d0926 [Quest API] Add DisableRespawnTimers to Perl and Lua (#4691)
* [Quest API] Add DisableRespawnTimers to Perl and Lua

* Update lua_zone.h

* Update lua_zone.cpp

* Change up how we're doing this

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-20 00:26:46 -06:00
Chris Miles 753d83c499 [Release] 23.0.0 (#4698)
* [Release] 23.0.0

* Update CHANGELOG.md

* Fix migration
2025-02-20 00:17:40 -06:00
Alex f0108826d3 [Client Mod] Adds a hacked fast camp rule for GMs (#4697)
Co-authored-by: KimLS <KimLS@peqtgc.com>
2025-02-19 23:20:22 -06:00
Chris Miles 6ac846c003 [Fix] Fix issue with getting an unset nested databucket (#4693) 2025-02-19 13:28:02 -06:00
Chris Miles 44963f3f21 [Fix] #rq and #reload quest alias (#4694) 2025-02-18 13:28:07 -06:00
Chris Miles 9fd935ef10 [Fix] Prevent zone from loading ETL ID's on bootup (#4696) 2025-02-18 13:27:56 -06:00
Chris Miles 6f390c81f9 [Fix] Fix non-error in player_event_logs (#4695) 2025-02-18 13:27:43 -06:00
Chris Miles 1bd281c8f2 [Performance] Server Reload Overhaul (#4689)
* [Performance] Server Reload Overhaul

* Client::SendReloadCommandMessages

* Remove global buffs
2025-02-18 00:54:37 -06:00
Chris Miles 49cf97ae9c [Databuckets] Add Zone Scoped Databuckets (#4690)
* [Databuckets] Add Zone Scoped Databuckets

* Add database indexes

* Update database_update_manifest.cpp

* Shutdown fix

* Testing

* Perf boost

* Revert "Perf boost"

This reverts commit 55d3e507d3.

* Update data_bucket.cpp
2025-02-18 00:14:49 -06:00
MortimerGreenwald 8315240b17 [Bug Fix] Find Zone - Expansion Settings (#4692)
* Bug Fix Find Zone - Expansion Settings

#fz expansion 30 Would crash your zone since the expansions don't go up that high. This Adds a check for range out of bounds and provides an exception to expansion 99 since those are test/dev zones.

* Update zone.cpp

* Update zone.cpp

* Update zone.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2025-02-17 23:37:35 -05:00
hg 55155ff800 [Expeditions] Move expedition code into DynamicZone (#4672)
This removes the separate Expedition class and moves lockout code and
/dz command handlers into DynamicZone classes. It also refactors some
code to reduce bloat and some database usage.

This completes the effort of moving everything to DynamicZone that
started when implementing shared tasks. It also makes sense to do this
since expeditions are just dynamic zones internally despite dzs being
used for other types. Expedition specific things are just handled with
dz type checks.

Functionally nothing should change. This is mainly internal refactoring
and moving code around along with some bug fixes and reduced database
usage.

Main changes:

 - The `expeditions` database table has been removed

 - Expeditions no longer use a separate id, the expedition id is just the dz id

 - Expedition lock state and replay timer option were moved to the
   `dynamic_zones` table

 - Expeditions no longer have a separate cache from dynamic zones

 - Expedition creation no longer has every zone query the database to cache it

 - Expedition internal lockouts are now stored on DynamicZone

 - The `expedition_lockouts` table has been renamed to `dynamic_zone_lockouts`

 - Fixed a small bug with the UpdateLockoutDuration api where the
   internal lockout would get the time added twice in memory in the
   initiating zone (this api is likely rarely used)

 - Fixed an issue where use of the group/raid DoesAnyMemberHaveExpeditionLockout
   api would query once for every out of zone character.

   - This api now checks all members in the current zone first and only
     performs a single bulk query for out of zone members if that check
     is exhausted

 - Deprecated the max_check_count param of DoesAnyMemberHaveExpeditionLockout,
   the quest api still exists to avoid api break but a passed arg has no effect
2025-02-15 18:40:35 -06:00
Mitch Freeman ab4e1191ef [Fix] Parcel Delivery Updates (#4688)
* Fix two parcel bugs

Fix two Parcel Bugs

- If a player was at their parcel limit and perform a bazaar purchase via parcel delivery, their money would be lost
- If a container with items was delivered via parcel, the parcel under certain inventory conditions could be delivered into an incorrect slot resulting in the container being lost.

* Incorrect field used for BagSize vs ItemSize.  Silly mistake.

* Remove duplicate check and reorder stacking check

* Fix edge case when Parcel Window remains open and Bazaar purchases are made.

* Repair
- bazaar purchase of items with charges reverting to 1 charge in error
- bazaar visual error with selling price. Was caused by the parcel fee not being properly reflected in the client
- corrected a type mismatch with parcel fee uint32 vs uin64
- corrected a few TraderPurchase and TraderSell event data points by splitting quantity and charges

* Formatting

* Use pre-existing AddMoney and TakeMoney and remove unnecessary routines

* Updates after rebase
2025-02-15 18:27:09 -06:00
Mitch Freeman c09fad5a75 [Feature] GuildBank Updates (#4674)
* First pass of a re-write of Guild Bank to enable RoF2 features

* Testing - Corrected a few bugs with merging, splitting and withdrawing

* Testing - Corrected a few bugs with depositing of bags

* Added player event logging for deposit, withdrawal and movement between deposit to main area.

* Fix the guilddelete routine

Fix the guilddelete routine as a result of the new guild_bank table structure

* Fix an issue with items not being withdrawn correctly.

* Final Testing Phase 1 - A few failures to be resolved yet.

* Final Testing Phase 2 - Looks good

* Final Testing Phase 3 - Repair a visual bug with withdrawal of items with charges

* Cleanup

* Formatting feedback updates

* Rebase and fix version.h

* Fix manifest issue after changes
2025-02-15 17:48:50 -06:00
Chris Miles 8201175c2c [Fix] Item Handins to Pets (#4687)
* [Fix] Item handins to pets

* Update npc.cpp
2025-02-15 17:07:40 -06:00
Chris Miles e88ea24966 [Fix] GMMove Update Edge Case With Clients (#4686)
* [Fix] GMMove with clients

* Exclude clients entirely for position update caching
2025-02-15 16:20:37 -06:00
nytmyr 02e2f6771c [Bots] Fix AE range calculation (#4683)
- Certain AE types weren't properly calculating their AE range and would base off the actual AE range for targeted types rather than the spells range itself
2025-02-15 15:41:08 -06:00
nytmyr 3b399dfac5 [Bots] Add missing stance options (#4681)
- Moved stance check to function
- Added check for Efficient and Assist stances.
- Sets aggressive to ignore aggrochecks by default
- Adds more types to default aggrocheck list
- Sets Assist to hold CCs
2025-02-15 15:03:55 -06:00
nytmyr 9aa0f7c695 [Spells] Add all types to checks for max_targets_allowed rule for AEs (#4682)
- Added all TargetedAE types to IsTargetableAESpell
- Added IsTargetableAESpell to IsAnyAESpell and changed order for earlier escapes
- IsPBAESpell now checks all PBAE types
- The rule Spells, TargetedAOEMaxTargets will now check all Targeted AE types
- The rule Spells, PointBlankAOEMaxTargets will now check all remaining types that can be a PBAE and not only Nuke PBAEs
2025-02-15 15:03:23 -06:00
nytmyr 3ba113a91d [Bots] Fix pets causing aggro (#4677)
- Adds the rule `Aggro, AggroBotPets`
2025-02-15 15:02:38 -06:00
nytmyr b0c951bd6e [Bots] Prevents casting on ineligible targets due to target type, stacking, etc. (#4680)
- Prevents casting on ineligible targets due to target type, stacking, etc.
- Adjust the rules Bots, MezChance, Bots, MezSuccessDelay and Bots, MezFailDelay
2025-02-15 15:01:39 -06:00
nytmyr 8a5f885558 [Bots] Add AEHateLine to HateLine ParentType (#4678) 2025-02-15 15:00:54 -06:00
nytmyr fd3f5cfd29 [Bots] Command Cleanup (#4676)
- Fix ^discipline saying no bots were selected
- Adds more information to certain commands to explain how they function.
- Rewrote ^copysettings and ^defaultsettings to not be so bloated and accept arguments properly.
- Added long names for setting categories
- Add Spell ID output to ^spells
2025-02-15 15:00:14 -06:00
nytmyr 74b8cf8bd3 [Hotfix] Update pre big bag corpse slot_id's to support big bags (#4679) 2025-02-15 14:58:39 -06:00
nytmyr 18685748f6 [Bots] Crash fixes related to GetNumberNeedingHealedInGroup (#4684)
- Add pre-death checks and early returns
- Cleanup pointers for GetUltimateSpellType checks
- Rename IsBotSpellTypeOtherBeneficial to BotSpellTypeUsesTargetSettings
- Rename GetUltimateSpellTypeDelayCheck to GetUltimateSpellTypeRecastCheck
-Add entity validation to GetNumberNeedingHealedInGroup
2025-02-15 14:55:52 -06:00
nytmyr da24bf467a [Commands] Fix #goto not accepting proper heading (#4685) 2025-02-15 11:12:23 -05:00
Alex King e948a6815c [Bug Fix] Fix Illusion Fade Texture Bug (#4673)
* [Bug Fix] Fix Illusion Fade Texture Bug

* Update spell_effects.cpp
2025-02-13 19:57:31 -06:00
Mitch Freeman dfb089b0c1 [Fix] Change logging level for no items found in a bazaar search to reduce spam logs. (#4675) 2025-02-13 12:21:15 -05:00
nytmyr d9d2d5d47c [Commands] [Hotfix] Fix Illusion Block (#4666)
* [Commands] [Hotfix] Fix Illusion Block

This wasn't properly being set or saved if bots were not enabled, moved to extended character profile for players.

* Move out of EPP

* ValueWithin

* I learned a new word today - idempotent

I'm dumb. Will forget it tomorrow.

* Move saving to ZoneDatabase, inline SetIllusionBlock
2025-02-12 00:18:34 -06:00
Chris Miles ac4ffefa09 [Crash] Fix raid/group crash regression (#4671) 2025-02-12 00:25:29 -05:00
Alex King c228604255 [Bug Fix] Fix Beastlord Warder Size Modifier (#4665)
* [Bug Fix] Fix Beastlord Warder Size Modifier

* Push

* Update repository-generator.pl

---------

Co-authored-by: Chris Miles <akkadius1@gmail.com>
2025-02-11 21:27:59 -06:00
Chris Miles 59292b15f6 [Loginserver] Fix iterator crash (#4670) 2025-02-11 21:22:56 -06:00
Chris Miles 843f6531a7 [Fix] Always spawn zone controller first (#4669) 2025-02-11 22:19:15 -05:00
nytmyr 432452c5c7 [Hotfix] [Spells] Fix ST_GroupNoPets and ST_GroupClientAndPet (#4667) 2025-02-10 01:44:25 -05:00
Alex King f3a2f97155 [Bug Fix] Fix Item Discovery (#4663)
* [Bug Fix] Fix Item Discovery for Pickups, Evolving, Fishing, and Forage

* Push

* Caching

* Update tradeskills.cpp

* Update task_client_state.cpp
2025-02-09 22:25:43 -05:00
Alex King 9e07d90664 [Quest API] Add Zone Support to Perl and Lua (#4662)
* [Quest API] Add Zone Support to Perl and Lua

* Final
2025-02-08 23:21:15 -06:00
Alex King 4fe229c475 [Bug Fix] Fix Tradeskill Queries (#4661) 2025-02-08 20:35:18 -06:00
nytmyr 4658e7f60d [Bots] Fix spell priority commands (#4660)
- Fix priority value check in spellpriority commands
- Fix list option
- Remove unnecessary temp vector on list grab

- Will move getter to cache in future PR
2025-02-08 02:18:36 -05:00
nytmyr 95559b2e17 [Bots] Fix typo in positioning (#4659) 2025-02-08 01:12:03 -05:00
Alex King 7ad63575c7 [Bug Fix] Fix SendStatsWindow Mod2 Value Display (#4658) 2025-02-07 16:23:24 -06:00
nytmyr bc6b21f601 [Bots] Correct helper message for forced casts (#4656)
* Fixed helper message for forced casts

* Update bot.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2025-02-07 14:32:32 -05:00
nytmyr 05c7e6409d [Bots] Fix a couple potential crashes with GetNumberNeedingHealedInGroup (#4652) 2025-02-07 14:06:59 -05:00
nytmyr 60ba76b39c [Cleanup] Bot RaidGroupSay (#4653) 2025-02-07 14:06:31 -05:00
nytmyr 41009aa19b [Bots] Add IsInRaidOrGroup checks to ^attack and ^pull (#4654) 2025-02-07 14:05:55 -05:00
nytmyr ed7023f336 [Bots] Move BotGetSpellsByType to cache (#4655) 2025-02-07 14:05:36 -05:00
Chris Miles e0d95b4302 [NPC Handins] Fix MultiQuest Handins (#4651)
* [NPC Handins] Fix multi-quest handins

* Update linux-build.sh
2025-02-07 03:28:02 -06:00
Alex King 537b585791 [Cleanup] Use Repositories for Titles (#4608)
* [Cleanup] Use Repositories for Titles

* Update titles.h

* Further use repositories

* Revert "Further use repositories"

This reverts commit 80d5f750f0157657af05497eeade8b45e15dc12a.

* Push

* Update titles.cpp

* Push

* Merge branch 'cleanup/titles_repositories' of https://github.com/EQEmu/Server into cleanup/titles_repositories

* Final push
2025-02-06 23:25:36 -06:00
Chris Miles 1a48add20e [Loginserver] Modernize codebase (#4647)
* Beginning of cleanup

* More cleanup

* More cleanup

* Enc cleanup

* client manager cleanup

* client cleanup

* More cleanup

* More cleanup

* Cleanup

* More cleanup, account  context, account management

* Remove positional fmt bindings

* Use LoginAccountContext

* Update loginserver_webserver.cpp

* Remove comments

* Port CreateLoginServerAccount to repositories

* More cleanup

* More cleanup

* More cleanup

* More cleanup

* Remove a ton of functions

* More cleanup

* More cleanup

* More cleanup

* Cleanup SendClientAuthToWorld

* Consolidate world server logic

* Update login_accounts_repository.h

* Update login_accounts_repository.h

* Move api tokens to repositories

* Cleanup options

* Move everything else to repositories

* Update account_management.cpp

* uint64 account

* Update login_schema.sql

* Fix

* Update world_server.cpp

* auto
2025-02-06 12:47:02 -06:00
nytmyr 1650efa787 [Bots] Correct camp count on ^camp (#4650)
* Correct camp count on ^camp

* Update bot.cpp

---------

Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com>
2025-02-06 04:40:09 -05:00
nytmyr 0dde51f518 [Bots] Fix crash related to GetTempSpellType() (#4649)
_tempSpellType was not getting defined during bot spawn process which could lead to a potential crash in RaidGroupSay.

Auto archery toggle was what triggered the crash as it announces their status on spawn.

Also moved this toggle for Rangers further down the proccess line.
2025-02-06 04:14:25 -05:00
Alex King 5cebc42f89 [Feature] Add Support for Tradeskill Recipe Inspect (#4648)
* [Feature] Add Support for Tradeskill Recipe Inspect

* Push

* Update client_packet.cpp
2025-02-05 23:10:16 -06:00
Fryguy 7021602bf4 [Bug] Item Purchase Offset when multiple buyers are buying at the same time. (#4628)
* [Bug] Item Purchase Offset when multiple buyers are buying at the same time.

- Much of the code lifted from TAKP/P2002 and adapted
- Needs Testing
- This should help prevent situations where multiple people are purchasing items from a merchant and both attempt to purchase the same temp merchant or limited item, it should result in the later person recieving a notice that the item no longer exists and refreshes the merchant table.
- Updated strings

* fix formatting

* Push

* Update client.cpp

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update client.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-05 20:56:57 -06:00
Chris Miles 752ac78c56 [CI] Fix database race condition (#4646)
* [CI] Fix race condition

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh
2025-02-05 19:29:16 -06:00
Fryguy e9678da311 [Fix] Big Bag additional fixes (#4644)
* [Fix] Big Bag additional fixes

* More inventory updates
2025-02-05 17:20:36 -05:00
catapultam-habeo 51f25ed779 [Feature] Add rule to allow /changepetname to function without being enabled by scripts. 2025-02-05 15:20:24 -05:00
Mitch Freeman 8f4f8368df [Player Event Logs] Migrate and Deprecate QS Legacy Logging (#4542)
* First pass of player_event_loot_items

* Second pass of player_event_loot_items

* Third pass of player_event_loot_items

* Example without RecordDetailEvent template

* Cleanup the removal of the template

* Fourth Pass

Add retention for etl tables
Rename tables/fields to etl nomenclature
Combine database work to one atomic load

* Reposition to reduce db tasks

* Refactor etl processing for easier additions

* Add merchant purchase event
testing passed though appears that the event itself has a few bugs.  Will fix them in another commit

* Fix PlayerEventMerchantPurchase in client_packet.cpp

* WIP - Handin

* Handin Event added

* Cleanup

* All a rentention period of 0 days which deletes all current records.

* Updates

Cleanup and refactor a few items.

* Cleanup and Formatting

Cleanup and Formatting

* Add etl for
Playerevent::Trade
PlayerEvent::Speech (new event to mirror functionality of qs_speech

* Add etl for
Playerevent::KilledNPC, KilledNamedNPC and KilledRaidNPC

* Add etl for Playerevent::AA_purchase

Add etl for Playerevent::AA_purchase

* Cleanup before PR

* Review comment updates.

* Add world cli etl:settings to output a json on all player event details.

* Add reserve for all etl_queues
Correct a failed test case for improper next id for etl tables when table is first created.

* Potential solution for a dedicated database connection for player events.

* Simple thread for player_events.  Likely there is a better way to do this.

* Add zone to qs communications for recordplayerevents

First pass of enabling zone to qs direct transport to allow for PlayerEvents to bypass world.

* Cleanup a linux compile issue

* Add augments to LOOT ITEM and DESTROY ITEM

* Add augments to ITEMCREATION, FORAGESUCCESS, FISHSUCCESS, DESTROYITEM, LOOTITEM, DROPPEDITEM, TRADERPURCHASE, TRADERSELL, GUILDTRIBUTEDONATE and cleaned up the naming convention of augments

* Formatting fixes

* Swap out GetNextTableId

* Statically load counter

* Add counter.clear() since the counter is static

* Upload optional QS conversion scripts

* Remove all qs_tables and code referencing them

* Update database.cpp

* Simplify ProcessBatchQueue

* Simplify PorcessBatchQueue

* Simplify event truncation

* Build event truncation to bulk query by retention groups

* Post rebase

* Update player_events.h

* Fix build

* Update npc.cpp

* First pass of direct zone to qs sending for player events

* Remove keepalive logic

* Fix event ordering

* Cleanup

* Update player_event_logs.cpp

* Wipe event data after ETL processed

* Split up database connections, hot reload logs for QS

* Load rules from database vs qs_database

* Update player_event_logs.cpp

* Hot toggle queryserv connect

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-05 02:02:16 -06:00
Fryguy 21d27a1122 [Fix] Big Bag Cleanup (#4643)
* [Bug] Big Bag Cleanup

- Fixed the Database Updates to properly check for the missing column
- Added the cursor slot overflow migration and drop - Only the first 200 overflow slots are migrated due to the destination buffer size shrinking from 1000 to 200. Anything over 200 is dropped (Generally just summoned food).
- Fixed a direct DB call in corpses to the inventory table with incorrect column names
- Fixed the Inventory Snapshot bidirectional queries to account for updated inventory table names.

* Accidently nuked a line.
2025-02-04 22:29:58 -06:00
nytmyr 6519fb40c7 [Bots] Sanity checks for spell type updates (#4641)
This isn't really necessary, but just in case anyone rolls back version or an error/crash happens during an update, it doesn't rerun these checks by returning false positives for the condition checks. Also validates most data from spells_new incase modifications were made..
2025-02-04 19:20:28 -06:00
nytmyr ff2763785c [Cleanup] Cleanup logic in cursor bag check (#4642)
* [Cleanup] Cleanup logic in cursor bag check

* oops
2025-02-04 17:16:34 -05:00
nytmyr f1852e16b7 [Inventory] Fix cursor bag saving to invalid slot_ids (#4640) 2025-02-04 01:36:07 -05:00
Alex King 49917bfb13 [Quest API] Add Potion Belt Methods (#4634)
* [Quest API] Add Potion Belt Methods

* Update client.h

* Cleanup

* Update client.h

* Constrain properly

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-03 19:37:46 -05:00
catapultam-habeo ff86cc3b8a [Crash] Fix zone crash caused by NPC::MoveTo (#4639) 2025-02-03 17:29:39 -06:00
Akkadius 91a0e14509 [Hotfix] Fix CI since hand-ins are merged 2025-02-03 16:57:46 -06:00
Chris Miles 6fb919a16f [Items] Overhaul Item Hand-in System (#4593)
* [Items] Overhaul Item Hand-in System

* Edge case lua fix

* Merge fix

* I'm going to be amazed if this works first try

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Update linux-build.sh

* Add protections against scripts that hand back items themselves

* Remove EVENT_ITEM_ScriptStopReturn

* test

* Update npc_handins.cpp

* Add Items:AlwaysReturnHandins

* Update spdat.cpp

* Bypass update prompt on CI
2025-02-03 16:51:09 -06:00
Alex King d1d6db3a09 [Feature] Implement Big Bags (#4606)
* [Feature] Implement "Big Bags"

* Update worlddb.cpp

* Update shareddb.cpp

* Cleanup

* Cleanup

* Add slot ID conversions

* Update shareddb.cpp

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update ruletypes.h

* Update database_update_manifest.cpp

* Inventory load fix

* Wrap Handle_OP_MoveItem in a transaction, taking 200+ queries from 200ms+ to 5-20ms

* Speed up lazy loading

* [Performance] Significantly Improve Client Network Resends

* Improve resend algorithm to be exact about when to resend

* Manifest merge

* Update database_update_manifest.cpp

* Post merge

* Add forced interactive update

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-03 16:14:41 -06:00
nytmyr e3ab90695f [Bots] Fix Bards not casting (#4638) 2025-02-03 15:40:04 -05:00
nytmyr aa423e398a [Hotfix] [Bots] Fix error in update manifest (#4637) 2025-02-03 14:00:51 -05:00
Alex King 1cf7709c9d [Quest API] Add Bandolier Methods (#4635) 2025-02-03 04:03:27 -06:00
nytmyr f466964db8 [Bots] Bot Overhaul (#4580)
* Implement spell AI pulling, fix throw stone

* more pull tweaks

* holding check at start of ai process

* fully implement ^pull logic to always return, can still be overidden by ^attack

* Rewrite ^pull logic and handling. **MORE**

Add ^setassistee command to set who your bots will assist. Bots will always assist you first before anyone else.

If the rule Bots, AllowCrossGroupRaidAssist is enabled bots will assist the group or raid main assists.

Rewrites logic in handling of pull and returning to ensure bots make it back to their location.

* Move HateLine to a better ID

* cleanup ST_Self logic in CastChecks

* Removed unused BotSpellTypeRequiresLoS

* Move fizzle message to define

* add timer checks to Idle/Engaged/Pursue CastCheck to early terminate

* Add back !IsBotNonSpellFighter() check to the different CastCheck

* Correct IsValidSpellRange

* Implement AAs and harmtouch/layonhands to ^cast --- fix IsValidSpellRange

* Add PetDamageShields and PetResistBuffs to IsPetBotSpellType()

* Add priorities to HateLine inserts for db update

* Remove SpellTypeRequiresCastChecks

* Add bot check to DetermineSpellTargets for IsIllusionSpell

* merge with previous

* Correct bot checks for ST_GroupClientAndPet

* Remove misc target_type checks

* Add lull/aelull to ^cast

* Add more checks for CommandedSubTypes::AETarget

* remove unneeded checks on IsValidSpellTypeBySpellID

* add to aelull

* rewrite GetCorrectSpellType

* Add IsBlockedBuff to CastChecks

* Add spellid option to ^cast to allow casting of a specific spell by ID

* ^cast adjustments for spellid casts

* Add missing alert round for ranged attacks

* More castcheck improvements

* CanUseBotSpell for ^cast

* remove ht/loh from attack ai

* remove SetCombatRoundForAlerts that triggered every engagement

* Add RangedAttackImmunity checks before trying to ranged attack

* move bot backstab to mob

* fix MinStatusToBypassCreateLimit

* more backstab to mob cleanup

* add bot checks to tryheadshot / tryassassinate

* adjust version number for bots

* add back m_mob_check_moving_timer, necessary?

* add sanity checks for classattacks

* Get rid of Bots:BotGroupXP and change logic to support Bots:SameRaidGroupForXP

Bots won't do anything if not in the same group so this should more accurately control only when in the same raid group.

* add "confirm" check to ^delete

* Update bot.cpp

* Remove `id` from bot_settings, correct types

* Implement blocked_buffs and blocked_pet_buffs

* more blocked buff tweaks

* add beneficial check to ^blockedbuffs

* command grammar

* missing )

* Move getnames for categories and settings to mob, rename hptomed/manatomed

* add GetBotSpellCategoryIDByShortName and CopyBotBlockedPetBuffs, update ^defaultsettings command

* cls cleanup

* Allow bots to clear HasProjectIllusion flag

* Add PercentChanceToCastGroupCure

* Implmenet PetCures, add some missing types for defaults/chance to cast

* Change GetRaidByBotName to GetRaidByBot

* Typo on PetBuffs implement

* Change GetSpellListSpellType to GetParentSpellType

* missing from GetChanceToCastBySpellType

* Fix performance in IsValidSpellRange by flipping HasProjectIllusion

* merge with prev

* merge with cls cleanup

* Reorder IsTargetAlreadyReceivingSpell/CheckSpellLevelRestriction/IsBlockedBuff

* Combine GatherGroupSpellTargets and GatherSpellTargets

* Cleanup IsTargetAlreadyReceivingSpell

* Fix ^petsettype to account for usable levels of spells and remove hardcoded level limits.

* Remove Bot_AICheckCloseBeneficialSpells and use AttemptCloseBeneficialSpells for better performance

* remove default hold for resist buffa

* move IsValidSpellRange further down castchecks

* raid optimizations

* correct name checking to match players

* more name checks and add proper soft deletes to bots

* organize some checks in IsImmuneToBotSpell

* Fix GetRaidByBotName and GetRaidByBot checks to not loop unnecessarily

* Move GatherSpellTargets to mob

* Change GetPrioritizedBotSpellsBySpellType to vector

Some slipped through in "organize some checks in IsImmuneToBotSpell"

* Move GatherSpellTargets and Raid to stored variables.

Missing some in "organize some checks in IsImmuneToBotSpell"

* comment out precheck, delays, thresholds, etc logging

missed some in "organize some checks in IsImmuneToBotSpell"

* Missing IsInGroupOrRaid cleanup

* Implement AIBot_spells_by_type to reduce looping when searching for spells

* Add _tempSpellType as placeholder for any future passthru

* todo

* Move bot_list from std::list to std::unordered_map like other entities

* Fix missing raid assignment for GetStoredRaid in IsInGroupOrRaid

* TempPet owned by bots that get the kill will now give exp like a client would

* Remove unnecessary checks in bot process (closescanmoving timer, verify raid, send hp/mana/end packet

* Fix client spell commands from saving the wrong setting

* Cleanup ^copysettings command and add new commands

* Add pet option to ^taunt

No longer has toggle, required on/off option and an optional "pet" option to control pets' taunting state

* Allow pet types to ^cast, prevent failure spam, add cure check

* more raid optimizations, should be final.

10 clients, 710 bots, 10 raids, ~250 pets sits around 3.5% CPU idle

* Move spell range check to proper location

* Implement ^discipline

* remove ^aggressive/^defensive

* remove this for a separate PR

* cleanup

* Add BotGroupSay method

* todo list

* Add missing bot_blocked_buffs to schema

* Remove plural on ^spelltypeidsand ^spelltypenames

* Move spelltype names, spell subtypes, category names and setting names to maps.

* move los checks to mob.cpp

* Bot CampAll fix

* Bots special_attacks.cpp fix

* Add zero check for bot spawn limits

If the spawn limit rule is set to 0 and spawn limit is set by bucket, if no class buckets are set, it defaults to the rule of 0 and renders the player unable to spawn bots.

This adds a check where if the rule and class bucket are 0, it will check for the spawn limit bucket

* Add HasSkill checks to bot special abilities (kick/bash/etc)

* code cleanup 1

* code cleanup 2

* code cleanup 3

* code cleanup 4

* fix ^cast wirh commanded types

* Remove bcspells, fix helper_send_usage_required_bots

* linux build fix

* remove completed todo

* Allow inventory give to specific ID slots

* Update TODO

* Correct slot ranges for inventorygive

* Add zone specific spawn limits and zone specific forced spawn limits

* remove bd. from update queries where it doesn't exist

* Rename _spellSettings to m_bot_spell_settings

* Add IsPetOwnerOfClientBot(), add Lua and Perl methods

* Make botOwnerCharacterID snakecase

* Throw bot_camp_timer behind Bots:Enabled rule

* Move various Bot<>Checks logging to BotSpellChecks

* Remove from LogCategoryName

* Consolidate IsInGroupOrRaid

* Consolidate GatherSpellTargets

* Add missing Bot Spell Type Checks to log

* Add GetParentSpellType when checking spelltypes for idle, engaged, pursue CastChecks.

* Consolidate AttemptForcedCastSpell

* Consolidate SetBotBlockedBuff/SetBotBlockedPetBuff

* Add list option to ^spellpriority commands.

* Move client functions to client_bot

* Move mob functions to mob_bot

* Move bot spdat functions to spdat_bot

* Move SendCommandHelpWindow to SendBotCommandHelpWindow and simplify

* Change char_id to character_id for bot_settings

* update todo

* Fix typo on merge conflict

* Cleanup command format changes, remove hardcoded class IDs in examples.

* Set #illusionblock for players to guide access

* Move client commands for bot spells from gm commands to existing bot commands

* Fix alignment issues

* More alignment fixes

* More cleanup 1

* More cleanup 2

* Fix BotMeditate to med at proper percentages

* Correct GetStopMeleeLevel checks for some buff checks

* Add back hpmanaend update to bot raid, force timer update to prevent spamming

* Remove log

* Cleanup ranged and ammo calculations - Adds throwing check for match

* Add check in distance calculations to stay at range if set even if no ammo or ranged

* Move melee distance calculations to better function

* Add GetBuffTargets helper

* Missing p_item, s_item in CombatRangeInput

* Linux test?

* Reduce GetCorrectBotSpellType branching slightly

This is still an ugly ass function but my brain is melted

* Line fixes

* Make bot pets only do half damage in pvp

* Add bot pet pvp damage to tune

* Add bot pet check for AIYellForHelp

* Add bots to UseSpellImpliedTargeting

* Move toggleranged, togglehelm and illusionblock to new help window. Add actionable support

* Add bot and bot pet checks to various spells, auras and targeting checks that were missing.

* update todo

* New lines

* Correct DoLosChecks

* Remove Log TestDebug

* Remove _Struct from struct declarations

* Add bot check to IsAttackAllowed for GetUltimateOwner to skip entity list where possible

* Wrap SaveBotSettings in Bots Enabled check

* Remove comment

* Wrap bot setting loading for clients in bots enabled rule

* Cleanup BlockedBuffs logic in SpellOnTarget

* Rename BotSpells_Struct/BotSpells_Struct_wIndex

* Rename spawn/create status bypass rules, fix return for spawn limit

* Remove unnecessary return in CanBuffStack, cleanup

* Enable recastdelay support for clients

* Remove unused variables

* Rename _assistee to bot_assistee

* hardcode BotCommandHelpWindow colors

* todo

* Fix ^cast summoncorpse

* todo

* Reimplement secondary colors to BotSendCommandHelpWindow

* Give ^copysettings/^defaultsettings more options, cleanup.

* Cleanup some commands

* Add comment to CheckLosCheat/CheckLosCheatExempt

* Make struct BotSpellSettings snake case

* Allow duplicate casts of same spell on target for heals and cures

* Add default delay to cures

* Remove unused methods

* Implement missing ^spellresistlimits/^resistlimits command

* Move functions out of mob.h and cleanup

* Return for GetRawBotList

This checks offline bots too

* Rename BotGroupSay to RaidGroupSay

* Prevent bots from forming their own group if a bot that is a group leader is removed from the raid

* Linux fix?

* IsPetOwner fixes

* Add remove option to list for ^blockedbuffs / ^blockedpetbuffs

* Implement ^spellannouncecasts to toggle announcing casts of spell types

* Remove rule Bots:BardsAnnounceCasts

* Update bot.h

* Remove unused no_pets option from GatherSpellTargets

* Move ^attack response back to normal chat window (other)

* Set lower limit of spell delays to 100 rather than 1

* Correct pet checks on GetUltimateSpell functions

* Add rules (Bots, AICastSpellTypeDelay, Bots, AICastSpellTypeHeldDelay) to prevent spamming of failed spell type AI casts

* Correct pet buff type logic to catch DS/Resists with other spell effects in them

* Fix defaults for clients

* Add more logic for necros/shaman for default heal thresholds due to lich and canni

* Rename SpellHold, SpellDelay, SpellMinThreshold, SpellMaxThreshold, SpellRecastDelay to fit SpellType style naming

* Use GetTempSpellType() for announce check in RaidGroupSay

* Make all spell shortnames plural where applicable

* Update bot.cpp

* Bots:BotsUseLiveBlockedMessage filter to spell failure

* Move GetSpellTargetList to only get called when necessary to reduce overhead

* formatting

* Formatting

* Simplify case SE_Illusion and SE_IllusionCopy for GetIllusionBlock

* Clean up InterruptSpell

* Cleanup IsBot() checks for DetermineSpellTargets->ST_GroupClientAndPet

* Cleanup range/aoe_range check in SpellFinished

* Cleanup DetermineSpellTargets->ST_GroupNoPets

* Cleanup DetermineSpellTargets->ST_Self for bot summon corpse

* Cleanup DetermineSpellTargets->ST_Pet

* Cleanup bot logic in TryBackstab

* Cleanup IsAttackAllowed checks for bots and their pets

* Cleanup StopMoving for bots

* Cleanup CanThisClassTripleAttack

* Fix casting for GetIllusionBlock checks

* Formatting

* Fix DetermineSpellTargets for group spells (this also wasn't properly checking the rule Character:EnableTGB in master)

* Cleanup spelltarget grabbing logic, consolidate group heals in to GetNumberNeedingHealedInGroup

* Throw added client los pet checks behind LoS cheat rule for bots

* CLeanup give_exp on npc death logic and ensure client pets always pass.

* Undo unintended rename from previous refactor

* Remove pointless Bots, SameRaidGroupForXP rule

* Revision to 0690783a9d

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-02-03 04:02:42 -06:00
Chris Miles 4fda3c045e [Release] 22.62.2 (#4633) 2025-02-01 16:25:53 -06:00
Mitch Freeman 0a20100d12 [Fix] Add price change check to the Bazaar Search Window purchase mechanics (#4632) 2025-02-01 14:30:07 -06:00
Mitch Freeman 29701d0ea7 [Fix] Update the shard bazaar search feature (#4630) 2025-02-01 13:36:26 -06:00
Mitch Freeman 4a38fd8829 [Fix] NewBazaar Search Consumables (#4631) 2025-02-01 13:35:08 -06:00
Chris Miles 08c8e0d81f [Performance] Significantly Improve Client Network Resends (#4629)
* [Performance] Significantly Improve Client Network Resends

* Update daybreak_connection.cpp

* Improve resend algorithm to be exact about when to resend
2025-01-31 22:23:08 -06:00
Chris Miles c966f26ac1 [Release] 22.62.1 (#4627) 2025-01-27 16:36:51 -06:00
Akkadius fe66c24352 Revert "[Memory Leak] Change raw pointer to unique_ptr to avoid potential leak in dbg stream (#4616)"
This reverts commit 1f3ac2dc4f.
2025-01-27 16:34:05 -06:00
Chris Miles bdcded7d45 [Performance] Re-use OP_PlayerStateAdd packet memory (#4626) 2025-01-27 15:33:03 -06:00
Chris Miles f939f25aa1 [Performance] Re-use OP_Damage packet memory (#4625) 2025-01-27 15:32:55 -06:00
Chris Miles 401f1038f3 [Performance] Re-use OP_SendFindableNPCs packet memory (#4623) 2025-01-27 15:32:48 -06:00
Chris Miles 95c6560e7c [Performance] Re-use OP_HPUpdate packet memory (#4622) 2025-01-27 15:32:40 -06:00
Chris Miles 59f645b5c3 [Performance] Re-use OP_Animation packet (#4621) 2025-01-27 15:32:30 -06:00
Chris Miles bbfed8300c [Repop] Make #repop instant (#4620) 2025-01-27 15:32:22 -06:00
Chris Miles 07c762068f [Performance] Re-use ClientUpdate packet memory (#4619) 2025-01-27 15:32:14 -06:00
dependabot[bot] 6525051d2d Bump golang.org/x/net in /utils/scripts/build/should-release (#4618)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.23.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.23.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-26 21:28:40 -06:00
Chris Miles b7f94e8315 [Release] 22.62.0 (#4617) 2025-01-26 21:26:34 -06:00
Chris Miles d1f368ab7f [Databuckets] Implement Nested Databuckets (#4604)
* WIP

* Fixes

* Fin

* Update data_bucket.cpp

* Update data_bucket.cpp

* Cleanup

* Update data_bucket.cpp

* Update data_bucket.cpp

* NESTED_KEY_DELIMITER
2025-01-26 21:13:31 -06:00
Alex 1f3ac2dc4f [Memory Leak] Change raw pointer to unique_ptr to avoid potential leak in dbg stream (#4616)
Co-authored-by: KimLS <KimLS@peqtgc.com>
2025-01-26 19:05:45 -06:00
Mitch Freeman 7a226ca4ef [Bazaar] Improve Bazaar Search Performance (#4615)
* Create Alternate BazaarSearch Routine

Establishes an alterative to the in memory bazaar search routine and instead uses a db query process.  For large Bazaars (with 1000s of items) this is much faster.  Testing with 30k items produced a search in ~1sec version 2.7sec for the in memory version.
Default is false - Do not use this version.

* Indexes for trader and items

* Set query-based bazaar search the default

* Update database_update_manifest.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2025-01-26 19:04:56 -06:00
427 changed files with 50188 additions and 27362 deletions
+317
View File
@@ -1,3 +1,320 @@
## [23.1.0] 3/1/2025
### Bots
* Fix unresponsive bots in groups upon group wipe ([#4712](https://github.com/EQEmu/Server/pull/4712)) @nytmyr 2025-02-28
### Code
* More login <-> world code cleanup ([#4724](https://github.com/EQEmu/Server/pull/4724)) @Akkadius 2025-02-28
### Crash
* Check for directory existence before traversing in CheckForCompatibleQuestPlugins ([#4730](https://github.com/EQEmu/Server/pull/4730)) @Akkadius 2025-03-02
* Fix filesystem crash / exception in DatabaseDumpService::RemoveCredentialsFile() ([#4731](https://github.com/EQEmu/Server/pull/4731)) @Akkadius 2025-03-01
* Fix large file size crash in File::GetContents for windows ([#4735](https://github.com/EQEmu/Server/pull/4735)) @Akkadius 2025-03-02
* Fix reload concurrency crash when ran from Spire ([#4733](https://github.com/EQEmu/Server/pull/4733)) @Akkadius 2025-03-02
* Validate item in SE_SummonItemIntoBag ([#4734](https://github.com/EQEmu/Server/pull/4734)) @Akkadius 2025-03-02
* World CLI validation ([#4728](https://github.com/EQEmu/Server/pull/4728)) @Akkadius 2025-03-01
### Database
* Remove force_interactive from big bag updates ([#4727](https://github.com/EQEmu/Server/pull/4727)) @Akkadius 2025-03-01
### Feature
* Add a rule for spells to bypass stacking rules ([#4716](https://github.com/EQEmu/Server/pull/4716)) @catapultam-habeo 2025-02-28
* Evolving items Additions ([#4725](https://github.com/EQEmu/Server/pull/4725)) @neckkola 2025-03-01
### Fixes
* Add character_pet_name to player tables schema @Akkadius 2025-03-02
* Add client packets to questmanager:setguild ([#4732](https://github.com/EQEmu/Server/pull/4732)) @neckkola 2025-03-01
* Clear m_completed_shared_tasks before reloading @Akkadius 2025-02-24
* Fix AA Reset Error Message ([#4720](https://github.com/EQEmu/Server/pull/4720)) @Kinglykrab 2025-02-28
* Fix Issue with Suffixes/Prefixes ([#4723](https://github.com/EQEmu/Server/pull/4723)) @Kinglykrab 2025-02-28
* Fix Trading Items to Bot Pets ([#4721](https://github.com/EQEmu/Server/pull/4721)) @MortimerGreenwald 2025-02-28
* Refactor ApplyItemBonuses to fix double-counting of ATK and recommended levels not correctly applying ([#4713](https://github.com/EQEmu/Server/pull/4713)) @catapultam-habeo 2025-03-01
### Loginserver
* Minor cleanup ([#4729](https://github.com/EQEmu/Server/pull/4729)) @Akkadius 2025-03-01
### Quest API
* Add Key Ring Methods to Perl and Lua ([#4719](https://github.com/EQEmu/Server/pull/4719)) @Kinglykrab 2025-02-28
* Implement eq.handin() and quest::handin() ([#4718](https://github.com/EQEmu/Server/pull/4718)) @Akkadius 2025-02-28
### Tasks
* Extend IsTaskCompleted to also be aware of shared task completion ([#4714](https://github.com/EQEmu/Server/pull/4714)) @Akkadius 2025-02-24
### Zone
* Implement Zone State Saving on Shutdown ([#4715](https://github.com/EQEmu/Server/pull/4715)) @Akkadius 2025-02-28
### Zone State
* Wrap all serialization/deserialization in try/catch ([#4726](https://github.com/EQEmu/Server/pull/4726)) @Akkadius 2025-03-01
## [23.0.2] 2/21/2025
### Bots
* Add checks to ensure bots and pets do not engage on ^pull ([#4708](https://github.com/EQEmu/Server/pull/4708)) @nytmyr 2025-02-22
* Improve positioning ([#4709](https://github.com/EQEmu/Server/pull/4709)) @nytmyr 2025-02-22
* Prevent medding in combat if any mob has bot targeted ([#4707](https://github.com/EQEmu/Server/pull/4707)) @nytmyr 2025-02-22
### Client Mod
* Adds a hacked fast camp rule for GMs ([#4697](https://github.com/EQEmu/Server/pull/4697)) @KimLS 2025-02-20
### Fixes
* Fix Lua Zone ID Exports ([#4700](https://github.com/EQEmu/Server/pull/4700)) @Kinglykrab 2025-02-22
* Fix bad Mob reference in QuestManager::resumetimer() ([#4710](https://github.com/EQEmu/Server/pull/4710)) @zimp-wow 2025-02-22
* Fix cursor load on zone ([#4704](https://github.com/EQEmu/Server/pull/4704)) @nytmyr 2025-02-22
* Fix infinite loop in QuestManager::stoptimer() ([#4703](https://github.com/EQEmu/Server/pull/4703)) @zimp-wow 2025-02-21
### Quest API
* Add GetSpawn() to Perl and Lua ([#4702](https://github.com/EQEmu/Server/pull/4702)) @Kinglykrab 2025-02-22
## [23.0.1] 2/20/2025
### Fixes
* Player event ordering merge fix ([#4699](https://github.com/EQEmu/Server/pull/4699)) @Akkadius 2025-02-20
### Quest API
* Add DisableRespawnTimers to Perl and Lua ([#4691](https://github.com/EQEmu/Server/pull/4691)) @Kinglykrab 2025-02-20
## [23.0.0] 2/19/2025
### Bots
* Add AEHateLine to HateLine ParentType ([#4678](https://github.com/EQEmu/Server/pull/4678)) @nytmyr 2025-02-15
* Add IsInRaidOrGroup checks to ^attack and ^pull ([#4654](https://github.com/EQEmu/Server/pull/4654)) @nytmyr 2025-02-07
* Add missing stance options ([#4681](https://github.com/EQEmu/Server/pull/4681)) @nytmyr 2025-02-15
* Bot Overhaul ([#4580](https://github.com/EQEmu/Server/pull/4580)) @nytmyr 2025-02-03
* Command Cleanup ([#4676](https://github.com/EQEmu/Server/pull/4676)) @nytmyr 2025-02-15
* Correct camp count on ^camp ([#4650](https://github.com/EQEmu/Server/pull/4650)) @nytmyr 2025-02-06
* Correct helper message for forced casts ([#4656](https://github.com/EQEmu/Server/pull/4656)) @nytmyr 2025-02-07
* Crash fixes related to GetNumberNeedingHealedInGroup ([#4684](https://github.com/EQEmu/Server/pull/4684)) @nytmyr 2025-02-15
* Fix AE range calculation ([#4683](https://github.com/EQEmu/Server/pull/4683)) @nytmyr 2025-02-15
* Fix Bards not casting ([#4638](https://github.com/EQEmu/Server/pull/4638)) @nytmyr 2025-02-03
* Fix a couple potential crashes with GetNumberNeedingHealedInGroup ([#4652](https://github.com/EQEmu/Server/pull/4652)) @nytmyr 2025-02-07
* Fix crash related to GetTempSpellType() ([#4649](https://github.com/EQEmu/Server/pull/4649)) @nytmyr 2025-02-06
* Fix pets causing aggro ([#4677](https://github.com/EQEmu/Server/pull/4677)) @nytmyr 2025-02-15
* Fix spell priority commands ([#4660](https://github.com/EQEmu/Server/pull/4660)) @nytmyr 2025-02-08
* Fix typo in positioning ([#4659](https://github.com/EQEmu/Server/pull/4659)) @nytmyr 2025-02-08
* Move BotGetSpellsByType to cache ([#4655](https://github.com/EQEmu/Server/pull/4655)) @nytmyr 2025-02-07
* Prevents casting on ineligible targets due to target type, stacking, etc. ([#4680](https://github.com/EQEmu/Server/pull/4680)) @nytmyr 2025-02-15
* Sanity checks for spell type updates ([#4641](https://github.com/EQEmu/Server/pull/4641)) @nytmyr 2025-02-05
### Bug
* Item Purchase Offset when multiple buyers are buying at the same time. ([#4628](https://github.com/EQEmu/Server/pull/4628)) @fryguy503 2025-02-06
### CI
* Fix database race condition ([#4646](https://github.com/EQEmu/Server/pull/4646)) @Akkadius 2025-02-06
### Client Mod
* Adds a hacked fast camp rule for GMs ([#4697](https://github.com/EQEmu/Server/pull/4697)) @KimLS 2025-02-20
### Code
* Bot RaidGroupSay ([#4653](https://github.com/EQEmu/Server/pull/4653)) @nytmyr 2025-02-07
* Cleanup logic in cursor bag check ([#4642](https://github.com/EQEmu/Server/pull/4642)) @nytmyr 2025-02-04
* Use Repositories for Titles ([#4608](https://github.com/EQEmu/Server/pull/4608)) @Kinglykrab 2025-02-07
### Commands
* Fix #goto not accepting proper heading ([#4685](https://github.com/EQEmu/Server/pull/4685)) @nytmyr 2025-02-15
* Fix Illusion Block ([#4666](https://github.com/EQEmu/Server/pull/4666)) @nytmyr 2025-02-12
### Crash
* Fix raid/group crash regression ([#4671](https://github.com/EQEmu/Server/pull/4671)) @Akkadius 2025-02-12
* Fix zone crash caused by NPC::MoveTo ([#4639](https://github.com/EQEmu/Server/pull/4639)) @catapultam-habeo 2025-02-03
### Databuckets
* Add Zone Scoped Databuckets ([#4690](https://github.com/EQEmu/Server/pull/4690)) @Akkadius 2025-02-18
### Expeditions
* Move expedition code into DynamicZone ([#4672](https://github.com/EQEmu/Server/pull/4672)) @hgtw 2025-02-16
### Feature
* Add Support for Tradeskill Recipe Inspect ([#4648](https://github.com/EQEmu/Server/pull/4648)) @Kinglykrab 2025-02-06
* Add rule to allow /changepetname to function without being enabled by scripts. @catapultam-habeo 2025-02-05
* GuildBank Updates ([#4674](https://github.com/EQEmu/Server/pull/4674)) @neckkola 2025-02-15
* Implement Big Bags ([#4606](https://github.com/EQEmu/Server/pull/4606)) @Kinglykrab 2025-02-03
### Fixes
* #rq and #reload quest alias ([#4694](https://github.com/EQEmu/Server/pull/4694)) @Akkadius 2025-02-18
* Always spawn zone controller first ([#4669](https://github.com/EQEmu/Server/pull/4669)) @Akkadius 2025-02-12
* Big Bag Cleanup ([#4643](https://github.com/EQEmu/Server/pull/4643)) @fryguy503 2025-02-05
* Big Bag additional fixes ([#4644](https://github.com/EQEmu/Server/pull/4644)) @fryguy503 2025-02-05
* Change logging level for no items found in a bazaar search to reduce spam logs. ([#4675](https://github.com/EQEmu/Server/pull/4675)) @neckkola 2025-02-13
* Find Zone - Expansion Settings ([#4692](https://github.com/EQEmu/Server/pull/4692)) @MortimerGreenwald 2025-02-18
* Fix Beastlord Warder Size Modifier ([#4665](https://github.com/EQEmu/Server/pull/4665)) @Kinglykrab 2025-02-12
* Fix CI since hand-ins are merged @Akkadius 2025-02-03
* Fix Illusion Fade Texture Bug ([#4673](https://github.com/EQEmu/Server/pull/4673)) @Kinglykrab 2025-02-14
* Fix Item Discovery ([#4663](https://github.com/EQEmu/Server/pull/4663)) @Kinglykrab 2025-02-10
* Fix ST_GroupNoPets and ST_GroupClientAndPet ([#4667](https://github.com/EQEmu/Server/pull/4667)) @nytmyr 2025-02-10
* Fix SendStatsWindow Mod2 Value Display ([#4658](https://github.com/EQEmu/Server/pull/4658)) @Kinglykrab 2025-02-07
* Fix Tradeskill Queries ([#4661](https://github.com/EQEmu/Server/pull/4661)) @Kinglykrab 2025-02-09
* Fix error in update manifest ([#4637](https://github.com/EQEmu/Server/pull/4637)) @nytmyr 2025-02-03
* Fix issue with getting an unset nested databucket ([#4693](https://github.com/EQEmu/Server/pull/4693)) @Akkadius 2025-02-19
* Fix non-error in player_event_logs ([#4695](https://github.com/EQEmu/Server/pull/4695)) @Akkadius 2025-02-18
* GMMove Update Edge Case With Clients ([#4686](https://github.com/EQEmu/Server/pull/4686)) @Akkadius 2025-02-15
* Item Handins to Pets ([#4687](https://github.com/EQEmu/Server/pull/4687)) @Akkadius 2025-02-15
* Parcel Delivery Updates ([#4688](https://github.com/EQEmu/Server/pull/4688)) @neckkola 2025-02-16
* Prevent zone from loading ETL ID's on bootup ([#4696](https://github.com/EQEmu/Server/pull/4696)) @Akkadius 2025-02-18
* Update pre big bag corpse slot_id's to support big bags ([#4679](https://github.com/EQEmu/Server/pull/4679)) @nytmyr 2025-02-15
### Inventory
* Fix cursor bag saving to invalid slot_ids ([#4640](https://github.com/EQEmu/Server/pull/4640)) @nytmyr 2025-02-04
### Items
* Overhaul Item Hand-in System ([#4593](https://github.com/EQEmu/Server/pull/4593)) @Akkadius 2025-02-03
### Loginserver
* Fix iterator crash ([#4670](https://github.com/EQEmu/Server/pull/4670)) @Akkadius 2025-02-12
* Modernize codebase ([#4647](https://github.com/EQEmu/Server/pull/4647)) @Akkadius 2025-02-06
### NPC Handins
* Fix MultiQuest Handins ([#4651](https://github.com/EQEmu/Server/pull/4651)) @Akkadius 2025-02-07
### Performance
* Server Reload Overhaul ([#4689](https://github.com/EQEmu/Server/pull/4689)) @Akkadius 2025-02-18
### Player Event Logs
* Migrate and Deprecate QS Legacy Logging ([#4542](https://github.com/EQEmu/Server/pull/4542)) @neckkola 2025-02-05
### Quest API
* Add Bandolier Methods ([#4635](https://github.com/EQEmu/Server/pull/4635)) @Kinglykrab 2025-02-03
* Add Potion Belt Methods ([#4634](https://github.com/EQEmu/Server/pull/4634)) @Kinglykrab 2025-02-04
* Add Zone Support to Perl and Lua ([#4662](https://github.com/EQEmu/Server/pull/4662)) @Kinglykrab 2025-02-09
### Spells
* Add all types to checks for max_targets_allowed rule for AEs ([#4682](https://github.com/EQEmu/Server/pull/4682)) @nytmyr 2025-02-15
## [22.62.2] 2/1/2025
### Fixes
* Add price change check to the Bazaar Search Window purchase mechanics ([#4632](https://github.com/EQEmu/Server/pull/4632)) @neckkola 2025-02-01
* NewBazaar Search Consumables ([#4631](https://github.com/EQEmu/Server/pull/4631)) @neckkola 2025-02-01
* Update the shard bazaar search feature ([#4630](https://github.com/EQEmu/Server/pull/4630)) @neckkola 2025-02-01
### Memory Leak
* Revert " Change raw pointer to unique_ptr to avoid potential leak in dbg stream " ([#4616](https://github.com/EQEmu/Server/pull/4616)) @Akkadius 2025-01-27
### Performance
* Significantly Improve Client Network Resends ([#4629](https://github.com/EQEmu/Server/pull/4629)) @Akkadius 2025-02-01
## [22.62.1] 1/27/2025
### Memory Leak
* Revert "Change raw pointer to unique_ptr to avoid potential leak in dbg stream" ([#4616](https://github.com/EQEmu/Server/pull/4616)) @Akkadius 2025-01-27
### Performance
* Re-use ClientUpdate packet memory ([#4619](https://github.com/EQEmu/Server/pull/4619)) @Akkadius 2025-01-27
* Re-use OP_Animation packet ([#4621](https://github.com/EQEmu/Server/pull/4621)) @Akkadius 2025-01-27
* Re-use OP_Damage packet memory ([#4625](https://github.com/EQEmu/Server/pull/4625)) @Akkadius 2025-01-27
* Re-use OP_HPUpdate packet memory ([#4622](https://github.com/EQEmu/Server/pull/4622)) @Akkadius 2025-01-27
* Re-use OP_PlayerStateAdd packet memory ([#4626](https://github.com/EQEmu/Server/pull/4626)) @Akkadius 2025-01-27
* Re-use OP_SendFindableNPCs packet memory ([#4623](https://github.com/EQEmu/Server/pull/4623)) @Akkadius 2025-01-27
### Repop
* Make #repop instant ([#4620](https://github.com/EQEmu/Server/pull/4620)) @Akkadius 2025-01-27
## [22.62.0] 1/26/2025
### Bazaar
* Improve Bazaar Search Performance ([#4615](https://github.com/EQEmu/Server/pull/4615)) @neckkola 2025-01-27
### CLI
* Add --skip-backup to world database:updates ([#4605](https://github.com/EQEmu/Server/pull/4605)) @Akkadius 2025-01-22
### Database
* Change npc_types walkspeed to be of type float ([#4589](https://github.com/EQEmu/Server/pull/4589)) @Akkadius 2025-01-07
### Databuckets
* Add Account Scoped Databuckets ([#4603](https://github.com/EQEmu/Server/pull/4603)) @Akkadius 2025-01-21
* Implement Nested Databuckets ([#4604](https://github.com/EQEmu/Server/pull/4604)) @Akkadius 2025-01-27
### Feature
* Add Alternate Bazaar Search Approach ([#4600](https://github.com/EQEmu/Server/pull/4600)) @neckkola 2025-01-20
* Add Support for Item Previews ([#4599](https://github.com/EQEmu/Server/pull/4599)) @Kinglykrab 2025-01-20
* Evolving Item Support for RoF2 ([#4496](https://github.com/EQEmu/Server/pull/4496)) @neckkola 2025-01-20
* Implement Custom Pet Names ([#4594](https://github.com/EQEmu/Server/pull/4594)) @catapultam-habeo 2025-01-22
### Fixes
* Add Bazaar BulkSendTrader Limit for RoF2 ([#4590](https://github.com/EQEmu/Server/pull/4590)) @neckkola 2025-01-08
* CLI help menu from parsing correctly in World @Akkadius 2025-01-22
* Delete later in RemoveItem second case @Akkadius 2025-01-25
* Fix query error in character_evolving_items @Akkadius 2025-01-21
* Repair a memory leak in #summonitem ([#4591](https://github.com/EQEmu/Server/pull/4591)) @neckkola 2025-01-08
* Repair an incorrect safe_delete call memory leak. ([#4588](https://github.com/EQEmu/Server/pull/4588)) @neckkola 2025-01-07
* Repair levers opening the Evolving XP Transfer Window ([#4607](https://github.com/EQEmu/Server/pull/4607)) @neckkola 2025-01-23
* Update a few Bazaar RoF2 routines for memory leaks ([#4592](https://github.com/EQEmu/Server/pull/4592)) @neckkola 2025-01-08
* Update database version to match manifest @Akkadius 2025-01-21
* Update trader add/remove packets to limits for RoF2 ([#4595](https://github.com/EQEmu/Server/pull/4595)) @neckkola 2025-01-19
### Linux
* Implement KSM Kernel Samepage Merging with Maps ([#4601](https://github.com/EQEmu/Server/pull/4601)) @Akkadius 2025-01-21
### Memory Leak
* Change raw pointer to unique_ptr to avoid potential leak in dbg stream ([#4616](https://github.com/EQEmu/Server/pull/4616)) @KimLS 2025-01-27
* Fix leak in BuyTraderItemOutsideBazaar ([#4609](https://github.com/EQEmu/Server/pull/4609)) @Akkadius 2025-01-24
* Fix leak in Client::RemoveDuplicateLore ([#4614](https://github.com/EQEmu/Server/pull/4614)) @Akkadius 2025-01-24
* Fix leak in NPC::RemoveItem ([#4611](https://github.com/EQEmu/Server/pull/4611)) @Akkadius 2025-01-24
* Fix leak in QuestManager::varlink ([#4610](https://github.com/EQEmu/Server/pull/4610)) @Akkadius 2025-01-24
* Fix leaks in Client::Handle_OP_AugmentItem ([#4612](https://github.com/EQEmu/Server/pull/4612)) @Akkadius 2025-01-24
* Fix memory leak in Client::Handle_OP_MoveMultipleItems ([#4613](https://github.com/EQEmu/Server/pull/4613)) @Akkadius 2025-01-24
### Performance
* Client / NPC Position Update Optimizations ([#4602](https://github.com/EQEmu/Server/pull/4602)) @Akkadius 2025-01-21
### Quest API
* Add SetAAEXPPercentage to Perl/Lua ([#4597](https://github.com/EQEmu/Server/pull/4597)) @Kinglykrab 2025-01-19
### Zone
* Implement zone player count sharding ([#4536](https://github.com/EQEmu/Server/pull/4536)) @Akkadius 2025-01-08
## [22.61.0] 1/6/2025
### Bots
+30 -6
View File
@@ -22,6 +22,7 @@ SET(common_sources
dbcore.cpp
deity.cpp
dynamic_zone_base.cpp
dynamic_zone_lockout.cpp
emu_constants.cpp
emu_limits.cpp
emu_opcodes.cpp
@@ -40,7 +41,6 @@ SET(common_sources
events/player_event_logs.cpp
events/player_event_discord_formatter.cpp
evolving_items.cpp
expedition_lockout_timer.cpp
extprofile.cpp
discord/discord_manager.cpp
faction.cpp
@@ -89,6 +89,7 @@ SET(common_sources
skills.cpp
skill_caps.cpp
spdat.cpp
spdat_bot.cpp
strings.cpp
struct_strategy.cpp
textures.cpp
@@ -212,10 +213,9 @@ SET(repositories
repositories/base/base_discovered_items_repository.h
repositories/base/base_doors_repository.h
repositories/base/base_dynamic_zones_repository.h
repositories/base/base_dynamic_zone_lockouts_repository.h
repositories/base/base_dynamic_zone_members_repository.h
repositories/base/base_dynamic_zone_templates_repository.h
repositories/base/base_expeditions_repository.h
repositories/base/base_expedition_lockouts_repository.h
repositories/base/base_faction_association_repository.h
repositories/base/base_faction_base_data_repository.h
repositories/base/base_faction_list_repository.h
@@ -281,8 +281,20 @@ SET(repositories
repositories/base/base_pets_equipmentset_repository.h
repositories/base/base_pets_equipmentset_entries_repository.h
repositories/base/base_player_titlesets_repository.h
repositories/base/base_player_event_aa_purchase_repository.h
repositories/base/base_player_event_killed_npc_repository.h
repositories/base/base_player_event_killed_named_npc_repository.h
repositories/base/base_player_event_killed_raid_npc_repository.h
repositories/base/base_player_event_log_settings_repository.h
repositories/base/base_player_event_logs_repository.h
repositories/base/base_player_event_loot_items_repository.h
repositories/base/base_player_event_merchant_purchase_repository.h
repositories/base/base_player_event_merchant_sell_repository.h
repositories/base/base_player_event_npc_handin_repository.h
repositories/base/base_player_event_npc_handin_entries_repository.h
repositories/base/base_player_event_speech_repository.h
repositories/base/base_player_event_trade_repository.h
repositories/base/base_player_event_trade_entries_repository.h
repositories/base/base_quest_globals_repository.h
repositories/base/base_raid_details_repository.h
repositories/base/base_raid_members_repository.h
@@ -397,10 +409,9 @@ SET(repositories
repositories/discovered_items_repository.h
repositories/doors_repository.h
repositories/dynamic_zones_repository.h
repositories/dynamic_zone_lockouts_repository.h
repositories/dynamic_zone_members_repository.h
repositories/dynamic_zone_templates_repository.h
repositories/expeditions_repository.h
repositories/expedition_lockouts_repository.h
repositories/faction_association_repository.h
repositories/faction_base_data_repository.h
repositories/faction_list_repository.h
@@ -466,8 +477,20 @@ SET(repositories
repositories/pets_equipmentset_repository.h
repositories/pets_equipmentset_entries_repository.h
repositories/player_titlesets_repository.h
repositories/player_event_aa_purchase_repository.h
repositories/player_event_killed_npc_repository.h
repositories/player_event_killed_named_npc_repository.h
repositories/player_event_killed_raid_npc_repository.h
repositories/player_event_log_settings_repository.h
repositories/player_event_logs_repository.h
repositories/player_event_loot_items_repository.h
repositories/player_event_merchant_purchase_repository.h
repositories/player_event_merchant_sell_repository.h
repositories/player_event_npc_handin_repository.h
repositories/player_event_npc_handin_entries_repository.h
repositories/player_event_speech_repository.h
repositories/player_event_trade_repository.h
repositories/player_event_trade_entries_repository.h
repositories/quest_globals_repository.h
repositories/raid_details_repository.h
repositories/raid_members_repository.h
@@ -536,6 +559,7 @@ SET(common_headers
discord/discord.h
discord/discord_manager.h
dynamic_zone_base.h
dynamic_zone_lockout.h
emu_constants.h
emu_limits.h
emu_opcodes.h
@@ -562,7 +586,6 @@ SET(common_headers
events/player_events.h
event_sub.h
evolving_items.h
expedition_lockout_timer.h
extprofile.h
faction.h
file.h
@@ -622,6 +645,7 @@ SET(common_headers
server_event_scheduler.h
serverinfo.h
servertalk.h
server_reload_types.h
shared_tasks.h
shareddb.h
skills.h
+230 -288
View File
@@ -6,7 +6,8 @@
std::vector<BazaarSearchResultsFromDB_Struct>
Bazaar::GetSearchResults(
SharedDatabase &db,
Database &db,
Database &content_db,
BazaarSearchCriteria_Struct search,
uint32 char_zone_id,
int32 char_zone_instance_id
@@ -31,8 +32,132 @@ Bazaar::GetSearchResults(
char_zone_instance_id
);
static std::map<uint8, uint32> item_slot_searches_new = {
{EQ::invslot::slotCharm, 1},
{EQ::invslot::slotEar1, 2},
{EQ::invslot::slotHead, 4},
{EQ::invslot::slotFace, 8},
{EQ::invslot::slotEar2, 16},
{EQ::invslot::slotNeck, 32},
{EQ::invslot::slotShoulders, 64},
{EQ::invslot::slotArms, 128},
{EQ::invslot::slotBack, 256},
{EQ::invslot::slotWrist1, 512},
{EQ::invslot::slotWrist2, 1024},
{EQ::invslot::slotRange, 2048},
{EQ::invslot::slotHands, 4096},
{EQ::invslot::slotPrimary, 8192},
{EQ::invslot::slotSecondary, 16384},
{EQ::invslot::slotFinger1, 32768},
{EQ::invslot::slotFinger2, 65536},
{EQ::invslot::slotChest, 131072},
{EQ::invslot::slotLegs, 262144},
{EQ::invslot::slotFeet, 524288},
{EQ::invslot::slotWaist, 1048576},
{EQ::invslot::slotPowerSource, 2097152},
{EQ::invslot::slotAmmo, 4194304},
};
struct ItemSearchType {
EQ::item::ItemType type;
std::string condition;
};
std::vector<ItemSearchType> item_search_types_new = {
{EQ::item::ItemType::ItemTypeBook, " AND (items.itemclass = 2 or items.itemclass = 31)"},
{EQ::item::ItemType::ItemTypeContainer, " AND (items.itemclass = 1 or items.itemclass = 67)"},
{EQ::item::ItemType::ItemTypeAllEffects, " AND (items.scrolleffect > 0 && items.scrolleffect < 65000)"},
{EQ::item::ItemType::ItemTypeUnknown9, " AND items.worneffect = 998"},
{EQ::item::ItemType::ItemTypeUnknown10, " AND (items.worneffect >= 1298 && items.worneffect <= 1307)"},
{EQ::item::ItemType::ItemTypeFocusEffect, " AND items.focuseffect > 0"},
{EQ::item::ItemType::ItemTypeArmor, " AND items.itemtype = 10"},
{EQ::item::ItemType::ItemType1HBlunt, " AND items.itemtype = 3"},
{EQ::item::ItemType::ItemType1HPiercing, " AND items.itemtype = 2"},
{EQ::item::ItemType::ItemType1HSlash, " AND items.itemtype = 0"},
{EQ::item::ItemType::ItemType2HBlunt, " AND items.itemtype = 4"},
{EQ::item::ItemType::ItemType2HSlash, " AND items.itemtype = 1"},
{EQ::item::ItemType::ItemTypeBow, " AND items.itemtype = 5"},
{EQ::item::ItemType::ItemTypeShield, " AND items.itemtype = 8"},
{EQ::item::ItemType::ItemTypeMisc, " AND items.itemtype = 11"},
{EQ::item::ItemType::ItemTypeFood, " AND items.itemtype = 14"},
{EQ::item::ItemType::ItemTypeDrink, " AND items.itemtype = 15"},
{EQ::item::ItemType::ItemTypeLight, " AND items.itemtype = 16"},
{EQ::item::ItemType::ItemTypeCombinable, " AND items.itemtype = 17"},
{EQ::item::ItemType::ItemTypeBandage, " AND items.itemtype = 18"},
{EQ::item::ItemType::ItemTypeSmallThrowing, " AND (items.itemtype = 19 OR items.itemtype = 7)"},
{EQ::item::ItemType::ItemTypeSpell, " AND items.itemtype = 20"},
{EQ::item::ItemType::ItemTypePotion, " AND items.itemtype = 21"},
{EQ::item::ItemType::ItemTypeBrassInstrument, " AND items.itemtype = 25"},
{EQ::item::ItemType::ItemTypeWindInstrument, " AND items.itemtype = 23"},
{EQ::item::ItemType::ItemTypeStringedInstrument, " AND items.itemtype = 24"},
{EQ::item::ItemType::ItemTypePercussionInstrument, " AND items.itemtype = 26"},
{EQ::item::ItemType::ItemTypeArrow, " AND items.itemtype = 27"},
{EQ::item::ItemType::ItemTypeJewelry, " AND items.itemtype = 29"},
{EQ::item::ItemType::ItemTypeNote, " AND items.itemtype = 32"},
{EQ::item::ItemType::ItemTypeKey, " AND items.itemtype = 33"},
{EQ::item::ItemType::ItemType2HPiercing, " AND items.itemtype = 35"},
{EQ::item::ItemType::ItemTypeAlcohol, " AND items.itemtype = 38"},
{EQ::item::ItemType::ItemTypeMartial, " AND items.itemtype = 45"},
{EQ::item::ItemType::ItemTypeAugmentation, " AND items.itemtype = 54"},
{EQ::item::ItemType::ItemTypeAlternateAbility, " AND items.itemtype = 57"},
{EQ::item::ItemType::ItemTypeCount, " AND items.itemtype = 65"},
{EQ::item::ItemType::ItemTypeCollectible, " AND items.itemtype = 66"}
};
// item stat searches
struct ItemStatSearch {
std::string query_string;
EQ::skills::SkillType skill_type;
};
std::map<uint32, ItemStatSearch> item_stat_searches_new = {
{STAT_AC, {" items.ac" , static_cast<EQ::skills::SkillType>(0)} },
{STAT_AGI, {" items.aagi", static_cast<EQ::skills::SkillType>(0)} },
{STAT_CHA, {" items.acha", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DEX, {" items.adex", static_cast<EQ::skills::SkillType>(0)} },
{STAT_INT, {" items.aint", static_cast<EQ::skills::SkillType>(0)} },
{STAT_STA, {" items.asta", static_cast<EQ::skills::SkillType>(0)} },
{STAT_STR, {" items.astr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_WIS, {" items.awis", static_cast<EQ::skills::SkillType>(0)} },
{STAT_COLD, {" items.cr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DISEASE, {" items.dr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_FIRE, {" items.fr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_MAGIC, {" items.mr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_POISON, {" items.pr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HP, {" items.hp", static_cast<EQ::skills::SkillType>(0)} },
{STAT_MANA, {" items.mana", static_cast<EQ::skills::SkillType>(0)} },
{STAT_ENDURANCE, {" items.endur", static_cast<EQ::skills::SkillType>(0)} },
{STAT_ATTACK, {" items.attack", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HP_REGEN, {" items.regen", static_cast<EQ::skills::SkillType>(0)} },
{STAT_MANA_REGEN, {" items.manaregen", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HASTE, {" items.haste", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DAMAGE_SHIELD, {" items.damageshield", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DS_MITIGATION, {" items.dsmitigation", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEAL_AMOUNT, {" items.healamt", static_cast<EQ::skills::SkillType>(0)} },
{STAT_SPELL_DAMAGE, {" items.spelldmg", static_cast<EQ::skills::SkillType>(0)} },
{STAT_CLAIRVOYANCE, {" items.clairvoyance", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_AGILITY, {" items.heroic_agi", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_CHARISMA, {" items.heroic_cha", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_DEXTERITY, {" items.heroic_dex", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_INTELLIGENCE, {" items.heroic_int", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_STAMINA, {" items.heroic_sta", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_STRENGTH, {" items.heroic_str", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_WISDOM, {" items.heroic_wis", static_cast<EQ::skills::SkillType>(0)} },
{STAT_BASH, {" items.skillmodvalue", EQ::skills::SkillBash} },
{STAT_BACKSTAB, {" items.backstabdmg", EQ::skills::SkillBackstab} },
{STAT_DRAGON_PUNCH, {" items.skillmodvalue", EQ::skills::SkillDragonPunch} },
{STAT_EAGLE_STRIKE, {" items.skillmodvalue", EQ::skills::SkillEagleStrike} },
{STAT_FLYING_KICK, {" items.skillmodvalue", EQ::skills::SkillFlyingKick} },
{STAT_KICK, {" items.skillmodvalue", EQ::skills::SkillKick} },
{STAT_ROUND_KICK, {" items.skillmodvalue", EQ::skills::SkillRoundKick} },
{STAT_TIGER_CLAW, {" items.skillmodvalue", EQ::skills::SkillTigerClaw} },
{STAT_FRENZY, {" items.skillmodvalue", EQ::skills::SkillFrenzy} },
};
bool convert = false;
std::string search_criteria_trader("TRUE ");
std::string search_criteria_trader("TRUE");
std::string field_criteria_items("FALSE");
std::string where_criteria_items(" TRUE ");
if (search.search_scope == NonRoFBazaarSearchScope) {
search_criteria_trader.append(
@@ -77,305 +202,122 @@ Bazaar::GetSearchResults(
search_criteria_trader.append(fmt::format(" AND trader.item_cost <= {}", (uint64) search.max_cost * 1000));
}
// not yet implemented
// if (search.prestige != 0) {
// 0xffffffff prestige only, 0xfffffffe non-prestige, 0 all
// search_criteria.append(fmt::format(" AND items.type = {} ", search.prestige));
// }
if (search.slot != std::numeric_limits<uint32>::max()) {
if (item_slot_searches_new.contains(search.slot)) {
where_criteria_items.append(
fmt::format(" AND items.slots & {0} = {0}", item_slot_searches_new[search.slot]));
}
}
std::string query = fmt::format(
"SELECT COUNT(item_id), trader.char_id, trader.item_id, trader.item_sn, trader.item_charges, trader.item_cost, "
"trader.slot_id, SUM(trader.item_charges), trader.char_zone_id, trader.char_entity_id, character_data.name, "
"aug_slot_1, aug_slot_2, aug_slot_3, aug_slot_4, aug_slot_5, aug_slot_6, trader.char_zone_instance_id "
"FROM trader, character_data "
"WHERE {} AND trader.char_id = character_data.id "
"GROUP BY trader.item_sn, trader.item_charges, trader.char_id",
search_criteria_trader.c_str()
);
if (search.type != std::numeric_limits<uint32>::max()) {
for (auto const &[type, condition]: item_search_types_new) {
if (type == search.type) {
where_criteria_items.append(condition);
break;
}
}
}
if (search.race != std::numeric_limits<uint32>::max()) {
where_criteria_items.append(
fmt::format(" AND items.races & {0} = {0}", GetPlayerRaceBit(GetRaceIDFromPlayerRaceValue(search.race))));
}
if (search._class != std::numeric_limits<uint32>::max()) {
where_criteria_items.append(fmt::format(" AND items.classes & {0} = {0}", GetPlayerClassBit(search._class)));
}
if (search.item_stat != std::numeric_limits<uint32>::max()) {
if (item_stat_searches_new.contains(search.item_stat)) {
field_criteria_items = fmt::format("{}", item_stat_searches_new[search.item_stat].query_string);
if (item_stat_searches_new[search.item_stat].skill_type) {
where_criteria_items.append(
fmt::format(" AND items.skillmodtype = {} ", item_stat_searches_new[search.item_stat].skill_type));
}
else {
where_criteria_items.append(
fmt::format(" AND {} > 0 ", item_stat_searches_new[search.item_stat].query_string));
}
}
}
if (search.augment) {
where_criteria_items.append(fmt::format(
" AND (items.augslot1type = {0} OR "
"items.augslot2type = {0} OR "
"items.augslot3type = {0} OR "
"items.augslot4type = {0} OR "
"items.augslot5type = {0} OR "
"items.augslot6type = {0})",
search.augment)
);
}
if (search.min_level != 1) {
where_criteria_items.append(fmt::format(" AND items.reclevel >= {}", search.min_level));
}
if (search.max_level != 100) {
where_criteria_items.append(fmt::format(" AND items.reclevel <= {}", search.max_level));
}
std::vector<BazaarSearchResultsFromDB_Struct> all_entries;
std::vector<std::string> trader_items_ids{};
auto results = db.QueryDatabase(query);
if (!results.Success()) {
auto const trader_results = TraderRepository::GetBazaarTraderDetails(db, search_criteria_trader);
if (trader_results.empty()) {
LogTradingDetail("Bazaar - No traders found in bazaar search.");
return all_entries;
}
struct ItemSearchType {
EQ::item::ItemType type;
bool condition;
};
for (auto const &i: trader_results) {
trader_items_ids.push_back(std::to_string(i.trader.item_id));
}
struct AddititiveSearchCriteria {
bool should_check;
bool condition;
};
auto const item_results = ItemsRepository::GetItemsForBazaarSearch(
content_db,
trader_items_ids,
std::string(search.item_name),
field_criteria_items,
where_criteria_items
);
if (item_results.empty()) {
LogTradingDetail("Bazaar - No items found in bazaar search.");
return all_entries;
}
all_entries.reserve(trader_results.size());
for (auto const& t:trader_results) {
if (!item_results.contains(t.trader.item_id)) {
continue;
}
for (auto row: results) {
BazaarSearchResultsFromDB_Struct r{};
r.count = 1;
r.trader_id = t.trader.char_id;
r.serial_number = t.trader.item_sn;
r.cost = t.trader.item_cost;
r.slot_id = t.trader.slot_id;
r.charges = t.trader.item_charges;
r.stackable = item_results.at(t.trader.item_id).stackable;
r.icon_id = item_results.at(t.trader.item_id).icon;
r.trader_zone_id = t.trader.char_zone_id;
r.trader_zone_instance_id = t.trader.char_zone_instance_id;
r.trader_entity_id = t.trader.char_entity_id;
r.serial_number_RoF = fmt::format("{:016}\0", t.trader.item_sn);
r.item_name = fmt::format("{:.63}\0", item_results.at(t.trader.item_id).name);
r.trader_name = fmt::format("{:.63}\0", t.trader_name);
r.item_stat = item_results.at(t.trader.item_id).stats;
r.item_id = Strings::ToInt(row[2]);
r.charges = Strings::ToInt(row[4]);
auto item = db.GetItem(r.item_id);
if (!item) {
continue;
}
uint32 aug_slot_1 = Strings::ToUnsignedInt(row[11]);
uint32 aug_slot_2 = Strings::ToUnsignedInt(row[12]);
uint32 aug_slot_3 = Strings::ToUnsignedInt(row[13]);
uint32 aug_slot_4 = Strings::ToUnsignedInt(row[14]);
uint32 aug_slot_5 = Strings::ToUnsignedInt(row[15]);
uint32 aug_slot_6 = Strings::ToUnsignedInt(row[16]);
std::unique_ptr<EQ::ItemInstance> inst(
db.CreateItem(
item,
r.charges,
aug_slot_1,
aug_slot_2,
aug_slot_3,
aug_slot_4,
aug_slot_5,
aug_slot_6
)
);
if (!inst->GetItem()) {
continue;
}
r.count = Strings::ToInt(row[0]);
r.trader_id = Strings::ToInt(row[1]);
r.serial_number = Strings::ToInt(row[3]);
r.cost = Strings::ToInt(row[5]);
r.slot_id = Strings::ToInt(row[6]);
r.sum_charges = Strings::ToInt(row[7]);
r.stackable = item->Stackable;
r.icon_id = item->Icon;
r.trader_zone_id = Strings::ToInt(row[8]);
r.trader_zone_instance_id = Strings::ToInt(row[17]);
r.trader_entity_id = Strings::ToInt(row[9]);
r.serial_number_RoF = fmt::format("{:016}\0", Strings::ToInt(row[3]));
r.item_name = fmt::format("{:.63}\0", item->Name);
r.trader_name = fmt::format("{:.63}\0", std::string(row[10]).c_str());
LogTradingDetail(
"Searching against item [{}] ({}) for trader [{}]",
item->Name,
item->ID,
r.trader_name
);
// item stat searches
std::map<uint32, uint32> item_stat_searches = {
{STAT_AC, inst->GetItemArmorClass(true)},
{STAT_AGI, static_cast<uint32>(inst->GetItemAgi(true))},
{STAT_CHA, static_cast<uint32>(inst->GetItemCha(true))},
{STAT_DEX, static_cast<uint32>(inst->GetItemDex(true))},
{STAT_INT, static_cast<uint32>(inst->GetItemInt(true))},
{STAT_STA, static_cast<uint32>(inst->GetItemSta(true))},
{STAT_STR, static_cast<uint32>(inst->GetItemStr(true))},
{STAT_WIS, static_cast<uint32>(inst->GetItemWis(true))},
{STAT_COLD, static_cast<uint32>(inst->GetItemCR(true))},
{STAT_DISEASE, static_cast<uint32>(inst->GetItemDR(true))},
{STAT_FIRE, static_cast<uint32>(inst->GetItemFR(true))},
{STAT_MAGIC, static_cast<uint32>(inst->GetItemMR(true))},
{STAT_POISON, static_cast<uint32>(inst->GetItemPR(true))},
{STAT_HP, static_cast<uint32>(inst->GetItemHP(true))},
{STAT_MANA, static_cast<uint32>(inst->GetItemMana(true))},
{STAT_ENDURANCE, static_cast<uint32>(inst->GetItemEndur(true))},
{STAT_ATTACK, static_cast<uint32>(inst->GetItemAttack(true))},
{STAT_HP_REGEN, static_cast<uint32>(inst->GetItemRegen(true))},
{STAT_MANA_REGEN, static_cast<uint32>(inst->GetItemManaRegen(true))},
{STAT_HASTE, static_cast<uint32>(inst->GetItemHaste(true))},
{STAT_DAMAGE_SHIELD, static_cast<uint32>(inst->GetItemDamageShield(true))},
{STAT_DS_MITIGATION, static_cast<uint32>(inst->GetItemDSMitigation(true))},
{STAT_HEAL_AMOUNT, static_cast<uint32>(inst->GetItemHealAmt(true))},
{STAT_SPELL_DAMAGE, static_cast<uint32>(inst->GetItemSpellDamage(true))},
{STAT_CLAIRVOYANCE, static_cast<uint32>(inst->GetItemClairvoyance(true))},
{STAT_HEROIC_AGILITY, static_cast<uint32>(inst->GetItemHeroicAgi(true))},
{STAT_HEROIC_CHARISMA, static_cast<uint32>(inst->GetItemHeroicCha(true))},
{STAT_HEROIC_DEXTERITY, static_cast<uint32>(inst->GetItemHeroicDex(true))},
{STAT_HEROIC_INTELLIGENCE, static_cast<uint32>(inst->GetItemHeroicInt(true))},
{STAT_HEROIC_STAMINA, static_cast<uint32>(inst->GetItemHeroicSta(true))},
{STAT_HEROIC_STRENGTH, static_cast<uint32>(inst->GetItemHeroicStr(true))},
{STAT_HEROIC_WISDOM, static_cast<uint32>(inst->GetItemHeroicWis(true))},
{STAT_BASH, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillBash, true))},
{STAT_BACKSTAB, static_cast<uint32>(inst->GetItemBackstabDamage(true))},
{STAT_DRAGON_PUNCH, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillDragonPunch, true))},
{STAT_EAGLE_STRIKE, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillEagleStrike, true))},
{STAT_FLYING_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillFlyingKick, true))},
{STAT_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillKick, true))},
{STAT_ROUND_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillRoundKick, true))},
{STAT_TIGER_CLAW, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillTigerClaw, true))},
{STAT_FRENZY, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillFrenzy, true))},
};
r.item_stat = item_stat_searches.contains(search.item_stat) ? item_stat_searches[search.item_stat] : 0;
if (item_stat_searches.contains(search.item_stat) && item_stat_searches[search.item_stat] <= 0) {
continue;
}
static std::map<uint8, uint32> item_slot_searches = {
{EQ::invslot::slotCharm, 1},
{EQ::invslot::slotEar1, 2},
{EQ::invslot::slotHead, 4},
{EQ::invslot::slotFace, 8},
{EQ::invslot::slotEar2, 16},
{EQ::invslot::slotNeck, 32},
{EQ::invslot::slotShoulders, 64},
{EQ::invslot::slotArms, 128},
{EQ::invslot::slotBack, 256},
{EQ::invslot::slotWrist1, 512},
{EQ::invslot::slotWrist2, 1024},
{EQ::invslot::slotRange, 2048},
{EQ::invslot::slotHands, 4096},
{EQ::invslot::slotPrimary, 8192},
{EQ::invslot::slotSecondary, 16384},
{EQ::invslot::slotFinger1, 32768},
{EQ::invslot::slotFinger2, 65536},
{EQ::invslot::slotChest, 131072},
{EQ::invslot::slotLegs, 262144},
{EQ::invslot::slotFeet, 524288},
{EQ::invslot::slotWaist, 1048576},
{EQ::invslot::slotPowerSource, 2097152},
{EQ::invslot::slotAmmo, 4194304},
};
auto GetEquipmentSlotBit = [&](uint32 slot) -> uint32 {
return item_slot_searches.contains(slot) ? item_slot_searches[slot] : 0;
};
auto FindItemAugSlot = [&]() -> bool {
for (auto const &s: inst->GetItem()->AugSlotType) {
return s == search.augment;
}
return false;
};
// item type searches
std::vector<ItemSearchType> item_search_types = {
{EQ::item::ItemType::ItemTypeAll, true},
{EQ::item::ItemType::ItemTypeBook, item->ItemClass == EQ::item::ItemType::ItemTypeBook},
{EQ::item::ItemType::ItemTypeContainer, item->ItemClass == EQ::item::ItemType::ItemTypeContainer ||
item->IsClassBag()},
{EQ::item::ItemType::ItemTypeAllEffects, item->Scroll.Effect > 0 && item->Scroll.Effect < 65000},
{EQ::item::ItemType::ItemTypeUnknown9, item->Worn.Effect == 998},
{EQ::item::ItemType::ItemTypeUnknown10, item->Worn.Effect >= 1298 && item->Worn.Effect <= 1307},
{EQ::item::ItemType::ItemTypeFocusEffect, item->Focus.Effect > 0},
{EQ::item::ItemType::ItemTypeArmor, item->ItemType == EQ::item::ItemType::ItemTypeArmor},
{EQ::item::ItemType::ItemType1HBlunt, item->ItemType == EQ::item::ItemType::ItemType1HBlunt},
{EQ::item::ItemType::ItemType1HPiercing, item->ItemType == EQ::item::ItemType::ItemType1HPiercing},
{EQ::item::ItemType::ItemType1HSlash, item->ItemType == EQ::item::ItemType::ItemType1HSlash},
{EQ::item::ItemType::ItemType2HBlunt, item->ItemType == EQ::item::ItemType::ItemType2HBlunt},
{EQ::item::ItemType::ItemType2HSlash, item->ItemType == EQ::item::ItemType::ItemType2HSlash},
{EQ::item::ItemType::ItemTypeBow, item->ItemType == EQ::item::ItemType::ItemTypeBow},
{EQ::item::ItemType::ItemTypeShield, item->ItemType == EQ::item::ItemType::ItemTypeShield},
{EQ::item::ItemType::ItemTypeMisc, item->ItemType == EQ::item::ItemType::ItemTypeMisc},
{EQ::item::ItemType::ItemTypeFood, item->ItemType == EQ::item::ItemType::ItemTypeFood},
{EQ::item::ItemType::ItemTypeDrink, item->ItemType == EQ::item::ItemType::ItemTypeDrink},
{EQ::item::ItemType::ItemTypeLight, item->ItemType == EQ::item::ItemType::ItemTypeLight},
{EQ::item::ItemType::ItemTypeCombinable, item->ItemType == EQ::item::ItemType::ItemTypeCombinable},
{EQ::item::ItemType::ItemTypeBandage, item->ItemType == EQ::item::ItemType::ItemTypeBandage},
{EQ::item::ItemType::ItemTypeSmallThrowing, item->ItemType == EQ::item::ItemType::ItemTypeSmallThrowing ||
item->ItemType == EQ::item::ItemType::ItemTypeLargeThrowing},
{EQ::item::ItemType::ItemTypeSpell, item->ItemType == EQ::item::ItemType::ItemTypeSpell},
{EQ::item::ItemType::ItemTypePotion, item->ItemType == EQ::item::ItemType::ItemTypePotion},
{EQ::item::ItemType::ItemTypeBrassInstrument, item->ItemType == EQ::item::ItemType::ItemTypeBrassInstrument},
{EQ::item::ItemType::ItemTypeWindInstrument, item->ItemType == EQ::item::ItemType::ItemTypeWindInstrument},
{EQ::item::ItemType::ItemTypeStringedInstrument, item->ItemType == EQ::item::ItemType::ItemTypeStringedInstrument},
{EQ::item::ItemType::ItemTypePercussionInstrument, item->ItemType == EQ::item::ItemType::ItemTypePercussionInstrument},
{EQ::item::ItemType::ItemTypeArrow, item->ItemType == EQ::item::ItemType::ItemTypeArrow},
{EQ::item::ItemType::ItemTypeJewelry, item->ItemType == EQ::item::ItemType::ItemTypeJewelry},
{EQ::item::ItemType::ItemTypeNote, item->ItemType == EQ::item::ItemType::ItemTypeNote},
{EQ::item::ItemType::ItemTypeKey, item->ItemType == EQ::item::ItemType::ItemTypeKey},
{EQ::item::ItemType::ItemType2HPiercing, item->ItemType == EQ::item::ItemType::ItemType2HPiercing},
{EQ::item::ItemType::ItemTypeAlcohol, item->ItemType == EQ::item::ItemType::ItemTypeAlcohol},
{EQ::item::ItemType::ItemTypeMartial, item->ItemType == EQ::item::ItemType::ItemTypeMartial},
{EQ::item::ItemType::ItemTypeAugmentation, item->ItemType == EQ::item::ItemType::ItemTypeAugmentation},
{EQ::item::ItemType::ItemTypeAlternateAbility, item->ItemType == EQ::item::ItemType::ItemTypeAlternateAbility},
{EQ::item::ItemType::ItemTypeCount, item->ItemType == EQ::item::ItemType::ItemTypeCount},
{EQ::item::ItemType::ItemTypeCollectible, item->ItemType == EQ::item::ItemType::ItemTypeCollectible}
};
bool met_filter = false;
bool has_filter = false;
for (auto &i: item_search_types) {
if (i.type == search.type) {
has_filter = true;
if (i.condition) {
LogTradingDetail("Item [{}] met search criteria for type [{}]", item->Name, uint8(i.type));
met_filter = true;
break;
}
}
}
if (has_filter && !met_filter) {
continue;
}
// TODO: Add catch-all item type filter for specific item types
// item additive searches
std::vector<AddititiveSearchCriteria> item_additive_searches = {
{
.should_check = search.min_level != 1 && inst->GetItemRequiredLevel(true) > 0,
.condition = inst->GetItemRequiredLevel(true) >= search.min_level
},
{
.should_check = search.max_level != 1 && inst->GetItemRequiredLevel(true) > 0,
.condition = inst->GetItemRequiredLevel(true) <= search.max_level
},
{
.should_check = !std::string(search.item_name).empty(),
.condition = Strings::ContainsLower(item->Name, search.item_name)
},
{
.should_check = search._class != 0xFFFFFFFF,
.condition = static_cast<bool>(item->Classes & GetPlayerClassBit(search._class))
},
{
.should_check = search.race != 0xFFFFFFFF,
.condition = static_cast<bool>(item->Races & GetPlayerRaceBit(GetRaceIDFromPlayerRaceValue(search.race)))
},
{
.should_check = search.augment != 0,
.condition = FindItemAugSlot()
},
{
.should_check = search.slot != 0xFFFFFFFF,
.condition = static_cast<bool>(item->Slots & GetEquipmentSlotBit(search.slot))
},
};
bool should_add = true;
for (auto &i: item_additive_searches) {
LogTradingDetail(
"Checking item [{}] for search criteria - should_check [{}] condition [{}]",
item->Name,
i.should_check,
i.condition
);
if (i.should_check && !i.condition) {
should_add = false;
continue;
}
}
if (!should_add) {
continue;
}
LogTradingDetail("Found item [{}] meeting search criteria.", r.item_name);
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
if (convert || (r.trader_zone_id == Zones::BAZAAR && r.trader_zone_instance_id != char_zone_instance_id)) {
if (convert ||
char_zone_id != Zones::BAZAAR ||
(char_zone_id == Zones::BAZAAR && r.trader_zone_instance_id != char_zone_instance_id)
) {
r.trader_id = TraderRepository::TRADER_CONVERT_ID + r.trader_zone_instance_id;
}
}
}
all_entries.push_back(r);
+3 -1
View File
@@ -3,11 +3,13 @@
#include <vector>
#include "shareddb.h"
#include "../../common/item_instance.h"
class Bazaar {
public:
static std::vector<BazaarSearchResultsFromDB_Struct>
GetSearchResults(SharedDatabase &db, BazaarSearchCriteria_Struct search, unsigned int char_zone_id, int char_zone_instance_id);
GetSearchResults(Database &content_db, Database &db, BazaarSearchCriteria_Struct search, unsigned int char_zone_id, int char_zone_instance_id);
};
+2
View File
@@ -131,6 +131,8 @@ static std::map<uint8, std::string> class_names = {
#define ARMOR_TYPE_LAST ARMOR_TYPE_PLATE
#define ARMOR_TYPE_COUNT 5
#define BOT_CLASS_BASE_ID_PREFIX 3000
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
+30 -13
View File
@@ -245,7 +245,7 @@ uint32 Database::CreateAccount(
e.password = password;
}
LogInfo("Account Attempting to be created: [{}:{}] status: {}", loginserver, name, status);
LogInfo("Account attempting to be created loginserver [{}] name [{}] status [{}]", loginserver, name, status);
e = AccountRepository::InsertOne(*this, e);
@@ -2155,18 +2155,18 @@ void Database::PurgeCharacterParcels()
pel.event_type_name = PlayerEvent::EventName[pel.event_type_id];
std::stringstream ss;
for (auto const &r: results) {
pd.from_name = r.from_name;
pd.item_id = r.item_id;
pd.aug_slot_1 = r.aug_slot_1;
pd.aug_slot_2 = r.aug_slot_2;
pd.aug_slot_3 = r.aug_slot_3;
pd.aug_slot_4 = r.aug_slot_4;
pd.aug_slot_5 = r.aug_slot_5;
pd.aug_slot_6 = r.aug_slot_6;
pd.note = r.note;
pd.quantity = r.quantity;
pd.sent_date = r.sent_date;
pd.char_id = r.char_id;
pd.from_name = r.from_name;
pd.item_id = r.item_id;
pd.augment_1_id = r.aug_slot_1;
pd.augment_2_id = r.aug_slot_2;
pd.augment_3_id = r.aug_slot_3;
pd.augment_4_id = r.aug_slot_4;
pd.augment_5_id = r.aug_slot_5;
pd.augment_6_id = r.aug_slot_6;
pd.note = r.note;
pd.quantity = r.quantity;
pd.sent_date = r.sent_date;
pd.char_id = r.char_id;
{
cereal::JSONOutputArchiveSingleLine ar(ss);
pd.serialize(ar);
@@ -2202,3 +2202,20 @@ void Database::ClearBuyerDetails()
{
BuyerRepository::DeleteBuyer(*this, 0);
}
uint64_t Database::GetNextTableId(const std::string &table_name)
{
auto results = QueryDatabase(fmt::format("SHOW TABLE STATUS LIKE '{}'", table_name));
for (auto row: results) {
for (int row_index = 0; row_index < results.ColumnCount(); row_index++) {
std::string field_name = Strings::ToLower(results.FieldName(row_index));
if (field_name == "auto_increment") {
std::string value = row[row_index] ? row[row_index] : "null";
return Strings::ToUnsignedBigInt(value, 1);
}
}
}
return 1;
}
+2
View File
@@ -274,6 +274,8 @@ public:
void Encode(std::string &in);
void Decode(std::string &in);
uint64_t GetNextTableId(const std::string& table_name);
private:
Mutex Mvarcache;
VarCache_Struct varcache;
+6 -22
View File
@@ -136,11 +136,6 @@ std::string DatabaseDumpService::GetLoginTableList()
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
}
std::string DatabaseDumpService::GetQueryServTables()
{
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
}
std::string DatabaseDumpService::GetSystemTablesList()
{
auto system_tables = DatabaseSchema::GetServerTables();
@@ -272,11 +267,6 @@ void DatabaseDumpService::DatabaseDump()
tables_to_dump += GetLoginTableList() + " ";
dump_descriptor += "-login";
}
if (IsDumpQueryServerTables()) {
tables_to_dump += GetQueryServTables();
dump_descriptor += "-queryserv";
}
}
if (IsDumpStaticInstanceData()) {
@@ -401,7 +391,6 @@ void DatabaseDumpService::DatabaseDump()
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
// LogDebug("[{}] dump-path", GetSetDumpPath());
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
// LogDebug("[{}] query-serv", (IsDumpQueryServerTables() ? "true" : "false"));
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
@@ -511,16 +500,6 @@ const std::string &DatabaseDumpService::GetDumpFileName() const
return dump_file_name;
}
bool DatabaseDumpService::IsDumpQueryServerTables() const
{
return dump_query_server_tables;
}
void DatabaseDumpService::SetDumpQueryServerTables(bool dump_query_server_tables)
{
DatabaseDumpService::dump_query_server_tables = dump_query_server_tables;
}
bool DatabaseDumpService::IsDumpOutputToConsole() const
{
return dump_output_to_console;
@@ -617,7 +596,12 @@ void DatabaseDumpService::BuildCredentialsFile()
void DatabaseDumpService::RemoveCredentialsFile()
{
if (File::Exists(CREDENTIALS_FILE)) {
std::filesystem::remove(CREDENTIALS_FILE);
try {
std::filesystem::remove(CREDENTIALS_FILE);
}
catch (std::exception &e) {
LogError("std::filesystem::remove err [{}]", e.what());
}
}
}
-3
View File
@@ -45,8 +45,6 @@ public:
void SetDumpPath(const std::string &dump_path);
const std::string &GetDumpFileName() const;
void SetDumpFileName(const std::string &dump_file_name);
bool IsDumpQueryServerTables() const;
void SetDumpQueryServerTables(bool dump_query_server_tables);
bool IsDumpOutputToConsole() const;
void SetDumpOutputToConsole(bool dump_output_to_console);
bool IsDumpDropTableSyntaxOnly() const;
@@ -96,7 +94,6 @@ private:
bool HasCompressionBinary();
std::string GetDumpFileNameWithPath();
std::string GetSetDumpPath();
std::string GetQueryServTables();
void RemoveSqlBackup();
void BuildCredentialsFile();
void RemoveCredentialsFile();
+41
View File
@@ -142,6 +142,7 @@ bool DatabaseUpdate::UpdateManifest(
if (version_low != version_high) {
LogSys.DisableMySQLErrorLogs();
bool force_interactive = false;
for (int version = version_low + 1; version <= version_high; ++version) {
for (auto &e: entries) {
if (e.version == version) {
@@ -163,6 +164,10 @@ bool DatabaseUpdate::UpdateManifest(
prefix,
e.description
);
if (!has_migration && e.force_interactive) {
force_interactive = true;
}
}
}
}
@@ -187,6 +192,42 @@ bool DatabaseUpdate::UpdateManifest(
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
}
if (force_interactive && !std::getenv("FORCE_INTERACTIVE")) {
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfo("Some migrations require user input. Running interactively");
LogInfo("This is usually due to a major change that could cause data loss");
LogInfo("Your server is automatically backed up before these updates are applied");
LogInfo("but you should also make sure you take a backup prior to running this update");
LogInfo("Would you like to run this update? [y/n] (Timeout 60s)");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
// user input
std::string input;
bool gave_input = false;
time_t start_time = time(nullptr);
time_t wait_time_seconds = 60;
// spawn a concurrent thread that waits for input from std::cin
std::thread t1(
[&]() {
std::cin >> input;
gave_input = true;
}
);
t1.detach();
// check the inputReceived flag once every 50ms for 10 seconds
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// prompt for user skip
if (Strings::Trim(input) != "y") {
LogInfo("Exiting due to user input");
std::exit(1);
}
}
for (auto &m: missing_migrations) {
for (auto &e: entries) {
if (e.version == m) {
+1
View File
@@ -11,6 +11,7 @@ struct ManifestEntry {
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
std::string sql{}; // the SQL DDL that gets ran when the condition is true
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
bool force_interactive; // if true, this migration will always be run interactively
};
struct DatabaseVersion {
@@ -6331,6 +6331,611 @@ CREATE TABLE `character_pet_name` (
`character_id` INT(11) NOT NULL PRIMARY KEY,
`name` VARCHAR(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
)",
},
ManifestEntry{
.version = 9294,
.description = "2025_01_26_items_table_bazaar_search_indexes.sql",
.check = "SHOW CREATE TABLE `items`",
.condition = "missing",
.match = "idx_slots_reclevel",
.sql = R"(
-- indexes for the `items` table
CREATE INDEX idx_slots_reclevel ON items (slots, reclevel);
CREATE INDEX idx_itemclass_itemtype ON items (itemclass, itemtype);
CREATE INDEX idx_augment_slots ON items (
augslot1type,
augslot2type,
augslot3type,
augslot4type,
augslot5type,
augslot6type
);
CREATE INDEX idx_races_classes ON items (races, classes);
-- common stat fields
CREATE INDEX idx_item_ac ON items (ac);
CREATE INDEX idx_item_hp ON items (hp);
CREATE INDEX idx_item_mana ON items (mana);
CREATE INDEX idx_item_reclevel ON items (reclevel);
CREATE INDEX idx_item_type_skill ON items (itemtype, skillmodtype);
)",
.content_schema_update = true
},
ManifestEntry{
.version = 9295,
.description = "2025_01_26_trader_table_bazaar_search_indexes.sql",
.check = "SHOW CREATE TABLE `trader`",
.condition = "missing",
.match = "idx_trader_item",
.sql = R"(
-- indexes for the `trader` table
CREATE INDEX idx_trader_item ON trader (item_id, item_cost);
CREATE INDEX idx_trader_char ON trader (char_id, char_zone_id, char_zone_instance_id);
CREATE INDEX idx_trader_item_sn ON trader (item_sn);
CREATE INDEX idx_trader_item_cost ON trader (item_cost);
CREATE INDEX idx_trader_active_transaction ON trader (active_transaction);
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9296,
.description = "2025_02_01_trader_table_listing_date.sql",
.check = "SHOW CREATE TABLE `trader`",
.condition = "missing",
.match = "listing_date",
.sql = R"(
ALTER TABLE `trader`
ADD COLUMN `listing_date` DATETIME NULL DEFAULT NULL AFTER `active_transaction`,
ADD INDEX `idx_trader_listing_date` (`listing_date`);
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9297,
.description = "2024_01_22_sharedbank_guid_primary_key.sql",
.check = "SHOW COLUMNS FROM `sharedbank` LIKE 'guid'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `sharedbank`
CHANGE COLUMN `acctid` `account_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
CHANGE COLUMN `slotid` `slot_id` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `account_id`,
CHANGE COLUMN `itemid` `item_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `slot_id`,
CHANGE COLUMN `augslot1` `augment_one` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `charges`,
CHANGE COLUMN `augslot2` `augment_two` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_one`,
CHANGE COLUMN `augslot3` `augment_three` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_two`,
CHANGE COLUMN `augslot4` `augment_four` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
CHANGE COLUMN `augslot5` `augment_five` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
CHANGE COLUMN `augslot6` `augment_six` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`,
MODIFY COLUMN `charges` smallint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `item_id`,
ADD COLUMN `color` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `charges`,
ADD COLUMN `ornament_icon` int(11) UNSIGNED NOT NULL AFTER `custom_data`,
ADD COLUMN `ornament_idfile` int(11) UNSIGNED NOT NULL AFTER `ornament_icon`,
ADD COLUMN `ornament_hero_model` int(11) NOT NULL AFTER `ornament_idfile`,
ADD COLUMN `guid` bigint(20) UNSIGNED NOT NULL DEFAULT 0 AFTER `ornament_hero_model`,
ADD PRIMARY KEY (`account_id`, `slot_id`);
)",
.content_schema_update = false,
.force_interactive = false
},
ManifestEntry{
.version = 9298,
.description = "2024_10_24_inventory_changes.sql",
.check = "SHOW COLUMNS FROM `inventory` LIKE 'character_id'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `inventory`
CHANGE COLUMN `charid` `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
CHANGE COLUMN `slotid` `slot_id` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `character_id`,
CHANGE COLUMN `itemid` `item_id` int(11) UNSIGNED NULL DEFAULT 0 AFTER `slot_id`,
CHANGE COLUMN `augslot1` `augment_one` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `color`,
CHANGE COLUMN `augslot2` `augment_two` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_one`,
CHANGE COLUMN `augslot3` `augment_three` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_two`,
CHANGE COLUMN `augslot4` `augment_four` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
CHANGE COLUMN `augslot5` `augment_five` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
CHANGE COLUMN `augslot6` `augment_six` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`,
CHANGE COLUMN `ornamenticon` `ornament_icon` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `custom_data`,
CHANGE COLUMN `ornamentidfile` `ornament_idfile` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `ornament_icon`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`character_id`, `slot_id`) USING BTREE;
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 251) + 4010) WHERE `slot_id` BETWEEN 251 AND 260; -- Bag 1
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 261) + 4210) WHERE `slot_id` BETWEEN 261 AND 270; -- Bag 2
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 271) + 4410) WHERE `slot_id` BETWEEN 271 AND 280; -- Bag 3
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 281) + 4610) WHERE `slot_id` BETWEEN 281 AND 290; -- Bag 4
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 291) + 4810) WHERE `slot_id` BETWEEN 291 AND 300; -- Bag 5
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 301) + 5010) WHERE `slot_id` BETWEEN 301 AND 310; -- Bag 6
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 311) + 5210) WHERE `slot_id` BETWEEN 311 AND 320; -- Bag 7
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 321) + 5410) WHERE `slot_id` BETWEEN 321 AND 330; -- Bag 8
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 331) + 5610) WHERE `slot_id` BETWEEN 331 AND 340; -- Bag 9
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 341) + 5810) WHERE `slot_id` BETWEEN 341 AND 350; -- Bag 10
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 8000) + 6010) WHERE `slot_id` BETWEEN 8000 AND 8199; -- Cursor Overflow
DELETE FROM `inventory` WHERE `slot_id` BETWEEN 8200 AND 8999; -- Extreme Cursor Overflow
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 351) + 6010) WHERE `slot_id` BETWEEN 351 AND 360; -- Cursor Bag
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2031) + 6210) WHERE `slot_id` BETWEEN 2031 AND 2040; -- Bank Bag 1
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2041) + 6410) WHERE `slot_id` BETWEEN 2041 AND 2050; -- Bank Bag 2
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2051) + 6610) WHERE `slot_id` BETWEEN 2051 AND 2060; -- Bank Bag 3
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2061) + 6810) WHERE `slot_id` BETWEEN 2061 AND 2070; -- Bank Bag 4
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2071) + 7010) WHERE `slot_id` BETWEEN 2071 AND 2080; -- Bank Bag 5
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2081) + 7210) WHERE `slot_id` BETWEEN 2081 AND 2090; -- Bank Bag 6
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2091) + 7410) WHERE `slot_id` BETWEEN 2091 AND 2100; -- Bank Bag 7
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2101) + 7610) WHERE `slot_id` BETWEEN 2101 AND 2110; -- Bank Bag 8
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2111) + 7810) WHERE `slot_id` BETWEEN 2111 AND 2120; -- Bank Bag 9
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2121) + 8010) WHERE `slot_id` BETWEEN 2121 AND 2130; -- Bank Bag 10
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2131) + 8210) WHERE `slot_id` BETWEEN 2131 AND 2140; -- Bank Bag 11
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2141) + 8410) WHERE `slot_id` BETWEEN 2141 AND 2150; -- Bank Bag 12
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2151) + 8610) WHERE `slot_id` BETWEEN 2151 AND 2160; -- Bank Bag 13
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2161) + 8810) WHERE `slot_id` BETWEEN 2161 AND 2170; -- Bank Bag 14
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2171) + 9010) WHERE `slot_id` BETWEEN 2171 AND 2180; -- Bank Bag 15
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2181) + 9210) WHERE `slot_id` BETWEEN 2181 AND 2190; -- Bank Bag 16
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2191) + 9410) WHERE `slot_id` BETWEEN 2191 AND 2200; -- Bank Bag 17
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2201) + 9610) WHERE `slot_id` BETWEEN 2201 AND 2210; -- Bank Bag 18
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2211) + 9810) WHERE `slot_id` BETWEEN 2211 AND 2220; -- Bank Bag 19
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2221) + 10010) WHERE `slot_id` BETWEEN 2221 AND 2230; -- Bank Bag 20
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2231) + 10210) WHERE `slot_id` BETWEEN 2231 AND 2240; -- Bank Bag 21
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2241) + 10410) WHERE `slot_id` BETWEEN 2241 AND 2250; -- Bank Bag 22
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2251) + 10610) WHERE `slot_id` BETWEEN 2251 AND 2260; -- Bank Bag 23
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2261) + 10810) WHERE `slot_id` BETWEEN 2261 AND 2270; -- Bank Bag 24
UPDATE `sharedbank` SET `slot_id` = ((`slot_id` - 2531) + 11010) WHERE `slot_id` BETWEEN 2531 AND 2540; -- Shared Bank Bag 1
UPDATE `sharedbank` SET `slot_id` = ((`slot_id` - 2541) + 11210) WHERE `slot_id` BETWEEN 2541 AND 2550; -- Shared Bank Bag 2
)",
.content_schema_update = false,
.force_interactive = false
},
ManifestEntry{
.version = 9299,
.description = "2024_10_24_merchantlist_temp_uncap.sql",
.check = "SHOW CREATE TABLE `merchantlist_temp`",
.condition = "contains",
.match = "`slot` tinyint(3)",
.sql = R"(
ALTER TABLE `merchantlist_temp`
MODIFY COLUMN `slot` int UNSIGNED NOT NULL DEFAULT 0 AFTER `npcid`;
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9300,
.description = "2024_10_15_npc_types_multiquest_enabled.sql",
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'multiquest_enabled'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `npc_types`
ADD COLUMN `multiquest_enabled` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `is_parcel_merchant`;
)",
.content_schema_update = true
},
ManifestEntry{
.version = 9301,
.description = "2024_10_08_add_detail_player_event_logging.sql",
.check = "SHOW COLUMNS FROM `player_event_log_settings` LIKE 'etl_enabled'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `player_event_log_settings`
ADD COLUMN `etl_enabled` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `discord_webhook_id`;
ALTER TABLE `player_event_logs`
ADD COLUMN `etl_table_id` BIGINT(20) NOT NULL DEFAULT '0' AFTER `event_data`;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 14;
CREATE TABLE `player_event_loot_items` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`item_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`item_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`charges` INT(11) NULL DEFAULT NULL,
`augment_1_id` INT UNSIGNED NULL DEFAULT '0',
`augment_2_id` INT UNSIGNED NULL DEFAULT '0',
`augment_3_id` INT UNSIGNED NULL DEFAULT '0',
`augment_4_id` INT UNSIGNED NULL DEFAULT '0',
`augment_5_id` INT UNSIGNED NULL DEFAULT '0',
`augment_6_id` INT UNSIGNED NULL DEFAULT '0',
`npc_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`corpse_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `item_id_npc_id` (`item_id`, `npc_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 16;
CREATE TABLE `player_event_merchant_sell` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`npc_id` INT(10) UNSIGNED NULL DEFAULT '0',
`merchant_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`merchant_type` INT(10) UNSIGNED NULL DEFAULT '0',
`item_id` INT(10) UNSIGNED NULL DEFAULT '0',
`item_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`charges` INT(11) NULL DEFAULT '0',
`cost` INT(10) UNSIGNED NULL DEFAULT '0',
`alternate_currency_id` INT(10) UNSIGNED NULL DEFAULT '0',
`player_money_balance` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`player_currency_balance` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `item_id_npc_id` (`item_id`, `npc_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 15;
CREATE TABLE `player_event_merchant_purchase` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`npc_id` INT(10) UNSIGNED NULL DEFAULT '0',
`merchant_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`merchant_type` INT(10) UNSIGNED NULL DEFAULT '0',
`item_id` INT(10) UNSIGNED NULL DEFAULT '0',
`item_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`charges` INT(11) NULL DEFAULT '0',
`cost` INT(10) UNSIGNED NULL DEFAULT '0',
`alternate_currency_id` INT(10) UNSIGNED NULL DEFAULT '0',
`player_money_balance` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`player_currency_balance` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `item_id_npc_id` (`item_id`, `npc_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 22;
CREATE TABLE `player_event_npc_handin` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`npc_id` INT(10) UNSIGNED NULL DEFAULT '0',
`npc_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`handin_copper` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`handin_silver` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`handin_gold` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`handin_platinum` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`return_copper` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`return_silver` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`return_gold` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`return_platinum` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`is_quest_handin` TINYINT(3) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `npc_id_is_quest_handin` (`npc_id`, `is_quest_handin`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
CREATE TABLE `player_event_npc_handin_entries` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`player_event_npc_handin_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
`type` INT(10) UNSIGNED NULL DEFAULT NULL,
`item_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`charges` INT(11) NOT NULL DEFAULT '0',
`evolve_level` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`evolve_amount` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
`augment_1_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`augment_2_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`augment_3_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`augment_4_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`augment_5_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`augment_6_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `type_item_id` (`type`, `item_id`) USING BTREE,
INDEX `player_event_npc_handin_id` (`player_event_npc_handin_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 27;
CREATE TABLE `player_event_trade` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`char1_id` INT(10) UNSIGNED NULL DEFAULT '0',
`char2_id` INT(10) UNSIGNED NULL DEFAULT '0',
`char1_copper` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char1_silver` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char1_gold` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char1_platinum` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char2_copper` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char2_silver` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char2_gold` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char2_platinum` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `char1_id_char2_id` (`char1_id`, `char2_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
CREATE TABLE `player_event_trade_entries` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`player_event_trade_id` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`char_id` INT(10) UNSIGNED NULL DEFAULT '0',
`slot` SMALLINT(6) NULL DEFAULT '0',
`item_id` INT(10) UNSIGNED NULL DEFAULT '0',
`charges` SMALLINT(6) NULL DEFAULT '0',
`augment_1_id` INT(10) UNSIGNED NULL DEFAULT '0',
`augment_2_id` INT(10) UNSIGNED NULL DEFAULT '0',
`augment_3_id` INT(10) UNSIGNED NULL DEFAULT '0',
`augment_4_id` INT(10) UNSIGNED NULL DEFAULT '0',
`augment_5_id` INT(10) UNSIGNED NULL DEFAULT '0',
`augment_6_id` INT(10) UNSIGNED NULL DEFAULT '0',
`in_bag` TINYINT(4) NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `player_event_trade_id` (`player_event_trade_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
UPDATE `player_event_log_settings` SET `etl_enabled` = 0 WHERE `id` = 54;
CREATE TABLE `player_event_speech` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`to_char_id` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`from_char_id` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`guild_id` INT(10) UNSIGNED NULL DEFAULT '0',
`type` INT(10) UNSIGNED NULL DEFAULT '0',
`min_status` INT(10) UNSIGNED NULL DEFAULT '0',
`message` LONGTEXT NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `to_char_id_from_char_id` (`to_char_id`, `from_char_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 44;
CREATE TABLE `player_event_killed_npc` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`npc_id` INT(10) UNSIGNED NULL DEFAULT '0',
`npc_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`combat_time_seconds` INT(10) UNSIGNED NULL DEFAULT '0',
`total_damage_per_second_taken` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`total_heal_per_second_taken` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `npc_id` (`npc_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 45;
CREATE TABLE `player_event_killed_named_npc` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`npc_id` INT(10) UNSIGNED NULL DEFAULT '0',
`npc_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`combat_time_seconds` INT(10) UNSIGNED NULL DEFAULT '0',
`total_damage_per_second_taken` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`total_heal_per_second_taken` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `npc_id` (`npc_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 46;
CREATE TABLE `player_event_killed_raid_npc` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`npc_id` INT(10) UNSIGNED NULL DEFAULT '0',
`npc_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
`combat_time_seconds` INT(10) UNSIGNED NULL DEFAULT '0',
`total_damage_per_second_taken` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`total_heal_per_second_taken` BIGINT(20) UNSIGNED NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `npc_id` (`npc_id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;
UPDATE `player_event_log_settings` SET `etl_enabled` = 1 WHERE `id` = 4;
CREATE TABLE `player_event_aa_purchase` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`aa_ability_id` INT(11) NULL DEFAULT '0',
`cost` INT(11) NULL DEFAULT '0',
`previous_id` INT(11) NULL DEFAULT '0',
`next_id` INT(11) NULL DEFAULT '0',
`created_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `created_at` (`created_at`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;
)"
},
ManifestEntry{
.version = 9302,
.description = "2025_02_09_illusion_block.sql",
.check = "SHOW COLUMNS FROM `character_data` LIKE 'illusion_block'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_data`
ADD COLUMN `illusion_block` TINYINT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `deleted_at`;
UPDATE `command_settings`
SET `aliases` =
CASE
WHEN LENGTH(`aliases`) > 0 AND `aliases` NOT LIKE '%|ib%'
THEN CONCAT(`aliases`, '|ib')
WHEN LENGTH(`aliases`) = 0
THEN 'ib'
ELSE `aliases`
END
WHERE `command` = 'illusionblock'
AND `aliases` NOT LIKE '%ib%';
)",
},
ManifestEntry{
.version = 9303,
.description = "2025_02_13_corpse_slot_fix.sql",
.check = "SELECT * FROM `character_corpse_items` WHERE `equip_slot` BETWEEN 251 AND 350",
.condition = "not_empty",
.match = "",
.sql = R"(
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 251) + 4010) WHERE `equip_slot` BETWEEN 251 AND 260; -- Bag 1
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 261) + 4210) WHERE `equip_slot` BETWEEN 261 AND 270; -- Bag 2
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 271) + 4410) WHERE `equip_slot` BETWEEN 271 AND 280; -- Bag 3
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 281) + 4610) WHERE `equip_slot` BETWEEN 281 AND 290; -- Bag 4
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 291) + 4810) WHERE `equip_slot` BETWEEN 291 AND 300; -- Bag 5
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 301) + 5010) WHERE `equip_slot` BETWEEN 301 AND 310; -- Bag 6
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 311) + 5210) WHERE `equip_slot` BETWEEN 311 AND 320; -- Bag 7
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 321) + 5410) WHERE `equip_slot` BETWEEN 321 AND 330; -- Bag 8
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 331) + 5610) WHERE `equip_slot` BETWEEN 331 AND 340; -- Bag 9
UPDATE `character_corpse_items` SET `equip_slot` = ((`equip_slot` - 341) + 5810) WHERE `equip_slot` BETWEEN 341 AND 350; -- Bag 10
)",
},
ManifestEntry{
.version = 9304,
.description = "2024_12_01_2024_update_guild_bank",
.check = "SHOW COLUMNS FROM `guild_bank` LIKE 'augment_one_id'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `guild_bank`
DROP INDEX `guildid`,
CHANGE COLUMN `guildid` `guild_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`,
CHANGE COLUMN `itemid` `item_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `slot`,
CHANGE COLUMN `whofor` `who_for` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci' AFTER `permissions`,
ADD COLUMN `augment_one_id` INT UNSIGNED NULL DEFAULT '0' AFTER `item_id`,
ADD COLUMN `augment_two_id` INT UNSIGNED NULL DEFAULT '0' AFTER `augment_one_id`,
ADD COLUMN `augment_three_id` INT UNSIGNED NULL DEFAULT '0' AFTER `augment_two_id`,
ADD COLUMN `augment_four_id` INT UNSIGNED NULL DEFAULT '0' AFTER `augment_three_id`,
ADD COLUMN `augment_five_id` INT UNSIGNED NULL DEFAULT '0' AFTER `augment_four_id`,
ADD COLUMN `augment_six_id` INT UNSIGNED NULL DEFAULT '0' AFTER `augment_five_id`,
CHANGE COLUMN `qty` `quantity` INT(10) NOT NULL DEFAULT '0' AFTER `augment_six_id`;
ALTER TABLE `guild_bank`
ADD INDEX `guild_id` (`guild_id`);
)"
},
ManifestEntry{
.version = 9305,
.description = "2024_12_01_expedition_dz_merge.sql",
.check = "SHOW COLUMNS FROM `dynamic_zones` LIKE 'is_locked'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `dynamic_zones`
ADD COLUMN `is_locked` TINYINT NOT NULL DEFAULT '0' AFTER `has_zone_in`,
ADD COLUMN `add_replay` TINYINT NOT NULL DEFAULT '1' AFTER `is_locked`;
ALTER TABLE `expedition_lockouts`
CHANGE COLUMN `expedition_id` `dynamic_zone_id` INT(10) UNSIGNED NOT NULL AFTER `id`,
DROP INDEX `expedition_id_event_name`,
ADD UNIQUE INDEX `dz_id_event_name` (`dynamic_zone_id`, `event_name`) USING BTREE;
UPDATE expedition_lockouts lockouts
INNER JOIN expeditions ON lockouts.dynamic_zone_id = expeditions.id
SET lockouts.dynamic_zone_id = expeditions.dynamic_zone_id;
DROP TABLE `expeditions`;
RENAME TABLE `expedition_lockouts` TO `dynamic_zone_lockouts`;
)"
},
ManifestEntry{
.version = 9306,
.description = "2025_02_16_data_buckets_zone_id_instance_id.sql",
.check = "SHOW COLUMNS FROM `data_buckets` LIKE 'zone_id'",
.condition = "empty",
.match = "",
.sql = R"(
-- Drop old indexes
DROP INDEX IF EXISTS `keys` ON `data_buckets`;
DROP INDEX IF EXISTS `idx_npc_expires` ON `data_buckets`;
DROP INDEX IF EXISTS `idx_bot_expires` ON `data_buckets`;
-- Add zone_id, instance_id
ALTER TABLE `data_buckets`
MODIFY COLUMN `npc_id` int(11) NOT NULL DEFAULT 0 AFTER `character_id`,
MODIFY COLUMN `bot_id` int(11) NOT NULL DEFAULT 0 AFTER `npc_id`,
ADD COLUMN `zone_id` smallint(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `bot_id`,
ADD COLUMN `instance_id` smallint(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `zone_id`;
ALTER TABLE `data_buckets`
MODIFY COLUMN `account_id` bigint(11) UNSIGNED NULL DEFAULT 0 AFTER `expires`,
MODIFY COLUMN `character_id` bigint(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `account_id`,
MODIFY COLUMN `npc_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `character_id`,
MODIFY COLUMN `bot_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `npc_id`;
-- Create optimized unique index with `key` first
CREATE UNIQUE INDEX `keys` ON data_buckets (`key`, character_id, npc_id, bot_id, account_id, zone_id, instance_id);
-- Create indexes for just instance_id (instance deletion)
CREATE INDEX idx_instance_id ON data_buckets (instance_id);
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9307,
.description = "2025_02_17_zone_state_spawns.sql",
.check = "SHOW TABLES LIKE 'zone_state_spawns'",
.condition = "empty",
.match = "",
.sql = R"(
CREATE TABLE `zone_state_spawns` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`zone_id` int(11) unsigned DEFAULT NULL,
`instance_id` int(11) unsigned DEFAULT NULL,
`is_corpse` tinyint(11) DEFAULT 0,
`decay_in_seconds` int(11) DEFAULT 0,
`npc_id` int(10) unsigned DEFAULT NULL,
`spawn2_id` int(10) unsigned NOT NULL,
`spawngroup_id` int(10) unsigned NOT NULL,
`x` float NOT NULL,
`y` float NOT NULL,
`z` float NOT NULL,
`heading` float NOT NULL,
`respawn_time` int(10) unsigned NOT NULL,
`variance` int(10) unsigned NOT NULL,
`grid` int(10) unsigned DEFAULT 0,
`current_waypoint` int(11) DEFAULT 0,
`path_when_zone_idle` smallint(6) DEFAULT 0,
`condition_id` smallint(5) unsigned DEFAULT 0,
`condition_min_value` smallint(6) DEFAULT 0,
`enabled` smallint(6) DEFAULT 1,
`anim` smallint(5) unsigned DEFAULT 0,
`loot_data` text DEFAULT NULL,
`entity_variables` text DEFAULT NULL,
`buffs` text DEFAULT NULL,
`hp` bigint(20) DEFAULT 0,
`mana` bigint(20) DEFAULT 0,
`endurance` bigint(20) DEFAULT 0,
`created_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9308,
.description = "2025_add_multivalue_support_to_evolving_subtype.sql",
.check = "SHOW COLUMNS FROM `items_evolving_details` LIKE 'sub_type'",
.condition = "missing",
.match = "varchar(200)",
.sql = R"(
ALTER TABLE `items_evolving_details`
CHANGE COLUMN `sub_type` `sub_type` VARCHAR(200) NULL DEFAULT '0' AFTER `type`;
)",
.content_schema_update = true
},
// this one got missed being added to PEQ dumps so adding it again so it gets added when folks take a new release
ManifestEntry{
.version = 9309,
.description = "2025_03_1_create_pet_names_table_if_not_exist.sql",
.check = "SHOW TABLES LIKE 'character_pet_name'",
.condition = "empty",
.match = "",
.sql = R"(
CREATE TABLE `character_pet_name` (
`character_id` INT(11) NOT NULL PRIMARY KEY,
`name` VARCHAR(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
)",
},
// -- template; copy/paste this when you need to create a new entry
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/repositories/respawn_times_repository.h"
#include "../common/repositories/spawn_condition_values_repository.h"
#include "repositories/spawn2_disabled_repository.h"
#include "repositories/data_buckets_repository.h"
#include "database.h"
@@ -479,6 +479,7 @@ void Database::DeleteInstance(uint16 instance_id)
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
DataBucketsRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
}
void Database::FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id)
+17 -28
View File
@@ -139,6 +139,7 @@ namespace DatabaseSchema {
"character_pet_buffs",
"character_pet_info",
"character_pet_inventory",
"character_pet_name",
"character_peqzone_flags",
"character_potionbelt",
"character_skills",
@@ -291,32 +292,6 @@ namespace DatabaseSchema {
};
}
/**
* Gets QueryServer tables
*
* @return
*/
static std::vector<std::string> GetQueryServerTables()
{
return {
"qs_merchant_transaction_record",
"qs_merchant_transaction_record_entries",
"qs_player_aa_rate_hourly",
"qs_player_delete_record",
"qs_player_delete_record_entries",
"qs_player_events",
"qs_player_handin_record",
"qs_player_handin_record_entries",
"qs_player_move_record",
"qs_player_move_record_entries",
"qs_player_npc_kill_record",
"qs_player_npc_kill_record_entries",
"qs_player_speech",
"qs_player_trade_record",
"qs_player_trade_record_entries",
};
}
/**
* Gets state tables
* Tables that keep track of server state
@@ -337,10 +312,9 @@ namespace DatabaseSchema {
"completed_shared_task_members",
"completed_shared_tasks",
"discord_webhooks",
"dynamic_zone_lockouts",
"dynamic_zone_members",
"dynamic_zones",
"expedition_lockouts",
"expeditions",
"gm_ips",
"group_id",
"group_leaders",
@@ -359,12 +333,25 @@ namespace DatabaseSchema {
"saylink",
"server_scheduled_events",
"spawn2_disabled",
"player_event_aa_purchase",
"player_event_killed_npc",
"player_event_killed_named_npc",
"player_event_killed_raid_npc",
"player_event_log_settings",
"player_event_logs",
"player_event_loot_items",
"player_event_merchant_purchase",
"player_event_merchant_sell",
"player_event_npc_handin",
"player_event_npc_handin_entries",
"player_event_speech",
"player_event_trade",
"player_event_trade_entries",
"shared_task_activity_state",
"shared_task_dynamic_zones",
"shared_task_members",
"shared_tasks",
"zone_state_spawns",
};
}
@@ -406,6 +393,7 @@ namespace DatabaseSchema {
static std::vector<std::string> GetBotTables()
{
return {
"bot_blocked_buffs",
"bot_buffs",
"bot_command_settings",
"bot_create_combinations",
@@ -419,6 +407,7 @@ namespace DatabaseSchema {
"bot_pet_buffs",
"bot_pet_inventories",
"bot_pets",
"bot_settings",
"bot_spell_casting_chances",
"bot_spell_settings",
"bot_spells_entries",
+293 -64
View File
@@ -1,11 +1,13 @@
#include "dynamic_zone_base.h"
#include "database.h"
#include "eqemu_logsys.h"
#include "repositories/instance_list_repository.h"
#include "repositories/instance_list_player_repository.h"
#include "rulesys.h"
#include "servertalk.h"
#include "util/uuid.h"
#include "repositories/character_expedition_lockouts_repository.h"
#include "repositories/dynamic_zone_lockouts_repository.h"
#include "repositories/instance_list_repository.h"
#include "repositories/instance_list_player_repository.h"
DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry)
{
@@ -93,13 +95,15 @@ void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneIn
m_zonein.y = dz_entry.zone_in_y;
m_zonein.z = dz_entry.zone_in_z;
m_zonein.heading = dz_entry.zone_in_heading;
m_has_zonein = (dz_entry.has_zone_in != 0);
m_has_zonein = dz_entry.has_zone_in != 0;
m_is_locked = dz_entry.is_locked;
m_add_replay = dz_entry.add_replay;
// instance_list portion
m_zone_id = dz_entry.zone;
m_zone_version = dz_entry.version;
m_start_time = std::chrono::system_clock::from_time_t(dz_entry.start_time);
m_duration = std::chrono::seconds(dz_entry.duration);
m_never_expires = (dz_entry.never_expires != 0);
m_never_expires = dz_entry.never_expires != 0;
m_expire_time = m_start_time + m_duration;
}
@@ -119,37 +123,40 @@ void DynamicZoneBase::AddMemberFromRepositoryResult(
uint32_t DynamicZoneBase::SaveToDatabase()
{
LogDynamicZonesDetail("Saving dz instance [{}] to database", m_instance_id);
if (m_instance_id != 0)
if (m_instance_id == 0)
{
auto insert_dz = DynamicZonesRepository::NewEntity();
insert_dz.uuid = m_uuid;
insert_dz.name = m_name;
insert_dz.leader_id = m_leader.id;
insert_dz.min_players = m_min_players;
insert_dz.max_players = m_max_players;
insert_dz.instance_id = m_instance_id,
insert_dz.type = static_cast<int>(m_type);
insert_dz.dz_switch_id = m_dz_switch_id;
insert_dz.compass_zone_id = m_compass.zone_id;
insert_dz.compass_x = m_compass.x;
insert_dz.compass_y = m_compass.y;
insert_dz.compass_z = m_compass.z;
insert_dz.safe_return_zone_id = m_safereturn.zone_id;
insert_dz.safe_return_x = m_safereturn.x;
insert_dz.safe_return_y = m_safereturn.y;
insert_dz.safe_return_z = m_safereturn.z;
insert_dz.safe_return_heading = m_safereturn.heading;
insert_dz.zone_in_x = m_zonein.x;
insert_dz.zone_in_y = m_zonein.y;
insert_dz.zone_in_z = m_zonein.z;
insert_dz.zone_in_heading = m_zonein.heading;
insert_dz.has_zone_in = m_has_zonein;
auto inserted_dz = DynamicZonesRepository::InsertOne(GetDatabase(), insert_dz);
return inserted_dz.id;
return 0;
}
return 0;
auto dz = DynamicZonesRepository::NewEntity();
dz.uuid = m_uuid;
dz.name = m_name;
dz.leader_id = m_leader.id;
dz.min_players = m_min_players;
dz.max_players = m_max_players;
dz.instance_id = static_cast<int32_t>(m_instance_id),
dz.type = static_cast<uint8_t>(m_type);
dz.dz_switch_id = m_dz_switch_id;
dz.compass_zone_id = m_compass.zone_id;
dz.compass_x = m_compass.x;
dz.compass_y = m_compass.y;
dz.compass_z = m_compass.z;
dz.safe_return_zone_id = m_safereturn.zone_id;
dz.safe_return_x = m_safereturn.x;
dz.safe_return_y = m_safereturn.y;
dz.safe_return_z = m_safereturn.z;
dz.safe_return_heading = m_safereturn.heading;
dz.zone_in_x = m_zonein.x;
dz.zone_in_y = m_zonein.y;
dz.zone_in_z = m_zonein.z;
dz.zone_in_heading = m_zonein.heading;
dz.has_zone_in = static_cast<uint8_t>(m_has_zonein);
dz.is_locked = static_cast<int8_t>(m_is_locked);
dz.add_replay = static_cast<int8_t>(m_add_replay);
dz = DynamicZonesRepository::InsertOne(GetDatabase(), std::move(dz));
return dz.id;
}
bool DynamicZoneBase::AddMember(const DynamicZoneMember& add_member)
@@ -196,10 +203,9 @@ bool DynamicZoneBase::RemoveMember(const DynamicZoneMember& remove_member)
return true;
}
bool DynamicZoneBase::SwapMember(
const DynamicZoneMember& add_member, const std::string& remove_char_name)
bool DynamicZoneBase::SwapMember(const DynamicZoneMember& add_member, const std::string& remove_name)
{
auto remove_member = GetMemberData(remove_char_name);
auto remove_member = GetMemberData(remove_name);
if (!add_member.IsValid() || !remove_member.IsValid())
{
return false;
@@ -230,9 +236,18 @@ void DynamicZoneBase::RemoveAllMembers()
void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
{
if (members.empty())
{
return;
}
LogDynamicZonesDetail("Saving [{}] member(s) for dz [{}]", members.size(), m_id);
m_members = members;
if (m_members.size() > m_max_players)
{
m_members.resize(m_max_players);
}
// the lower level instance_list_players needs to be kept updated as well
std::vector<DynamicZoneMembersRepository::DynamicZoneMembers> insert_members;
@@ -242,12 +257,12 @@ void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
DynamicZoneMembersRepository::DynamicZoneMembers member_entry{};
member_entry.dynamic_zone_id = m_id;
member_entry.character_id = member.id;
insert_members.emplace_back(member_entry);
insert_members.push_back(member_entry);
InstanceListPlayerRepository::InstanceListPlayer player_entry;
player_entry.id = static_cast<int>(m_instance_id);
player_entry.charid = static_cast<int>(member.id);
insert_players.emplace_back(player_entry);
InstanceListPlayerRepository::InstanceListPlayer player_entry{};
player_entry.id = m_instance_id;
player_entry.charid = member.id;
insert_players.push_back(player_entry);
}
DynamicZoneMembersRepository::InsertOrUpdateMany(GetDatabase(), insert_members);
@@ -339,6 +354,44 @@ void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update
}
}
void DynamicZoneBase::SetLocked(bool lock, bool update_db, DzLockMsg lock_msg, uint32_t color)
{
m_is_locked = lock;
if (update_db)
{
DynamicZonesRepository::UpdateLocked(GetDatabase(), m_id, lock);
ServerPacket pack(ServerOP_DzLock, sizeof(ServerDzLock_Struct));
auto buf = reinterpret_cast<ServerDzLock_Struct*>(pack.pBuffer);
buf->dz_id = GetID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->lock = m_is_locked;
buf->lock_msg = static_cast<uint8_t>(lock_msg);
buf->color = color;
SendServerPacket(&pack);
}
}
void DynamicZoneBase::SetReplayOnJoin(bool enabled, bool update_db)
{
m_add_replay = enabled;
if (update_db)
{
DynamicZonesRepository::UpdateReplayOnJoin(GetDatabase(), m_id, enabled);
ServerPacket pack(ServerOP_DzReplayOnJoin, sizeof(ServerDzBool_Struct));
auto buf = reinterpret_cast<ServerDzBool_Struct*>(pack.pBuffer);
buf->dz_id = GetID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->enabled = enabled;
SendServerPacket(&pack);
}
}
uint32_t DynamicZoneBase::GetSecondsRemaining() const
{
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(GetDurationRemaining()).count();
@@ -478,13 +531,13 @@ void DynamicZoneBase::RemoveInternalMember(uint32_t character_id)
), m_members.end());
}
bool DynamicZoneBase::HasMember(uint32_t character_id)
bool DynamicZoneBase::HasMember(uint32_t character_id) const
{
return std::any_of(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) { return member.id == character_id; });
}
bool DynamicZoneBase::HasMember(const std::string& character_name)
bool DynamicZoneBase::HasMember(const std::string& character_name) const
{
return std::any_of(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) {
@@ -590,35 +643,34 @@ std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
}
}
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerPacket(uint16_t zone_id, uint16_t instance_id)
{
EQ::Net::DynamicPacket dyn_pack;
dyn_pack.PutSerialize(0, *this);
std::ostringstream ss = GetSerialized();
std::string_view sv = ss.view();
LogDynamicZonesDetail("Serialized server dz size [{}]", dyn_pack.Length());
return dyn_pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzCreatePacket(
uint16_t origin_zone_id, uint16_t origin_instance_id)
{
EQ::Net::DynamicPacket dyn_pack = GetSerializedDzPacket();
auto pack_size = sizeof(ServerDzCreateSerialized_Struct) + dyn_pack.Length();
auto pack_size = sizeof(ServerDzCreate_Struct) + sv.size();
auto pack = std::make_unique<ServerPacket>(ServerOP_DzCreated, static_cast<uint32_t>(pack_size));
auto buf = reinterpret_cast<ServerDzCreateSerialized_Struct*>(pack->pBuffer);
buf->origin_zone_id = origin_zone_id;
buf->origin_instance_id = origin_instance_id;
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
auto buf = reinterpret_cast<ServerDzCreate_Struct*>(pack->pBuffer);
buf->origin_zone_id = zone_id;
buf->origin_instance_id = instance_id;
buf->dz_id = GetID();
buf->cereal_size = static_cast<uint32_t>(sv.size());
memcpy(buf->cereal_data, sv.data(), sv.size());
return pack;
}
void DynamicZoneBase::LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size)
std::ostringstream DynamicZoneBase::GetSerialized()
{
LogDynamicZonesDetail("Deserializing server dz size [{}]", cereal_size);
EQ::Util::MemoryStreamReader ss(cereal_data, cereal_size);
std::ostringstream ss;
cereal::BinaryOutputArchive archive(ss);
archive(*this);
return ss;
}
void DynamicZoneBase::Unserialize(std::span<char> buf)
{
EQ::Util::MemoryStreamReader ss(buf.data(), buf.size());
cereal::BinaryInputArchive archive(ss);
archive(*this);
}
@@ -647,3 +699,180 @@ void DynamicZoneBase::LoadTemplate(const DynamicZoneTemplatesRepository::Dynamic
m_zonein.z = dz_template.zone_in_z;
m_zonein.heading = dz_template.zone_in_h;
}
std::vector<uint32_t> DynamicZoneBase::GetMemberIds()
{
std::vector<uint32_t> ids;
ids.reserve(m_members.size());
for (const auto& member : m_members)
{
ids.push_back(member.id);
}
return ids;
}
bool DynamicZoneBase::HasLockout(const std::string& event)
{
return std::ranges::any_of(m_lockouts, [&](const auto& l) { return l.IsEvent(event); });
}
bool DynamicZoneBase::HasReplayLockout()
{
return HasLockout(DzLockout::ReplayTimer);
}
void DynamicZoneBase::AddLockout(const std::string& event, uint32_t seconds)
{
auto lockout = DzLockout::Create(m_name, event, seconds, m_uuid);
AddLockout(lockout);
}
void DynamicZoneBase::AddLockout(const DzLockout& lockout, bool members_only)
{
if (!members_only)
{
DynamicZoneLockoutsRepository::InsertLockouts(GetDatabase(), GetID(), { lockout });
}
CharacterExpeditionLockoutsRepository::InsertLockout(GetDatabase(), GetMemberIds(), lockout);
HandleLockoutUpdate(lockout, false, members_only);
SendServerPacket(CreateLockoutPacket(lockout, false, members_only).get());
}
void DynamicZoneBase::AddLockoutDuration(const std::string& event, int seconds, bool members_only)
{
auto lockout = DzLockout::Create(m_name, event, std::max(0, seconds), m_uuid);
// lockout has unsigned duration, pass original seconds to support reducing existing timers
int secs = static_cast<int>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
CharacterExpeditionLockoutsRepository::AddLockoutDuration(GetDatabase(), GetMemberIds(), lockout, secs);
HandleLockoutDuration(lockout, seconds, members_only, true);
SendServerPacket(CreateLockoutDurationPacket(lockout, seconds, members_only).get());
}
void DynamicZoneBase::UpdateLockoutDuration(const std::string& event, uint32_t seconds, bool members_only)
{
// some live expeditions update existing lockout timers during progression
auto it = std::ranges::find_if(m_lockouts, [&](const auto& l) { return l.IsEvent(event); });
if (it != m_lockouts.end())
{
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
DzLockout lockout(m_uuid, m_name, event, it->GetStartTime() + seconds, seconds);
AddLockout(lockout, members_only);
}
}
void DynamicZoneBase::RemoveLockout(const std::string& event)
{
DynamicZoneLockoutsRepository::DeleteWhere(GetDatabase(), fmt::format(
"dynamic_zone_id = {} AND event_name = '{}'", GetID(), Strings::Escape(event)));
CharacterExpeditionLockoutsRepository::DeleteWhere(GetDatabase(), fmt::format(
"character_id IN ({}) AND expedition_name = '{}' AND event_name = '{}'",
fmt::join(GetMemberIds(), ","), Strings::Escape(m_name), Strings::Escape(event)));
DzLockout lockout{m_uuid, m_name, event, 0, 0};
HandleLockoutUpdate(lockout, true, false);
SendServerPacket(CreateLockoutPacket(lockout, true).get());
}
void DynamicZoneBase::HandleLockoutUpdate(const DzLockout& lockout, bool remove, bool members_only)
{
if (!members_only)
{
std::erase_if(m_lockouts, [&](const auto& l) { return l.IsEvent(lockout.Event()); });
if (!remove)
{
m_lockouts.push_back(lockout);
}
}
}
void DynamicZoneBase::HandleLockoutDuration(const DzLockout& lockout, int seconds, bool members_only, bool insert_db)
{
if (!members_only)
{
auto it = std::ranges::find_if(m_lockouts, [&](const auto& l) { return l.IsEvent(lockout.Event()); });
if (it != m_lockouts.end())
{
it->AddLockoutTime(seconds);
}
else
{
it = m_lockouts.insert(m_lockouts.end(), lockout);
}
if (insert_db)
{
DynamicZoneLockoutsRepository::InsertLockouts(GetDatabase(), GetID(), { *it });
}
}
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateLockoutPacket(const DzLockout& lockout, bool remove, bool members_only) const
{
uint32_t pack_size = sizeof(ServerDzLockout_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzLockout, pack_size);
auto buf = reinterpret_cast<ServerDzLockout_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->expire_time = lockout.GetExpireTime();
buf->duration = lockout.GetDuration();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->remove = remove;
buf->members_only = members_only;
strn0cpy(buf->event_name, lockout.Event().c_str(), sizeof(buf->event_name));
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateLockoutDurationPacket(const DzLockout& lockout, int seconds, bool members_only) const
{
uint32_t pack_size = sizeof(ServerDzLockout_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzLockoutDuration, pack_size);
auto buf = reinterpret_cast<ServerDzLockout_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->expire_time = lockout.GetExpireTime();
buf->duration = lockout.GetDuration();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->members_only = members_only;
buf->seconds = seconds;
strn0cpy(buf->event_name, lockout.Event().c_str(), sizeof(buf->event_name));
return pack;
}
void DynamicZoneBase::SyncCharacterLockouts(uint32_t char_id, std::vector<DzLockout>& lockouts)
{
// adds missing event lockouts to client for this expedition and updates
// client timers that are both shorter and from another expedition
bool modified = false;
for (const auto& lockout : m_lockouts)
{
if (lockout.IsReplay() || lockout.IsExpired() || lockout.UUID() != m_uuid)
{
continue;
}
auto it = std::find_if(lockouts.begin(), lockouts.end(), [&](const DzLockout& l) { return l.IsSame(lockout); });
if (it == lockouts.end())
{
modified = true;
lockouts.push_back(lockout); // insert missing
}
else if (it->GetSecondsRemaining() < lockout.GetSecondsRemaining() && it->UUID() != m_uuid)
{
// only update lockout timer not uuid so loot event apis still work
modified = true;
it->SetDuration(lockout.GetDuration());
it->SetExpireTime(lockout.GetExpireTime());
}
}
if (modified)
{
CharacterExpeditionLockoutsRepository::InsertLockouts(GetDatabase(), char_id, lockouts);
}
}
+68 -14
View File
@@ -1,8 +1,8 @@
#ifndef COMMON_DYNAMIC_ZONE_BASE_H
#define COMMON_DYNAMIC_ZONE_BASE_H
#include "dynamic_zone_lockout.h"
#include "eq_constants.h"
#include "net/packet.h"
#include "repositories/dynamic_zones_repository.h"
#include "repositories/dynamic_zone_members_repository.h"
#include "repositories/dynamic_zone_templates_repository.h"
@@ -10,12 +10,40 @@
#include <chrono>
#include <cstdint>
#include <memory>
#include <span>
#include <string>
#include <vector>
class Database;
class ServerPacket;
// message string 8312 added in September 08 2020 Test patch (used by both dz and shared tasks)
inline constexpr char DzNotAllAdded[] = "Not all players in your {0} were added to the {1}. The {1} can take a maximum of {2} players, and your {0} has {3}.";
enum class DzLockMsg : uint8_t
{
None = 0, Close, Begin
};
enum class DynamicZoneType
{
None = 0,
Expedition,
Tutorial,
Task,
Mission, // Shared Task
Quest
};
enum class DynamicZoneMemberStatus
{
Unknown = 0,
Online,
Offline,
InDynamicZone,
LinkDead
};
struct DynamicZoneMember
{
uint32_t id = 0;
@@ -93,6 +121,7 @@ public:
const std::string& GetName() const { return m_name; }
const std::string& GetUUID() const { return m_uuid; }
const DynamicZoneMember& GetLeader() const { return m_leader; }
const std::vector<DzLockout>& GetLockouts() const { return m_lockouts; }
const std::vector<DynamicZoneMember>& GetMembers() const { return m_members; }
const DynamicZoneLocation& GetCompassLocation() const { return m_compass; }
const DynamicZoneLocation& GetSafeReturnLocation() const { return m_safereturn; }
@@ -104,31 +133,34 @@ public:
uint32_t GetDatabaseMemberCount();
DynamicZoneMember GetMemberData(uint32_t character_id);
DynamicZoneMember GetMemberData(const std::string& character_name);
EQ::Net::DynamicPacket GetSerializedDzPacket();
std::vector<uint32_t> GetMemberIds();
std::ostringstream GetSerialized();
bool HasDatabaseMember(uint32_t character_id);
bool HasMember(uint32_t character_id);
bool HasMember(const std::string& character_name);
bool HasMember(uint32_t character_id) const;
bool HasMember(const std::string& character_name) const;
bool HasMembers() const { return !m_members.empty(); }
bool HasZoneInLocation() const { return m_has_zonein; }
bool IsExpedition() const { return m_type == DynamicZoneType::Expedition; }
bool IsExpired() const { return m_expire_time < std::chrono::system_clock::now(); }
bool IsInstanceID(uint32_t instance_id) const { return (m_instance_id != 0 && m_instance_id == instance_id); }
bool IsLocked() const { return m_is_locked; }
bool IsValid() const { return m_instance_id != 0; }
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const { return zone_id == m_zone_id && instance_id == m_instance_id; }
void LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size);
void LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template);
void RemoveAllMembers();
bool RemoveMember(uint32_t character_id);
bool RemoveMember(const std::string& character_name);
bool RemoveMember(const DynamicZoneMember& remove_member);
void SaveMembers(const std::vector<DynamicZoneMember>& members);
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
void SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db = false);
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
void SetLeader(const DynamicZoneMember& leader, bool update_db = false);
void SetLocked(bool lock, bool update_db = false, DzLockMsg lock_msg = DzLockMsg::None, uint32_t color = Chat::Yellow);
void SetMaxPlayers(uint32_t max_players) { m_max_players = max_players; }
void SetMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
void SetMinPlayers(uint32_t min_players) { m_min_players = min_players; }
void SetName(const std::string& name) { m_name = name; }
void SetReplayOnJoin(bool enabled, bool update_db = false);
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
void SetSwitchID(int dz_switch_id, bool update_db = false);
@@ -136,34 +168,48 @@ public:
void SetUUID(std::string uuid) { m_uuid = std::move(uuid); }
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
void SetZoneInLocation(float x, float y, float z, float heading, bool update_db = false);
bool SwapMember(const DynamicZoneMember& add_member, const std::string& remove_char_name);
bool SwapMember(const DynamicZoneMember& add_member, const std::string& remove_name);
void AddLockout(const std::string& event, uint32_t seconds);
void AddLockoutDuration(const std::string& event, int seconds, bool members_only = true);
bool HasLockout(const std::string& event);
bool HasReplayLockout();
void RemoveLockout(const std::string& event);
void SyncCharacterLockouts(uint32_t char_id, std::vector<DzLockout>& lockouts);
void UpdateLockoutDuration(const std::string& event, uint32_t seconds, bool members_only = true);
protected:
virtual uint16_t GetCurrentInstanceID() { return 0; }
virtual uint16_t GetCurrentZoneID() { return 0; }
virtual uint16_t GetCurrentInstanceID() const { return 0; }
virtual uint16_t GetCurrentZoneID() const { return 0; }
virtual Database& GetDatabase() = 0;
virtual void HandleLockoutDuration(const DzLockout& lockout, int seconds, bool members_only, bool insert_db);
virtual void HandleLockoutUpdate(const DzLockout& lockout, bool remove, bool members_only);
virtual void ProcessCompassChange(const DynamicZoneLocation& location) { m_compass = location; }
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
virtual bool ProcessMemberStatusChange(uint32_t character_id, DynamicZoneMemberStatus status);
virtual void ProcessRemoveAllMembers() { m_members.clear(); }
virtual void ProcessSetSwitchID(int dz_switch_id) { m_dz_switch_id = dz_switch_id; }
virtual bool SendServerPacket(ServerPacket* packet) = 0;
void AddLockout(const DzLockout& lockout, bool members_only = false);
void AddInternalMember(const DynamicZoneMember& member);
uint32_t Create();
uint32_t CreateInstance();
void LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry);
void RemoveInternalMember(uint32_t character_id);
void SaveMembers(const std::vector<DynamicZoneMember>& members);
uint32_t SaveToDatabase();
bool SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
std::unique_ptr<ServerPacket> CreateServerDzCreatePacket(uint16_t origin_zone_id, uint16_t origin_instance_id);
std::unique_ptr<ServerPacket> CreateServerPacket(uint16_t zone_id, uint16_t instance_id);
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
std::unique_ptr<ServerPacket> CreateServerDzSwitchIDPacket();
std::unique_ptr<ServerPacket> CreateServerMemberAddRemovePacket(const DynamicZoneMember& member, bool removed);
std::unique_ptr<ServerPacket> CreateServerMemberStatusPacket(uint32_t character_id, DynamicZoneMemberStatus status);
std::unique_ptr<ServerPacket> CreateServerMemberSwapPacket(const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member);
std::unique_ptr<ServerPacket> CreateServerRemoveAllMembersPacket();
std::unique_ptr<ServerPacket> CreateLockoutPacket(const DzLockout& lockout, bool remove, bool members_only = false) const;
std::unique_ptr<ServerPacket> CreateLockoutDurationPacket(const DzLockout& lockout, int seconds, bool members_only = false) const;
uint32_t m_id = 0;
uint32_t m_zone_id = 0;
@@ -175,6 +221,8 @@ protected:
bool m_never_expires = false;
bool m_has_zonein = false;
bool m_has_member_statuses = false;
bool m_is_locked = false;
bool m_add_replay = true;
std::string m_name;
std::string m_uuid;
DynamicZoneMember m_leader;
@@ -182,12 +230,15 @@ protected:
DynamicZoneLocation m_compass;
DynamicZoneLocation m_safereturn;
DynamicZoneLocation m_zonein;
std::chrono::seconds m_duration;
std::chrono::seconds m_duration = {};
std::chrono::time_point<std::chrono::system_clock> m_start_time;
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
std::vector<DynamicZoneMember> m_members;
std::vector<DzLockout> m_lockouts;
public:
void Unserialize(std::span<char> buf);
template<class Archive>
void serialize(Archive& archive)
{
@@ -202,6 +253,8 @@ public:
m_never_expires,
m_has_zonein,
m_has_member_statuses,
m_is_locked,
m_add_replay,
m_name,
m_uuid,
m_leader,
@@ -212,7 +265,8 @@ public:
m_duration,
m_start_time,
m_expire_time,
m_members
m_members,
m_lockouts
);
}
};
+92
View File
@@ -0,0 +1,92 @@
#include "dynamic_zone_lockout.h"
#include "strings.h"
#include "rulesys.h"
#include "util/uuid.h"
#include <fmt/format.h>
#include <cereal/types/chrono.hpp>
DzLockout::DzLockout(std::string uuid, std::string expedition, std::string event, uint64_t expire_time, uint32_t duration)
: m_uuid(std::move(uuid))
, m_name(std::move(expedition))
, m_event(std::move(event))
, m_expire_time(std::chrono::system_clock::from_time_t(expire_time))
, m_duration(duration)
{
m_is_replay = m_event == ReplayTimer;
}
DzLockout::DzLockout(std::string_view name, BaseDynamicZoneLockoutsRepository::DynamicZoneLockouts&& lockout)
: m_uuid(std::move(lockout.from_expedition_uuid))
, m_name(name)
, m_event(std::move(lockout.event_name))
, m_expire_time(std::chrono::system_clock::from_time_t(lockout.expire_time))
, m_duration(lockout.duration)
{
m_is_replay = m_event == ReplayTimer;
}
DzLockout DzLockout::Create(const std::string& expedition, const std::string& event, uint32_t seconds, std::string uuid)
{
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
if (uuid.empty())
{
uuid = EQ::Util::UUID::Generate().ToString();
}
DzLockout lockout{uuid, expedition, event, 0, seconds};
lockout.Reset(); // sets expire time
return lockout;
}
uint32_t DzLockout::GetSecondsRemaining() const
{
auto now = std::chrono::system_clock::now();
if (m_expire_time > now)
{
auto remaining = m_expire_time - now;
return static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::seconds>(remaining).count());
}
return 0;
}
DzLockout::TimeStrings DzLockout::GetTimeRemainingStrs() const
{
auto seconds = GetSecondsRemaining();
return DzLockout::TimeStrings{
fmt::format_int(seconds / 86400).str(), // days
fmt::format_int(seconds / 3600 % 24).str(), // hours
fmt::format_int(seconds / 60 % 60).str(), // minutes
fmt::format_int(seconds % 60).str() // seconds
};
}
bool DzLockout::IsSame(const DzLockout& other) const
{
return other.IsSame(m_name, m_event);
}
bool DzLockout::IsSame(const std::string& expedition, const std::string& event) const
{
return m_name == expedition && m_event == event;
}
void DzLockout::AddLockoutTime(int seconds)
{
seconds = static_cast<int>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
auto new_duration = std::max(0, static_cast<int>(m_duration.count()) + seconds);
auto start_time = m_expire_time - m_duration;
m_duration = std::chrono::seconds(new_duration);
m_expire_time = start_time + m_duration;
}
template <typename T>
void DzLockout::serialize(T& archive)
{
archive(m_is_replay, m_uuid, m_name, m_event, m_duration, m_expire_time);
}
template void DzLockout::serialize(cereal::BinaryOutputArchive&);
template void DzLockout::serialize(cereal::BinaryInputArchive&);
+56
View File
@@ -0,0 +1,56 @@
#pragma once
#include <chrono>
#include <string>
#include "repositories/base/base_dynamic_zone_lockouts_repository.h"
class DzLockout
{
public:
DzLockout() = default;
DzLockout(std::string uuid, std::string expedition, std::string event, uint64_t expire_time, uint32_t duration);
DzLockout(std::string_view name, BaseDynamicZoneLockoutsRepository::DynamicZoneLockouts&& lockout);
static constexpr char ReplayTimer[] = "Replay Timer";
static DzLockout Create(const std::string& expedition, const std::string& event, uint32_t seconds, std::string uuid = {});
struct TimeStrings
{
std::string days;
std::string hours;
std::string mins;
std::string secs;
};
void AddLockoutTime(int seconds);
uint32_t GetDuration() const { return static_cast<uint32_t>(m_duration.count()); }
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
uint64_t GetStartTime() const { return std::chrono::system_clock::to_time_t(m_expire_time - m_duration); }
uint32_t GetSecondsRemaining() const;
TimeStrings GetTimeRemainingStrs() const;
const std::string& DzName() const { return m_name; }
const std::string& Event() const { return m_event; }
const std::string& UUID() const { return m_uuid; }
bool IsEvent(std::string_view event) const { return m_event == event; }
bool IsExpired() const { return GetSecondsRemaining() == 0; }
bool IsReplay() const { return m_is_replay; }
bool IsSame(const DzLockout& other) const;
bool IsSame(const std::string& expedition, const std::string& event) const;
bool IsUUID(const std::string& uuid) const { return uuid == m_uuid; }
void Reset() { m_expire_time = std::chrono::system_clock::now() + m_duration; }
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
void SetExpireTime(uint64_t expire_time) { m_expire_time = std::chrono::system_clock::from_time_t(expire_time); }
void SetUUID(const std::string& uuid) { m_uuid = uuid; }
template <typename T>
void serialize(T& archive);
private:
bool m_is_replay = false;
std::string m_uuid; // dz received in
std::string m_name;
std::string m_event;
std::chrono::seconds m_duration = {};
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
};
+37 -33
View File
@@ -130,9 +130,11 @@ namespace EQ
using RoF2::invtype::MAIL_SIZE;
using RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE;
using RoF2::invtype::KRONO_SIZE;
using RoF2::invtype::GUILD_BANK_MAIN_SIZE;
using RoF2::invtype::GUILD_BANK_DEPOSIT_SIZE;
using RoF2::invtype::OTHER_SIZE;
using Titanium::invtype::TRADE_NPC_SIZE;
using RoF2::invtype::TRADE_NPC_SIZE;
using RoF2::invtype::TYPE_INVALID;
using RoF2::invtype::TYPE_BEGIN;
@@ -159,7 +161,7 @@ namespace EQ
using RoF2::invslot::SLOT_INVALID;
using RoF2::invslot::SLOT_BEGIN;
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
using RoF2::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
@@ -179,28 +181,28 @@ namespace EQ
using RoF2::invslot::BONUS_STAT_END;
using RoF2::invslot::BONUS_SKILL_END;
using Titanium::invslot::BANK_BEGIN;
using SoF::invslot::BANK_END;
using RoF2::invslot::BANK_BEGIN;
using RoF2::invslot::BANK_END;
using Titanium::invslot::SHARED_BANK_BEGIN;
using Titanium::invslot::SHARED_BANK_END;
using RoF2::invslot::SHARED_BANK_BEGIN;
using RoF2::invslot::SHARED_BANK_END;
using Titanium::invslot::TRADE_BEGIN;
using Titanium::invslot::TRADE_END;
using RoF2::invslot::TRADE_BEGIN;
using RoF2::invslot::TRADE_END;
using Titanium::invslot::TRADE_NPC_END;
using RoF2::invslot::TRADE_NPC_END;
using Titanium::invslot::WORLD_BEGIN;
using Titanium::invslot::WORLD_END;
using RoF2::invslot::WORLD_BEGIN;
using RoF2::invslot::WORLD_END;
using Titanium::invslot::TRIBUTE_BEGIN;
using Titanium::invslot::TRIBUTE_END;
using RoF2::invslot::TRIBUTE_BEGIN;
using RoF2::invslot::TRIBUTE_END;
using Titanium::invslot::GUILD_TRIBUTE_BEGIN;
using Titanium::invslot::GUILD_TRIBUTE_END;
using RoF2::invslot::GUILD_TRIBUTE_BEGIN;
using RoF2::invslot::GUILD_TRIBUTE_END;
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
using RoF2::invslot::EQUIPMENT_BITMASK;
using RoF2::invslot::GENERAL_BITMASK;
@@ -214,38 +216,40 @@ namespace EQ
} // namespace invslot
namespace invbag {
using Titanium::invbag::SLOT_INVALID;
using Titanium::invbag::SLOT_BEGIN;
using Titanium::invbag::SLOT_END;
using Titanium::invbag::SLOT_COUNT;
using RoF2::invbag::SLOT_INVALID;
using RoF2::invbag::SLOT_BEGIN;
using RoF2::invbag::SLOT_END;
using RoF2::invbag::SLOT_COUNT;
using Titanium::invbag::GENERAL_BAGS_BEGIN;
using RoF2::invslot::WORLD_END;
const int16 GENERAL_BAGS_BEGIN = WORLD_END + 1;
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
const int16 CURSOR_BAG_BEGIN = 351;
const int16 CURSOR_BAG_BEGIN = GENERAL_BAGS_END + 1;
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
using Titanium::invbag::BANK_BAGS_BEGIN;
const int16 BANK_BAGS_BEGIN = CURSOR_BAG_END + 1;
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
using Titanium::invbag::SHARED_BANK_BAGS_BEGIN;
const int16 SHARED_BANK_BAGS_BEGIN = BANK_BAGS_END + 1;
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
using Titanium::invbag::TRADE_BAGS_BEGIN;
const int16 TRADE_BAGS_BEGIN = SHARED_BANK_BAGS_END + 1;
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
using Titanium::invbag::GetInvBagIndexName;
using RoF2::invbag::GetInvBagIndexName;
} // namespace invbag
+1
View File
@@ -574,6 +574,7 @@ N(OP_TradeRequestAck),
N(OP_TraderItemUpdate),
N(OP_TraderShop),
N(OP_TradeSkillCombine),
N(OP_TradeSkillRecipeInspect),
N(OP_Translocate),
N(OP_TributeInfo),
N(OP_TributeItem),
-19
View File
@@ -974,25 +974,6 @@ namespace ZoneBlockedSpellTypes {
const uint8 Region = 2;
};
enum class DynamicZoneType
{
None = 0,
Expedition,
Tutorial,
Task,
Mission, // Shared Task
Quest
};
enum class DynamicZoneMemberStatus : uint8_t
{
Unknown = 0,
Online,
Offline,
InDynamicZone,
LinkDead
};
enum StartZoneIndex {
Odus = 0,
Qeynos,
+22 -22
View File
@@ -173,7 +173,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL
),
ClientUnknown::INULL,
@@ -200,7 +200,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL
Client62::INULL, Client62::INULL, Client62::INULL
),
Client62::INULL,
@@ -227,7 +227,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Titanium::invtype::VIEW_MOD_PC_SIZE, Titanium::invtype::VIEW_MOD_BANK_SIZE, Titanium::invtype::VIEW_MOD_SHARED_BANK_SIZE,
Titanium::invtype::VIEW_MOD_LIMBO_SIZE, Titanium::invtype::ALT_STORAGE_SIZE, Titanium::invtype::ARCHIVED_SIZE,
Titanium::INULL, Titanium::INULL, Titanium::INULL,
Titanium::invtype::OTHER_SIZE
Titanium::INULL, Titanium::INULL, Titanium::invtype::OTHER_SIZE
),
Titanium::invslot::EQUIPMENT_BITMASK,
@@ -254,7 +254,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoF::invtype::VIEW_MOD_PC_SIZE, SoF::invtype::VIEW_MOD_BANK_SIZE, SoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
SoF::invtype::VIEW_MOD_LIMBO_SIZE, SoF::invtype::ALT_STORAGE_SIZE, SoF::invtype::ARCHIVED_SIZE,
SoF::INULL, SoF::INULL, SoF::INULL,
SoF::invtype::OTHER_SIZE
SoF::INULL, SoF::INULL, SoF::invtype::OTHER_SIZE
),
SoF::invslot::EQUIPMENT_BITMASK,
@@ -281,7 +281,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoD::invtype::VIEW_MOD_PC_SIZE, SoD::invtype::VIEW_MOD_BANK_SIZE, SoD::invtype::VIEW_MOD_SHARED_BANK_SIZE,
SoD::invtype::VIEW_MOD_LIMBO_SIZE, SoD::invtype::ALT_STORAGE_SIZE, SoD::invtype::ARCHIVED_SIZE,
SoD::INULL, SoD::INULL, SoD::INULL,
SoD::invtype::OTHER_SIZE
SoD::INULL, SoD::INULL, SoD::invtype::OTHER_SIZE
),
SoD::invslot::EQUIPMENT_BITMASK,
@@ -308,7 +308,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
UF::invtype::VIEW_MOD_PC_SIZE, UF::invtype::VIEW_MOD_BANK_SIZE, UF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
UF::invtype::VIEW_MOD_LIMBO_SIZE, UF::invtype::ALT_STORAGE_SIZE, UF::invtype::ARCHIVED_SIZE,
UF::INULL, UF::INULL, UF::INULL,
UF::invtype::OTHER_SIZE
UF::INULL, UF::INULL, UF::invtype::OTHER_SIZE
),
UF::invslot::EQUIPMENT_BITMASK,
@@ -335,7 +335,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF::invtype::VIEW_MOD_PC_SIZE, RoF::invtype::VIEW_MOD_BANK_SIZE, RoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
RoF::invtype::VIEW_MOD_LIMBO_SIZE, RoF::invtype::ALT_STORAGE_SIZE, RoF::invtype::ARCHIVED_SIZE,
RoF::invtype::MAIL_SIZE, RoF::invtype::GUILD_TROPHY_TRIBUTE_SIZE, RoF::INULL,
RoF::invtype::OTHER_SIZE
RoF::INULL,RoF::INULL,RoF::invtype::OTHER_SIZE
),
RoF::invslot::EQUIPMENT_BITMASK,
@@ -362,7 +362,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::invtype::ALT_STORAGE_SIZE, RoF2::invtype::ARCHIVED_SIZE,
RoF2::invtype::MAIL_SIZE, RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE, RoF2::invtype::KRONO_SIZE,
RoF2::invtype::OTHER_SIZE
RoF2::invtype::GUILD_BANK_MAIN_SIZE,RoF2::invtype::GUILD_BANK_DEPOSIT_SIZE, RoF2::invtype::OTHER_SIZE
),
RoF2::invslot::EQUIPMENT_BITMASK,
@@ -389,7 +389,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,EntityLimits::NPC::INULL
),
EntityLimits::NPC::INULL,
@@ -416,7 +416,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL
),
EntityLimits::NPCMerchant::INULL,
@@ -443,7 +443,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL
),
EntityLimits::Merc::INULL,
@@ -470,7 +470,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EntityLimits::Bot::INULL
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL
),
EntityLimits::Bot::invslot::EQUIPMENT_BITMASK,
@@ -497,7 +497,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL
),
EntityLimits::ClientPet::INULL,
@@ -524,7 +524,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL
),
EntityLimits::NPCPet::INULL,
@@ -551,7 +551,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL
),
EntityLimits::MercPet::INULL,
@@ -578,7 +578,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL
),
EntityLimits::BotPet::INULL,
@@ -605,7 +605,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Titanium::invtype::VIEW_MOD_PC_SIZE, Titanium::invtype::VIEW_MOD_BANK_SIZE, Titanium::invtype::VIEW_MOD_SHARED_BANK_SIZE,
Titanium::invtype::VIEW_MOD_LIMBO_SIZE, Titanium::INULL, Titanium::INULL,
Titanium::INULL, Titanium::INULL, Titanium::INULL,
Titanium::INULL
Titanium::INULL, Titanium::INULL, Titanium::INULL
),
Titanium::INULL,
@@ -632,7 +632,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoF::invtype::VIEW_MOD_PC_SIZE, SoF::invtype::VIEW_MOD_BANK_SIZE, SoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
SoF::invtype::VIEW_MOD_LIMBO_SIZE, SoF::INULL, SoF::INULL,
SoF::INULL, SoF::INULL, SoF::INULL,
SoF::INULL
SoF::INULL, SoF::INULL, SoF::INULL
),
SoF::INULL,
@@ -659,7 +659,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoD::invtype::VIEW_MOD_PC_SIZE, SoD::invtype::VIEW_MOD_BANK_SIZE, SoD::invtype::VIEW_MOD_SHARED_BANK_SIZE,
SoD::invtype::VIEW_MOD_LIMBO_SIZE, SoD::INULL, SoD::INULL,
SoD::INULL, SoD::INULL, SoD::INULL,
SoD::INULL
SoD::INULL, SoD::INULL, SoD::INULL
),
SoD::INULL,
@@ -686,7 +686,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
UF::invtype::VIEW_MOD_PC_SIZE, UF::invtype::VIEW_MOD_BANK_SIZE, UF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
UF::invtype::VIEW_MOD_LIMBO_SIZE, UF::INULL, UF::INULL,
UF::INULL, UF::INULL, UF::INULL,
UF::INULL
UF::INULL, UF::INULL, UF::INULL
),
UF::INULL,
@@ -713,7 +713,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF::invtype::VIEW_MOD_PC_SIZE, RoF::invtype::VIEW_MOD_BANK_SIZE, RoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
RoF::invtype::VIEW_MOD_LIMBO_SIZE, RoF::INULL, RoF::INULL,
RoF::INULL, RoF::INULL, RoF::INULL,
RoF::INULL
RoF::INULL, RoF::INULL, RoF::INULL
),
RoF::INULL,
@@ -740,7 +740,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::INULL, RoF2::INULL,
RoF2::INULL, RoF2::INULL, RoF2::INULL,
RoF2::INULL
RoF2::INULL, RoF2::INULL, RoF2::INULL
),
RoF2::INULL,
+3 -3
View File
@@ -87,7 +87,7 @@ namespace EQ
int16 ViewMODPC, ViewMODBank, ViewMODSharedBank;
int16 ViewMODLimbo, AltStorage, Archived;
int16 Mail, GuildTrophyTribute, Krono;
int16 Other;
int16 GuildBankMain,GuildBankDeposit, Other;
InventoryTypeSize_Struct(
int16 Possessions, int16 Bank, int16 SharedBank,
@@ -98,7 +98,7 @@ namespace EQ
int16 ViewMODPC, int16 ViewMODBank, int16 ViewMODSharedBank,
int16 ViewMODLimbo, int16 AltStorage, int16 Archived,
int16 Mail, int16 GuildTrophyTribute, int16 Krono,
int16 Other
int16 GuildBankMain,int16 GuildBankDeposit, int16 Other
) :
Possessions(Possessions), Bank(Bank), SharedBank(SharedBank),
Trade(Trade), World(World), Limbo(Limbo),
@@ -108,7 +108,7 @@ namespace EQ
ViewMODPC(ViewMODPC), ViewMODBank(ViewMODBank), ViewMODSharedBank(ViewMODSharedBank),
ViewMODLimbo(ViewMODLimbo), AltStorage(AltStorage), Archived(Archived),
Mail(Mail), GuildTrophyTribute(GuildTrophyTribute), Krono(Krono),
Other(Other)
GuildBankMain(GuildBankMain), GuildBankDeposit(GuildBankDeposit), Other(Other)
{ }
};
+58 -45
View File
@@ -19,17 +19,17 @@
#ifndef EQ_PACKET_STRUCTS_H
#define EQ_PACKET_STRUCTS_H
#include "types.h"
#include <list>
#include <string.h>
#include <string>
#include <list>
#include <time.h>
#include "../common/version.h"
#include "emu_constants.h"
#include "textures.h"
#include "../cereal/include/cereal/archives/binary.hpp"
#include "../cereal/include/cereal/types/string.hpp"
#include "../cereal/include/cereal/types/vector.hpp"
#include "../common/version.h"
#include "emu_constants.h"
#include "textures.h"
#include "types.h"
static const uint32 BUFF_COUNT = 42;
static const uint32 PET_BUFF_COUNT = 30;
@@ -47,7 +47,7 @@ static const uint32 ADVANCED_LORE_LENGTH = 8192;
*/
#pragma pack(1)
struct LoginInfo_Struct {
struct LoginInfo {
/*000*/ char login_info[64];
/*064*/ uint8 unknown064[124];
/*188*/ uint8 zoning; // 01 if zoning, 00 if not
@@ -4283,6 +4283,10 @@ struct NewCombine_Struct {
/*04*/
};
struct TradeSkillRecipeInspect_Struct {
uint32 recipe_id;
uint32 padding[17]; // unknown
};
//client requesting favorite recipies
struct TradeskillFavorites_Struct {
@@ -5525,56 +5529,65 @@ struct GuildBankWithdrawItem_Struct
struct GuildBankItemUpdate_Struct
{
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
void Init(
uint32 inAction,
uint32 inUnknown004,
uint16 inSlotID,
uint16 inArea,
uint16 inUnknown012,
uint32 inItemID,
uint32 inIcon,
uint32 inQuantity,
uint32 inPermissions,
uint32 inAllowMerge,
bool inUseable)
{
Action = inAction;
Unknown004 = inUnknown004;
SlotID = inSlotID;
Area = inArea;
Unknown012 = inUnknown012;
ItemID = inItemID;
Icon = inIcon;
Quantity = inQuantity;
Permissions = inPermissions;
AllowMerge = inAllowMerge;
Useable = inUseable;
ItemName[0] = '\0';
Donator[0] = '\0';
WhoFor[0] = '\0';
action = inAction;
unknown004 = inUnknown004;
slot_id = inSlotID;
area = inArea;
display = inUnknown012;
item_id = inItemID;
icon_id = inIcon;
quantity = inQuantity;
permissions = inPermissions;
allow_merge = inAllowMerge;
is_useable = inUseable;
item_name[0] = '\0';
donator[0] = '\0';
who_for[0] = '\0';
};
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint16 SlotID;
/*010*/ uint16 Area;
/*012*/ uint32 Unknown012;
/*016*/ uint32 ItemID;
/*020*/ uint32 Icon;
/*024*/ uint32 Quantity;
/*028*/ uint32 Permissions;
/*032*/ uint8 AllowMerge;
/*033*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
/*034*/ char ItemName[64];
/*098*/ char Donator[64];
/*162*/ char WhoFor[64];
/*226*/ uint16 Unknown226;
/*000*/ uint32 action;
/*004*/ uint32 unknown004;
/*008*/ uint16 slot_id;
/*010*/ uint16 area;
/*012*/ uint32 display;
/*016*/ uint32 item_id;
/*020*/ uint32 icon_id;
/*024*/ uint32 quantity;
/*028*/ uint32 permissions;
/*032*/ uint8 allow_merge;
/*033*/ uint8 is_useable; // Used in conjunction with the Public-if-useable permission.
/*034*/ char item_name[64];
/*098*/ char donator[64];
/*162*/ char who_for[64];
/*226*/ uint16 unknown226;
};
// newer clients (RoF+) send a list that contains 240 entries
// The packets don't actually use all 64 chars in the strings, but we'll just overallocate for these
struct GuildBankItemListEntry_Struct
{
uint8 vaild;
struct GuildBankItemListEntry_Struct {
uint8 vaild;
uint32 permissions;
char whofor[64];
char donator[64];
char whofor[64];
char donator[64];
uint32 item_id;
uint32 item_icon;
uint32 quantity;
uint8 allow_merge; // 1 here for non-full stacks
uint8 usable;
char item_name[64];
uint8 allow_merge; // 1 here for non-full stacks
uint8 usable;
char item_name[64];
};
struct GuildBankClear_Struct
+2
View File
@@ -147,6 +147,8 @@ void EQEmuConfig::parse_config()
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
QSHost = _root["server"]["queryserver"].get("host", "localhost").asString();
QSPort = Strings::ToUnsignedInt(_root["server"]["queryserver"].get("port", "9500").asString());
/**
* Zones
+3 -1
View File
@@ -81,7 +81,9 @@ class EQEmuConfig
std::string QSDatabaseUsername;
std::string QSDatabasePassword;
std::string QSDatabaseDB;
uint16 QSDatabasePort;
uint16 QSDatabasePort;
std::string QSHost;
int QSPort;
// From <files/>
std::string SpellsFile;
+4
View File
@@ -105,6 +105,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::EqTime].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::NpcHandin].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NpcHandin].log_to_gmsay = static_cast<uint8>(Logs::General);
/**
* RFC 5424
@@ -599,6 +601,8 @@ void EQEmuLogSys::SilenceConsoleLogging()
log_settings[log_index].is_category_enabled = 0;
}
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::MySQLError);
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::Error);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
}
+11 -1
View File
@@ -145,6 +145,11 @@ namespace Logs {
EvolveItem,
PositionUpdate,
KSM,
BotSettings,
BotSpellChecks,
BotSpellTypeChecks,
NpcHandin,
ZoneState,
MaxCategoryID /* Don't Remove this */
};
@@ -248,7 +253,12 @@ namespace Logs {
"XTargets",
"EvolveItem",
"PositionUpdate",
"KSM" // Kernel Samepage Merging
"KSM", // Kernel Samepage Merging
"Bot Settings",
"Bot Spell Checks",
"Bot Spell Type Checks",
"NpcHandin",
"ZoneState"
};
}
+50
View File
@@ -874,6 +874,56 @@
OutF(LogSys, Logs::Detail, Logs::KSM, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBotSettings(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSettings))\
OutF(LogSys, Logs::General, Logs::BotSettings, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBotSettingsDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSettings))\
OutF(LogSys, Logs::Detail, Logs::BotSettings, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBotSpellChecks(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSpellChecks))\
OutF(LogSys, Logs::General, Logs::BotSpellChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBotSpellChecksDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSpellChecks))\
OutF(LogSys, Logs::Detail, Logs::BotSpellChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBotSpellTypeChecks(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSpellTypeChecks))\
OutF(LogSys, Logs::General, Logs::BotSpellTypeChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBotSpellTypeChecksDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSpellTypeChecks))\
OutF(LogSys, Logs::Detail, Logs::BotSpellTypeChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNpcHandin(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::NpcHandin))\
OutF(LogSys, Logs::General, Logs::NpcHandin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNpcHandinDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::NpcHandin))\
OutF(LogSys, Logs::Detail, Logs::NpcHandin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogZoneState(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::ZoneState))\
OutF(LogSys, Logs::General, Logs::ZoneState, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogZoneStateDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::ZoneState))\
OutF(LogSys, Logs::Detail, Logs::ZoneState, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.IsLogEnabled(debug_level, log_category))\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -714,6 +714,18 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
h.charges > 1 ? fmt::format(" Charges: {}", h.charges) : "",
h.attuned ? " (Attuned)" : ""
);
for (int i = 0; i < h.augment_ids.size(); i++) {
if (!Strings::EqualFold(h.augment_names[i], "None")) {
const uint8 slot_id = (i + 1);
handin_items_info += fmt::format(
"Augment {}: {} ({})\n",
slot_id,
h.augment_names[i],
h.augment_ids[i]
);
}
}
}
}
@@ -727,6 +739,18 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
r.charges > 1 ? fmt::format(" Charges: {}", r.charges) : "",
r.attuned ? " (Attuned)" : ""
);
for (int i = 0; i < r.augment_ids.size(); i++) {
if (!Strings::EqualFold(r.augment_names[i], "None")) {
const uint8 slot_id = (i + 1);
return_items_info += fmt::format(
"Augment {}: {} ({})\n",
slot_id,
r.augment_names[i],
r.augment_ids[i]
);
}
}
}
}
@@ -1057,51 +1081,51 @@ std::string PlayerEventDiscordFormatter::FormatTradeEvent(
if (!e.character_1_give_items.empty()) {
for (const auto &i: e.character_1_give_items) {
std::string augment_info;
if (i.aug_1_item_id > 0) {
if (i.augment_1_id > 0) {
augment_info += fmt::format(
"Augment 1: {} ({})",
i.aug_1_item_name,
i.aug_1_item_id
i.augment_1_name,
i.augment_1_id
);
}
if (i.aug_2_item_id > 0) {
if (i.augment_2_id > 0) {
augment_info += fmt::format(
"Augment 2: {} ({})",
i.aug_2_item_name,
i.aug_2_item_id
i.augment_2_name,
i.augment_2_id
);
}
if (i.aug_3_item_id > 0) {
if (i.augment_3_id > 0) {
augment_info += fmt::format(
"Augment 3: {} ({})",
i.aug_3_item_name,
i.aug_3_item_id
i.augment_3_name,
i.augment_3_id
);
}
if (i.aug_4_item_id > 0) {
if (i.augment_4_id > 0) {
augment_info += fmt::format(
"Augment 4: {} ({})\n",
i.aug_4_item_name,
i.aug_4_item_id
i.augment_4_name,
i.augment_4_id
);
}
if (i.aug_5_item_id > 0) {
if (i.augment_5_id > 0) {
augment_info += fmt::format(
"Augment 5: {} ({})\n",
i.aug_5_item_name,
i.aug_5_item_id
i.augment_5_name,
i.augment_5_id
);
}
if (i.aug_6_item_id > 0) {
if (i.augment_6_id > 0) {
augment_info += fmt::format(
"Augment 6: {} ({})",
i.aug_6_item_name,
i.aug_6_item_id
i.augment_6_name,
i.augment_6_id
);
}
@@ -1122,51 +1146,51 @@ std::string PlayerEventDiscordFormatter::FormatTradeEvent(
if (!e.character_2_give_items.empty()) {
for (const auto &i: e.character_2_give_items) {
std::string augment_info;
if (i.aug_1_item_id > 0) {
if (i.augment_1_id > 0) {
augment_info += fmt::format(
"Augment 1: {} ({})",
i.aug_1_item_name,
i.aug_1_item_id
i.augment_1_name,
i.augment_1_id
);
}
if (i.aug_2_item_id > 0) {
if (i.augment_2_id > 0) {
augment_info += fmt::format(
"Augment 2: {} ({})",
i.aug_2_item_name,
i.aug_2_item_id
i.augment_2_name,
i.augment_2_id
);
}
if (i.aug_3_item_id > 0) {
if (i.augment_3_id > 0) {
augment_info += fmt::format(
"Augment 3: {} ({})",
i.aug_3_item_name,
i.aug_3_item_id
i.augment_3_name,
i.augment_3_id
);
}
if (i.aug_4_item_id > 0) {
if (i.augment_4_id > 0) {
augment_info += fmt::format(
"Augment 4: {} ({})\n",
i.aug_4_item_name,
i.aug_4_item_id
i.augment_4_name,
i.augment_4_id
);
}
if (i.aug_5_item_id > 0) {
if (i.augment_5_id > 0) {
augment_info += fmt::format(
"Augment 5: {} ({})\n",
i.aug_5_item_name,
i.aug_5_item_id
i.augment_5_name,
i.augment_5_id
);
}
if (i.aug_6_item_id > 0) {
if (i.augment_6_id > 0) {
augment_info += fmt::format(
"Augment 6: {} ({})",
i.aug_6_item_name,
i.aug_6_item_id
i.augment_6_name,
i.augment_6_id
);
}
+554 -26
View File
@@ -1,14 +1,21 @@
#include <cereal/archives/json.hpp>
#include "player_event_logs.h"
#include "player_event_discord_formatter.h"
#include <cereal/archives/json.hpp>
#include "../platform.h"
#include "../rulesys.h"
#include "player_event_discord_formatter.h"
#include "../repositories/player_event_loot_items_repository.h"
#include "../repositories/player_event_merchant_sell_repository.h"
#include "../repositories/player_event_merchant_purchase_repository.h"
#include "../repositories/player_event_npc_handin_repository.h"
#include "../repositories/player_event_npc_handin_entries_repository.h"
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
// general initialization routine
void PlayerEventLogs::Init()
{
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
@@ -21,6 +28,7 @@ void PlayerEventLogs::Init()
m_settings[i].event_enabled = 1;
m_settings[i].retention_days = 0;
m_settings[i].discord_webhook_id = 0;
m_settings[i].etl_enabled = false;
}
SetSettingsDefaults();
@@ -65,6 +73,7 @@ void PlayerEventLogs::Init()
c.event_name = PlayerEvent::EventName[i];
c.event_enabled = m_settings[i].event_enabled;
c.retention_days = m_settings[i].retention_days;
c.etl_enabled = false;
settings_to_insert.emplace_back(c);
}
}
@@ -72,12 +81,13 @@ void PlayerEventLogs::Init()
if (!settings_to_insert.empty()) {
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
}
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
// on initial boot process truncation
if (processing_in_world || processing_in_qs) {
LoadEtlIds();
ProcessRetentionTruncation();
}
}
@@ -121,23 +131,319 @@ void PlayerEventLogs::ProcessBatchQueue()
return;
}
static std::map<uint32, uint32> counter{};
counter.clear();
for (auto const &e: m_record_batch_queue) {
counter[e.event_type_id]++;
}
BenchTimer benchmark;
EtlQueues etl_queues{};
for (const auto &[type, count]: counter) {
if (count > 0) {
switch (type) {
case PlayerEvent::TRADE:
etl_queues.trade.reserve(count);
break;
case PlayerEvent::SPEECH:
etl_queues.speech.reserve(count);
break;
case PlayerEvent::LOOT_ITEM:
etl_queues.loot_items.reserve(count);
break;
case PlayerEvent::KILLED_NPC:
etl_queues.killed_npc.reserve(count);
break;
case PlayerEvent::NPC_HANDIN:
etl_queues.npc_handin.reserve(count);
break;
case PlayerEvent::AA_PURCHASE:
etl_queues.aa_purchase.reserve(count);
break;
case PlayerEvent::MERCHANT_SELL:
etl_queues.merchant_sell.reserve(count);
break;
case PlayerEvent::KILLED_RAID_NPC:
etl_queues.killed_raid_npc.reserve(count);
break;
case PlayerEvent::KILLED_NAMED_NPC:
etl_queues.killed_named_npc.reserve(count);
break;
case PlayerEvent::MERCHANT_PURCHASE:
etl_queues.merchant_purchase.reserve(count);
break;
default:
break;
}
}
}
// Helper to deserialize event data
auto Deserialize = [](const std::string &data, auto &out) {
std::stringstream ss(data);
cereal::JSONInputArchive ar(ss);
out.serialize(ar);
};
// Helper to assign ETL table ID
auto AssignEtlId = [&](
PlayerEventLogsRepository::PlayerEventLogs &r,
PlayerEvent::EventType type
) {
if (m_etl_settings.contains(type)) {
r.etl_table_id = m_etl_settings.at(type).next_id++;
}
};
// Define event processors
std::unordered_map<PlayerEvent::EventType, std::function<void(PlayerEventLogsRepository::PlayerEventLogs &)>> event_processors = {
{
PlayerEvent::EventType::LOOT_ITEM, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::LootItemEvent in{};
PlayerEventLootItemsRepository::PlayerEventLootItems out{};
Deserialize(r.event_data, in);
out.charges = in.charges;
out.corpse_name = in.corpse_name;
out.item_id = in.item_id;
out.item_name = in.item_name;
out.augment_1_id = in.augment_1_id;
out.augment_2_id = in.augment_2_id;
out.augment_3_id = in.augment_3_id;
out.augment_4_id = in.augment_4_id;
out.augment_5_id = in.augment_5_id;
out.augment_6_id = in.augment_6_id;
out.npc_id = in.npc_id;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::LOOT_ITEM);
etl_queues.loot_items.push_back(out);
}
},
{
PlayerEvent::EventType::MERCHANT_SELL, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::MerchantSellEvent in{};
PlayerEventMerchantSellRepository::PlayerEventMerchantSell out{};
Deserialize(r.event_data, in);
out.npc_id = in.npc_id;
out.merchant_name = in.merchant_name;
out.merchant_type = in.merchant_type;
out.item_id = in.item_id;
out.item_name = in.item_name;
out.charges = in.charges;
out.cost = in.cost;
out.alternate_currency_id = in.alternate_currency_id;
out.player_money_balance = in.player_money_balance;
out.player_currency_balance = in.player_currency_balance;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::MERCHANT_SELL);
etl_queues.merchant_sell.push_back(out);
}},
{
PlayerEvent::EventType::MERCHANT_PURCHASE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::MerchantPurchaseEvent in{};
PlayerEventMerchantPurchaseRepository::PlayerEventMerchantPurchase out{};
Deserialize(r.event_data, in);
out.npc_id = in.npc_id;
out.merchant_name = in.merchant_name;
out.merchant_type = in.merchant_type;
out.item_id = in.item_id;
out.item_name = in.item_name;
out.charges = in.charges;
out.cost = in.cost;
out.alternate_currency_id = in.alternate_currency_id;
out.player_money_balance = in.player_money_balance;
out.player_currency_balance = in.player_currency_balance;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::MERCHANT_PURCHASE);
etl_queues.merchant_purchase.push_back(out);
}},
{
PlayerEvent::EventType::NPC_HANDIN, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::HandinEvent in{};
PlayerEventNpcHandinRepository::PlayerEventNpcHandin out{};
Deserialize(r.event_data, in);
out.npc_id = in.npc_id;
out.npc_name = in.npc_name;
out.handin_copper = in.handin_money.copper;
out.handin_silver = in.handin_money.silver;
out.handin_gold = in.handin_money.gold;
out.handin_platinum = in.handin_money.platinum;
out.return_copper = in.return_money.copper;
out.return_silver = in.return_money.silver;
out.return_gold = in.return_money.gold;
out.return_platinum = in.return_money.platinum;
out.is_quest_handin = in.is_quest_handin;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::NPC_HANDIN);
etl_queues.npc_handin.push_back(out);
for (const auto &i: in.handin_items) {
PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries entry{};
entry.player_event_npc_handin_id = r.etl_table_id;
entry.item_id = i.item_id;
entry.charges = i.charges;
entry.type = 1;
etl_queues.npc_handin_entries.push_back(entry);
}
for (const auto &i: in.return_items) {
PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries entry{};
entry.player_event_npc_handin_id = r.etl_table_id;
entry.item_id = i.item_id;
entry.charges = i.charges;
entry.type = 2;
etl_queues.npc_handin_entries.push_back(entry);
}
}},
{
PlayerEvent::EventType::TRADE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::TradeEvent in{};
PlayerEventTradeRepository::PlayerEventTrade out{};
Deserialize(r.event_data, in);
out.char1_id = in.character_1_id;
out.char2_id = in.character_2_id;
out.char1_copper = in.character_1_give_money.copper;
out.char1_silver = in.character_1_give_money.silver;
out.char1_gold = in.character_1_give_money.gold;
out.char1_platinum = in.character_1_give_money.platinum;
out.char2_copper = in.character_2_give_money.copper;
out.char2_silver = in.character_2_give_money.silver;
out.char2_gold = in.character_2_give_money.gold;
out.char2_platinum = in.character_2_give_money.platinum;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::TRADE);
etl_queues.trade.push_back(out);
for (const auto &i: in.character_1_give_items) {
PlayerEventTradeEntriesRepository::PlayerEventTradeEntries entry{};
entry.player_event_trade_id = r.etl_table_id;
entry.char_id = in.character_1_id;
entry.item_id = i.item_id;
entry.charges = i.charges;
entry.slot = i.slot;
etl_queues.trade_entries.push_back(entry);
}
for (const auto &i: in.character_2_give_items) {
PlayerEventTradeEntriesRepository::PlayerEventTradeEntries entry{};
entry.player_event_trade_id = r.etl_table_id;
entry.char_id = in.character_2_id;
entry.item_id = i.item_id;
entry.charges = i.charges;
entry.slot = i.slot;
etl_queues.trade_entries.push_back(entry);
}
}},
{
PlayerEvent::EventType::SPEECH, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::PlayerSpeech in{};
PlayerEventSpeechRepository::PlayerEventSpeech out{};
Deserialize(r.event_data, in);
out.from_char_id = in.from;
out.to_char_id = in.to;
out.type = in.type;
out.min_status = in.min_status;
out.message = in.message;
out.guild_id = in.guild_id;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::SPEECH);
etl_queues.speech.push_back(out);
}},
{
PlayerEvent::EventType::KILLED_NPC, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::KilledNPCEvent in{};
PlayerEventKilledNpcRepository::PlayerEventKilledNpc out{};
Deserialize(r.event_data, in);
out.npc_id = in.npc_id;
out.npc_name = in.npc_name;
out.combat_time_seconds = in.combat_time_seconds;
out.total_damage_per_second_taken = in.total_damage_per_second_taken;
out.total_heal_per_second_taken = in.total_heal_per_second_taken;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::KILLED_NPC);
etl_queues.killed_npc.push_back(out);
}},
{
PlayerEvent::EventType::AA_PURCHASE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
PlayerEvent::AAPurchasedEvent in{};
PlayerEventAaPurchaseRepository::PlayerEventAaPurchase out{};
Deserialize(r.event_data, in);
out.aa_ability_id = in.aa_id;
out.cost = in.aa_cost;
out.previous_id = in.aa_previous_id;
out.next_id = in.aa_next_id;
out.created_at = r.created_at;
AssignEtlId(r, PlayerEvent::EventType::AA_PURCHASE);
etl_queues.aa_purchase.push_back(out);
}},
};
// Process the batch queue
for (auto &r: m_record_batch_queue) {
if (m_settings[r.event_type_id].etl_enabled) {
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
if (it != event_processors.end()) {
it->second(r); // Call the appropriate lambda
r.event_data = "{}"; // Clear event data
}
else {
LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id);
}
}
}
// Helper to flush and clear queues
auto flush_queue = [&](auto insert_many, auto &queue) {
if (!queue.empty()) {
insert_many(*m_database, queue);
queue.clear();
}
};
// flush many
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
LogPlayerEventsDetail(
// flush etl queues
flush_queue(PlayerEventLootItemsRepository::InsertMany, etl_queues.loot_items);
flush_queue(PlayerEventMerchantSellRepository::InsertMany, etl_queues.merchant_sell);
flush_queue(PlayerEventMerchantPurchaseRepository::InsertMany, etl_queues.merchant_purchase);
flush_queue(PlayerEventNpcHandinRepository::InsertMany, etl_queues.npc_handin);
flush_queue(PlayerEventNpcHandinEntriesRepository::InsertMany, etl_queues.npc_handin_entries);
flush_queue(PlayerEventTradeRepository::InsertMany, etl_queues.trade);
flush_queue(PlayerEventTradeEntriesRepository::InsertMany, etl_queues.trade_entries);
flush_queue(PlayerEventSpeechRepository::InsertMany, etl_queues.speech);
flush_queue(PlayerEventKilledNpcRepository::InsertMany, etl_queues.killed_npc);
flush_queue(PlayerEventKilledNamedNpcRepository::InsertMany, etl_queues.killed_named_npc);
flush_queue(PlayerEventKilledRaidNpcRepository::InsertMany, etl_queues.killed_raid_npc);
flush_queue(PlayerEventAaPurchaseRepository::InsertMany, etl_queues.aa_purchase);
LogPlayerEvents(
"Processing batch player event log queue of [{}] took [{}]",
m_record_batch_queue.size(),
benchmark.elapsed()
);
// empty
m_record_batch_queue = {};
m_record_batch_queue.clear();
m_batch_queue_lock.unlock();
}
// adds a player event to the queue
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
void PlayerEventLogs::AddToQueue(PlayerEventLogsRepository::PlayerEventLogs &log)
{
m_batch_queue_lock.lock();
m_record_batch_queue.emplace_back(log);
@@ -588,7 +894,7 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
break;
}
default: {
LogInfo(
LogPlayerEventsDetail(
"Player event [{}] ({}) Discord formatter not implemented",
e.player_event_log.event_type_name,
e.player_event_log.event_type_id
@@ -602,7 +908,8 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
void PlayerEventLogs::Process()
{
if (m_process_batch_events_timer.Check() || m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
if (m_process_batch_events_timer.Check() ||
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
ProcessBatchQueue();
}
@@ -613,29 +920,115 @@ void PlayerEventLogs::Process()
void PlayerEventLogs::ProcessRetentionTruncation()
{
LogPlayerEvents("Running truncation");
LogPlayerEventsDetail("Running truncation");
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
// Map of repository-specific deletion functions
std::unordered_map<PlayerEvent::EventType, std::function<uint32(const std::string &)>> repository_deleters = {
{
PlayerEvent::LOOT_ITEM, [&](const std::string &condition) {
return PlayerEventLootItemsRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::MERCHANT_SELL, [&](const std::string &condition) {
return PlayerEventMerchantSellRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::MERCHANT_PURCHASE, [&](const std::string &condition) {
return PlayerEventMerchantPurchaseRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::NPC_HANDIN, [&](const std::string &condition) {
uint32 deleted_count = PlayerEventNpcHandinRepository::DeleteWhere(*m_database, condition);
deleted_count += PlayerEventNpcHandinEntriesRepository::DeleteWhere(*m_database, condition);
return deleted_count;
}},
{
PlayerEvent::TRADE, [&](const std::string &condition) {
uint32 deleted_count = PlayerEventTradeRepository::DeleteWhere(*m_database, condition);
deleted_count += PlayerEventTradeEntriesRepository::DeleteWhere(*m_database, condition);
return deleted_count;
}},
{
PlayerEvent::SPEECH, [&](const std::string &condition) {
return PlayerEventSpeechRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::KILLED_NPC, [&](const std::string &condition) {
return PlayerEventKilledNpcRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::KILLED_NAMED_NPC, [&](const std::string &condition) {
return PlayerEventKilledNamedNpcRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::KILLED_RAID_NPC, [&](const std::string &condition) {
return PlayerEventKilledRaidNpcRepository::DeleteWhere(*m_database, condition);
}},
{
PlayerEvent::AA_PURCHASE, [&](const std::string &condition) {
return PlayerEventAaPurchaseRepository::DeleteWhere(*m_database, condition);
}}
};
// Group event types by retention interval
std::unordered_map<int, std::vector<int>> retention_groups;
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
if (m_settings[i].retention_days > 0) {
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
*m_database,
fmt::format(
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
i,
m_settings[i].retention_days
)
);
retention_groups[m_settings[i].retention_days].push_back(i);
}
}
if (deleted_count > 0) {
LogInfo(
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
deleted_count,
PlayerEvent::EventName[i],
i,
m_settings[i].retention_days
);
for (const auto &[retention_days, event_types]: retention_groups) {
std::string condition = fmt::format(
"created_at < (NOW() - INTERVAL {} DAY)",
retention_days
);
// Handle ETL deletions for each event type in the group
uint32 total_deleted_count = 0;
for (int event_type_id: event_types) {
if (m_settings[event_type_id].etl_enabled) {
auto it = repository_deleters.find(static_cast<PlayerEvent::EventType>(m_settings[event_type_id].id));
if (it != repository_deleters.end()) {
total_deleted_count += it->second(condition);
}
else {
LogError("Non-Implemented ETL Event Type [{}]", static_cast<uint32>(m_settings[event_type_id].id));
}
}
}
if (total_deleted_count > 0) {
LogInfo(
"Truncated [{}] ETL events older than [{}] days",
total_deleted_count,
retention_days
);
}
// Batch deletion for player_event_logs
std::string event_type_ids = fmt::format(
"({})",
fmt::join(event_types, ", ")
);
uint32 deleted_count = PlayerEventLogsRepository::DeleteWhere(
*m_database,
fmt::format(
"event_type_id IN {} AND {}",
event_type_ids,
condition
)
);
if (deleted_count > 0) {
LogInfo(
"Truncated [{}] events of types [{}] older than [{}] days",
deleted_count,
event_type_ids,
retention_days
);
}
}
}
@@ -708,8 +1101,143 @@ void PlayerEventLogs::SetSettingsDefaults()
m_settings[PlayerEvent::PARCEL_DELETE].event_enabled = 1;
m_settings[PlayerEvent::BARTER_TRANSACTION].event_enabled = 1;
m_settings[PlayerEvent::EVOLVE_ITEM].event_enabled = 1;
m_settings[PlayerEvent::SPEECH].event_enabled = 0;
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
}
}
void PlayerEventLogs::LoadEtlIds()
{
auto e = [&](auto p) -> bool {
for (PlayerEventLogSettingsRepository::PlayerEventLogSettings const &c: m_settings) {
if (c.id == p) {
return c.etl_enabled ? true : false;
}
}
return false;
};
m_etl_settings.clear();
m_etl_settings = {
{
PlayerEvent::LOOT_ITEM,
{
.enabled = e(PlayerEvent::LOOT_ITEM),
.table_name = "player_event_loot_items",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventLootItemsRepository::TableName()))
}
},
{
PlayerEvent::MERCHANT_SELL,
{
.enabled = e(PlayerEvent::MERCHANT_SELL),
.table_name = "player_event_merchant_sell",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventMerchantSellRepository::TableName()))
}
},
{
PlayerEvent::MERCHANT_PURCHASE,
{
.enabled = e(PlayerEvent::MERCHANT_PURCHASE),
.table_name = "player_event_merchant_purchase",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventMerchantPurchaseRepository::TableName()))
}
},
{
PlayerEvent::NPC_HANDIN,
{
.enabled = e(PlayerEvent::NPC_HANDIN),
.table_name = "player_event_npc_handin",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventNpcHandinRepository::TableName()))
}
},
{
PlayerEvent::TRADE,
{
.enabled = e(PlayerEvent::TRADE),
.table_name = "player_event_trade",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventTradeRepository::TableName()))
}
},
{
PlayerEvent::SPEECH,
{
.enabled = e(PlayerEvent::SPEECH),
.table_name = "player_event_speech",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventSpeechRepository::TableName()))
}
},
{
PlayerEvent::KILLED_NPC,
{
.enabled = e(PlayerEvent::KILLED_NPC),
.table_name = "player_event_killed_npc",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledNpcRepository::TableName()))
}
},
{
PlayerEvent::KILLED_NAMED_NPC,
{
.enabled = e(PlayerEvent::KILLED_NAMED_NPC),
.table_name = "player_event_killed_named_npc",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledNamedNpcRepository::TableName()))
}
},
{
PlayerEvent::KILLED_RAID_NPC,
{
.enabled = e(PlayerEvent::KILLED_RAID_NPC),
.table_name = "player_event_killed_raid_npc",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledRaidNpcRepository::TableName()))
}
},
{
PlayerEvent::AA_PURCHASE,
{
.enabled = e(PlayerEvent::AA_PURCHASE),
.table_name = "player_event_aa_purchase",
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventAaPurchaseRepository::TableName()))
}
}
};
for (auto &e: m_etl_settings) {
LogPlayerEventsDetail(
"ETL Settings [{}] Enabled [{}] Table [{}] NextId [{}]",
PlayerEvent::EventName[e.first],
e.second.enabled,
e.second.table_name,
e.second.next_id
);
}
}
bool PlayerEventLogs::LoadDatabaseConnection()
{
const auto c = EQEmuConfig::get();
LogInfo(
"Connecting to MySQL for PlayerEvents [{}]@[{}]:[{}]",
c->DatabaseUsername.c_str(),
c->DatabaseHost.c_str(),
c->DatabasePort
);
if (!player_event_database.Connect(
c->DatabaseHost.c_str(),
c->DatabaseUsername.c_str(),
c->DatabasePassword.c_str(),
c->DatabaseDB.c_str(),
c->DatabasePort
)) {
LogError("Cannot continue without a database connection for player events.");
return false;
}
SetDatabase(&player_event_database);
return true;
}
+53 -7
View File
@@ -1,19 +1,38 @@
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
#define EQEMU_PLAYER_EVENT_LOGS_H
#include "../repositories/player_event_log_settings_repository.h"
#include "player_events.h"
#include "../servertalk.h"
#include "../repositories/player_event_logs_repository.h"
#include "../timer.h"
#include "../json/json_archive_single_line.h"
#include <cereal/archives/json.hpp>
#include <mutex>
#include "../json/json_archive_single_line.h"
#include "../servertalk.h"
#include "../timer.h"
#include "../eqemu_config.h"
#include "../repositories/player_event_log_settings_repository.h"
#include "../repositories/player_event_logs_repository.h"
#include "../repositories/player_event_loot_items_repository.h"
#include "../repositories/player_event_merchant_purchase_repository.h"
#include "../repositories/player_event_merchant_sell_repository.h"
#include "../repositories/player_event_npc_handin_repository.h"
#include "../repositories/player_event_npc_handin_entries_repository.h"
#include "../repositories/player_event_trade_repository.h"
#include "../repositories/player_event_trade_entries_repository.h"
#include "../repositories/player_event_speech_repository.h"
#include "../repositories/player_event_killed_npc_repository.h"
#include "../repositories/player_event_killed_named_npc_repository.h"
#include "../repositories/player_event_killed_raid_npc_repository.h"
#include "../repositories/player_event_aa_purchase_repository.h"
class PlayerEventLogs {
public:
Database player_event_database{};
void Init();
bool LoadDatabaseConnection();
void ReloadSettings();
void LoadEtlIds();
PlayerEventLogs *SetDatabase(Database *db);
bool ValidateDatabaseConnection();
bool IsEventEnabled(PlayerEvent::EventType event);
@@ -21,7 +40,7 @@ public:
void Process();
// batch queue
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
void AddToQueue(PlayerEventLogsRepository::PlayerEventLogs &logs);
// main event record generic function
// can ingest any struct event types
@@ -59,7 +78,29 @@ public:
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
struct EtlQueues {
std::vector<PlayerEventLootItemsRepository::PlayerEventLootItems> loot_items;
std::vector<PlayerEventMerchantPurchaseRepository::PlayerEventMerchantPurchase> merchant_purchase;
std::vector<PlayerEventMerchantSellRepository::PlayerEventMerchantSell> merchant_sell;
std::vector<PlayerEventNpcHandinRepository::PlayerEventNpcHandin> npc_handin;
std::vector<PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries> npc_handin_entries;
std::vector<PlayerEventTradeRepository::PlayerEventTrade> trade;
std::vector<PlayerEventTradeEntriesRepository::PlayerEventTradeEntries> trade_entries;
std::vector<PlayerEventSpeechRepository::PlayerEventSpeech> speech;
std::vector<PlayerEventKilledNpcRepository::PlayerEventKilledNpc> killed_npc;
std::vector<PlayerEventKilledNamedNpcRepository::PlayerEventKilledNamedNpc> killed_named_npc;
std::vector<PlayerEventKilledRaidNpcRepository::PlayerEventKilledRaidNpc> killed_raid_npc;
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
};
private:
struct EtlSettings {
bool enabled;
std::string table_name;
int64 next_id;
};
Database *m_database; // reference to database
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
@@ -69,6 +110,8 @@ private:
static std::unique_ptr<ServerPacket>
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
// timers
Timer m_process_batch_events_timer; // events processing timer
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
@@ -78,6 +121,9 @@ private:
void ProcessBatchQueue();
void ProcessRetentionTruncation();
void SetSettingsDefaults();
public:
std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;}
};
extern PlayerEventLogs player_event_logs;
+316 -116
View File
@@ -4,6 +4,7 @@
#include <string>
#include <cereal/cereal.hpp>
#include "../types.h"
#include "../rulesys.h"
#include "../repositories/player_event_logs_repository.h"
namespace PlayerEvent {
@@ -62,7 +63,11 @@ namespace PlayerEvent {
PARCEL_RETRIEVE,
PARCEL_DELETE,
BARTER_TRANSACTION,
SPEECH,
EVOLVE_ITEM,
GUILD_BANK_DEPOSIT,
GUILD_BANK_WITHDRAWAL,
GUILD_BANK_MOVE_TO_BANK_AREA,
MAX // dont remove
};
@@ -126,7 +131,11 @@ namespace PlayerEvent {
"Parcel Item Retrieved",
"Parcel Prune Routine",
"Barter Transaction",
"Evolve Item Update"
"Player Speech",
"Evolve Item Update",
"Guild Bank Item Deposit",
"Guild Bank Item Withdrawal",
"Guild Bank Move From Deposit Area to Bank Area"
};
// Generic struct used by all events
@@ -206,12 +215,12 @@ namespace PlayerEvent {
std::string item_name;
uint16 to_slot;
int16 charges;
uint32 aug1;
uint32 aug2;
uint32 aug3;
uint32 aug4;
uint32 aug5;
uint32 aug6;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
bool attuned;
// cereal
@@ -223,56 +232,57 @@ namespace PlayerEvent {
CEREAL_NVP(item_name),
CEREAL_NVP(to_slot),
CEREAL_NVP(charges),
CEREAL_NVP(aug1),
CEREAL_NVP(aug2),
CEREAL_NVP(aug3),
CEREAL_NVP(aug4),
CEREAL_NVP(aug5),
CEREAL_NVP(aug6),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(attuned)
);
}
};
// used in Trade event
struct TradeItem {
int64 item_id;
std::string item_name;
int32 slot;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(slot)
);
}
};
// struct TradeItem {
// int64 item_id;
// std::string item_name;
// int32 slot;
//
// // cereal
// template<class Archive>
// void serialize(Archive &ar)
// {
// ar(
// CEREAL_NVP(item_id),
// CEREAL_NVP(item_name),
// CEREAL_NVP(slot)
// );
// }
// };
// used in Trade event
class TradeItemEntry {
public:
uint16 slot;
uint32 item_id;
uint32 augment_1_id;
std::string augment_1_name;
uint32 augment_2_id;
std::string augment_2_name;
uint32 augment_3_id;
std::string augment_3_name;
uint32 augment_4_id;
std::string augment_4_name;
uint32 augment_5_id;
std::string augment_5_name;
uint32 augment_6_id;
std::string augment_6_name;
std::string item_name;
uint16 charges;
uint32 aug_1_item_id;
std::string aug_1_item_name;
uint32 aug_2_item_id;
std::string aug_2_item_name;
uint32 aug_3_item_id;
std::string aug_3_item_name;
uint32 aug_4_item_id;
std::string aug_4_item_name;
uint32 aug_5_item_id;
std::string aug_5_item_name;
uint32 aug_6_item_id;
std::string aug_6_item_name;
bool in_bag;
// cereal
template<class Archive>
void serialize(Archive &ar)
@@ -280,12 +290,20 @@ namespace PlayerEvent {
ar(
CEREAL_NVP(slot),
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_1_name),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_2_name),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_1_name),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_4_name),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_5_name),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(augment_6_name),
CEREAL_NVP(item_name),
CEREAL_NVP(charges),
CEREAL_NVP(aug_1_item_id),
CEREAL_NVP(aug_2_item_id),
CEREAL_NVP(aug_3_item_id),
CEREAL_NVP(aug_4_item_id),
CEREAL_NVP(aug_5_item_id),
CEREAL_NVP(in_bag)
);
}
@@ -399,9 +417,9 @@ namespace PlayerEvent {
struct AAPurchasedEvent {
uint32 aa_id;
int32 aa_cost;
int32 aa_previous_id;
int32 aa_next_id;
int32 aa_cost;
int32 aa_previous_id;
int32 aa_next_id;
// cereal
template<class Archive>
@@ -418,6 +436,12 @@ namespace PlayerEvent {
struct ForageSuccessEvent {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
std::string item_name;
// cereal
@@ -426,6 +450,12 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(item_name)
);
}
@@ -433,6 +463,12 @@ namespace PlayerEvent {
struct FishSuccessEvent {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
std::string item_name;
// cereal
@@ -441,6 +477,12 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(item_name)
);
}
@@ -450,6 +492,13 @@ namespace PlayerEvent {
uint32 item_id;
std::string item_name;
int16 charges;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
bool attuned;
std::string reason;
// cereal
@@ -459,8 +508,15 @@ namespace PlayerEvent {
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(reason),
CEREAL_NVP(charges)
CEREAL_NVP(charges),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(attuned),
CEREAL_NVP(reason)
);
}
};
@@ -503,6 +559,12 @@ namespace PlayerEvent {
uint32 item_id;
std::string item_name;
int16 charges;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
uint32 npc_id;
std::string corpse_name;
@@ -514,6 +576,12 @@ namespace PlayerEvent {
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(charges),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(npc_id),
CEREAL_NVP(corpse_name)
);
@@ -726,6 +794,12 @@ namespace PlayerEvent {
struct DroppedItemEvent {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
std::string item_name;
int16 slot_id;
uint32 charges;
@@ -736,6 +810,12 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(item_name),
CEREAL_NVP(slot_id),
CEREAL_NVP(charges)
@@ -791,12 +871,19 @@ namespace PlayerEvent {
struct TraderPurchaseEvent {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
std::string item_name;
uint32 trader_id;
std::string trader_name;
uint32 price;
uint32 charges;
uint32 total_cost;
uint32 quantity;
int32 charges;
uint64 total_cost;
uint64 player_money_balance;
@@ -806,10 +893,17 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(item_name),
CEREAL_NVP(trader_id),
CEREAL_NVP(trader_name),
CEREAL_NVP(price),
CEREAL_NVP(quantity),
CEREAL_NVP(charges),
CEREAL_NVP(total_cost),
CEREAL_NVP(player_money_balance)
@@ -819,12 +913,19 @@ namespace PlayerEvent {
struct TraderSellEvent {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
std::string item_name;
uint32 buyer_id;
std::string buyer_name;
uint32 price;
uint32 charges;
uint32 total_cost;
uint32 quantity;
int32 charges;
uint64 total_cost;
uint64 player_money_balance;
@@ -834,10 +935,17 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(item_name),
CEREAL_NVP(buyer_id),
CEREAL_NVP(buyer_name),
CEREAL_NVP(price),
CEREAL_NVP(quantity),
CEREAL_NVP(charges),
CEREAL_NVP(total_cost),
CEREAL_NVP(player_money_balance)
@@ -964,8 +1072,16 @@ namespace PlayerEvent {
};
struct GuildTributeDonateItem {
uint32 item_id;
uint32 guild_favor;
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
int16 charges;
bool attuned;
uint32 guild_favor;
// cereal
template<class Archive>
@@ -973,14 +1089,20 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(guild_favor)
);
}
};
struct GuildTributeDonatePlat {
uint32 plat;
uint32 guild_favor;
uint32 plat;
uint32 guild_favor;
// cereal
template<class Archive>
@@ -995,15 +1117,15 @@ namespace PlayerEvent {
struct ParcelRetrieve {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
uint32 quantity;
std::string from_player_name;
uint32 sent_date;
uint32 aug_slot_1;
uint32 aug_slot_2;
uint32 aug_slot_3;
uint32 aug_slot_4;
uint32 aug_slot_5;
uint32 aug_slot_6;
// cereal
template<class Archive>
@@ -1011,31 +1133,32 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(quantity),
CEREAL_NVP(from_player_name),
CEREAL_NVP(sent_date),
CEREAL_NVP(aug_slot_1),
CEREAL_NVP(aug_slot_2),
CEREAL_NVP(aug_slot_3),
CEREAL_NVP(aug_slot_4),
CEREAL_NVP(aug_slot_5),
CEREAL_NVP(aug_slot_6)
CEREAL_NVP(sent_date)
);
}
};
struct ParcelSend {
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
uint32 quantity;
int32 charges;
std::string from_player_name;
std::string to_player_name;
uint32 sent_date;
uint32 aug_slot_1;
uint32 aug_slot_2;
uint32 aug_slot_3;
uint32 aug_slot_4;
uint32 aug_slot_5;
uint32 aug_slot_6;
// cereal
template<class Archive>
@@ -1043,33 +1166,34 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(quantity),
CEREAL_NVP(charges),
CEREAL_NVP(from_player_name),
CEREAL_NVP(to_player_name),
CEREAL_NVP(sent_date),
CEREAL_NVP(aug_slot_1),
CEREAL_NVP(aug_slot_2),
CEREAL_NVP(aug_slot_3),
CEREAL_NVP(aug_slot_4),
CEREAL_NVP(aug_slot_5),
CEREAL_NVP(aug_slot_6)
CEREAL_NVP(sent_date)
);
}
};
struct ParcelDelete {
uint32 item_id;
uint32 quantity;
uint32 char_id;
uint32 item_id;
uint32 augment_1_id;
uint32 augment_2_id;
uint32 augment_3_id;
uint32 augment_4_id;
uint32 augment_5_id;
uint32 augment_6_id;
uint32 quantity;
uint32 sent_date;
std::string from_name;
std::string note;
uint32 sent_date;
uint32 aug_slot_1;
uint32 aug_slot_2;
uint32 aug_slot_3;
uint32 aug_slot_4;
uint32 aug_slot_5;
uint32 aug_slot_6;
// cereal
template<class Archive>
@@ -1077,18 +1201,18 @@ namespace PlayerEvent {
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(augment_1_id),
CEREAL_NVP(augment_2_id),
CEREAL_NVP(augment_3_id),
CEREAL_NVP(augment_4_id),
CEREAL_NVP(augment_5_id),
CEREAL_NVP(augment_6_id),
CEREAL_NVP(quantity),
CEREAL_NVP(char_id),
CEREAL_NVP(from_name),
CEREAL_NVP(note),
CEREAL_NVP(sent_date),
CEREAL_NVP(aug_slot_1),
CEREAL_NVP(aug_slot_2),
CEREAL_NVP(aug_slot_3),
CEREAL_NVP(aug_slot_4),
CEREAL_NVP(aug_slot_5),
CEREAL_NVP(aug_slot_6)
);
CEREAL_NVP(sent_date)
);
}
};
@@ -1140,30 +1264,106 @@ namespace PlayerEvent {
);
}
};
struct PlayerSpeech {
std::string to;
std::string from;
uint32 guild_id;
int16 min_status;
uint32 type;
std::string message;
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(to),
CEREAL_NVP(from),
CEREAL_NVP(guild_id),
CEREAL_NVP(min_status),
CEREAL_NVP(type),
CEREAL_NVP(message)
);
}
};
struct GuildBankTransaction {
uint32 char_id;
uint32 guild_id;
uint32 item_id;
uint32 aug_slot_one;
uint32 aug_slot_two;
uint32 aug_slot_three;
uint32 aug_slot_four;
uint32 aug_slot_five;
uint32 aug_slot_six;
uint32 quantity;
uint32 permission;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(char_id),
CEREAL_NVP(guild_id),
CEREAL_NVP(item_id),
CEREAL_NVP(aug_slot_one),
CEREAL_NVP(aug_slot_two),
CEREAL_NVP(aug_slot_three),
CEREAL_NVP(aug_slot_four),
CEREAL_NVP(aug_slot_five),
CEREAL_NVP(aug_slot_six),
CEREAL_NVP(quantity)
);
}
};
}
#endif //EQEMU_PLAYER_EVENTS_H
#define RecordPlayerEventLog(event_type, event_data) do {\
if (player_event_logs.IsEventEnabled(event_type)) {\
worldserver.SendPacket(\
player_event_logs.RecordEvent(\
event_type,\
GetPlayerEvent(),\
event_data\
).get()\
);\
if (RuleB(Logging, PlayerEventsQSProcess)) {\
QServ->SendPacket(\
player_event_logs.RecordEvent(\
event_type,\
GetPlayerEvent(),\
event_data\
).get()\
);\
} \
else { \
worldserver.SendPacket(\
player_event_logs.RecordEvent(\
event_type,\
GetPlayerEvent(),\
event_data\
).get()\
);\
}\
}\
} while (0)
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
if (player_event_logs.IsEventEnabled(event_type)) {\
worldserver.SendPacket(\
player_event_logs.RecordEvent(\
event_type,\
(c)->GetPlayerEvent(),\
event_data\
).get()\
);\
if (RuleB(Logging, PlayerEventsQSProcess)) {\
QServ->SendPacket(\
player_event_logs.RecordEvent(\
event_type,\
(c)->GetPlayerEvent(),\
event_data\
).get()\
);\
}\
else {\
worldserver.SendPacket(\
player_event_logs.RecordEvent(\
event_type,\
(c)->GetPlayerEvent(),\
event_data\
).get()\
);\
}\
}\
} while (0)
-101
View File
@@ -1,101 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "expedition_lockout_timer.h"
#include "../common/strings.h"
#include "../common/rulesys.h"
#include "../common/util/uuid.h"
#include <fmt/format.h>
const char* const DZ_REPLAY_TIMER_NAME = "Replay Timer"; // see December 14, 2016 patch notes
ExpeditionLockoutTimer::ExpeditionLockoutTimer(
std::string expedition_uuid, std::string expedition_name,
std::string event_name, uint64_t expire_time, uint32_t duration
) :
m_expedition_uuid{std::move(expedition_uuid)},
m_expedition_name{std::move(expedition_name)},
m_event_name{std::move(event_name)},
m_expire_time(std::chrono::system_clock::from_time_t(expire_time)),
m_duration(duration)
{
if (m_event_name == DZ_REPLAY_TIMER_NAME)
{
m_is_replay_timer = true;
}
}
ExpeditionLockoutTimer ExpeditionLockoutTimer::CreateLockout(
const std::string& expedition_name, const std::string& event_name, uint32_t seconds, std::string uuid)
{
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
if (uuid.empty())
{
uuid = EQ::Util::UUID::Generate().ToString();
}
ExpeditionLockoutTimer lockout{uuid, expedition_name, event_name, 0, seconds};
lockout.Reset(); // sets expire time
return lockout;
}
uint32_t ExpeditionLockoutTimer::GetSecondsRemaining() const
{
auto now = std::chrono::system_clock::now();
if (m_expire_time > now)
{
auto remaining = m_expire_time - now;
return static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::seconds>(remaining).count());
}
return 0;
}
ExpeditionLockoutTimer::DaysHoursMinutes ExpeditionLockoutTimer::GetDaysHoursMinutesRemaining() const
{
auto seconds = GetSecondsRemaining();
return ExpeditionLockoutTimer::DaysHoursMinutes{
fmt::format_int(seconds / 86400).str(), // days
fmt::format_int((seconds / 3600) % 24).str(), // hours
fmt::format_int((seconds / 60) % 60).str() // minutes
};
}
bool ExpeditionLockoutTimer::IsSameLockout(const ExpeditionLockoutTimer& compare_lockout) const
{
return compare_lockout.IsSameLockout(GetExpeditionName(), GetEventName());
}
bool ExpeditionLockoutTimer::IsSameLockout(
const std::string& expedition_name, const std::string& event_name) const
{
return GetExpeditionName() == expedition_name && GetEventName() == event_name;
}
void ExpeditionLockoutTimer::AddLockoutTime(int seconds)
{
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
auto new_duration = std::max(0, static_cast<int>(m_duration.count()) + seconds);
auto start_time = m_expire_time - m_duration;
m_duration = std::chrono::seconds(new_duration);
m_expire_time = start_time + m_duration;
}
-76
View File
@@ -1,76 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef EXPEDITION_LOCKOUT_TIMER_H
#define EXPEDITION_LOCKOUT_TIMER_H
#include <chrono>
#include <string>
extern const char* const DZ_REPLAY_TIMER_NAME;
class ExpeditionLockoutTimer
{
public:
ExpeditionLockoutTimer() = default;
ExpeditionLockoutTimer(
std::string expedition_uuid, std::string expedition_name,
std::string event_name, uint64_t expire_time, uint32_t duration);
static ExpeditionLockoutTimer CreateLockout(
const std::string& expedition_name, const std::string& event_name,
uint32_t seconds, std::string uuid = {});
struct DaysHoursMinutes
{
std::string days;
std::string hours;
std::string mins;
};
void AddLockoutTime(int seconds);
uint32_t GetDuration() const { return static_cast<uint32_t>(m_duration.count()); }
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
uint64_t GetStartTime() const { return std::chrono::system_clock::to_time_t(m_expire_time - m_duration); }
uint32_t GetSecondsRemaining() const;
DaysHoursMinutes GetDaysHoursMinutesRemaining() const;
const std::string& GetExpeditionName() const { return m_expedition_name; }
const std::string& GetExpeditionUUID() const { return m_expedition_uuid; }
const std::string& GetEventName() const { return m_event_name; }
bool IsExpired() const { return GetSecondsRemaining() == 0; }
bool IsFromExpedition(const std::string& uuid) const { return uuid == m_expedition_uuid; }
bool IsReplayTimer() const { return m_is_replay_timer; }
bool IsSameLockout(const ExpeditionLockoutTimer& compare_lockout) const;
bool IsSameLockout(const std::string& expedition_name, const std::string& event_name) const;
void Reset() { m_expire_time = std::chrono::system_clock::now() + m_duration; }
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
void SetExpireTime(uint64_t expire_time) { m_expire_time = std::chrono::system_clock::from_time_t(expire_time); }
void SetUUID(const std::string& uuid) { m_expedition_uuid = uuid; }
private:
bool m_is_replay_timer = false;
std::string m_expedition_uuid; // expedition received in
std::string m_expedition_name;
std::string m_event_name;
std::chrono::seconds m_duration;
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
};
#endif
+12 -13
View File
@@ -39,6 +39,7 @@
#include <filesystem>
#include <iostream>
#include <sys/stat.h>
#include <vector>
namespace fs = std::filesystem;
@@ -90,23 +91,21 @@ std::string File::GetCwd()
FileContentsResult File::GetContents(const std::string &file_name)
{
std::string error;
std::ifstream f;
f.open(file_name);
std::string line;
std::string lines;
if (f.is_open()) {
while (f) {
std::getline(f, line);
lines += line + "\n";
}
std::ifstream f(file_name, std::ios::in | std::ios::binary);
if (!f) {
return { .error = fmt::format("Couldn't open file [{}]", file_name) };
}
else {
error = fmt::format("Couldn't open file [{}]", file_name);
constexpr size_t CHUNK_SIZE = 4096; // Read 4KB chunks
std::string lines;
std::vector<char> buffer(CHUNK_SIZE);
while (f.read(buffer.data(), CHUNK_SIZE) || f.gcount() > 0) {
lines.append(buffer.data(), f.gcount());
}
return FileContentsResult{
.contents = lines,
.error = error,
.error = {}
};
}
+28 -26
View File
@@ -547,60 +547,62 @@ uint32 BaseGuildManager::UpdateDbCreateGuild(std::string name, uint32 leader)
bool BaseGuildManager::UpdateDbDeleteGuild(uint32 guild_id, bool local_delete, bool db_delete)
{
auto const where_filter = fmt::format("guild_id = {}", guild_id);
auto const bank_items = GuildBankRepository::GetWhere(*m_db, where_filter);
if (local_delete) {
auto where_filter = fmt::format("guildid = {}", guild_id);
auto bank_items = GuildBankRepository::GetWhere(*m_db, where_filter);
if (!bank_items.empty()) {
LogError(
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try again.",
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try "
"again.",
guild_id,
bank_items.size()
);
LogGuilds(
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try again.",
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try "
"again.",
guild_id,
bank_items.size()
);
return false;
}
else {
std::map<uint32, GuildInfo *>::iterator res;
res = m_guilds.find(guild_id);
if (res != m_guilds.end()) {
delete res->second;
m_guilds.erase(res);
LogGuilds("Deleted guild [{}] from memory", guild_id);
//Does this need to be sent to world?
}
auto res = m_guilds.find(guild_id);
if (res != m_guilds.end()) {
safe_delete(res->second);
m_guilds.erase(res);
LogGuilds("Deleted guild [{}] from memory", guild_id);
// Does this need to be sent to world?
}
}
if (db_delete) {
auto where_filter = fmt::format("guildid = {}", guild_id);
auto bank_items = GuildBankRepository::GetWhere(*m_db, where_filter);
if (!bank_items.empty()) {
LogError(
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try again.",
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try "
"again.",
guild_id,
bank_items.size()
);
LogGuilds(
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try again.",
"Attempt to delete guild id [{}] that still has [{}] items in the bank. Please remove them and try "
"again.",
guild_id,
bank_items.size()
);
return false;
}
else {
auto where_filter = fmt::format("guild_id = {}", guild_id);
GuildTributesRepository::DeleteOne(*m_db, guild_id);
GuildsRepository::DeleteOne(*m_db, guild_id);
GuildRanksRepository::DeleteWhere(*m_db, where_filter);
GuildPermissionsRepository::DeleteWhere(*m_db, where_filter);
GuildMembersRepository::DeleteWhere(*m_db, where_filter);
LogGuilds("Deleted guild [{}] from the database", guild_id);
}
GuildTributesRepository::DeleteOne(*m_db, guild_id);
GuildsRepository::DeleteOne(*m_db, guild_id);
GuildRanksRepository::DeleteWhere(*m_db, where_filter);
GuildPermissionsRepository::DeleteWhere(*m_db, where_filter);
GuildMembersRepository::DeleteWhere(*m_db, where_filter);
LogGuilds("Deleted guild [{}] from the database", guild_id);
}
return true;
}
File diff suppressed because it is too large Load Diff
+1 -9
View File
@@ -178,8 +178,8 @@ namespace EQ
// Locate an available inventory slot
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
std::vector<int16> FindAllFreeSlotsThatFitItem(const EQ::ItemData *inst);
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
int16 FindFirstFreeSlotThatFitsItemWithStacking(ItemInstance *inst) const;
// Calculate slot_id for an item within a bag
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
@@ -201,12 +201,6 @@ namespace EQ
uint8 FindBrightestLightType();
void dumpEntireInventory();
void dumpWornItems();
void dumpInventory();
void dumpBankItems();
void dumpSharedBankItems();
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
@@ -226,8 +220,6 @@ namespace EQ
///////////////////////////////
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
void dumpItemCollection(const std::map<int16, ItemInstance*> &collection);
void dumpBagContents(ItemInstance *inst, std::map<int16, ItemInstance*>::const_iterator *it);
// Retrieves item within an inventory bucket
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
+28
View File
@@ -220,6 +220,34 @@ bool EQ::ItemData::IsType1HWeapon() const
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing) || (ItemType == item::ItemTypeMartial));
}
bool EQ::ItemData::IsPetUsable() const
{
if (ItemClass == item::ItemClassBag) {
return true;
}
// if it's a misc item and has slots, it's wearable
// this item type is conflated with many other item types
if (ItemClass == item::ItemTypeMisc && Slots != 0) {
return true;
}
switch (ItemType) {
case item::ItemType1HBlunt:
case item::ItemType1HSlash:
case item::ItemType1HPiercing:
case item::ItemType2HBlunt:
case item::ItemType2HSlash:
case item::ItemTypeMartial:
case item::ItemTypeShield:
case item::ItemTypeArmor:
case item::ItemTypeJewelry:
return true;
default:
return false;
}
}
bool EQ::ItemData::IsType2HWeapon() const
{
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
+1
View File
@@ -550,6 +550,7 @@ namespace EQ
bool IsType1HWeapon() const;
bool IsType2HWeapon() const;
bool IsTypeShield() const;
bool IsPetUsable() const;
bool IsQuestItem() const;
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
+12
View File
@@ -1785,6 +1785,18 @@ std::vector<uint32> EQ::ItemInstance::GetAugmentIDs() const
return augments;
}
std::vector<std::string> EQ::ItemInstance::GetAugmentNames() const
{
std::vector<std::string> augment_names;
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
const auto augment = GetAugment(slot_id);
augment_names.push_back(augment ? augment->GetItem()->Name : "None");
}
return augment_names;
}
int EQ::ItemInstance::GetItemRegen(bool augments) const
{
int stat = 0;
+1
View File
@@ -305,6 +305,7 @@ namespace EQ
int GetItemSkillsStat(EQ::skills::SkillType skill, bool augments = false) const;
uint32 GetItemGuildFavor() const;
std::vector<uint32> GetAugmentIDs() const;
std::vector<std::string> GetAugmentNames() const;
static void AddGUIDToMap(uint64 existing_serial_number);
static void ClearGUIDMap();
+1
View File
@@ -25,6 +25,7 @@ struct LootItem {
uint16 trivial_max_level;
uint16 npc_min_level;
uint16 npc_max_level;
uint32 lootdrop_id; // required for zone state referencing
};
typedef std::list<LootItem*> LootItems;
+92 -52
View File
@@ -1091,70 +1091,109 @@ void EQ::Net::DaybreakConnection::ProcessResend()
}
}
// observed client receive window is 300 packets, 140KB
constexpr size_t MAX_CLIENT_RECV_PACKETS_PER_WINDOW = 300;
constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
{
if (m_status == DbProtocolStatus::StatusDisconnected) {
return;
}
auto resends = 0;
auto now = Clock::now();
auto s = &m_streams[stream];
for (auto &entry : s->sent_packets) {
auto time_since_last_send = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.last_sent);
if (entry.second.times_resent == 0) {
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
auto &p = entry.second.packet;
if (p.Length() >= DaybreakHeader::size()) {
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
m_stats.resent_fragments++;
}
else {
m_stats.resent_full++;
}
}
else {
m_stats.resent_full++;
}
m_stats.resent_packets++;
if (m_streams[stream].sent_packets.empty()) {
return;
}
InternalBufferedSend(p);
entry.second.last_sent = now;
entry.second.times_resent++;
entry.second.resend_delay = EQ::Clamp(entry.second.resend_delay * 2, m_owner->m_options.resend_delay_min, m_owner->m_options.resend_delay_max);
resends++;
m_resend_packets_sent = 0;
m_resend_bytes_sent = 0;
auto now = Clock::now(); // Current time
auto s = &m_streams[stream];
// Get a reference resend delay (assume first packet represents the typical case)
if (!s->sent_packets.empty()) {
// Check if the first packet has timed out
auto &first_packet = s->sent_packets.begin()->second;
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - first_packet.first_sent).count();
// make sure that the first_packet in the list first_sent time is within the resend_delay and now
// if it is not, then we need to resend all packets in the list
if (time_since_first_sent <= first_packet.resend_delay && !m_acked_since_last_resend) {
LogNetcodeDetail(
"Not resending packets for stream [{}] time since first sent [{}] resend delay [{}] m_acked_since_last_resend [{}]",
stream,
time_since_first_sent,
first_packet.resend_delay,
m_acked_since_last_resend
);
return;
}
if (time_since_first_sent >= m_owner->m_options.resend_timeout) {
Close();
return;
}
}
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Netcode)) {
size_t total_size = 0;
for (auto &e: s->sent_packets) {
total_size += e.second.packet.Length();
}
LogNetcodeDetail(
"Resending packets for stream [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
stream,
s->sent_packets.size(),
total_size,
m_acked_since_last_resend
);
}
for (auto &e: s->sent_packets) {
if (m_resend_packets_sent >= MAX_CLIENT_RECV_PACKETS_PER_WINDOW ||
m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) {
LogNetcodeDetail(
"Stopping resend because we hit thresholds m_resend_packets_sent [{}] max [{}] m_resend_bytes_sent [{}] max [{}]",
m_resend_packets_sent,
MAX_CLIENT_RECV_PACKETS_PER_WINDOW,
m_resend_bytes_sent,
MAX_CLIENT_RECV_BYTES_PER_WINDOW
);
break;
}
auto &sp = e.second;
auto &p = sp.packet;
if (p.Length() >= DaybreakHeader::size()) {
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
m_stats.resent_fragments++;
}
else {
m_stats.resent_full++;
}
}
else {
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.first_sent);
if (time_since_first_sent.count() >= m_owner->m_options.resend_timeout) {
Close();
return;
}
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
auto &p = entry.second.packet;
if (p.Length() >= DaybreakHeader::size()) {
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
m_stats.resent_fragments++;
}
else {
m_stats.resent_full++;
}
}
else {
m_stats.resent_full++;
}
m_stats.resent_packets++;
InternalBufferedSend(p);
entry.second.last_sent = now;
entry.second.times_resent++;
entry.second.resend_delay = EQ::Clamp(entry.second.resend_delay * 2, m_owner->m_options.resend_delay_min, m_owner->m_options.resend_delay_max);
resends++;
}
m_stats.resent_full++;
}
m_stats.resent_packets++;
// Resend the packet
InternalBufferedSend(p);
m_resend_packets_sent++;
m_resend_bytes_sent += p.Length();
sp.last_sent = now;
sp.times_resent++;
sp.resend_delay = EQ::Clamp(
sp.resend_delay * 2,
m_owner->m_options.resend_delay_min,
m_owner->m_options.resend_delay_max
);
}
m_acked_since_last_resend = false;
}
void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
@@ -1175,6 +1214,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
iter = s->sent_packets.erase(iter);
m_acked_since_last_resend = true;
}
else {
++iter;
+5
View File
@@ -181,6 +181,11 @@ namespace EQ
Timestamp m_close_time;
double m_outgoing_budget;
// resend tracking
size_t m_resend_packets_sent = 0;
size_t m_resend_bytes_sent = 0;
bool m_acked_since_last_resend = false;
struct DaybreakSentPacket
{
DynamicPacket packet;
@@ -23,6 +23,9 @@ namespace EQ
bool Connected() const { return m_connecting != true; }
std::shared_ptr<EQ::Net::TCPConnection> Handle() { return m_connection; }
const std::unique_ptr<EQ::Timer> &GetTimer() const { return m_timer; }
private:
void Connect();
void ProcessData(EQ::Net::TCPConnection *c, const unsigned char *data, size_t length);
+5 -5
View File
@@ -25,7 +25,7 @@ void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet
return;
if (opcode == ServerOP_UsertoWorldReq) {
auto req_in = (UsertoWorldRequest_Struct*)p.Data();
auto req_in = (UsertoWorldRequest*)p.Data();
EQ::Net::DynamicPacket req;
size_t i = 0;
@@ -45,7 +45,7 @@ void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet
}
if (opcode == ServerOP_LSClientAuth) {
auto req_in = (ClientAuth_Struct*)p.Data();
auto req_in = (ClientAuth*)p.Data();
EQ::Net::DynamicPacket req;
size_t i = 0;
@@ -54,7 +54,7 @@ void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet
req.PutData(i, req_in->key, 30); i += 30;
req.PutUInt8(i, req_in->lsadmin); i += 1;
req.PutUInt16(i, req_in->is_world_admin); i += 2;
req.PutUInt32(i, req_in->ip); i += 4;
req.PutUInt32(i, req_in->ip_address); i += 4;
req.PutUInt8(i, req_in->is_client_from_local_network); i += 1;
EQ::Net::DynamicPacket out;
@@ -123,7 +123,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
{
size_t current = 0;
size_t total = m_buffer.size();
constexpr size_t ls_info_size = sizeof(ServerNewLSInfo_Struct);
constexpr size_t ls_info_size = sizeof(LoginserverNewWorldRequest);
while (current < total) {
auto left = total - current;
@@ -138,7 +138,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
//this creates a small edge case where the exact size of a
//packet from the modern protocol can't be "43061256"
//so in send we pad it one byte if that's the case
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(ServerNewLSInfo_Struct)) {
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(LoginserverNewWorldRequest)) {
m_legacy_mode = true;
m_identifier = "World";
m_parent->ConnectionIdentified(this);
+1
View File
@@ -197,6 +197,7 @@ IN(OP_RecipeDetails, uint32);
//there is also a complicated OP_RecipeDetails reply struct OUT
IN(OP_RecipeAutoCombine, RecipeAutoCombine_Struct);
IN(OP_TradeSkillCombine, NewCombine_Struct);
IN(OP_TradeSkillRecipeInspect, TradeSkillRecipeInspect_Struct);
IN(OP_ItemName, ItemNamePacket_Struct);
IN(OP_AugmentItem, AugmentItem_Struct);
IN(OP_ClickDoor, ClickDoor_Struct);
+16 -16
View File
@@ -1213,22 +1213,22 @@ namespace RoF
case 1: { // GuildBankItemUpdate
auto emu = (GuildBankItemUpdate_Struct *)in->pBuffer;
auto eq = (structs::GuildBankItemUpdate_Struct *)outapp->pBuffer;
eq->Action = 0;
OUT(Unknown004);
eq->Unknown08 = 0;
OUT(SlotID);
OUT(Area);
OUT(Unknown012);
OUT(ItemID);
OUT(Icon);
OUT(Quantity);
OUT(Permissions);
OUT(AllowMerge);
OUT(Useable);
OUT_str(ItemName);
OUT_str(Donator);
OUT_str(WhoFor);
OUT(Unknown226);
eq->action = 0;
OUT(unknown004);
eq->unknown008 = 0;
OUT(slot_id);
OUT(area);
OUT(display);
OUT(item_id);
OUT(icon_id);
OUT(quantity);
OUT(permissions);
OUT(allow_merge);
OUT(is_useable);
OUT_str(item_name);
OUT_str(donator);
OUT_str(who_for);
OUT(unknown226);
break;
}
default:
+13 -16
View File
@@ -1743,22 +1743,19 @@ namespace RoF2
case 1: { // GuildBankItemUpdate
auto emu = (GuildBankItemUpdate_Struct *)in->pBuffer;
auto eq = (structs::GuildBankItemUpdate_Struct *)outapp->pBuffer;
eq->Action = 0;
OUT(Unknown004);
eq->Unknown08 = 0;
OUT(SlotID);
OUT(Area);
OUT(Unknown012);
OUT(ItemID);
OUT(Icon);
OUT(Quantity);
OUT(Permissions);
OUT(AllowMerge);
OUT(Useable);
OUT_str(ItemName);
OUT_str(Donator);
OUT_str(WhoFor);
OUT(Unknown226);
eq->action = 0;
OUT(display);
OUT(slot_id);
OUT(area);
OUT(item_id);
OUT(icon_id);
OUT(quantity);
OUT(permissions);
OUT(allow_merge);
OUT(is_useable);
OUT_str(item_name);
OUT_str(donator);
OUT_str(who_for);
break;
}
default:
+83 -49
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@ namespace RoF2
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = true;
const bool AllowEmptyBagInBag = true;
const bool AllowClickCastFromBag = true;
} /*inventory*/
@@ -77,38 +77,40 @@ namespace RoF2
} // namespace enum_
using namespace enum_;
const int16 POSSESSIONS_SIZE = 34;
const int16 BANK_SIZE = 24;
const int16 SHARED_BANK_SIZE = 2;
const int16 TRADE_SIZE = 8;
const int16 WORLD_SIZE = 10;
const int16 LIMBO_SIZE = 36;
const int16 TRIBUTE_SIZE = 5;
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
const int16 MERCHANT_SIZE = 200;
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
const int16 BAZAAR_SIZE = 200;
const int16 INSPECT_SIZE = 23;
const int16 REAL_ESTATE_SIZE = 0;//unknown
const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE;
const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE;
const int16 POSSESSIONS_SIZE = 34;
const int16 BANK_SIZE = 24;
const int16 SHARED_BANK_SIZE = 2;
const int16 TRADE_SIZE = 8;
const int16 WORLD_SIZE = 10;
const int16 LIMBO_SIZE = 36;
const int16 TRIBUTE_SIZE = 5;
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
const int16 MERCHANT_SIZE = 500;
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
const int16 BAZAAR_SIZE = 200;
const int16 INSPECT_SIZE = 23;
const int16 REAL_ESTATE_SIZE = 0;//unknown
const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE;
const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE;
const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE;
const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE;
const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank"
const int16 ARCHIVED_SIZE = 0;//unknown
const int16 MAIL_SIZE = 0;//unknown
const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE;
const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank"
const int16 ARCHIVED_SIZE = 0;//unknown
const int16 MAIL_SIZE = 0;//unknown
const int16 GUILD_TROPHY_TRIBUTE_SIZE = 0;//unknown
const int16 KRONO_SIZE = 0;//unknown
const int16 OTHER_SIZE = 0;//unknown
const int16 KRONO_SIZE = 0;//unknown
const int16 GUILD_BANK_MAIN_SIZE = 200;
const int16 GUILD_BANK_DEPOSIT_SIZE = 40;
const int16 OTHER_SIZE = 0;//unknown
const int16 TRADE_NPC_SIZE = 4; // defined by implication
const int16 TYPE_INVALID = IINVALID;
const int16 TYPE_BEGIN = typePossessions;
const int16 TYPE_END = typeOther;
const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1;
const int16 TYPE_BEGIN = typePossessions;
const int16 TYPE_END = typeOther;
const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1;
int16 GetInvTypeSize(int16 inv_type);
const char* GetInvTypeName(int16 inv_type);
@@ -162,33 +164,54 @@ namespace RoF2
} // namespace enum_
using namespace enum_;
const int16 SLOT_INVALID = IINVALID;
const int16 SLOT_BEGIN = INULL;
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
const int16 SLOT_INVALID = IINVALID;
const int16 SLOT_BEGIN = INULL;
const int16 BANK_BEGIN = 2000;
const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1;
const int16 SHARED_BANK_BEGIN = 2500;
const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1;
const int16 TRADE_BEGIN = 3000;
const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1;
const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication
const int16 WORLD_BEGIN = 4000;
const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1;
const int16 TRIBUTE_BEGIN = 400;
const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1;
const int16 GUILD_TRIBUTE_BEGIN = 450;
const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1;
const int16 POSSESSIONS_BEGIN = slotCharm;
const int16 POSSESSIONS_END = slotCursor;
const int16 POSSESSIONS_END = slotCursor;
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
const int16 EQUIPMENT_BEGIN = slotCharm;
const int16 EQUIPMENT_END = slotAmmo;
const int16 EQUIPMENT_END = slotAmmo;
const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN) + 1;
const int16 GENERAL_BEGIN = slotGeneral1;
const int16 GENERAL_END = slotGeneral10;
const int16 GENERAL_END = slotGeneral10;
const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN) + 1;
const int16 BONUS_BEGIN = invslot::slotCharm;
const int16 BONUS_STAT_END = invslot::slotPowerSource;
const int16 BONUS_BEGIN = invslot::slotCharm;
const int16 BONUS_STAT_END = invslot::slotPowerSource;
const int16 BONUS_SKILL_END = invslot::slotAmmo;
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x00000001FF800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x00000001FF800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
@@ -199,10 +222,21 @@ namespace RoF2
namespace invbag {
inline EQ::versions::ClientVersion GetInvBagRef() { return EQ::versions::ClientVersion::RoF2; }
const int16 SLOT_INVALID = IINVALID;
const int16 SLOT_BEGIN = INULL;
const int16 SLOT_END = 9; //254;
const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test)
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
const int16 SLOT_INVALID = IINVALID;
const int16 SLOT_BEGIN = INULL;
const int16 SLOT_COUNT = 200;
const int16 SLOT_END = SLOT_COUNT - 1;
const int16 GENERAL_BAGS_BEGIN = 251;
const int16 CURSOR_BAG_BEGIN = 351;
const int16 BANK_BAGS_BEGIN = 2031;
const int16 SHARED_BANK_BAGS_BEGIN = 2531;
const int16 TRADE_BAGS_BEGIN = 3031;
const char* GetInvBagIndexName(int16 bag_index);
@@ -212,9 +246,9 @@ namespace RoF2
inline EQ::versions::ClientVersion GetInvAugRef() { return EQ::versions::ClientVersion::RoF2; }
const int16 SOCKET_INVALID = IINVALID;
const int16 SOCKET_BEGIN = INULL;
const int16 SOCKET_END = 5;
const int16 SOCKET_COUNT = 6;
const int16 SOCKET_BEGIN = INULL;
const int16 SOCKET_END = 5;
const int16 SOCKET_COUNT = 6;
const char* GetInvAugIndexName(int16 aug_index);
@@ -292,7 +326,7 @@ namespace RoF2
namespace spells {
inline EQ::versions::ClientVersion GetSkillsRef() { return EQ::versions::ClientVersion::RoF2; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
@@ -315,7 +349,7 @@ namespace RoF2
const int SPELL_ID_MAX = 45000;
const int SPELLBOOK_SIZE = 720;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 42;
const int SHORT_BUFFS = 20;
const int DISC_BUFFS = 1;
+35 -32
View File
@@ -1965,41 +1965,39 @@ struct GuildBankWithdrawItem_Struct
struct GuildBankItemUpdate_Struct
{
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown016, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
{
Action = inAction;
Unknown004 = inUnknown004;
SlotID = inSlotID;
Area = inArea;
Unknown012 = inUnknown012;
ItemID = inItemID;
Icon = inIcon;
Quantity = inQuantity;
Permissions = inPermissions;
AllowMerge = inAllowMerge;
Useable = inUseable;
ItemName[0] = '\0';
Donator[0] = '\0';
WhoFor[0] = '\0';
action = inAction;
slot_id = inSlotID;
area = inArea;
display = inUnknown016;
item_id = inItemID;
icon_id = inIcon;
quantity = inQuantity;
permissions = inPermissions;
allow_merge = inAllowMerge;
is_useable = inUseable;
item_name[0] = '\0';
donator[0] = '\0';
who_for[0] = '\0';
};
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown08;
/*012*/ uint16 SlotID;
/*014*/ uint16 Area;
/*016*/ uint32 Unknown012;
/*020*/ uint32 ItemID;
/*024*/ uint32 Icon;
/*028*/ uint32 Quantity;
/*032*/ uint32 Permissions;
/*036*/ uint8 AllowMerge;
/*037*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
/*038*/ char ItemName[64];
/*102*/ char Donator[64];
/*166*/ char WhoFor[64];
/*230*/ uint16 Unknown226;
/*000*/ uint32 action;
/*004*/ uint32 not_used004; //disassemble of client did not use this
/*008*/ uint32 not_used008; //disassemble of client did not use this
/*012*/ uint16 slot_id;
/*014*/ uint16 area;
/*016*/ uint32 display;
/*020*/ uint32 item_id;
/*024*/ uint32 icon_id;
/*028*/ uint32 quantity;
/*032*/ uint32 permissions;
/*036*/ uint8 allow_merge;
/*037*/ uint8 is_useable; // Used in conjunction with the Public-if-useable permission.
/*038*/ char item_name[64];
/*102*/ char donator[64];
/*166*/ char who_for[64];
};
struct GuildBankClear_Struct
@@ -3935,6 +3933,11 @@ struct NewCombine_Struct
/*24*/
};
struct TradeSkillRecipeInspect_Struct {
uint32 recipe_id;
uint32 padding[17];
};
//client requesting favorite recipies
struct TradeskillFavorites_Struct {
@@ -4736,7 +4739,7 @@ struct ItemSerializationHeader
/*036*/ uint32 merchant_slot; // 1 if not a merchant item
/*040*/ uint32 scaled_value; // 0
/*044*/ uint32 instance_id; // unique instance id if not merchant item, else is merchant slot
/*048*/ uint32 parcel_item_id;
/*048*/ uint32 parcel_item_id;
/*052*/ uint32 last_cast_time; // Unix Time from PP of last cast for this recast type if recast delay > 0
/*056*/ uint32 charges; // Total Charges an item has (-1 for unlimited)
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
+30 -30
View File
@@ -1946,38 +1946,38 @@ struct GuildBankItemUpdate_Struct
void Init(uint32 inAction, uint32 inUnknown004, uint16 inSlotID, uint16 inArea, uint16 inUnknown012, uint32 inItemID, uint32 inIcon, uint32 inQuantity,
uint32 inPermissions, uint32 inAllowMerge, bool inUseable)
{
Action = inAction;
Unknown004 = inUnknown004;
SlotID = inSlotID;
Area = inArea;
Unknown012 = inUnknown012;
ItemID = inItemID;
Icon = inIcon;
Quantity = inQuantity;
Permissions = inPermissions;
AllowMerge = inAllowMerge;
Useable = inUseable;
ItemName[0] = '\0';
Donator[0] = '\0';
WhoFor[0] = '\0';
action = inAction;
unknown004 = inUnknown004;
slot_id = inSlotID;
area = inArea;
display = inUnknown012;
item_id = inItemID;
icon_id = inIcon;
quantity = inQuantity;
permissions = inPermissions;
allow_merge = inAllowMerge;
is_useable = inUseable;
item_name[0] = '\0';
donator[0] = '\0';
who_for[0] = '\0';
};
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown08;
/*012*/ uint16 SlotID;
/*014*/ uint16 Area;
/*016*/ uint32 Unknown012;
/*020*/ uint32 ItemID;
/*024*/ uint32 Icon;
/*028*/ uint32 Quantity;
/*032*/ uint32 Permissions;
/*036*/ uint8 AllowMerge;
/*037*/ uint8 Useable; // Used in conjunction with the Public-if-useable permission.
/*038*/ char ItemName[64];
/*102*/ char Donator[64];
/*166*/ char WhoFor[64];
/*230*/ uint16 Unknown226;
/*000*/ uint32 action;
/*004*/ uint32 unknown004;
/*008*/ uint32 unknown008;
/*012*/ uint16 slot_id;
/*014*/ uint16 area;
/*016*/ uint32 display;
/*020*/ uint32 item_id;
/*024*/ uint32 icon_id;
/*028*/ uint32 quantity;
/*032*/ uint32 permissions;
/*036*/ uint8 allow_merge;
/*037*/ uint8 is_useable; // Used in conjunction with the Public-if-useable permission.
/*038*/ char item_name[64];
/*102*/ char donator[64];
/*166*/ char who_for[64];
/*230*/ uint16 unknown226;
};
struct GuildBankClear_Struct
+6 -6
View File
@@ -2463,25 +2463,25 @@ struct WhoAllReturnStruct {
struct BeginTrader_Struct {
uint32 action;
uint32 unknown04;
uint64 serial_number[80];
uint32 cost[80];
uint64 serial_number[EQ::invtype::BAZAAR_SIZE];
uint32 cost[EQ::invtype::BAZAAR_SIZE];
};
struct Trader_Struct {
uint32 action;
uint32 unknown004;
uint64 item_id[80];
uint32 item_cost[80];
uint64 item_id[EQ::invtype::BAZAAR_SIZE];
uint32 item_cost[EQ::invtype::BAZAAR_SIZE];
};
struct ClickTrader_Struct {
uint32 code;
uint32 unknown[161];//damn soe this is totally pointless :/ but at least your finally using memset! Good job :) -LE
uint32 itemcost[80];
uint32 itemcost[EQ::invtype::BAZAAR_SIZE];
};
struct GetItems_Struct{
uint32 items[80];
uint32 items[EQ::invtype::BAZAAR_SIZE];
};
struct BecomeTrader_Struct {
+1 -1
View File
@@ -76,7 +76,7 @@ void PathManager::LoadPaths()
constexpr int path_width = 0;
constexpr int break_length = 70;
std::cout << std::endl;
LogInfo("Loading server paths");
LogInfo("{}", Strings::Repeat("-", break_length));
for (const auto& [name, in_path] : paths) {
if (!in_path.empty()) {
@@ -9,44 +9,44 @@
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_EXPEDITIONS_REPOSITORY_H
#define EQEMU_BASE_EXPEDITIONS_REPOSITORY_H
#ifndef EQEMU_BASE_BOT_BLOCKED_BUFFS_REPOSITORY_H
#define EQEMU_BASE_BOT_BLOCKED_BUFFS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseExpeditionsRepository {
class BaseBotBlockedBuffsRepository {
public:
struct Expeditions {
uint32_t id;
uint32_t dynamic_zone_id;
uint8_t add_replay_on_join;
uint8_t is_locked;
struct BotBlockedBuffs {
uint32_t bot_id;
uint32_t spell_id;
uint8_t blocked;
uint8_t blocked_pet;
};
static std::string PrimaryKey()
{
return std::string("id");
return std::string("bot_id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"dynamic_zone_id",
"add_replay_on_join",
"is_locked",
"bot_id",
"spell_id",
"blocked",
"blocked_pet",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"dynamic_zone_id",
"add_replay_on_join",
"is_locked",
"bot_id",
"spell_id",
"blocked",
"blocked_pet",
};
}
@@ -62,7 +62,7 @@ public:
static std::string TableName()
{
return std::string("expeditions");
return std::string("bot_blocked_buffs");
}
static std::string BaseSelect()
@@ -83,35 +83,35 @@ public:
);
}
static Expeditions NewEntity()
static BotBlockedBuffs NewEntity()
{
Expeditions e{};
BotBlockedBuffs e{};
e.id = 0;
e.dynamic_zone_id = 0;
e.add_replay_on_join = 1;
e.is_locked = 0;
e.bot_id = 0;
e.spell_id = 0;
e.blocked = 0;
e.blocked_pet = 0;
return e;
}
static Expeditions GetExpeditions(
const std::vector<Expeditions> &expeditionss,
int expeditions_id
static BotBlockedBuffs GetBotBlockedBuffs(
const std::vector<BotBlockedBuffs> &bot_blocked_buffss,
int bot_blocked_buffs_id
)
{
for (auto &expeditions : expeditionss) {
if (expeditions.id == expeditions_id) {
return expeditions;
for (auto &bot_blocked_buffs : bot_blocked_buffss) {
if (bot_blocked_buffs.bot_id == bot_blocked_buffs_id) {
return bot_blocked_buffs;
}
}
return NewEntity();
}
static Expeditions FindOne(
static BotBlockedBuffs FindOne(
Database& db,
int expeditions_id
int bot_blocked_buffs_id
)
{
auto results = db.QueryDatabase(
@@ -119,18 +119,18 @@ public:
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
expeditions_id
bot_blocked_buffs_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Expeditions e{};
BotBlockedBuffs e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.dynamic_zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.add_replay_on_join = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 1;
e.is_locked = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
e.bot_id = row[0] ? static_cast<uint32_t>(atoi(row[0])) : 0;
e.spell_id = row[1] ? static_cast<uint32_t>(atoi(row[1])) : 0;
e.blocked = row[2] ? static_cast<uint8_t>(atoi(row[2])) : 0;
e.blocked_pet = row[3] ? static_cast<uint8_t>(atoi(row[3])) : 0;
return e;
}
@@ -140,7 +140,7 @@ public:
static int DeleteOne(
Database& db,
int expeditions_id
int bot_blocked_buffs_id
)
{
auto results = db.QueryDatabase(
@@ -148,7 +148,7 @@ public:
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
expeditions_id
bot_blocked_buffs_id
)
);
@@ -157,16 +157,17 @@ public:
static int UpdateOne(
Database& db,
const Expeditions &e
const BotBlockedBuffs &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.dynamic_zone_id));
v.push_back(columns[2] + " = " + std::to_string(e.add_replay_on_join));
v.push_back(columns[3] + " = " + std::to_string(e.is_locked));
v.push_back(columns[0] + " = " + std::to_string(e.bot_id));
v.push_back(columns[1] + " = " + std::to_string(e.spell_id));
v.push_back(columns[2] + " = " + std::to_string(e.blocked));
v.push_back(columns[3] + " = " + std::to_string(e.blocked_pet));
auto results = db.QueryDatabase(
fmt::format(
@@ -174,24 +175,24 @@ public:
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
e.bot_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static Expeditions InsertOne(
static BotBlockedBuffs InsertOne(
Database& db,
Expeditions e
BotBlockedBuffs e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back(std::to_string(e.add_replay_on_join));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.blocked));
v.push_back(std::to_string(e.blocked_pet));
auto results = db.QueryDatabase(
fmt::format(
@@ -202,7 +203,7 @@ public:
);
if (results.Success()) {
e.id = results.LastInsertedID();
e.bot_id = results.LastInsertedID();
return e;
}
@@ -213,7 +214,7 @@ public:
static int InsertMany(
Database& db,
const std::vector<Expeditions> &entries
const std::vector<BotBlockedBuffs> &entries
)
{
std::vector<std::string> insert_chunks;
@@ -221,10 +222,10 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back(std::to_string(e.add_replay_on_join));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.blocked));
v.push_back(std::to_string(e.blocked_pet));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -242,9 +243,9 @@ public:
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<Expeditions> All(Database& db)
static std::vector<BotBlockedBuffs> All(Database& db)
{
std::vector<Expeditions> all_entries;
std::vector<BotBlockedBuffs> all_entries;
auto results = db.QueryDatabase(
fmt::format(
@@ -256,12 +257,12 @@ public:
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Expeditions e{};
BotBlockedBuffs e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.dynamic_zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.add_replay_on_join = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 1;
e.is_locked = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
e.bot_id = row[0] ? static_cast<uint32_t>(atoi(row[0])) : 0;
e.spell_id = row[1] ? static_cast<uint32_t>(atoi(row[1])) : 0;
e.blocked = row[2] ? static_cast<uint8_t>(atoi(row[2])) : 0;
e.blocked_pet = row[3] ? static_cast<uint8_t>(atoi(row[3])) : 0;
all_entries.push_back(e);
}
@@ -269,9 +270,9 @@ public:
return all_entries;
}
static std::vector<Expeditions> GetWhere(Database& db, const std::string &where_filter)
static std::vector<BotBlockedBuffs> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<Expeditions> all_entries;
std::vector<BotBlockedBuffs> all_entries;
auto results = db.QueryDatabase(
fmt::format(
@@ -284,12 +285,12 @@ public:
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Expeditions e{};
BotBlockedBuffs e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.dynamic_zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.add_replay_on_join = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 1;
e.is_locked = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
e.bot_id = row[0] ? static_cast<uint32_t>(atoi(row[0])) : 0;
e.spell_id = row[1] ? static_cast<uint32_t>(atoi(row[1])) : 0;
e.blocked = row[2] ? static_cast<uint8_t>(atoi(row[2])) : 0;
e.blocked_pet = row[3] ? static_cast<uint8_t>(atoi(row[3])) : 0;
all_entries.push_back(e);
}
@@ -359,15 +360,15 @@ public:
static int ReplaceOne(
Database& db,
const Expeditions &e
const BotBlockedBuffs &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back(std::to_string(e.add_replay_on_join));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.blocked));
v.push_back(std::to_string(e.blocked_pet));
auto results = db.QueryDatabase(
fmt::format(
@@ -382,7 +383,7 @@ public:
static int ReplaceMany(
Database& db,
const std::vector<Expeditions> &entries
const std::vector<BotBlockedBuffs> &entries
)
{
std::vector<std::string> insert_chunks;
@@ -390,10 +391,10 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back(std::to_string(e.add_replay_on_join));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.blocked));
v.push_back(std::to_string(e.blocked_pet));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -412,4 +413,4 @@ public:
}
};
#endif //EQEMU_BASE_EXPEDITIONS_REPOSITORY_H
#endif //EQEMU_BASE_BOT_BLOCKED_BUFFS_REPOSITORY_H
@@ -64,13 +64,6 @@ public:
int16_t poison;
int16_t disease;
int16_t corruption;
uint32_t show_helm;
uint32_t follow_distance;
uint8_t stop_melee_level;
int32_t expansion_bitmask;
uint8_t enforce_spell_settings;
uint8_t archery_setting;
uint32_t caster_range;
};
static std::string PrimaryKey()
@@ -126,13 +119,6 @@ public:
"poison",
"disease",
"corruption",
"show_helm",
"follow_distance",
"stop_melee_level",
"expansion_bitmask",
"enforce_spell_settings",
"archery_setting",
"caster_range",
};
}
@@ -184,13 +170,6 @@ public:
"poison",
"disease",
"corruption",
"show_helm",
"follow_distance",
"stop_melee_level",
"expansion_bitmask",
"enforce_spell_settings",
"archery_setting",
"caster_range",
};
}
@@ -276,13 +255,7 @@ public:
e.poison = 0;
e.disease = 0;
e.corruption = 0;
e.show_helm = 0;
e.follow_distance = 200;
e.stop_melee_level = 255;
e.expansion_bitmask = -1;
e.enforce_spell_settings = 0;
e.archery_setting = 0;
e.caster_range = 300;
return e;
}
@@ -364,13 +337,6 @@ public:
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
return e;
}
@@ -383,14 +349,25 @@ public:
int bot_data_id
)
{
auto results = db.QueryDatabase(
fmt::format(
std::string query;
if (RuleB(Bots, BotSoftDeletes)) {
query = fmt::format(
"UPDATE {} SET name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64) WHERE {} = {}",
TableName(),
PrimaryKey(),
bot_data_id
);
}
else {
query = fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
bot_data_id
)
);
);
}
auto results = db.QueryDatabase(query);
return (results.Success() ? results.RowsAffected() : 0);
}
@@ -448,13 +425,6 @@ public:
v.push_back(columns[42] + " = " + std::to_string(e.poison));
v.push_back(columns[43] + " = " + std::to_string(e.disease));
v.push_back(columns[44] + " = " + std::to_string(e.corruption));
v.push_back(columns[45] + " = " + std::to_string(e.show_helm));
v.push_back(columns[46] + " = " + std::to_string(e.follow_distance));
v.push_back(columns[47] + " = " + std::to_string(e.stop_melee_level));
v.push_back(columns[48] + " = " + std::to_string(e.expansion_bitmask));
v.push_back(columns[49] + " = " + std::to_string(e.enforce_spell_settings));
v.push_back(columns[50] + " = " + std::to_string(e.archery_setting));
v.push_back(columns[51] + " = " + std::to_string(e.caster_range));
auto results = db.QueryDatabase(
fmt::format(
@@ -521,13 +491,6 @@ public:
v.push_back(std::to_string(e.poison));
v.push_back(std::to_string(e.disease));
v.push_back(std::to_string(e.corruption));
v.push_back(std::to_string(e.show_helm));
v.push_back(std::to_string(e.follow_distance));
v.push_back(std::to_string(e.stop_melee_level));
v.push_back(std::to_string(e.expansion_bitmask));
v.push_back(std::to_string(e.enforce_spell_settings));
v.push_back(std::to_string(e.archery_setting));
v.push_back(std::to_string(e.caster_range));
auto results = db.QueryDatabase(
fmt::format(
@@ -602,13 +565,6 @@ public:
v.push_back(std::to_string(e.poison));
v.push_back(std::to_string(e.disease));
v.push_back(std::to_string(e.corruption));
v.push_back(std::to_string(e.show_helm));
v.push_back(std::to_string(e.follow_distance));
v.push_back(std::to_string(e.stop_melee_level));
v.push_back(std::to_string(e.expansion_bitmask));
v.push_back(std::to_string(e.enforce_spell_settings));
v.push_back(std::to_string(e.archery_setting));
v.push_back(std::to_string(e.caster_range));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -687,13 +643,6 @@ public:
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
all_entries.push_back(e);
}
@@ -763,13 +712,6 @@ public:
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
all_entries.push_back(e);
}
@@ -889,13 +831,6 @@ public:
v.push_back(std::to_string(e.poison));
v.push_back(std::to_string(e.disease));
v.push_back(std::to_string(e.corruption));
v.push_back(std::to_string(e.show_helm));
v.push_back(std::to_string(e.follow_distance));
v.push_back(std::to_string(e.stop_melee_level));
v.push_back(std::to_string(e.expansion_bitmask));
v.push_back(std::to_string(e.enforce_spell_settings));
v.push_back(std::to_string(e.archery_setting));
v.push_back(std::to_string(e.caster_range));
auto results = db.QueryDatabase(
fmt::format(
@@ -963,13 +898,6 @@ public:
v.push_back(std::to_string(e.poison));
v.push_back(std::to_string(e.disease));
v.push_back(std::to_string(e.corruption));
v.push_back(std::to_string(e.show_helm));
v.push_back(std::to_string(e.follow_distance));
v.push_back(std::to_string(e.stop_melee_level));
v.push_back(std::to_string(e.expansion_bitmask));
v.push_back(std::to_string(e.enforce_spell_settings));
v.push_back(std::to_string(e.archery_setting));
v.push_back(std::to_string(e.caster_range));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -0,0 +1,464 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_BOT_SETTINGS_REPOSITORY_H
#define EQEMU_BASE_BOT_SETTINGS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseBotSettingsRepository {
public:
struct BotSettings {
uint32_t character_id;
uint32_t bot_id;
uint8_t stance;
uint16_t setting_id;
uint8_t setting_type;
int32_t value;
std::string category_name;
std::string setting_name;
};
static std::string PrimaryKey()
{
return std::string("character_id");
}
static std::vector<std::string> Columns()
{
return {
"character_id",
"bot_id",
"stance",
"setting_id",
"setting_type",
"value",
"category_name",
"setting_name",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"character_id",
"bot_id",
"stance",
"setting_id",
"setting_type",
"value",
"category_name",
"setting_name",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("bot_settings");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static BotSettings NewEntity()
{
BotSettings e{};
e.character_id = 0;
e.bot_id = 0;
e.stance = 0;
e.setting_id = 0;
e.setting_type = 0;
e.value = 0;
e.category_name = "";
e.setting_name = "";
return e;
}
static BotSettings GetBotSettings(
const std::vector<BotSettings> &bot_settingss,
int bot_settings_id
)
{
for (auto &bot_settings : bot_settingss) {
if (bot_settings.character_id == bot_settings_id) {
return bot_settings;
}
}
return NewEntity();
}
static BotSettings FindOne(
Database& db,
int bot_settings_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
bot_settings_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
BotSettings e{};
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.bot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.stance = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.setting_id = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.setting_type = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
e.value = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.category_name = row[6] ? row[6] : "";
e.setting_name = row[7] ? row[7] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int bot_settings_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
bot_settings_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const BotSettings &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.character_id));
v.push_back(columns[1] + " = " + std::to_string(e.bot_id));
v.push_back(columns[2] + " = " + std::to_string(e.stance));
v.push_back(columns[3] + " = " + std::to_string(e.setting_id));
v.push_back(columns[4] + " = " + std::to_string(e.setting_type));
v.push_back(columns[5] + " = " + std::to_string(e.value));
v.push_back(columns[6] + " = '" + Strings::Escape(e.category_name) + "'");
v.push_back(columns[7] + " = '" + Strings::Escape(e.setting_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.character_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static BotSettings InsertOne(
Database& db,
BotSettings e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.stance));
v.push_back(std::to_string(e.setting_id));
v.push_back(std::to_string(e.setting_type));
v.push_back(std::to_string(e.value));
v.push_back("'" + Strings::Escape(e.category_name) + "'");
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.character_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<BotSettings> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.stance));
v.push_back(std::to_string(e.setting_id));
v.push_back(std::to_string(e.setting_type));
v.push_back(std::to_string(e.value));
v.push_back("'" + Strings::Escape(e.category_name) + "'");
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<BotSettings> All(Database& db)
{
std::vector<BotSettings> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BotSettings e{};
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.bot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.stance = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.setting_id = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.setting_type = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
e.value = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.category_name = row[6] ? row[6] : "";
e.setting_name = row[7] ? row[7] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<BotSettings> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<BotSettings> 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) {
BotSettings e{};
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.bot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.stance = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.setting_id = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.setting_type = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
e.value = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.category_name = row[6] ? row[6] : "";
e.setting_name = row[7] ? row[7] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const BotSettings &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.stance));
v.push_back(std::to_string(e.setting_id));
v.push_back(std::to_string(e.setting_type));
v.push_back(std::to_string(e.value));
v.push_back("'" + Strings::Escape(e.category_name) + "'");
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<BotSettings> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.stance));
v.push_back(std::to_string(e.setting_id));
v.push_back(std::to_string(e.setting_type));
v.push_back(std::to_string(e.value));
v.push_back("'" + Strings::Escape(e.category_name) + "'");
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_BOT_SETTINGS_REPOSITORY_H
@@ -123,6 +123,7 @@ public:
uint32_t aa_points_old;
uint32_t e_last_invsnapshot;
time_t deleted_at;
uint8_t illusion_block;
};
static std::string PrimaryKey()
@@ -237,6 +238,7 @@ public:
"aa_points_old",
"e_last_invsnapshot",
"deleted_at",
"illusion_block",
};
}
@@ -347,6 +349,7 @@ public:
"aa_points_old",
"e_last_invsnapshot",
"UNIX_TIMESTAMP(deleted_at)",
"illusion_block",
};
}
@@ -491,6 +494,7 @@ public:
e.aa_points_old = 0;
e.e_last_invsnapshot = 0;
e.deleted_at = 0;
e.illusion_block = 0;
return e;
}
@@ -631,6 +635,7 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
return e;
}
@@ -767,6 +772,7 @@ public:
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(columns[104] + " = " + std::to_string(e.illusion_block));
auto results = db.QueryDatabase(
fmt::format(
@@ -892,6 +898,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
auto results = db.QueryDatabase(
fmt::format(
@@ -1025,6 +1032,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -1162,6 +1170,7 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -1290,6 +1299,7 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -1468,6 +1478,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
auto results = db.QueryDatabase(
fmt::format(
@@ -1594,6 +1605,7 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -23,10 +23,12 @@ public:
std::string key_;
std::string value;
uint32_t expires;
int64_t account_id;
int64_t character_id;
int64_t npc_id;
int64_t bot_id;
uint64_t account_id;
uint64_t character_id;
uint32_t npc_id;
uint32_t bot_id;
uint16_t zone_id;
uint16_t instance_id;
// cereal
template<class Archive>
@@ -40,7 +42,9 @@ public:
CEREAL_NVP(account_id),
CEREAL_NVP(character_id),
CEREAL_NVP(npc_id),
CEREAL_NVP(bot_id)
CEREAL_NVP(bot_id),
CEREAL_NVP(zone_id),
CEREAL_NVP(instance_id)
);
}
};
@@ -61,6 +65,8 @@ public:
"character_id",
"npc_id",
"bot_id",
"zone_id",
"instance_id",
};
}
@@ -75,6 +81,8 @@ public:
"character_id",
"npc_id",
"bot_id",
"zone_id",
"instance_id",
};
}
@@ -123,6 +131,8 @@ public:
e.character_id = 0;
e.npc_id = 0;
e.bot_id = 0;
e.zone_id = 0;
e.instance_id = 0;
return e;
}
@@ -163,10 +173,12 @@ public:
e.key_ = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.account_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
e.character_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
e.npc_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
e.bot_id = row[7] ? strtoll(row[7], nullptr, 10) : 0;
e.account_id = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.character_id = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.npc_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.bot_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.zone_id = row[8] ? static_cast<uint16_t>(strtoul(row[8], nullptr, 10)) : 0;
e.instance_id = row[9] ? static_cast<uint16_t>(strtoul(row[9], nullptr, 10)) : 0;
return e;
}
@@ -207,6 +219,8 @@ public:
v.push_back(columns[5] + " = " + std::to_string(e.character_id));
v.push_back(columns[6] + " = " + std::to_string(e.npc_id));
v.push_back(columns[7] + " = " + std::to_string(e.bot_id));
v.push_back(columns[8] + " = " + std::to_string(e.zone_id));
v.push_back(columns[9] + " = " + std::to_string(e.instance_id));
auto results = db.QueryDatabase(
fmt::format(
@@ -236,6 +250,8 @@ public:
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
auto results = db.QueryDatabase(
fmt::format(
@@ -273,6 +289,8 @@ public:
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -310,10 +328,12 @@ public:
e.key_ = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.account_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
e.character_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
e.npc_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
e.bot_id = row[7] ? strtoll(row[7], nullptr, 10) : 0;
e.account_id = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.character_id = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.npc_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.bot_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.zone_id = row[8] ? static_cast<uint16_t>(strtoul(row[8], nullptr, 10)) : 0;
e.instance_id = row[9] ? static_cast<uint16_t>(strtoul(row[9], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -342,10 +362,12 @@ public:
e.key_ = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : "";
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.account_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
e.character_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
e.npc_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
e.bot_id = row[7] ? strtoll(row[7], nullptr, 10) : 0;
e.account_id = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.character_id = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.npc_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.bot_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.zone_id = row[8] ? static_cast<uint16_t>(strtoul(row[8], nullptr, 10)) : 0;
e.instance_id = row[9] ? static_cast<uint16_t>(strtoul(row[9], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -428,6 +450,8 @@ public:
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
auto results = db.QueryDatabase(
fmt::format(
@@ -458,6 +482,8 @@ public:
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -9,18 +9,18 @@
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_EXPEDITION_LOCKOUTS_REPOSITORY_H
#define EQEMU_BASE_EXPEDITION_LOCKOUTS_REPOSITORY_H
#ifndef EQEMU_BASE_DYNAMIC_ZONE_LOCKOUTS_REPOSITORY_H
#define EQEMU_BASE_DYNAMIC_ZONE_LOCKOUTS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseExpeditionLockoutsRepository {
class BaseDynamicZoneLockoutsRepository {
public:
struct ExpeditionLockouts {
struct DynamicZoneLockouts {
uint32_t id;
uint32_t expedition_id;
uint32_t dynamic_zone_id;
std::string event_name;
time_t expire_time;
uint32_t duration;
@@ -36,7 +36,7 @@ public:
{
return {
"id",
"expedition_id",
"dynamic_zone_id",
"event_name",
"expire_time",
"duration",
@@ -48,7 +48,7 @@ public:
{
return {
"id",
"expedition_id",
"dynamic_zone_id",
"event_name",
"UNIX_TIMESTAMP(expire_time)",
"duration",
@@ -68,7 +68,7 @@ public:
static std::string TableName()
{
return std::string("expedition_lockouts");
return std::string("dynamic_zone_lockouts");
}
static std::string BaseSelect()
@@ -89,12 +89,12 @@ public:
);
}
static ExpeditionLockouts NewEntity()
static DynamicZoneLockouts NewEntity()
{
ExpeditionLockouts e{};
DynamicZoneLockouts e{};
e.id = 0;
e.expedition_id = 0;
e.dynamic_zone_id = 0;
e.event_name = "";
e.expire_time = std::time(nullptr);
e.duration = 0;
@@ -103,23 +103,23 @@ public:
return e;
}
static ExpeditionLockouts GetExpeditionLockouts(
const std::vector<ExpeditionLockouts> &expedition_lockoutss,
int expedition_lockouts_id
static DynamicZoneLockouts GetDynamicZoneLockouts(
const std::vector<DynamicZoneLockouts> &dynamic_zone_lockoutss,
int dynamic_zone_lockouts_id
)
{
for (auto &expedition_lockouts : expedition_lockoutss) {
if (expedition_lockouts.id == expedition_lockouts_id) {
return expedition_lockouts;
for (auto &dynamic_zone_lockouts : dynamic_zone_lockoutss) {
if (dynamic_zone_lockouts.id == dynamic_zone_lockouts_id) {
return dynamic_zone_lockouts;
}
}
return NewEntity();
}
static ExpeditionLockouts FindOne(
static DynamicZoneLockouts FindOne(
Database& db,
int expedition_lockouts_id
int dynamic_zone_lockouts_id
)
{
auto results = db.QueryDatabase(
@@ -127,16 +127,16 @@ public:
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
expedition_lockouts_id
dynamic_zone_lockouts_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
ExpeditionLockouts e{};
DynamicZoneLockouts e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.expedition_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.dynamic_zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.event_name = row[2] ? row[2] : "";
e.expire_time = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
e.duration = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
@@ -150,7 +150,7 @@ public:
static int DeleteOne(
Database& db,
int expedition_lockouts_id
int dynamic_zone_lockouts_id
)
{
auto results = db.QueryDatabase(
@@ -158,7 +158,7 @@ public:
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
expedition_lockouts_id
dynamic_zone_lockouts_id
)
);
@@ -167,14 +167,14 @@ public:
static int UpdateOne(
Database& db,
const ExpeditionLockouts &e
const DynamicZoneLockouts &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.expedition_id));
v.push_back(columns[1] + " = " + std::to_string(e.dynamic_zone_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.event_name) + "'");
v.push_back(columns[3] + " = FROM_UNIXTIME(" + (e.expire_time > 0 ? std::to_string(e.expire_time) : "null") + ")");
v.push_back(columns[4] + " = " + std::to_string(e.duration));
@@ -193,15 +193,15 @@ public:
return (results.Success() ? results.RowsAffected() : 0);
}
static ExpeditionLockouts InsertOne(
static DynamicZoneLockouts InsertOne(
Database& db,
ExpeditionLockouts e
DynamicZoneLockouts e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.expedition_id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back("'" + Strings::Escape(e.event_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.expire_time > 0 ? std::to_string(e.expire_time) : "null") + ")");
v.push_back(std::to_string(e.duration));
@@ -227,7 +227,7 @@ public:
static int InsertMany(
Database& db,
const std::vector<ExpeditionLockouts> &entries
const std::vector<DynamicZoneLockouts> &entries
)
{
std::vector<std::string> insert_chunks;
@@ -236,7 +236,7 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.expedition_id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back("'" + Strings::Escape(e.event_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.expire_time > 0 ? std::to_string(e.expire_time) : "null") + ")");
v.push_back(std::to_string(e.duration));
@@ -258,9 +258,9 @@ public:
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<ExpeditionLockouts> All(Database& db)
static std::vector<DynamicZoneLockouts> All(Database& db)
{
std::vector<ExpeditionLockouts> all_entries;
std::vector<DynamicZoneLockouts> all_entries;
auto results = db.QueryDatabase(
fmt::format(
@@ -272,10 +272,10 @@ public:
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
ExpeditionLockouts e{};
DynamicZoneLockouts e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.expedition_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.dynamic_zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.event_name = row[2] ? row[2] : "";
e.expire_time = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
e.duration = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
@@ -287,9 +287,9 @@ public:
return all_entries;
}
static std::vector<ExpeditionLockouts> GetWhere(Database& db, const std::string &where_filter)
static std::vector<DynamicZoneLockouts> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<ExpeditionLockouts> all_entries;
std::vector<DynamicZoneLockouts> all_entries;
auto results = db.QueryDatabase(
fmt::format(
@@ -302,10 +302,10 @@ public:
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
ExpeditionLockouts e{};
DynamicZoneLockouts e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.expedition_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.dynamic_zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.event_name = row[2] ? row[2] : "";
e.expire_time = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
e.duration = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
@@ -379,13 +379,13 @@ public:
static int ReplaceOne(
Database& db,
const ExpeditionLockouts &e
const DynamicZoneLockouts &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.expedition_id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back("'" + Strings::Escape(e.event_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.expire_time > 0 ? std::to_string(e.expire_time) : "null") + ")");
v.push_back(std::to_string(e.duration));
@@ -404,7 +404,7 @@ public:
static int ReplaceMany(
Database& db,
const std::vector<ExpeditionLockouts> &entries
const std::vector<DynamicZoneLockouts> &entries
)
{
std::vector<std::string> insert_chunks;
@@ -413,7 +413,7 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.expedition_id));
v.push_back(std::to_string(e.dynamic_zone_id));
v.push_back("'" + Strings::Escape(e.event_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.expire_time > 0 ? std::to_string(e.expire_time) : "null") + ")");
v.push_back(std::to_string(e.duration));
@@ -436,4 +436,4 @@ public:
}
};
#endif //EQEMU_BASE_EXPEDITION_LOCKOUTS_REPOSITORY_H
#endif //EQEMU_BASE_DYNAMIC_ZONE_LOCKOUTS_REPOSITORY_H
@@ -42,6 +42,8 @@ public:
float zone_in_z;
float zone_in_heading;
uint8_t has_zone_in;
int8_t is_locked;
int8_t add_replay;
};
static std::string PrimaryKey()
@@ -75,6 +77,8 @@ public:
"zone_in_z",
"zone_in_heading",
"has_zone_in",
"is_locked",
"add_replay",
};
}
@@ -104,6 +108,8 @@ public:
"zone_in_z",
"zone_in_heading",
"has_zone_in",
"is_locked",
"add_replay",
};
}
@@ -167,6 +173,8 @@ public:
e.zone_in_z = 0;
e.zone_in_heading = 0;
e.has_zone_in = 0;
e.is_locked = 0;
e.add_replay = 1;
return e;
}
@@ -226,6 +234,8 @@ public:
e.zone_in_z = row[20] ? strtof(row[20], nullptr) : 0;
e.zone_in_heading = row[21] ? strtof(row[21], nullptr) : 0;
e.has_zone_in = row[22] ? static_cast<uint8_t>(strtoul(row[22], nullptr, 10)) : 0;
e.is_locked = row[23] ? static_cast<int8_t>(atoi(row[23])) : 0;
e.add_replay = row[24] ? static_cast<int8_t>(atoi(row[24])) : 1;
return e;
}
@@ -281,6 +291,8 @@ public:
v.push_back(columns[20] + " = " + std::to_string(e.zone_in_z));
v.push_back(columns[21] + " = " + std::to_string(e.zone_in_heading));
v.push_back(columns[22] + " = " + std::to_string(e.has_zone_in));
v.push_back(columns[23] + " = " + std::to_string(e.is_locked));
v.push_back(columns[24] + " = " + std::to_string(e.add_replay));
auto results = db.QueryDatabase(
fmt::format(
@@ -325,6 +337,8 @@ public:
v.push_back(std::to_string(e.zone_in_z));
v.push_back(std::to_string(e.zone_in_heading));
v.push_back(std::to_string(e.has_zone_in));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.add_replay));
auto results = db.QueryDatabase(
fmt::format(
@@ -377,6 +391,8 @@ public:
v.push_back(std::to_string(e.zone_in_z));
v.push_back(std::to_string(e.zone_in_heading));
v.push_back(std::to_string(e.has_zone_in));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.add_replay));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -433,6 +449,8 @@ public:
e.zone_in_z = row[20] ? strtof(row[20], nullptr) : 0;
e.zone_in_heading = row[21] ? strtof(row[21], nullptr) : 0;
e.has_zone_in = row[22] ? static_cast<uint8_t>(strtoul(row[22], nullptr, 10)) : 0;
e.is_locked = row[23] ? static_cast<int8_t>(atoi(row[23])) : 0;
e.add_replay = row[24] ? static_cast<int8_t>(atoi(row[24])) : 1;
all_entries.push_back(e);
}
@@ -480,6 +498,8 @@ public:
e.zone_in_z = row[20] ? strtof(row[20], nullptr) : 0;
e.zone_in_heading = row[21] ? strtof(row[21], nullptr) : 0;
e.has_zone_in = row[22] ? static_cast<uint8_t>(strtoul(row[22], nullptr, 10)) : 0;
e.is_locked = row[23] ? static_cast<int8_t>(atoi(row[23])) : 0;
e.add_replay = row[24] ? static_cast<int8_t>(atoi(row[24])) : 1;
all_entries.push_back(e);
}
@@ -577,6 +597,8 @@ public:
v.push_back(std::to_string(e.zone_in_z));
v.push_back(std::to_string(e.zone_in_heading));
v.push_back(std::to_string(e.has_zone_in));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.add_replay));
auto results = db.QueryDatabase(
fmt::format(
@@ -622,6 +644,8 @@ public:
v.push_back(std::to_string(e.zone_in_z));
v.push_back(std::to_string(e.zone_in_heading));
v.push_back(std::to_string(e.has_zone_in));
v.push_back(std::to_string(e.is_locked));
v.push_back(std::to_string(e.add_replay));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -6,7 +6,7 @@
* 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
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_GUILD_BANK_REPOSITORY_H
@@ -16,19 +16,24 @@
#include "../../strings.h"
#include <ctime>
class BaseGuildBankRepository {
public:
struct GuildBank {
uint32_t id;
uint32_t guildid;
uint32_t guild_id;
uint8_t area;
uint32_t slot;
uint32_t itemid;
uint32_t qty;
uint32_t item_id;
uint32_t augment_one_id;
uint32_t augment_two_id;
uint32_t augment_three_id;
uint32_t augment_four_id;
uint32_t augment_five_id;
uint32_t augment_six_id;
int32_t quantity;
std::string donator;
uint8_t permissions;
std::string whofor;
std::string who_for;
};
static std::string PrimaryKey()
@@ -40,14 +45,20 @@ public:
{
return {
"id",
"guildid",
"guild_id",
"area",
"slot",
"itemid",
"qty",
"item_id",
"augment_one_id",
"augment_two_id",
"augment_three_id",
"augment_four_id",
"augment_five_id",
"augment_six_id",
"quantity",
"donator",
"permissions",
"whofor",
"who_for",
};
}
@@ -55,14 +66,20 @@ public:
{
return {
"id",
"guildid",
"guild_id",
"area",
"slot",
"itemid",
"qty",
"item_id",
"augment_one_id",
"augment_two_id",
"augment_three_id",
"augment_four_id",
"augment_five_id",
"augment_six_id",
"quantity",
"donator",
"permissions",
"whofor",
"who_for",
};
}
@@ -103,15 +120,21 @@ public:
{
GuildBank e{};
e.id = 0;
e.guildid = 0;
e.area = 0;
e.slot = 0;
e.itemid = 0;
e.qty = 0;
e.donator = "";
e.permissions = 0;
e.whofor = "";
e.id = 0;
e.guild_id = 0;
e.area = 0;
e.slot = 0;
e.item_id = 0;
e.augment_one_id = 0;
e.augment_two_id = 0;
e.augment_three_id = 0;
e.augment_four_id = 0;
e.augment_five_id = 0;
e.augment_six_id = 0;
e.quantity = 0;
e.donator = "";
e.permissions = 0;
e.who_for = "";
return e;
}
@@ -148,15 +171,21 @@ public:
if (results.RowCount() == 1) {
GuildBank e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.guildid = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.area = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.slot = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.itemid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.qty = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.donator = row[6] ? row[6] : "";
e.permissions = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.whofor = row[8] ? row[8] : "";
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.guild_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.area = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.slot = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_one_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.quantity = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
e.donator = row[12] ? row[12] : "";
e.permissions = row[13] ? static_cast<uint8_t>(strtoul(row[13], nullptr, 10)) : 0;
e.who_for = row[14] ? row[14] : "";
return e;
}
@@ -190,14 +219,20 @@ public:
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.guildid));
v.push_back(columns[1] + " = " + std::to_string(e.guild_id));
v.push_back(columns[2] + " = " + std::to_string(e.area));
v.push_back(columns[3] + " = " + std::to_string(e.slot));
v.push_back(columns[4] + " = " + std::to_string(e.itemid));
v.push_back(columns[5] + " = " + std::to_string(e.qty));
v.push_back(columns[6] + " = '" + Strings::Escape(e.donator) + "'");
v.push_back(columns[7] + " = " + std::to_string(e.permissions));
v.push_back(columns[8] + " = '" + Strings::Escape(e.whofor) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.item_id));
v.push_back(columns[5] + " = " + std::to_string(e.augment_one_id));
v.push_back(columns[6] + " = " + std::to_string(e.augment_two_id));
v.push_back(columns[7] + " = " + std::to_string(e.augment_three_id));
v.push_back(columns[8] + " = " + std::to_string(e.augment_four_id));
v.push_back(columns[9] + " = " + std::to_string(e.augment_five_id));
v.push_back(columns[10] + " = " + std::to_string(e.augment_six_id));
v.push_back(columns[11] + " = " + std::to_string(e.quantity));
v.push_back(columns[12] + " = '" + Strings::Escape(e.donator) + "'");
v.push_back(columns[13] + " = " + std::to_string(e.permissions));
v.push_back(columns[14] + " = '" + Strings::Escape(e.who_for) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -220,14 +255,20 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.guildid));
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.area));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.itemid));
v.push_back(std::to_string(e.qty));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.augment_one_id));
v.push_back(std::to_string(e.augment_two_id));
v.push_back(std::to_string(e.augment_three_id));
v.push_back(std::to_string(e.augment_four_id));
v.push_back(std::to_string(e.augment_five_id));
v.push_back(std::to_string(e.augment_six_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.donator) + "'");
v.push_back(std::to_string(e.permissions));
v.push_back("'" + Strings::Escape(e.whofor) + "'");
v.push_back("'" + Strings::Escape(e.who_for) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -258,14 +299,20 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.guildid));
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.area));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.itemid));
v.push_back(std::to_string(e.qty));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.augment_one_id));
v.push_back(std::to_string(e.augment_two_id));
v.push_back(std::to_string(e.augment_three_id));
v.push_back(std::to_string(e.augment_four_id));
v.push_back(std::to_string(e.augment_five_id));
v.push_back(std::to_string(e.augment_six_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.donator) + "'");
v.push_back(std::to_string(e.permissions));
v.push_back("'" + Strings::Escape(e.whofor) + "'");
v.push_back("'" + Strings::Escape(e.who_for) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -299,15 +346,21 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
GuildBank e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.guildid = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.area = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.slot = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.itemid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.qty = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.donator = row[6] ? row[6] : "";
e.permissions = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.whofor = row[8] ? row[8] : "";
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.guild_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.area = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.slot = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_one_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.quantity = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
e.donator = row[12] ? row[12] : "";
e.permissions = row[13] ? static_cast<uint8_t>(strtoul(row[13], nullptr, 10)) : 0;
e.who_for = row[14] ? row[14] : "";
all_entries.push_back(e);
}
@@ -332,15 +385,21 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
GuildBank e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.guildid = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.area = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.slot = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.itemid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.qty = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.donator = row[6] ? row[6] : "";
e.permissions = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.whofor = row[8] ? row[8] : "";
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.guild_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.area = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.slot = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_one_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.quantity = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
e.donator = row[12] ? row[12] : "";
e.permissions = row[13] ? static_cast<uint8_t>(strtoul(row[13], nullptr, 10)) : 0;
e.who_for = row[14] ? row[14] : "";
all_entries.push_back(e);
}
@@ -399,6 +458,90 @@ public:
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const GuildBank &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.area));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.augment_one_id));
v.push_back(std::to_string(e.augment_two_id));
v.push_back(std::to_string(e.augment_three_id));
v.push_back(std::to_string(e.augment_four_id));
v.push_back(std::to_string(e.augment_five_id));
v.push_back(std::to_string(e.augment_six_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.donator) + "'");
v.push_back(std::to_string(e.permissions));
v.push_back("'" + Strings::Escape(e.who_for) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<GuildBank> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.area));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.augment_one_id));
v.push_back(std::to_string(e.augment_two_id));
v.push_back(std::to_string(e.augment_three_id));
v.push_back(std::to_string(e.augment_four_id));
v.push_back(std::to_string(e.augment_five_id));
v.push_back(std::to_string(e.augment_six_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.donator) + "'");
v.push_back(std::to_string(e.permissions));
v.push_back("'" + Strings::Escape(e.who_for) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_GUILD_BANK_REPOSITORY_H
@@ -19,48 +19,48 @@
class BaseInventoryRepository {
public:
struct Inventory {
uint32_t charid;
uint32_t slotid;
uint32_t itemid;
uint32_t character_id;
uint32_t slot_id;
uint32_t item_id;
uint16_t charges;
uint32_t color;
uint32_t augslot1;
uint32_t augslot2;
uint32_t augslot3;
uint32_t augslot4;
uint32_t augslot5;
int32_t augslot6;
uint32_t augment_one;
uint32_t augment_two;
uint32_t augment_three;
uint32_t augment_four;
uint32_t augment_five;
uint32_t augment_six;
uint8_t instnodrop;
std::string custom_data;
uint32_t ornamenticon;
uint32_t ornamentidfile;
uint32_t ornament_icon;
uint32_t ornament_idfile;
int32_t ornament_hero_model;
uint64_t guid;
};
static std::string PrimaryKey()
{
return std::string("charid");
return std::string("character_id");
}
static std::vector<std::string> Columns()
{
return {
"charid",
"slotid",
"itemid",
"character_id",
"slot_id",
"item_id",
"charges",
"color",
"augslot1",
"augslot2",
"augslot3",
"augslot4",
"augslot5",
"augslot6",
"augment_one",
"augment_two",
"augment_three",
"augment_four",
"augment_five",
"augment_six",
"instnodrop",
"custom_data",
"ornamenticon",
"ornamentidfile",
"ornament_icon",
"ornament_idfile",
"ornament_hero_model",
"guid",
};
@@ -69,21 +69,21 @@ public:
static std::vector<std::string> SelectColumns()
{
return {
"charid",
"slotid",
"itemid",
"character_id",
"slot_id",
"item_id",
"charges",
"color",
"augslot1",
"augslot2",
"augslot3",
"augslot4",
"augslot5",
"augslot6",
"augment_one",
"augment_two",
"augment_three",
"augment_four",
"augment_five",
"augment_six",
"instnodrop",
"custom_data",
"ornamenticon",
"ornamentidfile",
"ornament_icon",
"ornament_idfile",
"ornament_hero_model",
"guid",
};
@@ -126,21 +126,21 @@ public:
{
Inventory e{};
e.charid = 0;
e.slotid = 0;
e.itemid = 0;
e.character_id = 0;
e.slot_id = 0;
e.item_id = 0;
e.charges = 0;
e.color = 0;
e.augslot1 = 0;
e.augslot2 = 0;
e.augslot3 = 0;
e.augslot4 = 0;
e.augslot5 = 0;
e.augslot6 = 0;
e.augment_one = 0;
e.augment_two = 0;
e.augment_three = 0;
e.augment_four = 0;
e.augment_five = 0;
e.augment_six = 0;
e.instnodrop = 0;
e.custom_data = "";
e.ornamenticon = 0;
e.ornamentidfile = 0;
e.ornament_icon = 0;
e.ornament_idfile = 0;
e.ornament_hero_model = 0;
e.guid = 0;
@@ -153,7 +153,7 @@ public:
)
{
for (auto &inventory : inventorys) {
if (inventory.charid == inventory_id) {
if (inventory.character_id == inventory_id) {
return inventory;
}
}
@@ -179,21 +179,21 @@ public:
if (results.RowCount() == 1) {
Inventory e{};
e.charid = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slotid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.itemid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augslot1 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augslot2 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augslot3 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augslot4 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augslot5 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augslot6 = row[10] ? static_cast<int32_t>(atoi(row[10])) : 0;
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
e.custom_data = row[12] ? row[12] : "";
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_icon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornament_idfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
@@ -229,21 +229,21 @@ public:
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.charid));
v.push_back(columns[1] + " = " + std::to_string(e.slotid));
v.push_back(columns[2] + " = " + std::to_string(e.itemid));
v.push_back(columns[0] + " = " + std::to_string(e.character_id));
v.push_back(columns[1] + " = " + std::to_string(e.slot_id));
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
v.push_back(columns[3] + " = " + std::to_string(e.charges));
v.push_back(columns[4] + " = " + std::to_string(e.color));
v.push_back(columns[5] + " = " + std::to_string(e.augslot1));
v.push_back(columns[6] + " = " + std::to_string(e.augslot2));
v.push_back(columns[7] + " = " + std::to_string(e.augslot3));
v.push_back(columns[8] + " = " + std::to_string(e.augslot4));
v.push_back(columns[9] + " = " + std::to_string(e.augslot5));
v.push_back(columns[10] + " = " + std::to_string(e.augslot6));
v.push_back(columns[5] + " = " + std::to_string(e.augment_one));
v.push_back(columns[6] + " = " + std::to_string(e.augment_two));
v.push_back(columns[7] + " = " + std::to_string(e.augment_three));
v.push_back(columns[8] + " = " + std::to_string(e.augment_four));
v.push_back(columns[9] + " = " + std::to_string(e.augment_five));
v.push_back(columns[10] + " = " + std::to_string(e.augment_six));
v.push_back(columns[11] + " = " + std::to_string(e.instnodrop));
v.push_back(columns[12] + " = '" + Strings::Escape(e.custom_data) + "'");
v.push_back(columns[13] + " = " + std::to_string(e.ornamenticon));
v.push_back(columns[14] + " = " + std::to_string(e.ornamentidfile));
v.push_back(columns[13] + " = " + std::to_string(e.ornament_icon));
v.push_back(columns[14] + " = " + std::to_string(e.ornament_idfile));
v.push_back(columns[15] + " = " + std::to_string(e.ornament_hero_model));
v.push_back(columns[16] + " = " + std::to_string(e.guid));
@@ -253,7 +253,7 @@ public:
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.charid
e.character_id
)
);
@@ -267,21 +267,21 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.slotid));
v.push_back(std::to_string(e.itemid));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augslot1));
v.push_back(std::to_string(e.augslot2));
v.push_back(std::to_string(e.augslot3));
v.push_back(std::to_string(e.augslot4));
v.push_back(std::to_string(e.augslot5));
v.push_back(std::to_string(e.augslot6));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back(std::to_string(e.instnodrop));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
@@ -294,7 +294,7 @@ public:
);
if (results.Success()) {
e.charid = results.LastInsertedID();
e.character_id = results.LastInsertedID();
return e;
}
@@ -313,21 +313,21 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.slotid));
v.push_back(std::to_string(e.itemid));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augslot1));
v.push_back(std::to_string(e.augslot2));
v.push_back(std::to_string(e.augslot3));
v.push_back(std::to_string(e.augslot4));
v.push_back(std::to_string(e.augslot5));
v.push_back(std::to_string(e.augslot6));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back(std::to_string(e.instnodrop));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
@@ -363,21 +363,21 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
Inventory e{};
e.charid = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slotid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.itemid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augslot1 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augslot2 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augslot3 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augslot4 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augslot5 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augslot6 = row[10] ? static_cast<int32_t>(atoi(row[10])) : 0;
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
e.custom_data = row[12] ? row[12] : "";
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_icon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornament_idfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
@@ -404,21 +404,21 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
Inventory e{};
e.charid = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slotid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.itemid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augslot1 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augslot2 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augslot3 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augslot4 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augslot5 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augslot6 = row[10] ? static_cast<int32_t>(atoi(row[10])) : 0;
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
e.custom_data = row[12] ? row[12] : "";
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_icon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornament_idfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
@@ -495,21 +495,21 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.slotid));
v.push_back(std::to_string(e.itemid));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augslot1));
v.push_back(std::to_string(e.augslot2));
v.push_back(std::to_string(e.augslot3));
v.push_back(std::to_string(e.augslot4));
v.push_back(std::to_string(e.augslot5));
v.push_back(std::to_string(e.augslot6));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back(std::to_string(e.instnodrop));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
@@ -534,21 +534,21 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.slotid));
v.push_back(std::to_string(e.itemid));
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augslot1));
v.push_back(std::to_string(e.augslot2));
v.push_back(std::to_string(e.augslot3));
v.push_back(std::to_string(e.augslot4));
v.push_back(std::to_string(e.augslot5));
v.push_back(std::to_string(e.augslot6));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back(std::to_string(e.instnodrop));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
@@ -19,13 +19,13 @@
class BaseItemsEvolvingDetailsRepository {
public:
struct ItemsEvolvingDetails {
uint32_t id;
uint32_t item_evo_id;
uint32_t item_evolve_level;
uint32_t item_id;
uint32_t type;
uint32_t sub_type;
int64_t required_amount;
uint32_t id;
uint32_t item_evo_id;
uint32_t item_evolve_level;
uint32_t item_id;
uint32_t type;
std::string sub_type;
int64_t required_amount;
};
static std::string PrimaryKey()
@@ -101,7 +101,7 @@ public:
e.item_evolve_level = 0;
e.item_id = 0;
e.type = 0;
e.sub_type = 0;
e.sub_type = "0";
e.required_amount = 0;
return e;
@@ -144,7 +144,7 @@ public:
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.sub_type = row[5] ? row[5] : "0";
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
return e;
@@ -183,7 +183,7 @@ public:
v.push_back(columns[2] + " = " + std::to_string(e.item_evolve_level));
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
v.push_back(columns[4] + " = " + std::to_string(e.type));
v.push_back(columns[5] + " = " + std::to_string(e.sub_type));
v.push_back(columns[5] + " = '" + Strings::Escape(e.sub_type) + "'");
v.push_back(columns[6] + " = " + std::to_string(e.required_amount));
auto results = db.QueryDatabase(
@@ -211,7 +211,7 @@ public:
v.push_back(std::to_string(e.item_evolve_level));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.sub_type));
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
v.push_back(std::to_string(e.required_amount));
auto results = db.QueryDatabase(
@@ -247,7 +247,7 @@ public:
v.push_back(std::to_string(e.item_evolve_level));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.sub_type));
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
v.push_back(std::to_string(e.required_amount));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
@@ -287,7 +287,7 @@ public:
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.sub_type = row[5] ? row[5] : "0";
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
all_entries.push_back(e);
@@ -318,7 +318,7 @@ public:
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.sub_type = row[5] ? row[5] : "0";
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
all_entries.push_back(e);
@@ -399,7 +399,7 @@ public:
v.push_back(std::to_string(e.item_evolve_level));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.sub_type));
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
v.push_back(std::to_string(e.required_amount));
auto results = db.QueryDatabase(
@@ -428,7 +428,7 @@ public:
v.push_back(std::to_string(e.item_evolve_level));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.sub_type));
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
v.push_back(std::to_string(e.required_amount));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
@@ -123,7 +123,7 @@ public:
int8_t legtexture;
int8_t feettexture;
int8_t light;
int8_t walkspeed;
float walkspeed;
int32_t peqid;
int8_t unique_;
int8_t fixed;
@@ -148,6 +148,7 @@ public:
int32_t faction_amount;
uint8_t keeps_sold_items;
uint8_t is_parcel_merchant;
uint8_t multiquest_enabled;
};
static std::string PrimaryKey()
@@ -287,6 +288,7 @@ public:
"faction_amount",
"keeps_sold_items",
"is_parcel_merchant",
"multiquest_enabled",
};
}
@@ -422,6 +424,7 @@ public:
"faction_amount",
"keeps_sold_items",
"is_parcel_merchant",
"multiquest_enabled",
};
}
@@ -591,6 +594,7 @@ public:
e.faction_amount = 0;
e.keeps_sold_items = 1;
e.is_parcel_merchant = 0;
e.multiquest_enabled = 0;
return e;
}
@@ -731,7 +735,7 @@ public:
e.legtexture = row[101] ? static_cast<int8_t>(atoi(row[101])) : 0;
e.feettexture = row[102] ? static_cast<int8_t>(atoi(row[102])) : 0;
e.light = row[103] ? static_cast<int8_t>(atoi(row[103])) : 0;
e.walkspeed = row[104] ? static_cast<int8_t>(atoi(row[104])) : 0;
e.walkspeed = row[104] ? strtof(row[104], nullptr) : 0;
e.peqid = row[105] ? static_cast<int32_t>(atoi(row[105])) : 0;
e.unique_ = row[106] ? static_cast<int8_t>(atoi(row[106])) : 0;
e.fixed = row[107] ? static_cast<int8_t>(atoi(row[107])) : 0;
@@ -756,6 +760,7 @@ public:
e.faction_amount = row[126] ? static_cast<int32_t>(atoi(row[126])) : 0;
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
return e;
}
@@ -917,6 +922,7 @@ public:
v.push_back(columns[126] + " = " + std::to_string(e.faction_amount));
v.push_back(columns[127] + " = " + std::to_string(e.keeps_sold_items));
v.push_back(columns[128] + " = " + std::to_string(e.is_parcel_merchant));
v.push_back(columns[129] + " = " + std::to_string(e.multiquest_enabled));
auto results = db.QueryDatabase(
fmt::format(
@@ -1067,6 +1073,7 @@ public:
v.push_back(std::to_string(e.faction_amount));
v.push_back(std::to_string(e.keeps_sold_items));
v.push_back(std::to_string(e.is_parcel_merchant));
v.push_back(std::to_string(e.multiquest_enabled));
auto results = db.QueryDatabase(
fmt::format(
@@ -1225,6 +1232,7 @@ public:
v.push_back(std::to_string(e.faction_amount));
v.push_back(std::to_string(e.keeps_sold_items));
v.push_back(std::to_string(e.is_parcel_merchant));
v.push_back(std::to_string(e.multiquest_enabled));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -1362,7 +1370,7 @@ public:
e.legtexture = row[101] ? static_cast<int8_t>(atoi(row[101])) : 0;
e.feettexture = row[102] ? static_cast<int8_t>(atoi(row[102])) : 0;
e.light = row[103] ? static_cast<int8_t>(atoi(row[103])) : 0;
e.walkspeed = row[104] ? static_cast<int8_t>(atoi(row[104])) : 0;
e.walkspeed = row[104] ? strtof(row[104], nullptr) : 0;
e.peqid = row[105] ? static_cast<int32_t>(atoi(row[105])) : 0;
e.unique_ = row[106] ? static_cast<int8_t>(atoi(row[106])) : 0;
e.fixed = row[107] ? static_cast<int8_t>(atoi(row[107])) : 0;
@@ -1387,6 +1395,7 @@ public:
e.faction_amount = row[126] ? static_cast<int32_t>(atoi(row[126])) : 0;
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -1515,7 +1524,7 @@ public:
e.legtexture = row[101] ? static_cast<int8_t>(atoi(row[101])) : 0;
e.feettexture = row[102] ? static_cast<int8_t>(atoi(row[102])) : 0;
e.light = row[103] ? static_cast<int8_t>(atoi(row[103])) : 0;
e.walkspeed = row[104] ? static_cast<int8_t>(atoi(row[104])) : 0;
e.walkspeed = row[104] ? strtof(row[104], nullptr) : 0;
e.peqid = row[105] ? static_cast<int32_t>(atoi(row[105])) : 0;
e.unique_ = row[106] ? static_cast<int8_t>(atoi(row[106])) : 0;
e.fixed = row[107] ? static_cast<int8_t>(atoi(row[107])) : 0;
@@ -1540,6 +1549,7 @@ public:
e.faction_amount = row[126] ? static_cast<int32_t>(atoi(row[126])) : 0;
e.keeps_sold_items = row[127] ? static_cast<uint8_t>(strtoul(row[127], nullptr, 10)) : 1;
e.is_parcel_merchant = row[128] ? static_cast<uint8_t>(strtoul(row[128], nullptr, 10)) : 0;
e.multiquest_enabled = row[129] ? static_cast<uint8_t>(strtoul(row[129], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -1743,6 +1753,7 @@ public:
v.push_back(std::to_string(e.faction_amount));
v.push_back(std::to_string(e.keeps_sold_items));
v.push_back(std::to_string(e.is_parcel_merchant));
v.push_back(std::to_string(e.multiquest_enabled));
auto results = db.QueryDatabase(
fmt::format(
@@ -1894,6 +1905,7 @@ public:
v.push_back(std::to_string(e.faction_amount));
v.push_back(std::to_string(e.keeps_sold_items));
v.push_back(std::to_string(e.is_parcel_merchant));
v.push_back(std::to_string(e.multiquest_enabled));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -144,6 +144,7 @@ public:
e.texture = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.helm_texture = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
e.gender = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 2;
e.size_modifier = row[5] ? (strtof(row[5], nullptr) > 0.0f ? strtof(row[5], nullptr) : 1) : 1;
e.face = row[6] ? static_cast<uint8_t>(strtoul(row[6], nullptr, 10)) : 0;
return e;
@@ -287,6 +288,7 @@ public:
e.texture = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.helm_texture = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
e.gender = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 2;
e.size_modifier = row[5] ? (strtof(row[5], nullptr) > 0.0f ? strtof(row[5], nullptr) : 1) : 1;
e.face = row[6] ? static_cast<uint8_t>(strtoul(row[6], nullptr, 10)) : 0;
all_entries.push_back(e);
@@ -317,6 +319,7 @@ public:
e.texture = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
e.helm_texture = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
e.gender = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 2;
e.size_modifier = row[5] ? (strtof(row[5], nullptr) > 0.0f ? strtof(row[5], nullptr) : 1) : 1;
e.face = row[6] ? static_cast<uint8_t>(strtoul(row[6], nullptr, 10)) : 0;
all_entries.push_back(e);
@@ -0,0 +1,439 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_AA_PURCHASE_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_AA_PURCHASE_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventAaPurchaseRepository {
public:
struct PlayerEventAaPurchase {
uint64_t id;
int32_t aa_ability_id;
int32_t cost;
int32_t previous_id;
int32_t next_id;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"aa_ability_id",
"cost",
"previous_id",
"next_id",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"aa_ability_id",
"cost",
"previous_id",
"next_id",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_aa_purchase");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventAaPurchase NewEntity()
{
PlayerEventAaPurchase e{};
e.id = 0;
e.aa_ability_id = 0;
e.cost = 0;
e.previous_id = 0;
e.next_id = 0;
e.created_at = 0;
return e;
}
static PlayerEventAaPurchase GetPlayerEventAaPurchase(
const std::vector<PlayerEventAaPurchase> &player_event_aa_purchases,
int player_event_aa_purchase_id
)
{
for (auto &player_event_aa_purchase : player_event_aa_purchases) {
if (player_event_aa_purchase.id == player_event_aa_purchase_id) {
return player_event_aa_purchase;
}
}
return NewEntity();
}
static PlayerEventAaPurchase FindOne(
Database& db,
int player_event_aa_purchase_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_aa_purchase_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventAaPurchase e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.aa_ability_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.cost = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.previous_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.next_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.created_at = strtoll(row[5] ? row[5] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_aa_purchase_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_aa_purchase_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventAaPurchase &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.aa_ability_id));
v.push_back(columns[2] + " = " + std::to_string(e.cost));
v.push_back(columns[3] + " = " + std::to_string(e.previous_id));
v.push_back(columns[4] + " = " + std::to_string(e.next_id));
v.push_back(columns[5] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventAaPurchase InsertOne(
Database& db,
PlayerEventAaPurchase e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.aa_ability_id));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.previous_id));
v.push_back(std::to_string(e.next_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventAaPurchase> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.aa_ability_id));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.previous_id));
v.push_back(std::to_string(e.next_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventAaPurchase> All(Database& db)
{
std::vector<PlayerEventAaPurchase> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventAaPurchase e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.aa_ability_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.cost = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.previous_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.next_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.created_at = strtoll(row[5] ? row[5] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventAaPurchase> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventAaPurchase> 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) {
PlayerEventAaPurchase e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.aa_ability_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.cost = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.previous_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.next_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.created_at = strtoll(row[5] ? row[5] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventAaPurchase &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.aa_ability_id));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.previous_id));
v.push_back(std::to_string(e.next_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventAaPurchase> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.aa_ability_id));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.previous_id));
v.push_back(std::to_string(e.next_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_AA_PURCHASE_REPOSITORY_H
@@ -0,0 +1,451 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_KILLED_NAMED_NPC_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_KILLED_NAMED_NPC_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventKilledNamedNpcRepository {
public:
struct PlayerEventKilledNamedNpc {
uint64_t id;
uint32_t npc_id;
std::string npc_name;
uint32_t combat_time_seconds;
uint64_t total_damage_per_second_taken;
uint64_t total_heal_per_second_taken;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"npc_id",
"npc_name",
"combat_time_seconds",
"total_damage_per_second_taken",
"total_heal_per_second_taken",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"npc_id",
"npc_name",
"combat_time_seconds",
"total_damage_per_second_taken",
"total_heal_per_second_taken",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_killed_named_npc");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventKilledNamedNpc NewEntity()
{
PlayerEventKilledNamedNpc e{};
e.id = 0;
e.npc_id = 0;
e.npc_name = "";
e.combat_time_seconds = 0;
e.total_damage_per_second_taken = 0;
e.total_heal_per_second_taken = 0;
e.created_at = 0;
return e;
}
static PlayerEventKilledNamedNpc GetPlayerEventKilledNamedNpc(
const std::vector<PlayerEventKilledNamedNpc> &player_event_killed_named_npcs,
int player_event_killed_named_npc_id
)
{
for (auto &player_event_killed_named_npc : player_event_killed_named_npcs) {
if (player_event_killed_named_npc.id == player_event_killed_named_npc_id) {
return player_event_killed_named_npc;
}
}
return NewEntity();
}
static PlayerEventKilledNamedNpc FindOne(
Database& db,
int player_event_killed_named_npc_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_killed_named_npc_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventKilledNamedNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_killed_named_npc_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_killed_named_npc_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventKilledNamedNpc &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.npc_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.combat_time_seconds));
v.push_back(columns[4] + " = " + std::to_string(e.total_damage_per_second_taken));
v.push_back(columns[5] + " = " + std::to_string(e.total_heal_per_second_taken));
v.push_back(columns[6] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventKilledNamedNpc InsertOne(
Database& db,
PlayerEventKilledNamedNpc e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventKilledNamedNpc> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventKilledNamedNpc> All(Database& db)
{
std::vector<PlayerEventKilledNamedNpc> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventKilledNamedNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventKilledNamedNpc> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventKilledNamedNpc> 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) {
PlayerEventKilledNamedNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventKilledNamedNpc &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventKilledNamedNpc> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_KILLED_NAMED_NPC_REPOSITORY_H
@@ -0,0 +1,451 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_KILLED_NPC_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_KILLED_NPC_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventKilledNpcRepository {
public:
struct PlayerEventKilledNpc {
uint64_t id;
uint32_t npc_id;
std::string npc_name;
uint32_t combat_time_seconds;
uint64_t total_damage_per_second_taken;
uint64_t total_heal_per_second_taken;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"npc_id",
"npc_name",
"combat_time_seconds",
"total_damage_per_second_taken",
"total_heal_per_second_taken",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"npc_id",
"npc_name",
"combat_time_seconds",
"total_damage_per_second_taken",
"total_heal_per_second_taken",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_killed_npc");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventKilledNpc NewEntity()
{
PlayerEventKilledNpc e{};
e.id = 0;
e.npc_id = 0;
e.npc_name = "";
e.combat_time_seconds = 0;
e.total_damage_per_second_taken = 0;
e.total_heal_per_second_taken = 0;
e.created_at = 0;
return e;
}
static PlayerEventKilledNpc GetPlayerEventKilledNpc(
const std::vector<PlayerEventKilledNpc> &player_event_killed_npcs,
int player_event_killed_npc_id
)
{
for (auto &player_event_killed_npc : player_event_killed_npcs) {
if (player_event_killed_npc.id == player_event_killed_npc_id) {
return player_event_killed_npc;
}
}
return NewEntity();
}
static PlayerEventKilledNpc FindOne(
Database& db,
int player_event_killed_npc_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_killed_npc_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventKilledNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_killed_npc_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_killed_npc_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventKilledNpc &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.npc_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.combat_time_seconds));
v.push_back(columns[4] + " = " + std::to_string(e.total_damage_per_second_taken));
v.push_back(columns[5] + " = " + std::to_string(e.total_heal_per_second_taken));
v.push_back(columns[6] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventKilledNpc InsertOne(
Database& db,
PlayerEventKilledNpc e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventKilledNpc> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventKilledNpc> All(Database& db)
{
std::vector<PlayerEventKilledNpc> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventKilledNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventKilledNpc> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventKilledNpc> 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) {
PlayerEventKilledNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventKilledNpc &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventKilledNpc> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_KILLED_NPC_REPOSITORY_H
@@ -0,0 +1,451 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_KILLED_RAID_NPC_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_KILLED_RAID_NPC_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventKilledRaidNpcRepository {
public:
struct PlayerEventKilledRaidNpc {
uint64_t id;
uint32_t npc_id;
std::string npc_name;
uint32_t combat_time_seconds;
uint64_t total_damage_per_second_taken;
uint64_t total_heal_per_second_taken;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"npc_id",
"npc_name",
"combat_time_seconds",
"total_damage_per_second_taken",
"total_heal_per_second_taken",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"npc_id",
"npc_name",
"combat_time_seconds",
"total_damage_per_second_taken",
"total_heal_per_second_taken",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_killed_raid_npc");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventKilledRaidNpc NewEntity()
{
PlayerEventKilledRaidNpc e{};
e.id = 0;
e.npc_id = 0;
e.npc_name = "";
e.combat_time_seconds = 0;
e.total_damage_per_second_taken = 0;
e.total_heal_per_second_taken = 0;
e.created_at = 0;
return e;
}
static PlayerEventKilledRaidNpc GetPlayerEventKilledRaidNpc(
const std::vector<PlayerEventKilledRaidNpc> &player_event_killed_raid_npcs,
int player_event_killed_raid_npc_id
)
{
for (auto &player_event_killed_raid_npc : player_event_killed_raid_npcs) {
if (player_event_killed_raid_npc.id == player_event_killed_raid_npc_id) {
return player_event_killed_raid_npc;
}
}
return NewEntity();
}
static PlayerEventKilledRaidNpc FindOne(
Database& db,
int player_event_killed_raid_npc_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_killed_raid_npc_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventKilledRaidNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_killed_raid_npc_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_killed_raid_npc_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventKilledRaidNpc &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.npc_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.combat_time_seconds));
v.push_back(columns[4] + " = " + std::to_string(e.total_damage_per_second_taken));
v.push_back(columns[5] + " = " + std::to_string(e.total_heal_per_second_taken));
v.push_back(columns[6] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventKilledRaidNpc InsertOne(
Database& db,
PlayerEventKilledRaidNpc e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventKilledRaidNpc> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventKilledRaidNpc> All(Database& db)
{
std::vector<PlayerEventKilledRaidNpc> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventKilledRaidNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventKilledRaidNpc> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventKilledRaidNpc> 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) {
PlayerEventKilledRaidNpc e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.combat_time_seconds = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.total_damage_per_second_taken = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.total_heal_per_second_taken = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.created_at = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventKilledRaidNpc &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventKilledRaidNpc> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.combat_time_seconds));
v.push_back(std::to_string(e.total_damage_per_second_taken));
v.push_back(std::to_string(e.total_heal_per_second_taken));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_KILLED_RAID_NPC_REPOSITORY_H
@@ -24,6 +24,7 @@ public:
int8_t event_enabled;
int32_t retention_days;
int32_t discord_webhook_id;
uint8_t etl_enabled;
};
static std::string PrimaryKey()
@@ -39,6 +40,7 @@ public:
"event_enabled",
"retention_days",
"discord_webhook_id",
"etl_enabled",
};
}
@@ -50,6 +52,7 @@ public:
"event_enabled",
"retention_days",
"discord_webhook_id",
"etl_enabled",
};
}
@@ -95,6 +98,7 @@ public:
e.event_enabled = 0;
e.retention_days = 0;
e.discord_webhook_id = 0;
e.etl_enabled = 0;
return e;
}
@@ -136,6 +140,7 @@ public:
e.event_enabled = row[2] ? static_cast<int8_t>(atoi(row[2])) : 0;
e.retention_days = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.discord_webhook_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.etl_enabled = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 0;
return e;
}
@@ -174,6 +179,7 @@ public:
v.push_back(columns[2] + " = " + std::to_string(e.event_enabled));
v.push_back(columns[3] + " = " + std::to_string(e.retention_days));
v.push_back(columns[4] + " = " + std::to_string(e.discord_webhook_id));
v.push_back(columns[5] + " = " + std::to_string(e.etl_enabled));
auto results = db.QueryDatabase(
fmt::format(
@@ -200,6 +206,7 @@ public:
v.push_back(std::to_string(e.event_enabled));
v.push_back(std::to_string(e.retention_days));
v.push_back(std::to_string(e.discord_webhook_id));
v.push_back(std::to_string(e.etl_enabled));
auto results = db.QueryDatabase(
fmt::format(
@@ -234,6 +241,7 @@ public:
v.push_back(std::to_string(e.event_enabled));
v.push_back(std::to_string(e.retention_days));
v.push_back(std::to_string(e.discord_webhook_id));
v.push_back(std::to_string(e.etl_enabled));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -272,6 +280,7 @@ public:
e.event_enabled = row[2] ? static_cast<int8_t>(atoi(row[2])) : 0;
e.retention_days = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.discord_webhook_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.etl_enabled = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -301,6 +310,7 @@ public:
e.event_enabled = row[2] ? static_cast<int8_t>(atoi(row[2])) : 0;
e.retention_days = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.discord_webhook_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.etl_enabled = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -380,6 +390,7 @@ public:
v.push_back(std::to_string(e.event_enabled));
v.push_back(std::to_string(e.retention_days));
v.push_back(std::to_string(e.discord_webhook_id));
v.push_back(std::to_string(e.etl_enabled));
auto results = db.QueryDatabase(
fmt::format(
@@ -407,6 +418,7 @@ public:
v.push_back(std::to_string(e.event_enabled));
v.push_back(std::to_string(e.retention_days));
v.push_back(std::to_string(e.discord_webhook_id));
v.push_back(std::to_string(e.etl_enabled));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -31,6 +31,7 @@ public:
int32_t event_type_id;
std::string event_type_name;
std::string event_data;
int64_t etl_table_id;
time_t created_at;
// cereal
@@ -50,6 +51,7 @@ public:
CEREAL_NVP(event_type_id),
CEREAL_NVP(event_type_name),
CEREAL_NVP(event_data),
CEREAL_NVP(etl_table_id),
CEREAL_NVP(created_at)
);
}
@@ -75,6 +77,7 @@ public:
"event_type_id",
"event_type_name",
"event_data",
"etl_table_id",
"created_at",
};
}
@@ -94,6 +97,7 @@ public:
"event_type_id",
"event_type_name",
"event_data",
"etl_table_id",
"UNIX_TIMESTAMP(created_at)",
};
}
@@ -147,6 +151,7 @@ public:
e.event_type_id = 0;
e.event_type_name = "";
e.event_data = "";
e.etl_table_id = 0;
e.created_at = 0;
return e;
@@ -196,7 +201,8 @@ public:
e.event_type_id = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
e.event_type_name = row[10] ? row[10] : "";
e.event_data = row[11] ? row[11] : "";
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
e.etl_table_id = row[12] ? strtoll(row[12], nullptr, 10) : 0;
e.created_at = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
return e;
}
@@ -241,7 +247,8 @@ public:
v.push_back(columns[9] + " = " + std::to_string(e.event_type_id));
v.push_back(columns[10] + " = '" + Strings::Escape(e.event_type_name) + "'");
v.push_back(columns[11] + " = '" + Strings::Escape(e.event_data) + "'");
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
v.push_back(columns[12] + " = " + std::to_string(e.etl_table_id));
v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@@ -275,6 +282,7 @@ public:
v.push_back(std::to_string(e.event_type_id));
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
v.push_back("'" + Strings::Escape(e.event_data) + "'");
v.push_back(std::to_string(e.etl_table_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
@@ -317,6 +325,7 @@ public:
v.push_back(std::to_string(e.event_type_id));
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
v.push_back("'" + Strings::Escape(e.event_data) + "'");
v.push_back(std::to_string(e.etl_table_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
@@ -363,7 +372,8 @@ public:
e.event_type_id = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
e.event_type_name = row[10] ? row[10] : "";
e.event_data = row[11] ? row[11] : "";
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
e.etl_table_id = row[12] ? strtoll(row[12], nullptr, 10) : 0;
e.created_at = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@@ -400,7 +410,8 @@ public:
e.event_type_id = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
e.event_type_name = row[10] ? row[10] : "";
e.event_data = row[11] ? row[11] : "";
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
e.etl_table_id = row[12] ? strtoll(row[12], nullptr, 10) : 0;
e.created_at = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@@ -487,6 +498,7 @@ public:
v.push_back(std::to_string(e.event_type_id));
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
v.push_back("'" + Strings::Escape(e.event_data) + "'");
v.push_back(std::to_string(e.etl_table_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
@@ -522,6 +534,7 @@ public:
v.push_back(std::to_string(e.event_type_id));
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
v.push_back("'" + Strings::Escape(e.event_data) + "'");
v.push_back(std::to_string(e.etl_table_id));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
@@ -0,0 +1,523 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_LOOT_ITEMS_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_LOOT_ITEMS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventLootItemsRepository {
public:
struct PlayerEventLootItems {
uint64_t id;
uint32_t item_id;
std::string item_name;
int32_t charges;
uint32_t augment_1_id;
uint32_t augment_2_id;
uint32_t augment_3_id;
uint32_t augment_4_id;
uint32_t augment_5_id;
uint32_t augment_6_id;
uint32_t npc_id;
std::string corpse_name;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"item_id",
"item_name",
"charges",
"augment_1_id",
"augment_2_id",
"augment_3_id",
"augment_4_id",
"augment_5_id",
"augment_6_id",
"npc_id",
"corpse_name",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"item_id",
"item_name",
"charges",
"augment_1_id",
"augment_2_id",
"augment_3_id",
"augment_4_id",
"augment_5_id",
"augment_6_id",
"npc_id",
"corpse_name",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_loot_items");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventLootItems NewEntity()
{
PlayerEventLootItems e{};
e.id = 0;
e.item_id = 0;
e.item_name = "";
e.charges = 0;
e.augment_1_id = 0;
e.augment_2_id = 0;
e.augment_3_id = 0;
e.augment_4_id = 0;
e.augment_5_id = 0;
e.augment_6_id = 0;
e.npc_id = 0;
e.corpse_name = "";
e.created_at = 0;
return e;
}
static PlayerEventLootItems GetPlayerEventLootItems(
const std::vector<PlayerEventLootItems> &player_event_loot_itemss,
int player_event_loot_items_id
)
{
for (auto &player_event_loot_items : player_event_loot_itemss) {
if (player_event_loot_items.id == player_event_loot_items_id) {
return player_event_loot_items;
}
}
return NewEntity();
}
static PlayerEventLootItems FindOne(
Database& db,
int player_event_loot_items_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_loot_items_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventLootItems e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.item_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_name = row[2] ? row[2] : "";
e.charges = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.augment_1_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_2_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_3_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_4_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_5_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_6_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.npc_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.corpse_name = row[11] ? row[11] : "";
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_loot_items_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_loot_items_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventLootItems &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.item_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.item_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.charges));
v.push_back(columns[4] + " = " + std::to_string(e.augment_1_id));
v.push_back(columns[5] + " = " + std::to_string(e.augment_2_id));
v.push_back(columns[6] + " = " + std::to_string(e.augment_3_id));
v.push_back(columns[7] + " = " + std::to_string(e.augment_4_id));
v.push_back(columns[8] + " = " + std::to_string(e.augment_5_id));
v.push_back(columns[9] + " = " + std::to_string(e.augment_6_id));
v.push_back(columns[10] + " = " + std::to_string(e.npc_id));
v.push_back(columns[11] + " = '" + Strings::Escape(e.corpse_name) + "'");
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventLootItems InsertOne(
Database& db,
PlayerEventLootItems e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.corpse_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventLootItems> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.corpse_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventLootItems> All(Database& db)
{
std::vector<PlayerEventLootItems> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventLootItems e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.item_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_name = row[2] ? row[2] : "";
e.charges = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.augment_1_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_2_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_3_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_4_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_5_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_6_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.npc_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.corpse_name = row[11] ? row[11] : "";
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventLootItems> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventLootItems> 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) {
PlayerEventLootItems e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.item_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_name = row[2] ? row[2] : "";
e.charges = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.augment_1_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_2_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_3_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_4_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_5_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_6_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.npc_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.corpse_name = row[11] ? row[11] : "";
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventLootItems &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.corpse_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventLootItems> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.corpse_name) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_LOOT_ITEMS_REPOSITORY_H
@@ -0,0 +1,511 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_MERCHANT_PURCHASE_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_MERCHANT_PURCHASE_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventMerchantPurchaseRepository {
public:
struct PlayerEventMerchantPurchase {
uint64_t id;
uint32_t npc_id;
std::string merchant_name;
uint32_t merchant_type;
uint32_t item_id;
std::string item_name;
int32_t charges;
uint32_t cost;
uint32_t alternate_currency_id;
uint64_t player_money_balance;
uint64_t player_currency_balance;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"npc_id",
"merchant_name",
"merchant_type",
"item_id",
"item_name",
"charges",
"cost",
"alternate_currency_id",
"player_money_balance",
"player_currency_balance",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"npc_id",
"merchant_name",
"merchant_type",
"item_id",
"item_name",
"charges",
"cost",
"alternate_currency_id",
"player_money_balance",
"player_currency_balance",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_merchant_purchase");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventMerchantPurchase NewEntity()
{
PlayerEventMerchantPurchase e{};
e.id = 0;
e.npc_id = 0;
e.merchant_name = "";
e.merchant_type = 0;
e.item_id = 0;
e.item_name = "";
e.charges = 0;
e.cost = 0;
e.alternate_currency_id = 0;
e.player_money_balance = 0;
e.player_currency_balance = 0;
e.created_at = 0;
return e;
}
static PlayerEventMerchantPurchase GetPlayerEventMerchantPurchase(
const std::vector<PlayerEventMerchantPurchase> &player_event_merchant_purchases,
int player_event_merchant_purchase_id
)
{
for (auto &player_event_merchant_purchase : player_event_merchant_purchases) {
if (player_event_merchant_purchase.id == player_event_merchant_purchase_id) {
return player_event_merchant_purchase;
}
}
return NewEntity();
}
static PlayerEventMerchantPurchase FindOne(
Database& db,
int player_event_merchant_purchase_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_merchant_purchase_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventMerchantPurchase e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.merchant_name = row[2] ? row[2] : "";
e.merchant_type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.item_name = row[5] ? row[5] : "";
e.charges = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.cost = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.alternate_currency_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.player_money_balance = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.player_currency_balance = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_merchant_purchase_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_merchant_purchase_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventMerchantPurchase &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.merchant_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.merchant_type));
v.push_back(columns[4] + " = " + std::to_string(e.item_id));
v.push_back(columns[5] + " = '" + Strings::Escape(e.item_name) + "'");
v.push_back(columns[6] + " = " + std::to_string(e.charges));
v.push_back(columns[7] + " = " + std::to_string(e.cost));
v.push_back(columns[8] + " = " + std::to_string(e.alternate_currency_id));
v.push_back(columns[9] + " = " + std::to_string(e.player_money_balance));
v.push_back(columns[10] + " = " + std::to_string(e.player_currency_balance));
v.push_back(columns[11] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventMerchantPurchase InsertOne(
Database& db,
PlayerEventMerchantPurchase e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventMerchantPurchase> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventMerchantPurchase> All(Database& db)
{
std::vector<PlayerEventMerchantPurchase> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventMerchantPurchase e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.merchant_name = row[2] ? row[2] : "";
e.merchant_type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.item_name = row[5] ? row[5] : "";
e.charges = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.cost = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.alternate_currency_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.player_money_balance = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.player_currency_balance = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventMerchantPurchase> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventMerchantPurchase> 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) {
PlayerEventMerchantPurchase e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.merchant_name = row[2] ? row[2] : "";
e.merchant_type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.item_name = row[5] ? row[5] : "";
e.charges = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.cost = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.alternate_currency_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.player_money_balance = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.player_currency_balance = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventMerchantPurchase &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventMerchantPurchase> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_MERCHANT_PURCHASE_REPOSITORY_H
@@ -0,0 +1,511 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_MERCHANT_SELL_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_MERCHANT_SELL_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventMerchantSellRepository {
public:
struct PlayerEventMerchantSell {
uint64_t id;
uint32_t npc_id;
std::string merchant_name;
uint32_t merchant_type;
uint32_t item_id;
std::string item_name;
int32_t charges;
uint32_t cost;
uint32_t alternate_currency_id;
uint64_t player_money_balance;
uint64_t player_currency_balance;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"npc_id",
"merchant_name",
"merchant_type",
"item_id",
"item_name",
"charges",
"cost",
"alternate_currency_id",
"player_money_balance",
"player_currency_balance",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"npc_id",
"merchant_name",
"merchant_type",
"item_id",
"item_name",
"charges",
"cost",
"alternate_currency_id",
"player_money_balance",
"player_currency_balance",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_merchant_sell");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventMerchantSell NewEntity()
{
PlayerEventMerchantSell e{};
e.id = 0;
e.npc_id = 0;
e.merchant_name = "";
e.merchant_type = 0;
e.item_id = 0;
e.item_name = "";
e.charges = 0;
e.cost = 0;
e.alternate_currency_id = 0;
e.player_money_balance = 0;
e.player_currency_balance = 0;
e.created_at = 0;
return e;
}
static PlayerEventMerchantSell GetPlayerEventMerchantSell(
const std::vector<PlayerEventMerchantSell> &player_event_merchant_sells,
int player_event_merchant_sell_id
)
{
for (auto &player_event_merchant_sell : player_event_merchant_sells) {
if (player_event_merchant_sell.id == player_event_merchant_sell_id) {
return player_event_merchant_sell;
}
}
return NewEntity();
}
static PlayerEventMerchantSell FindOne(
Database& db,
int player_event_merchant_sell_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_merchant_sell_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventMerchantSell e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.merchant_name = row[2] ? row[2] : "";
e.merchant_type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.item_name = row[5] ? row[5] : "";
e.charges = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.cost = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.alternate_currency_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.player_money_balance = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.player_currency_balance = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_merchant_sell_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_merchant_sell_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventMerchantSell &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.merchant_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.merchant_type));
v.push_back(columns[4] + " = " + std::to_string(e.item_id));
v.push_back(columns[5] + " = '" + Strings::Escape(e.item_name) + "'");
v.push_back(columns[6] + " = " + std::to_string(e.charges));
v.push_back(columns[7] + " = " + std::to_string(e.cost));
v.push_back(columns[8] + " = " + std::to_string(e.alternate_currency_id));
v.push_back(columns[9] + " = " + std::to_string(e.player_money_balance));
v.push_back(columns[10] + " = " + std::to_string(e.player_currency_balance));
v.push_back(columns[11] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventMerchantSell InsertOne(
Database& db,
PlayerEventMerchantSell e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventMerchantSell> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventMerchantSell> All(Database& db)
{
std::vector<PlayerEventMerchantSell> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventMerchantSell e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.merchant_name = row[2] ? row[2] : "";
e.merchant_type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.item_name = row[5] ? row[5] : "";
e.charges = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.cost = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.alternate_currency_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.player_money_balance = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.player_currency_balance = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventMerchantSell> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventMerchantSell> 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) {
PlayerEventMerchantSell e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.merchant_name = row[2] ? row[2] : "";
e.merchant_type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.item_name = row[5] ? row[5] : "";
e.charges = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.cost = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.alternate_currency_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.player_money_balance = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.player_currency_balance = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventMerchantSell &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventMerchantSell> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.merchant_name) + "'");
v.push_back(std::to_string(e.merchant_type));
v.push_back(std::to_string(e.item_id));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.cost));
v.push_back(std::to_string(e.alternate_currency_id));
v.push_back(std::to_string(e.player_money_balance));
v.push_back(std::to_string(e.player_currency_balance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_MERCHANT_SELL_REPOSITORY_H
@@ -0,0 +1,523 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_NPC_HANDIN_ENTRIES_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_NPC_HANDIN_ENTRIES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventNpcHandinEntriesRepository {
public:
struct PlayerEventNpcHandinEntries {
uint64_t id;
uint64_t player_event_npc_handin_id;
uint32_t type;
uint32_t item_id;
int32_t charges;
uint32_t evolve_level;
uint64_t evolve_amount;
uint32_t augment_1_id;
uint32_t augment_2_id;
uint32_t augment_3_id;
uint32_t augment_4_id;
uint32_t augment_5_id;
uint32_t augment_6_id;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"player_event_npc_handin_id",
"type",
"item_id",
"charges",
"evolve_level",
"evolve_amount",
"augment_1_id",
"augment_2_id",
"augment_3_id",
"augment_4_id",
"augment_5_id",
"augment_6_id",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"player_event_npc_handin_id",
"type",
"item_id",
"charges",
"evolve_level",
"evolve_amount",
"augment_1_id",
"augment_2_id",
"augment_3_id",
"augment_4_id",
"augment_5_id",
"augment_6_id",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_npc_handin_entries");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventNpcHandinEntries NewEntity()
{
PlayerEventNpcHandinEntries e{};
e.id = 0;
e.player_event_npc_handin_id = 0;
e.type = 0;
e.item_id = 0;
e.charges = 0;
e.evolve_level = 0;
e.evolve_amount = 0;
e.augment_1_id = 0;
e.augment_2_id = 0;
e.augment_3_id = 0;
e.augment_4_id = 0;
e.augment_5_id = 0;
e.augment_6_id = 0;
return e;
}
static PlayerEventNpcHandinEntries GetPlayerEventNpcHandinEntries(
const std::vector<PlayerEventNpcHandinEntries> &player_event_npc_handin_entriess,
int player_event_npc_handin_entries_id
)
{
for (auto &player_event_npc_handin_entries : player_event_npc_handin_entriess) {
if (player_event_npc_handin_entries.id == player_event_npc_handin_entries_id) {
return player_event_npc_handin_entries;
}
}
return NewEntity();
}
static PlayerEventNpcHandinEntries FindOne(
Database& db,
int player_event_npc_handin_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_npc_handin_entries_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventNpcHandinEntries e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.player_event_npc_handin_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.type = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.charges = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.evolve_level = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.evolve_amount = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.augment_1_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_2_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_3_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_4_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.augment_5_id = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
e.augment_6_id = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_npc_handin_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_npc_handin_entries_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventNpcHandinEntries &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.player_event_npc_handin_id));
v.push_back(columns[2] + " = " + std::to_string(e.type));
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
v.push_back(columns[4] + " = " + std::to_string(e.charges));
v.push_back(columns[5] + " = " + std::to_string(e.evolve_level));
v.push_back(columns[6] + " = " + std::to_string(e.evolve_amount));
v.push_back(columns[7] + " = " + std::to_string(e.augment_1_id));
v.push_back(columns[8] + " = " + std::to_string(e.augment_2_id));
v.push_back(columns[9] + " = " + std::to_string(e.augment_3_id));
v.push_back(columns[10] + " = " + std::to_string(e.augment_4_id));
v.push_back(columns[11] + " = " + std::to_string(e.augment_5_id));
v.push_back(columns[12] + " = " + std::to_string(e.augment_6_id));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventNpcHandinEntries InsertOne(
Database& db,
PlayerEventNpcHandinEntries e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_npc_handin_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.evolve_level));
v.push_back(std::to_string(e.evolve_amount));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventNpcHandinEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_npc_handin_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.evolve_level));
v.push_back(std::to_string(e.evolve_amount));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventNpcHandinEntries> All(Database& db)
{
std::vector<PlayerEventNpcHandinEntries> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventNpcHandinEntries e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.player_event_npc_handin_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.type = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.charges = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.evolve_level = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.evolve_amount = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.augment_1_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_2_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_3_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_4_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.augment_5_id = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
e.augment_6_id = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventNpcHandinEntries> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventNpcHandinEntries> 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) {
PlayerEventNpcHandinEntries e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.player_event_npc_handin_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.type = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.charges = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.evolve_level = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.evolve_amount = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.augment_1_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_2_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_3_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_4_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.augment_5_id = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
e.augment_6_id = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventNpcHandinEntries &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_npc_handin_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.evolve_level));
v.push_back(std::to_string(e.evolve_amount));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventNpcHandinEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_npc_handin_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.evolve_level));
v.push_back(std::to_string(e.evolve_amount));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_NPC_HANDIN_ENTRIES_REPOSITORY_H
@@ -0,0 +1,523 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_NPC_HANDIN_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_NPC_HANDIN_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventNpcHandinRepository {
public:
struct PlayerEventNpcHandin {
uint64_t id;
uint32_t npc_id;
std::string npc_name;
uint64_t handin_copper;
uint64_t handin_silver;
uint64_t handin_gold;
uint64_t handin_platinum;
uint64_t return_copper;
uint64_t return_silver;
uint64_t return_gold;
uint64_t return_platinum;
uint8_t is_quest_handin;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"npc_id",
"npc_name",
"handin_copper",
"handin_silver",
"handin_gold",
"handin_platinum",
"return_copper",
"return_silver",
"return_gold",
"return_platinum",
"is_quest_handin",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"npc_id",
"npc_name",
"handin_copper",
"handin_silver",
"handin_gold",
"handin_platinum",
"return_copper",
"return_silver",
"return_gold",
"return_platinum",
"is_quest_handin",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_npc_handin");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventNpcHandin NewEntity()
{
PlayerEventNpcHandin e{};
e.id = 0;
e.npc_id = 0;
e.npc_name = "";
e.handin_copper = 0;
e.handin_silver = 0;
e.handin_gold = 0;
e.handin_platinum = 0;
e.return_copper = 0;
e.return_silver = 0;
e.return_gold = 0;
e.return_platinum = 0;
e.is_quest_handin = 0;
e.created_at = 0;
return e;
}
static PlayerEventNpcHandin GetPlayerEventNpcHandin(
const std::vector<PlayerEventNpcHandin> &player_event_npc_handins,
int player_event_npc_handin_id
)
{
for (auto &player_event_npc_handin : player_event_npc_handins) {
if (player_event_npc_handin.id == player_event_npc_handin_id) {
return player_event_npc_handin;
}
}
return NewEntity();
}
static PlayerEventNpcHandin FindOne(
Database& db,
int player_event_npc_handin_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_npc_handin_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventNpcHandin e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.handin_copper = row[3] ? strtoull(row[3], nullptr, 10) : 0;
e.handin_silver = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.handin_gold = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.handin_platinum = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.return_copper = row[7] ? strtoull(row[7], nullptr, 10) : 0;
e.return_silver = row[8] ? strtoull(row[8], nullptr, 10) : 0;
e.return_gold = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.return_platinum = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.is_quest_handin = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_npc_handin_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_npc_handin_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventNpcHandin &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.npc_name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.handin_copper));
v.push_back(columns[4] + " = " + std::to_string(e.handin_silver));
v.push_back(columns[5] + " = " + std::to_string(e.handin_gold));
v.push_back(columns[6] + " = " + std::to_string(e.handin_platinum));
v.push_back(columns[7] + " = " + std::to_string(e.return_copper));
v.push_back(columns[8] + " = " + std::to_string(e.return_silver));
v.push_back(columns[9] + " = " + std::to_string(e.return_gold));
v.push_back(columns[10] + " = " + std::to_string(e.return_platinum));
v.push_back(columns[11] + " = " + std::to_string(e.is_quest_handin));
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventNpcHandin InsertOne(
Database& db,
PlayerEventNpcHandin e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.handin_copper));
v.push_back(std::to_string(e.handin_silver));
v.push_back(std::to_string(e.handin_gold));
v.push_back(std::to_string(e.handin_platinum));
v.push_back(std::to_string(e.return_copper));
v.push_back(std::to_string(e.return_silver));
v.push_back(std::to_string(e.return_gold));
v.push_back(std::to_string(e.return_platinum));
v.push_back(std::to_string(e.is_quest_handin));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventNpcHandin> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.handin_copper));
v.push_back(std::to_string(e.handin_silver));
v.push_back(std::to_string(e.handin_gold));
v.push_back(std::to_string(e.handin_platinum));
v.push_back(std::to_string(e.return_copper));
v.push_back(std::to_string(e.return_silver));
v.push_back(std::to_string(e.return_gold));
v.push_back(std::to_string(e.return_platinum));
v.push_back(std::to_string(e.is_quest_handin));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventNpcHandin> All(Database& db)
{
std::vector<PlayerEventNpcHandin> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventNpcHandin e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.handin_copper = row[3] ? strtoull(row[3], nullptr, 10) : 0;
e.handin_silver = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.handin_gold = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.handin_platinum = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.return_copper = row[7] ? strtoull(row[7], nullptr, 10) : 0;
e.return_silver = row[8] ? strtoull(row[8], nullptr, 10) : 0;
e.return_gold = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.return_platinum = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.is_quest_handin = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventNpcHandin> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventNpcHandin> 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) {
PlayerEventNpcHandin e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.npc_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.npc_name = row[2] ? row[2] : "";
e.handin_copper = row[3] ? strtoull(row[3], nullptr, 10) : 0;
e.handin_silver = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.handin_gold = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.handin_platinum = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.return_copper = row[7] ? strtoull(row[7], nullptr, 10) : 0;
e.return_silver = row[8] ? strtoull(row[8], nullptr, 10) : 0;
e.return_gold = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.return_platinum = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.is_quest_handin = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventNpcHandin &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.handin_copper));
v.push_back(std::to_string(e.handin_silver));
v.push_back(std::to_string(e.handin_gold));
v.push_back(std::to_string(e.handin_platinum));
v.push_back(std::to_string(e.return_copper));
v.push_back(std::to_string(e.return_silver));
v.push_back(std::to_string(e.return_gold));
v.push_back(std::to_string(e.return_platinum));
v.push_back(std::to_string(e.is_quest_handin));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventNpcHandin> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_id));
v.push_back("'" + Strings::Escape(e.npc_name) + "'");
v.push_back(std::to_string(e.handin_copper));
v.push_back(std::to_string(e.handin_silver));
v.push_back(std::to_string(e.handin_gold));
v.push_back(std::to_string(e.handin_platinum));
v.push_back(std::to_string(e.return_copper));
v.push_back(std::to_string(e.return_silver));
v.push_back(std::to_string(e.return_gold));
v.push_back(std::to_string(e.return_platinum));
v.push_back(std::to_string(e.is_quest_handin));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_NPC_HANDIN_REPOSITORY_H
@@ -0,0 +1,463 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_SPEECH_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_SPEECH_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventSpeechRepository {
public:
struct PlayerEventSpeech {
uint64_t id;
std::string to_char_id;
std::string from_char_id;
uint32_t guild_id;
uint32_t type;
uint32_t min_status;
std::string message;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"to_char_id",
"from_char_id",
"guild_id",
"type",
"min_status",
"message",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"to_char_id",
"from_char_id",
"guild_id",
"type",
"min_status",
"message",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_speech");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventSpeech NewEntity()
{
PlayerEventSpeech e{};
e.id = 0;
e.to_char_id = "";
e.from_char_id = "";
e.guild_id = 0;
e.type = 0;
e.min_status = 0;
e.message = "";
e.created_at = 0;
return e;
}
static PlayerEventSpeech GetPlayerEventSpeech(
const std::vector<PlayerEventSpeech> &player_event_speechs,
int player_event_speech_id
)
{
for (auto &player_event_speech : player_event_speechs) {
if (player_event_speech.id == player_event_speech_id) {
return player_event_speech;
}
}
return NewEntity();
}
static PlayerEventSpeech FindOne(
Database& db,
int player_event_speech_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_speech_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventSpeech e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.to_char_id = row[1] ? row[1] : "";
e.from_char_id = row[2] ? row[2] : "";
e.guild_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.min_status = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.message = row[6] ? row[6] : "";
e.created_at = strtoll(row[7] ? row[7] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_speech_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_speech_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventSpeech &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.to_char_id) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.from_char_id) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.guild_id));
v.push_back(columns[4] + " = " + std::to_string(e.type));
v.push_back(columns[5] + " = " + std::to_string(e.min_status));
v.push_back(columns[6] + " = '" + Strings::Escape(e.message) + "'");
v.push_back(columns[7] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventSpeech InsertOne(
Database& db,
PlayerEventSpeech e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.to_char_id) + "'");
v.push_back("'" + Strings::Escape(e.from_char_id) + "'");
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.min_status));
v.push_back("'" + Strings::Escape(e.message) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventSpeech> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.to_char_id) + "'");
v.push_back("'" + Strings::Escape(e.from_char_id) + "'");
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.min_status));
v.push_back("'" + Strings::Escape(e.message) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventSpeech> All(Database& db)
{
std::vector<PlayerEventSpeech> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventSpeech e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.to_char_id = row[1] ? row[1] : "";
e.from_char_id = row[2] ? row[2] : "";
e.guild_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.min_status = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.message = row[6] ? row[6] : "";
e.created_at = strtoll(row[7] ? row[7] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventSpeech> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventSpeech> 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) {
PlayerEventSpeech e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.to_char_id = row[1] ? row[1] : "";
e.from_char_id = row[2] ? row[2] : "";
e.guild_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.min_status = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.message = row[6] ? row[6] : "";
e.created_at = strtoll(row[7] ? row[7] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventSpeech &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.to_char_id) + "'");
v.push_back("'" + Strings::Escape(e.from_char_id) + "'");
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.min_status));
v.push_back("'" + Strings::Escape(e.message) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventSpeech> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.to_char_id) + "'");
v.push_back("'" + Strings::Escape(e.from_char_id) + "'");
v.push_back(std::to_string(e.guild_id));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.min_status));
v.push_back("'" + Strings::Escape(e.message) + "'");
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_SPEECH_REPOSITORY_H
@@ -0,0 +1,535 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_TRADE_ENTRIES_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_TRADE_ENTRIES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventTradeEntriesRepository {
public:
struct PlayerEventTradeEntries {
uint64_t id;
uint64_t player_event_trade_id;
uint32_t char_id;
int16_t slot;
uint32_t item_id;
int16_t charges;
uint32_t augment_1_id;
uint32_t augment_2_id;
uint32_t augment_3_id;
uint32_t augment_4_id;
uint32_t augment_5_id;
uint32_t augment_6_id;
int8_t in_bag;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"player_event_trade_id",
"char_id",
"slot",
"item_id",
"charges",
"augment_1_id",
"augment_2_id",
"augment_3_id",
"augment_4_id",
"augment_5_id",
"augment_6_id",
"in_bag",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"player_event_trade_id",
"char_id",
"slot",
"item_id",
"charges",
"augment_1_id",
"augment_2_id",
"augment_3_id",
"augment_4_id",
"augment_5_id",
"augment_6_id",
"in_bag",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_trade_entries");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventTradeEntries NewEntity()
{
PlayerEventTradeEntries e{};
e.id = 0;
e.player_event_trade_id = 0;
e.char_id = 0;
e.slot = 0;
e.item_id = 0;
e.charges = 0;
e.augment_1_id = 0;
e.augment_2_id = 0;
e.augment_3_id = 0;
e.augment_4_id = 0;
e.augment_5_id = 0;
e.augment_6_id = 0;
e.in_bag = 0;
e.created_at = 0;
return e;
}
static PlayerEventTradeEntries GetPlayerEventTradeEntries(
const std::vector<PlayerEventTradeEntries> &player_event_trade_entriess,
int player_event_trade_entries_id
)
{
for (auto &player_event_trade_entries : player_event_trade_entriess) {
if (player_event_trade_entries.id == player_event_trade_entries_id) {
return player_event_trade_entries;
}
}
return NewEntity();
}
static PlayerEventTradeEntries FindOne(
Database& db,
int player_event_trade_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_trade_entries_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventTradeEntries e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.player_event_trade_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.slot = row[3] ? static_cast<int16_t>(atoi(row[3])) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.charges = row[5] ? static_cast<int16_t>(atoi(row[5])) : 0;
e.augment_1_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_2_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_3_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_4_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_5_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.augment_6_id = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
e.in_bag = row[12] ? static_cast<int8_t>(atoi(row[12])) : 0;
e.created_at = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_trade_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_trade_entries_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventTradeEntries &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.player_event_trade_id));
v.push_back(columns[2] + " = " + std::to_string(e.char_id));
v.push_back(columns[3] + " = " + std::to_string(e.slot));
v.push_back(columns[4] + " = " + std::to_string(e.item_id));
v.push_back(columns[5] + " = " + std::to_string(e.charges));
v.push_back(columns[6] + " = " + std::to_string(e.augment_1_id));
v.push_back(columns[7] + " = " + std::to_string(e.augment_2_id));
v.push_back(columns[8] + " = " + std::to_string(e.augment_3_id));
v.push_back(columns[9] + " = " + std::to_string(e.augment_4_id));
v.push_back(columns[10] + " = " + std::to_string(e.augment_5_id));
v.push_back(columns[11] + " = " + std::to_string(e.augment_6_id));
v.push_back(columns[12] + " = " + std::to_string(e.in_bag));
v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventTradeEntries InsertOne(
Database& db,
PlayerEventTradeEntries e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_trade_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.in_bag));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventTradeEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_trade_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.in_bag));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventTradeEntries> All(Database& db)
{
std::vector<PlayerEventTradeEntries> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventTradeEntries e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.player_event_trade_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.slot = row[3] ? static_cast<int16_t>(atoi(row[3])) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.charges = row[5] ? static_cast<int16_t>(atoi(row[5])) : 0;
e.augment_1_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_2_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_3_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_4_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_5_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.augment_6_id = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
e.in_bag = row[12] ? static_cast<int8_t>(atoi(row[12])) : 0;
e.created_at = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventTradeEntries> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventTradeEntries> 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) {
PlayerEventTradeEntries e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.player_event_trade_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.slot = row[3] ? static_cast<int16_t>(atoi(row[3])) : 0;
e.item_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.charges = row[5] ? static_cast<int16_t>(atoi(row[5])) : 0;
e.augment_1_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_2_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_3_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_4_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_5_id = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.augment_6_id = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
e.in_bag = row[12] ? static_cast<int8_t>(atoi(row[12])) : 0;
e.created_at = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventTradeEntries &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_trade_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.in_bag));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventTradeEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.player_event_trade_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.augment_1_id));
v.push_back(std::to_string(e.augment_2_id));
v.push_back(std::to_string(e.augment_3_id));
v.push_back(std::to_string(e.augment_4_id));
v.push_back(std::to_string(e.augment_5_id));
v.push_back(std::to_string(e.augment_6_id));
v.push_back(std::to_string(e.in_bag));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_TRADE_ENTRIES_REPOSITORY_H
@@ -0,0 +1,511 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_TRADE_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_TRADE_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventTradeRepository {
public:
struct PlayerEventTrade {
uint32_t id;
uint32_t char1_id;
uint32_t char2_id;
uint64_t char1_copper;
uint64_t char1_silver;
uint64_t char1_gold;
uint64_t char1_platinum;
uint64_t char2_copper;
uint64_t char2_silver;
uint64_t char2_gold;
uint64_t char2_platinum;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"char1_id",
"char2_id",
"char1_copper",
"char1_silver",
"char1_gold",
"char1_platinum",
"char2_copper",
"char2_silver",
"char2_gold",
"char2_platinum",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"char1_id",
"char2_id",
"char1_copper",
"char1_silver",
"char1_gold",
"char1_platinum",
"char2_copper",
"char2_silver",
"char2_gold",
"char2_platinum",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("player_event_trade");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventTrade NewEntity()
{
PlayerEventTrade e{};
e.id = 0;
e.char1_id = 0;
e.char2_id = 0;
e.char1_copper = 0;
e.char1_silver = 0;
e.char1_gold = 0;
e.char1_platinum = 0;
e.char2_copper = 0;
e.char2_silver = 0;
e.char2_gold = 0;
e.char2_platinum = 0;
e.created_at = 0;
return e;
}
static PlayerEventTrade GetPlayerEventTrade(
const std::vector<PlayerEventTrade> &player_event_trades,
int player_event_trade_id
)
{
for (auto &player_event_trade : player_event_trades) {
if (player_event_trade.id == player_event_trade_id) {
return player_event_trade;
}
}
return NewEntity();
}
static PlayerEventTrade FindOne(
Database& db,
int player_event_trade_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_trade_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventTrade e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char1_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.char2_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.char1_copper = row[3] ? strtoull(row[3], nullptr, 10) : 0;
e.char1_silver = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.char1_gold = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.char1_platinum = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.char2_copper = row[7] ? strtoull(row[7], nullptr, 10) : 0;
e.char2_silver = row[8] ? strtoull(row[8], nullptr, 10) : 0;
e.char2_gold = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.char2_platinum = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_trade_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_trade_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventTrade &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.char1_id));
v.push_back(columns[2] + " = " + std::to_string(e.char2_id));
v.push_back(columns[3] + " = " + std::to_string(e.char1_copper));
v.push_back(columns[4] + " = " + std::to_string(e.char1_silver));
v.push_back(columns[5] + " = " + std::to_string(e.char1_gold));
v.push_back(columns[6] + " = " + std::to_string(e.char1_platinum));
v.push_back(columns[7] + " = " + std::to_string(e.char2_copper));
v.push_back(columns[8] + " = " + std::to_string(e.char2_silver));
v.push_back(columns[9] + " = " + std::to_string(e.char2_gold));
v.push_back(columns[10] + " = " + std::to_string(e.char2_platinum));
v.push_back(columns[11] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventTrade InsertOne(
Database& db,
PlayerEventTrade e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char1_id));
v.push_back(std::to_string(e.char2_id));
v.push_back(std::to_string(e.char1_copper));
v.push_back(std::to_string(e.char1_silver));
v.push_back(std::to_string(e.char1_gold));
v.push_back(std::to_string(e.char1_platinum));
v.push_back(std::to_string(e.char2_copper));
v.push_back(std::to_string(e.char2_silver));
v.push_back(std::to_string(e.char2_gold));
v.push_back(std::to_string(e.char2_platinum));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<PlayerEventTrade> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char1_id));
v.push_back(std::to_string(e.char2_id));
v.push_back(std::to_string(e.char1_copper));
v.push_back(std::to_string(e.char1_silver));
v.push_back(std::to_string(e.char1_gold));
v.push_back(std::to_string(e.char1_platinum));
v.push_back(std::to_string(e.char2_copper));
v.push_back(std::to_string(e.char2_silver));
v.push_back(std::to_string(e.char2_gold));
v.push_back(std::to_string(e.char2_platinum));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<PlayerEventTrade> All(Database& db)
{
std::vector<PlayerEventTrade> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventTrade e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char1_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.char2_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.char1_copper = row[3] ? strtoull(row[3], nullptr, 10) : 0;
e.char1_silver = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.char1_gold = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.char1_platinum = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.char2_copper = row[7] ? strtoull(row[7], nullptr, 10) : 0;
e.char2_silver = row[8] ? strtoull(row[8], nullptr, 10) : 0;
e.char2_gold = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.char2_platinum = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventTrade> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventTrade> 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) {
PlayerEventTrade e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char1_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.char2_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.char1_copper = row[3] ? strtoull(row[3], nullptr, 10) : 0;
e.char1_silver = row[4] ? strtoull(row[4], nullptr, 10) : 0;
e.char1_gold = row[5] ? strtoull(row[5], nullptr, 10) : 0;
e.char1_platinum = row[6] ? strtoull(row[6], nullptr, 10) : 0;
e.char2_copper = row[7] ? strtoull(row[7], nullptr, 10) : 0;
e.char2_silver = row[8] ? strtoull(row[8], nullptr, 10) : 0;
e.char2_gold = row[9] ? strtoull(row[9], nullptr, 10) : 0;
e.char2_platinum = row[10] ? strtoull(row[10], nullptr, 10) : 0;
e.created_at = strtoll(row[11] ? row[11] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const PlayerEventTrade &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char1_id));
v.push_back(std::to_string(e.char2_id));
v.push_back(std::to_string(e.char1_copper));
v.push_back(std::to_string(e.char1_silver));
v.push_back(std::to_string(e.char1_gold));
v.push_back(std::to_string(e.char1_platinum));
v.push_back(std::to_string(e.char2_copper));
v.push_back(std::to_string(e.char2_silver));
v.push_back(std::to_string(e.char2_gold));
v.push_back(std::to_string(e.char2_platinum));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<PlayerEventTrade> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char1_id));
v.push_back(std::to_string(e.char2_id));
v.push_back(std::to_string(e.char1_copper));
v.push_back(std::to_string(e.char1_silver));
v.push_back(std::to_string(e.char1_gold));
v.push_back(std::to_string(e.char1_platinum));
v.push_back(std::to_string(e.char2_copper));
v.push_back(std::to_string(e.char2_silver));
v.push_back(std::to_string(e.char2_gold));
v.push_back(std::to_string(e.char2_platinum));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_TRADE_REPOSITORY_H
@@ -0,0 +1,560 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_SHAREDBANK_REPOSITORY_H
#define EQEMU_BASE_SHAREDBANK_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseSharedbankRepository {
public:
struct Sharedbank {
uint32_t account_id;
uint32_t slot_id;
uint32_t item_id;
uint16_t charges;
uint32_t color;
uint32_t augment_one;
uint32_t augment_two;
uint32_t augment_three;
uint32_t augment_four;
uint32_t augment_five;
uint32_t augment_six;
std::string custom_data;
uint32_t ornament_icon;
uint32_t ornament_idfile;
int32_t ornament_hero_model;
uint64_t guid;
};
static std::string PrimaryKey()
{
return std::string("account_id");
}
static std::vector<std::string> Columns()
{
return {
"account_id",
"slot_id",
"item_id",
"charges",
"color",
"augment_one",
"augment_two",
"augment_three",
"augment_four",
"augment_five",
"augment_six",
"custom_data",
"ornament_icon",
"ornament_idfile",
"ornament_hero_model",
"guid",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"account_id",
"slot_id",
"item_id",
"charges",
"color",
"augment_one",
"augment_two",
"augment_three",
"augment_four",
"augment_five",
"augment_six",
"custom_data",
"ornament_icon",
"ornament_idfile",
"ornament_hero_model",
"guid",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("sharedbank");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static Sharedbank NewEntity()
{
Sharedbank e{};
e.account_id = 0;
e.slot_id = 0;
e.item_id = 0;
e.charges = 0;
e.color = 0;
e.augment_one = 0;
e.augment_two = 0;
e.augment_three = 0;
e.augment_four = 0;
e.augment_five = 0;
e.augment_six = 0;
e.custom_data = "";
e.ornament_icon = 0;
e.ornament_idfile = 0;
e.ornament_hero_model = 0;
e.guid = 0;
return e;
}
static Sharedbank GetSharedbank(
const std::vector<Sharedbank> &sharedbanks,
int sharedbank_id
)
{
for (auto &sharedbank : sharedbanks) {
if (sharedbank.account_id == sharedbank_id) {
return sharedbank;
}
}
return NewEntity();
}
static Sharedbank FindOne(
Database& db,
int sharedbank_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
sharedbank_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Sharedbank e{};
e.account_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.custom_data = row[11] ? row[11] : "";
e.ornament_icon = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.ornament_idfile = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornament_hero_model = row[14] ? static_cast<int32_t>(atoi(row[14])) : 0;
e.guid = row[15] ? strtoull(row[15], nullptr, 10) : 0;
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int sharedbank_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
sharedbank_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const Sharedbank &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.account_id));
v.push_back(columns[1] + " = " + std::to_string(e.slot_id));
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
v.push_back(columns[3] + " = " + std::to_string(e.charges));
v.push_back(columns[4] + " = " + std::to_string(e.color));
v.push_back(columns[5] + " = " + std::to_string(e.augment_one));
v.push_back(columns[6] + " = " + std::to_string(e.augment_two));
v.push_back(columns[7] + " = " + std::to_string(e.augment_three));
v.push_back(columns[8] + " = " + std::to_string(e.augment_four));
v.push_back(columns[9] + " = " + std::to_string(e.augment_five));
v.push_back(columns[10] + " = " + std::to_string(e.augment_six));
v.push_back(columns[11] + " = '" + Strings::Escape(e.custom_data) + "'");
v.push_back(columns[12] + " = " + std::to_string(e.ornament_icon));
v.push_back(columns[13] + " = " + std::to_string(e.ornament_idfile));
v.push_back(columns[14] + " = " + std::to_string(e.ornament_hero_model));
v.push_back(columns[15] + " = " + std::to_string(e.guid));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.account_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static Sharedbank InsertOne(
Database& db,
Sharedbank e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.account_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.account_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<Sharedbank> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.account_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<Sharedbank> All(Database& db)
{
std::vector<Sharedbank> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Sharedbank e{};
e.account_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.custom_data = row[11] ? row[11] : "";
e.ornament_icon = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.ornament_idfile = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornament_hero_model = row[14] ? static_cast<int32_t>(atoi(row[14])) : 0;
e.guid = row[15] ? strtoull(row[15], nullptr, 10) : 0;
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<Sharedbank> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<Sharedbank> 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) {
Sharedbank e{};
e.account_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.custom_data = row[11] ? row[11] : "";
e.ornament_icon = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.ornament_idfile = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornament_hero_model = row[14] ? static_cast<int32_t>(atoi(row[14])) : 0;
e.guid = row[15] ? strtoull(row[15], nullptr, 10) : 0;
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const Sharedbank &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.account_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<Sharedbank> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.account_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.charges));
v.push_back(std::to_string(e.color));
v.push_back(std::to_string(e.augment_one));
v.push_back(std::to_string(e.augment_two));
v.push_back(std::to_string(e.augment_three));
v.push_back(std::to_string(e.augment_four));
v.push_back(std::to_string(e.augment_five));
v.push_back(std::to_string(e.augment_six));
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
v.push_back(std::to_string(e.ornament_icon));
v.push_back(std::to_string(e.ornament_idfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_SHAREDBANK_REPOSITORY_H
@@ -36,6 +36,7 @@ public:
uint32_t char_zone_id;
int32_t char_zone_instance_id;
uint8_t active_transaction;
time_t listing_date;
};
static std::string PrimaryKey()
@@ -63,6 +64,7 @@ public:
"char_zone_id",
"char_zone_instance_id",
"active_transaction",
"listing_date",
};
}
@@ -86,6 +88,7 @@ public:
"char_zone_id",
"char_zone_instance_id",
"active_transaction",
"UNIX_TIMESTAMP(listing_date)",
};
}
@@ -143,6 +146,7 @@ public:
e.char_zone_id = 0;
e.char_zone_instance_id = 0;
e.active_transaction = 0;
e.listing_date = 0;
return e;
}
@@ -196,6 +200,7 @@ public:
e.char_zone_id = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.char_zone_instance_id = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.active_transaction = row[16] ? static_cast<uint8_t>(strtoul(row[16], nullptr, 10)) : 0;
e.listing_date = strtoll(row[17] ? row[17] : "-1", nullptr, 10);
return e;
}
@@ -245,6 +250,7 @@ public:
v.push_back(columns[14] + " = " + std::to_string(e.char_zone_id));
v.push_back(columns[15] + " = " + std::to_string(e.char_zone_instance_id));
v.push_back(columns[16] + " = " + std::to_string(e.active_transaction));
v.push_back(columns[17] + " = FROM_UNIXTIME(" + (e.listing_date > 0 ? std::to_string(e.listing_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@@ -283,6 +289,7 @@ public:
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back(std::to_string(e.active_transaction));
v.push_back("FROM_UNIXTIME(" + (e.listing_date > 0 ? std::to_string(e.listing_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@@ -329,6 +336,7 @@ public:
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back(std::to_string(e.active_transaction));
v.push_back("FROM_UNIXTIME(" + (e.listing_date > 0 ? std::to_string(e.listing_date) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -379,6 +387,7 @@ public:
e.char_zone_id = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.char_zone_instance_id = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.active_transaction = row[16] ? static_cast<uint8_t>(strtoul(row[16], nullptr, 10)) : 0;
e.listing_date = strtoll(row[17] ? row[17] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@@ -420,6 +429,7 @@ public:
e.char_zone_id = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.char_zone_instance_id = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.active_transaction = row[16] ? static_cast<uint8_t>(strtoul(row[16], nullptr, 10)) : 0;
e.listing_date = strtoll(row[17] ? row[17] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@@ -511,6 +521,7 @@ public:
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back(std::to_string(e.active_transaction));
v.push_back("FROM_UNIXTIME(" + (e.listing_date > 0 ? std::to_string(e.listing_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@@ -550,6 +561,7 @@ public:
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back(std::to_string(e.active_transaction));
v.push_back("FROM_UNIXTIME(" + (e.listing_date > 0 ? std::to_string(e.listing_date) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -0,0 +1,703 @@
/**
* 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://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_ZONE_STATE_SPAWNS_REPOSITORY_H
#define EQEMU_BASE_ZONE_STATE_SPAWNS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseZoneStateSpawnsRepository {
public:
struct ZoneStateSpawns {
int64_t id;
uint32_t zone_id;
uint32_t instance_id;
int8_t is_corpse;
int32_t decay_in_seconds;
uint32_t npc_id;
uint32_t spawn2_id;
uint32_t spawngroup_id;
float x;
float y;
float z;
float heading;
uint32_t respawn_time;
uint32_t variance;
uint32_t grid;
int32_t current_waypoint;
int16_t path_when_zone_idle;
uint16_t condition_id;
int16_t condition_min_value;
int16_t enabled;
uint16_t anim;
std::string loot_data;
std::string entity_variables;
std::string buffs;
int64_t hp;
int64_t mana;
int64_t endurance;
time_t created_at;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"zone_id",
"instance_id",
"is_corpse",
"decay_in_seconds",
"npc_id",
"spawn2_id",
"spawngroup_id",
"x",
"y",
"z",
"heading",
"respawn_time",
"variance",
"grid",
"current_waypoint",
"path_when_zone_idle",
"condition_id",
"condition_min_value",
"enabled",
"anim",
"loot_data",
"entity_variables",
"buffs",
"hp",
"mana",
"endurance",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"zone_id",
"instance_id",
"is_corpse",
"decay_in_seconds",
"npc_id",
"spawn2_id",
"spawngroup_id",
"x",
"y",
"z",
"heading",
"respawn_time",
"variance",
"grid",
"current_waypoint",
"path_when_zone_idle",
"condition_id",
"condition_min_value",
"enabled",
"anim",
"loot_data",
"entity_variables",
"buffs",
"hp",
"mana",
"endurance",
"UNIX_TIMESTAMP(created_at)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("zone_state_spawns");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static ZoneStateSpawns NewEntity()
{
ZoneStateSpawns e{};
e.id = 0;
e.zone_id = 0;
e.instance_id = 0;
e.is_corpse = 0;
e.decay_in_seconds = 0;
e.npc_id = 0;
e.spawn2_id = 0;
e.spawngroup_id = 0;
e.x = 0;
e.y = 0;
e.z = 0;
e.heading = 0;
e.respawn_time = 0;
e.variance = 0;
e.grid = 0;
e.current_waypoint = 0;
e.path_when_zone_idle = 0;
e.condition_id = 0;
e.condition_min_value = 0;
e.enabled = 1;
e.anim = 0;
e.loot_data = "";
e.entity_variables = "";
e.buffs = "";
e.hp = 0;
e.mana = 0;
e.endurance = 0;
e.created_at = 0;
return e;
}
static ZoneStateSpawns GetZoneStateSpawns(
const std::vector<ZoneStateSpawns> &zone_state_spawnss,
int zone_state_spawns_id
)
{
for (auto &zone_state_spawns : zone_state_spawnss) {
if (zone_state_spawns.id == zone_state_spawns_id) {
return zone_state_spawns;
}
}
return NewEntity();
}
static ZoneStateSpawns FindOne(
Database& db,
int zone_state_spawns_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
zone_state_spawns_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
ZoneStateSpawns e{};
e.id = row[0] ? strtoll(row[0], nullptr, 10) : 0;
e.zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.instance_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.is_corpse = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
e.decay_in_seconds = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.npc_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.spawn2_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.spawngroup_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.x = row[8] ? strtof(row[8], nullptr) : 0;
e.y = row[9] ? strtof(row[9], nullptr) : 0;
e.z = row[10] ? strtof(row[10], nullptr) : 0;
e.heading = row[11] ? strtof(row[11], nullptr) : 0;
e.respawn_time = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.variance = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.grid = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.current_waypoint = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.path_when_zone_idle = row[16] ? static_cast<int16_t>(atoi(row[16])) : 0;
e.condition_id = row[17] ? static_cast<uint16_t>(strtoul(row[17], nullptr, 10)) : 0;
e.condition_min_value = row[18] ? static_cast<int16_t>(atoi(row[18])) : 0;
e.enabled = row[19] ? static_cast<int16_t>(atoi(row[19])) : 1;
e.anim = row[20] ? static_cast<uint16_t>(strtoul(row[20], nullptr, 10)) : 0;
e.loot_data = row[21] ? row[21] : "";
e.entity_variables = row[22] ? row[22] : "";
e.buffs = row[23] ? row[23] : "";
e.hp = row[24] ? strtoll(row[24], nullptr, 10) : 0;
e.mana = row[25] ? strtoll(row[25], nullptr, 10) : 0;
e.endurance = row[26] ? strtoll(row[26], nullptr, 10) : 0;
e.created_at = strtoll(row[27] ? row[27] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int zone_state_spawns_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
zone_state_spawns_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const ZoneStateSpawns &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.zone_id));
v.push_back(columns[2] + " = " + std::to_string(e.instance_id));
v.push_back(columns[3] + " = " + std::to_string(e.is_corpse));
v.push_back(columns[4] + " = " + std::to_string(e.decay_in_seconds));
v.push_back(columns[5] + " = " + std::to_string(e.npc_id));
v.push_back(columns[6] + " = " + std::to_string(e.spawn2_id));
v.push_back(columns[7] + " = " + std::to_string(e.spawngroup_id));
v.push_back(columns[8] + " = " + std::to_string(e.x));
v.push_back(columns[9] + " = " + std::to_string(e.y));
v.push_back(columns[10] + " = " + std::to_string(e.z));
v.push_back(columns[11] + " = " + std::to_string(e.heading));
v.push_back(columns[12] + " = " + std::to_string(e.respawn_time));
v.push_back(columns[13] + " = " + std::to_string(e.variance));
v.push_back(columns[14] + " = " + std::to_string(e.grid));
v.push_back(columns[15] + " = " + std::to_string(e.current_waypoint));
v.push_back(columns[16] + " = " + std::to_string(e.path_when_zone_idle));
v.push_back(columns[17] + " = " + std::to_string(e.condition_id));
v.push_back(columns[18] + " = " + std::to_string(e.condition_min_value));
v.push_back(columns[19] + " = " + std::to_string(e.enabled));
v.push_back(columns[20] + " = " + std::to_string(e.anim));
v.push_back(columns[21] + " = '" + Strings::Escape(e.loot_data) + "'");
v.push_back(columns[22] + " = '" + Strings::Escape(e.entity_variables) + "'");
v.push_back(columns[23] + " = '" + Strings::Escape(e.buffs) + "'");
v.push_back(columns[24] + " = " + std::to_string(e.hp));
v.push_back(columns[25] + " = " + std::to_string(e.mana));
v.push_back(columns[26] + " = " + std::to_string(e.endurance));
v.push_back(columns[27] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static ZoneStateSpawns InsertOne(
Database& db,
ZoneStateSpawns e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
v.push_back(std::to_string(e.is_corpse));
v.push_back(std::to_string(e.decay_in_seconds));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.spawn2_id));
v.push_back(std::to_string(e.spawngroup_id));
v.push_back(std::to_string(e.x));
v.push_back(std::to_string(e.y));
v.push_back(std::to_string(e.z));
v.push_back(std::to_string(e.heading));
v.push_back(std::to_string(e.respawn_time));
v.push_back(std::to_string(e.variance));
v.push_back(std::to_string(e.grid));
v.push_back(std::to_string(e.current_waypoint));
v.push_back(std::to_string(e.path_when_zone_idle));
v.push_back(std::to_string(e.condition_id));
v.push_back(std::to_string(e.condition_min_value));
v.push_back(std::to_string(e.enabled));
v.push_back(std::to_string(e.anim));
v.push_back("'" + Strings::Escape(e.loot_data) + "'");
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
v.push_back("'" + Strings::Escape(e.buffs) + "'");
v.push_back(std::to_string(e.hp));
v.push_back(std::to_string(e.mana));
v.push_back(std::to_string(e.endurance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<ZoneStateSpawns> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
v.push_back(std::to_string(e.is_corpse));
v.push_back(std::to_string(e.decay_in_seconds));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.spawn2_id));
v.push_back(std::to_string(e.spawngroup_id));
v.push_back(std::to_string(e.x));
v.push_back(std::to_string(e.y));
v.push_back(std::to_string(e.z));
v.push_back(std::to_string(e.heading));
v.push_back(std::to_string(e.respawn_time));
v.push_back(std::to_string(e.variance));
v.push_back(std::to_string(e.grid));
v.push_back(std::to_string(e.current_waypoint));
v.push_back(std::to_string(e.path_when_zone_idle));
v.push_back(std::to_string(e.condition_id));
v.push_back(std::to_string(e.condition_min_value));
v.push_back(std::to_string(e.enabled));
v.push_back(std::to_string(e.anim));
v.push_back("'" + Strings::Escape(e.loot_data) + "'");
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
v.push_back("'" + Strings::Escape(e.buffs) + "'");
v.push_back(std::to_string(e.hp));
v.push_back(std::to_string(e.mana));
v.push_back(std::to_string(e.endurance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<ZoneStateSpawns> All(Database& db)
{
std::vector<ZoneStateSpawns> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
ZoneStateSpawns e{};
e.id = row[0] ? strtoll(row[0], nullptr, 10) : 0;
e.zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.instance_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.is_corpse = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
e.decay_in_seconds = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.npc_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.spawn2_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.spawngroup_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.x = row[8] ? strtof(row[8], nullptr) : 0;
e.y = row[9] ? strtof(row[9], nullptr) : 0;
e.z = row[10] ? strtof(row[10], nullptr) : 0;
e.heading = row[11] ? strtof(row[11], nullptr) : 0;
e.respawn_time = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.variance = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.grid = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.current_waypoint = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.path_when_zone_idle = row[16] ? static_cast<int16_t>(atoi(row[16])) : 0;
e.condition_id = row[17] ? static_cast<uint16_t>(strtoul(row[17], nullptr, 10)) : 0;
e.condition_min_value = row[18] ? static_cast<int16_t>(atoi(row[18])) : 0;
e.enabled = row[19] ? static_cast<int16_t>(atoi(row[19])) : 1;
e.anim = row[20] ? static_cast<uint16_t>(strtoul(row[20], nullptr, 10)) : 0;
e.loot_data = row[21] ? row[21] : "";
e.entity_variables = row[22] ? row[22] : "";
e.buffs = row[23] ? row[23] : "";
e.hp = row[24] ? strtoll(row[24], nullptr, 10) : 0;
e.mana = row[25] ? strtoll(row[25], nullptr, 10) : 0;
e.endurance = row[26] ? strtoll(row[26], nullptr, 10) : 0;
e.created_at = strtoll(row[27] ? row[27] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<ZoneStateSpawns> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<ZoneStateSpawns> 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) {
ZoneStateSpawns e{};
e.id = row[0] ? strtoll(row[0], nullptr, 10) : 0;
e.zone_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.instance_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.is_corpse = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
e.decay_in_seconds = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.npc_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.spawn2_id = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.spawngroup_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.x = row[8] ? strtof(row[8], nullptr) : 0;
e.y = row[9] ? strtof(row[9], nullptr) : 0;
e.z = row[10] ? strtof(row[10], nullptr) : 0;
e.heading = row[11] ? strtof(row[11], nullptr) : 0;
e.respawn_time = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.variance = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.grid = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.current_waypoint = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.path_when_zone_idle = row[16] ? static_cast<int16_t>(atoi(row[16])) : 0;
e.condition_id = row[17] ? static_cast<uint16_t>(strtoul(row[17], nullptr, 10)) : 0;
e.condition_min_value = row[18] ? static_cast<int16_t>(atoi(row[18])) : 0;
e.enabled = row[19] ? static_cast<int16_t>(atoi(row[19])) : 1;
e.anim = row[20] ? static_cast<uint16_t>(strtoul(row[20], nullptr, 10)) : 0;
e.loot_data = row[21] ? row[21] : "";
e.entity_variables = row[22] ? row[22] : "";
e.buffs = row[23] ? row[23] : "";
e.hp = row[24] ? strtoll(row[24], nullptr, 10) : 0;
e.mana = row[25] ? strtoll(row[25], nullptr, 10) : 0;
e.endurance = row[26] ? strtoll(row[26], nullptr, 10) : 0;
e.created_at = strtoll(row[27] ? row[27] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const ZoneStateSpawns &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
v.push_back(std::to_string(e.is_corpse));
v.push_back(std::to_string(e.decay_in_seconds));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.spawn2_id));
v.push_back(std::to_string(e.spawngroup_id));
v.push_back(std::to_string(e.x));
v.push_back(std::to_string(e.y));
v.push_back(std::to_string(e.z));
v.push_back(std::to_string(e.heading));
v.push_back(std::to_string(e.respawn_time));
v.push_back(std::to_string(e.variance));
v.push_back(std::to_string(e.grid));
v.push_back(std::to_string(e.current_waypoint));
v.push_back(std::to_string(e.path_when_zone_idle));
v.push_back(std::to_string(e.condition_id));
v.push_back(std::to_string(e.condition_min_value));
v.push_back(std::to_string(e.enabled));
v.push_back(std::to_string(e.anim));
v.push_back("'" + Strings::Escape(e.loot_data) + "'");
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
v.push_back("'" + Strings::Escape(e.buffs) + "'");
v.push_back(std::to_string(e.hp));
v.push_back(std::to_string(e.mana));
v.push_back(std::to_string(e.endurance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<ZoneStateSpawns> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.zone_id));
v.push_back(std::to_string(e.instance_id));
v.push_back(std::to_string(e.is_corpse));
v.push_back(std::to_string(e.decay_in_seconds));
v.push_back(std::to_string(e.npc_id));
v.push_back(std::to_string(e.spawn2_id));
v.push_back(std::to_string(e.spawngroup_id));
v.push_back(std::to_string(e.x));
v.push_back(std::to_string(e.y));
v.push_back(std::to_string(e.z));
v.push_back(std::to_string(e.heading));
v.push_back(std::to_string(e.respawn_time));
v.push_back(std::to_string(e.variance));
v.push_back(std::to_string(e.grid));
v.push_back(std::to_string(e.current_waypoint));
v.push_back(std::to_string(e.path_when_zone_idle));
v.push_back(std::to_string(e.condition_id));
v.push_back(std::to_string(e.condition_min_value));
v.push_back(std::to_string(e.enabled));
v.push_back(std::to_string(e.anim));
v.push_back("'" + Strings::Escape(e.loot_data) + "'");
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
v.push_back("'" + Strings::Escape(e.buffs) + "'");
v.push_back(std::to_string(e.hp));
v.push_back(std::to_string(e.mana));
v.push_back(std::to_string(e.endurance));
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_ZONE_STATE_SPAWNS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_BOT_BLOCKED_BUFFS_REPOSITORY_H
#define EQEMU_BOT_BLOCKED_BUFFS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_bot_blocked_buffs_repository.h"
class BotBlockedBuffsRepository: public BaseBotBlockedBuffsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* BotBlockedBuffsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* BotBlockedBuffsRepository::GetWhereNeverExpires()
* BotBlockedBuffsRepository::GetWhereXAndY()
* BotBlockedBuffsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
};
#endif //EQEMU_BOT_BLOCKED_BUFFS_REPOSITORY_H
-40
View File
@@ -44,46 +44,6 @@ public:
*/
// Custom extended repository methods here
static bool SaveAllHelmAppearances(Database& db, const uint32 owner_id, const bool show_flag)
{
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `show_helm` = {} WHERE `owner_id` = {}",
TableName(),
show_flag ? 1 : 0,
owner_id
)
);
return results.Success();
}
static bool ToggleAllHelmAppearances(Database& db, const uint32 owner_id)
{
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `show_helm` = (`show_helm` XOR '1') WHERE `owner_id` = {}",
TableName(),
owner_id
)
);
return results.Success();
}
static bool SaveAllFollowDistances(Database& db, const uint32 owner_id, const uint32 follow_distance)
{
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `follow_distance` = {} WHERE `owner_id` = {}",
TableName(),
follow_distance,
owner_id
)
);
return results.Success();
}
};
#endif //EQEMU_BOT_DATA_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_BOT_SETTINGS_REPOSITORY_H
#define EQEMU_BOT_SETTINGS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_bot_settings_repository.h"
class BotSettingsRepository: public BaseBotSettingsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* BotSettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* BotSettingsRepository::GetWhereNeverExpires()
* BotSettingsRepository::GetWhereXAndY()
* BotSettingsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
};
#endif //EQEMU_BOT_SETTINGS_REPOSITORY_H
@@ -2,7 +2,7 @@
#define EQEMU_CHARACTER_EXPEDITION_LOCKOUTS_REPOSITORY_H
#include "../database.h"
#include "../expedition_lockout_timer.h"
#include "../dynamic_zone_lockout.h"
#include "../strings.h"
#include "base/base_character_expedition_lockouts_repository.h"
#include <unordered_map>
@@ -47,33 +47,8 @@ public:
// Custom extended repository methods here
struct CharacterExpeditionLockoutsTimeStamp {
int id;
int character_id;
std::string expedition_name;
std::string event_name;
time_t expire_time;
int duration;
std::string from_expedition_uuid;
};
static ExpeditionLockoutTimer GetExpeditionLockoutTimerFromEntry(
CharacterExpeditionLockoutsTimeStamp&& entry)
{
ExpeditionLockoutTimer lockout_timer{
std::move(entry.from_expedition_uuid),
std::move(entry.expedition_name),
std::move(entry.event_name),
static_cast<uint64_t>(entry.expire_time),
static_cast<uint32_t>(entry.duration)
};
return lockout_timer;
}
static std::unordered_map<uint32_t, std::vector<ExpeditionLockoutTimer>> GetManyCharacterLockoutTimers(
Database& db, const std::vector<uint32_t>& character_ids,
const std::string& expedition_name, const std::string& ordered_event_name)
static std::unordered_map<uint32_t, std::vector<DzLockout>> GetLockouts(
Database& db, const std::vector<uint32_t>& char_ids, const std::string& expedition)
{
auto results = db.QueryDatabase(fmt::format(SQL(
SELECT
@@ -84,39 +59,171 @@ public:
from_expedition_uuid
FROM character_expedition_lockouts
WHERE
character_id IN ({})
character_id IN ({0})
AND expire_time > NOW()
AND expedition_name = '{}'
AND expedition_name = '{1}'
ORDER BY
FIELD(character_id, {}),
FIELD(event_name, '{}') DESC
FIELD(character_id, {0}),
FIELD(event_name, '{2}') DESC
),
fmt::join(character_ids, ","),
Strings::Escape(expedition_name),
fmt::join(character_ids, ","),
Strings::Escape(ordered_event_name)
fmt::join(char_ids, ","),
Strings::Escape(expedition),
Strings::Escape(DzLockout::ReplayTimer)
));
std::unordered_map<uint32_t, std::vector<ExpeditionLockoutTimer>> lockouts;
std::unordered_map<uint32_t, std::vector<DzLockout>> lockouts;
for (auto row = results.begin(); row != results.end(); ++row)
{
CharacterExpeditionLockoutsTimeStamp entry{};
int col = 0;
entry.character_id = std::strtoul(row[col++], nullptr, 10);
entry.expire_time = std::strtoull(row[col++], nullptr, 10);
entry.duration = std::strtoul(row[col++], nullptr, 10);
entry.event_name = row[col++];
entry.expedition_name = expedition_name;
entry.from_expedition_uuid = row[col++];
uint32_t char_id = std::strtoul(row[col++], nullptr, 10);
time_t expire_time = std::strtoull(row[col++], nullptr, 10);
uint32_t duration = std::strtoul(row[col++], nullptr, 10);
std::string event = row[col++];
std::string uuid = row[col++];
auto lockout = GetExpeditionLockoutTimerFromEntry(std::move(entry));
lockouts[entry.character_id].emplace_back(std::move(lockout));
lockouts[char_id].emplace_back(std::move(uuid), expedition, std::move(event), expire_time, duration);
}
return lockouts;
}
static std::vector<DzLockout> GetLockouts(Database& db, uint32_t char_id)
{
std::vector<DzLockout> lockouts;
auto rows = GetWhere(db, fmt::format("character_id = {} AND expire_time > NOW()", char_id));
lockouts.reserve(rows.size());
for (auto& row : rows)
{
lockouts.emplace_back(
std::move(row.from_expedition_uuid),
std::move(row.expedition_name),
std::move(row.event_name),
row.expire_time,
row.duration
);
}
return lockouts;
}
static std::vector<CharacterExpeditionLockouts> GetLockouts(Database& db, const std::vector<std::string>& names, const std::string& expedition, const std::string& event)
{
if (names.empty())
{
return {};
}
return GetWhere(db, fmt::format(
"character_id IN (select id from character_data where name IN ('{}')) AND expire_time > NOW() AND expedition_name = '{}' AND event_name = '{}' LIMIT 1",
fmt::join(names, "','"), Strings::Escape(expedition), Strings::Escape(event)));
}
static void InsertLockouts(Database& db, uint32_t char_id, const std::vector<DzLockout>& lockouts)
{
std::string insert_values;
for (const auto& lockout : lockouts)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, FROM_UNIXTIME({}), {}, '{}', '{}', '{}'),",
char_id,
lockout.GetExpireTime(),
lockout.GetDuration(),
Strings::Escape(lockout.UUID()),
Strings::Escape(lockout.DzName()),
Strings::Escape(lockout.Event())
);
}
if (!insert_values.empty())
{
insert_values.pop_back(); // trailing comma
auto query = fmt::format(SQL(
INSERT INTO character_expedition_lockouts
(character_id, expire_time, duration, from_expedition_uuid, expedition_name, event_name)
VALUES {}
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration);
), insert_values);
db.QueryDatabase(query);
}
}
static void InsertLockout(Database& db, const std::vector<uint32_t>& char_ids, const DzLockout& lockout)
{
std::string insert_values;
for (const auto& char_id : char_ids)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, FROM_UNIXTIME({}), {}, '{}', '{}', '{}'),",
char_id,
lockout.GetExpireTime(),
lockout.GetDuration(),
Strings::Escape(lockout.UUID()),
Strings::Escape(lockout.DzName()),
Strings::Escape(lockout.Event())
);
}
if (!insert_values.empty())
{
insert_values.pop_back(); // trailing comma
auto query = fmt::format(SQL(
INSERT INTO character_expedition_lockouts
(character_id, expire_time, duration, from_expedition_uuid, expedition_name, event_name)
VALUES {}
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration);
), insert_values);
db.QueryDatabase(query);
}
}
// inserts a new lockout or updates existing lockout with seconds added to current time
static void AddLockoutDuration(Database& db, const std::vector<uint32_t>& char_ids, const DzLockout& lockout, int seconds)
{
std::string insert_values;
for (const auto& char_id : char_ids)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, FROM_UNIXTIME({}), {}, '{}', '{}', '{}'),",
char_id,
lockout.GetExpireTime(),
lockout.GetDuration(),
Strings::Escape(lockout.UUID()),
Strings::Escape(lockout.DzName()),
Strings::Escape(lockout.Event())
);
}
if (!insert_values.empty())
{
insert_values.pop_back(); // trailing comma
auto query = fmt::format(SQL(
INSERT INTO character_expedition_lockouts
(character_id, expire_time, duration, from_expedition_uuid, expedition_name, event_name)
VALUES {0}
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = DATE_ADD(expire_time, INTERVAL {1} SECOND),
duration = GREATEST(0, CAST(duration AS SIGNED) + {1});
), insert_values, seconds);
db.QueryDatabase(query);
}
}
};
#endif //EQEMU_CHARACTER_EXPEDITION_LOCKOUTS_REPOSITORY_H
@@ -0,0 +1,84 @@
#ifndef EQEMU_DYNAMIC_ZONE_LOCKOUTS_REPOSITORY_H
#define EQEMU_DYNAMIC_ZONE_LOCKOUTS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "../dynamic_zone_lockout.h"
#include "base/base_dynamic_zone_lockouts_repository.h"
class DynamicZoneLockoutsRepository: public BaseDynamicZoneLockoutsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* DynamicZoneLockoutsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* DynamicZoneLockoutsRepository::GetWhereNeverExpires()
* DynamicZoneLockoutsRepository::GetWhereXAndY()
* DynamicZoneLockoutsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
static void InsertLockouts(Database& db, uint32_t dz_id, const std::vector<DzLockout>& lockouts)
{
std::string insert_values;
for (const auto& lockout : lockouts)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, '{}', '{}', FROM_UNIXTIME({}), {}),",
dz_id,
Strings::Escape(lockout.UUID()),
Strings::Escape(lockout.Event()),
lockout.GetExpireTime(),
lockout.GetDuration()
);
}
if (!insert_values.empty())
{
insert_values.pop_back(); // trailing comma
auto query = fmt::format(SQL(
INSERT INTO dynamic_zone_lockouts
(dynamic_zone_id, from_expedition_uuid, event_name, expire_time, duration)
VALUES {}
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration);
), insert_values);
db.QueryDatabase(query);
}
}
};
#endif //EQEMU_DYNAMIC_ZONE_LOCKOUTS_REPOSITORY_H
@@ -65,7 +65,7 @@ public:
));
}
static std::vector<MemberWithName> GetAllWithNames(Database& db)
static std::vector<MemberWithName> AllWithNames(Database& db)
{
std::vector<MemberWithName> all_entries;
@@ -146,65 +146,34 @@ public:
static void RemoveMember(Database& db, uint32_t dynamic_zone_id, uint32_t character_id)
{
db.QueryDatabase(fmt::format(SQL(
DELETE FROM {}
WHERE dynamic_zone_id = {} AND character_id = {};
),
TableName(), dynamic_zone_id, character_id
));
DeleteWhere(db, fmt::format("dynamic_zone_id = {} AND character_id = {}", dynamic_zone_id, character_id));
}
static void RemoveAllMembers(Database& db, uint32_t dynamic_zone_id)
{
db.QueryDatabase(fmt::format(SQL(
DELETE FROM {}
WHERE dynamic_zone_id = {};
),
TableName(), dynamic_zone_id
));
DeleteWhere(db, fmt::format("dynamic_zone_id = {}", dynamic_zone_id));
}
static void RemoveAllMembers(Database& db, std::vector<uint32_t> dynamic_zone_ids)
static uint32_t InsertOrUpdateMany(Database& db, const std::vector<DynamicZoneMembers>& entries)
{
if (!dynamic_zone_ids.empty())
if (entries.empty())
{
db.QueryDatabase(fmt::format(SQL(
DELETE FROM {}
WHERE dynamic_zone_id IN ({});
),
TableName(), Strings::Join(dynamic_zone_ids, ",")
));
}
}
static int InsertOrUpdateMany(Database& db,
const std::vector<DynamicZoneMembers>& dynamic_zone_members_entries)
{
std::vector<std::string> insert_chunks;
for (auto &dynamic_zone_members_entry: dynamic_zone_members_entries)
{
std::vector<std::string> insert_values;
insert_values.push_back(std::to_string(dynamic_zone_members_entry.id));
insert_values.push_back(std::to_string(dynamic_zone_members_entry.dynamic_zone_id));
insert_values.push_back(std::to_string(dynamic_zone_members_entry.character_id));
insert_chunks.push_back("(" + Strings::Implode(",", insert_values) + ")");
return 0;
}
std::vector<std::string> insert_values;
std::vector<std::string> values;
values.reserve(entries.size());
auto results = db.QueryDatabase(
fmt::format(
"INSERT INTO {} ({}) VALUES {} ON DUPLICATE KEY UPDATE id = id;",
TableName(),
ColumnsRaw(),
Strings::Implode(",", insert_chunks)
)
);
for (const auto& entry : entries)
{
values.push_back(fmt::format("({},{},{})", entry.id, entry.dynamic_zone_id, entry.character_id));
}
return (results.Success() ? results.RowsAffected() : 0);
auto results = db.QueryDatabase(fmt::format(
"INSERT INTO {} ({}) VALUES {} ON DUPLICATE KEY UPDATE id = id;",
TableName(), ColumnsRaw(), fmt::join(values, ",")));
return results.Success() ? results.RowsAffected() : 0;
}
};
@@ -70,6 +70,8 @@ public:
float zone_in_z;
float zone_in_heading;
int has_zone_in;
int8_t is_locked;
int8_t add_replay;
int zone;
int version;
int is_global;
@@ -105,6 +107,8 @@ public:
dynamic_zones.zone_in_z,
dynamic_zones.zone_in_heading,
dynamic_zones.has_zone_in,
dynamic_zones.is_locked,
dynamic_zones.add_replay,
instance_list.zone,
instance_list.version,
instance_list.is_global,
@@ -144,6 +148,8 @@ public:
entry.zone_in_z = strtof(row[col++], nullptr);
entry.zone_in_heading = strtof(row[col++], nullptr);
entry.has_zone_in = strtol(row[col++], nullptr, 10) != 0;
entry.is_locked = static_cast<int8_t>(strtol(row[col++], nullptr, 10));
entry.add_replay = static_cast<int8_t>(strtol(row[col++], nullptr, 10));
// from instance_list
entry.zone = strtol(row[col++], nullptr, 10);
entry.version = strtol(row[col++], nullptr, 10);
@@ -244,6 +250,22 @@ public:
}
}
static void UpdateLocked(Database& db, uint32_t dz_id, bool lock)
{
if (dz_id != 0)
{
db.QueryDatabase(fmt::format("UPDATE dynamic_zones SET is_locked = {} WHERE id = {}", lock, dz_id));
}
}
static void UpdateReplayOnJoin(Database& db, uint32_t dz_id, bool enabled)
{
if (dz_id != 0)
{
db.QueryDatabase(fmt::format("UPDATE dynamic_zones SET add_replay = {} WHERE id = {}", enabled, dz_id));
}
}
static void UpdateSwitchID(Database& db, uint32_t dz_id, int dz_switch_id)
{
if (dz_id != 0)
@@ -351,6 +373,59 @@ public:
return all_entries;
}
struct CharacterDz
{
uint32_t id;
std::string name;
uint32_t dz_id;
};
// get character ids with possible active dz id by type
static std::vector<CharacterDz> GetCharactersWithDz(Database& db, const std::vector<std::string>& names, int type)
{
if (names.empty())
{
return {};
}
std::vector<CharacterDz> entries;
entries.reserve(names.size());
auto results = db.QueryDatabase(fmt::format(SQL(
SELECT
character_data.id,
character_data.name,
MAX(dynamic_zones.id)
FROM character_data
LEFT JOIN dynamic_zone_members
ON character_data.id = dynamic_zone_members.character_id
LEFT JOIN dynamic_zones
ON dynamic_zone_members.dynamic_zone_id = dynamic_zones.id
AND dynamic_zones.`type` = {0}
WHERE character_data.name IN ('{1}')
GROUP BY character_data.id
ORDER BY FIELD(character_data.name, '{1}')
),
type,
fmt::join(names, "','")
));
if (results.Success())
{
for (auto row = results.begin(); row != results.end(); ++row)
{
CharacterDz entry{};
entry.id = std::strtoul(row[0], nullptr, 10);
entry.name = row[1];
entry.dz_id = row[2] ? std::strtoul(row[2], nullptr, 10) : 0;
entries.push_back(std::move(entry));
}
}
return entries;
}
};
#endif //EQEMU_DYNAMIC_ZONES_REPOSITORY_H
@@ -1,102 +0,0 @@
#ifndef EQEMU_EXPEDITION_LOCKOUTS_REPOSITORY_H
#define EQEMU_EXPEDITION_LOCKOUTS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_expedition_lockouts_repository.h"
class ExpeditionLockoutsRepository: public BaseExpeditionLockoutsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* ExpeditionLockoutsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* ExpeditionLockoutsRepository::GetWhereNeverExpires()
* ExpeditionLockoutsRepository::GetWhereXAndY()
* ExpeditionLockoutsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
struct ExpeditionLockoutsWithTimestamp {
uint32_t id;
uint32_t expedition_id;
std::string event_name;
time_t expire_time;
int duration;
std::string from_expedition_uuid;
};
static std::vector<ExpeditionLockoutsWithTimestamp> GetWithTimestamp(
Database& db, const std::vector<uint32_t>& expedition_ids)
{
if (expedition_ids.empty())
{
return {};
}
std::vector<ExpeditionLockoutsWithTimestamp> all_entries;
auto results = db.QueryDatabase(fmt::format(SQL(
SELECT
id,
expedition_id,
event_name,
UNIX_TIMESTAMP(expire_time),
duration,
from_expedition_uuid
FROM expedition_lockouts
WHERE expedition_id IN ({})
),
Strings::Join(expedition_ids, ",")
));
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row)
{
ExpeditionLockoutsWithTimestamp entry{};
int col = 0;
entry.id = strtoul(row[col++], nullptr, 10);
entry.expedition_id = strtoul(row[col++], nullptr, 10);
entry.event_name = row[col++];
entry.expire_time = strtoull(row[col++], nullptr, 10);
entry.duration = strtol(row[col++], nullptr, 10);
entry.from_expedition_uuid = row[col++];
all_entries.emplace_back(std::move(entry));
}
return all_entries;
}
};
#endif //EQEMU_EXPEDITION_LOCKOUTS_REPOSITORY_H
@@ -1,134 +0,0 @@
#ifndef EQEMU_EXPEDITIONS_REPOSITORY_H
#define EQEMU_EXPEDITIONS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_expeditions_repository.h"
class ExpeditionsRepository: public BaseExpeditionsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* ExpeditionsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* ExpeditionsRepository::GetWhereNeverExpires()
* ExpeditionsRepository::GetWhereXAndY()
* ExpeditionsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
struct CharacterExpedition
{
uint32_t id;
std::string name;
uint32_t expedition_id;
};
static std::vector<CharacterExpedition> GetCharactersWithExpedition(
Database& db, const std::vector<std::string>& character_names)
{
if (character_names.empty())
{
return {};
}
std::vector<CharacterExpedition> entries;
auto joined_character_names = fmt::format("'{}'", Strings::Join(character_names, "','"));
auto results = db.QueryDatabase(fmt::format(SQL(
SELECT
character_data.id,
character_data.name,
MAX(expeditions.id)
FROM character_data
LEFT JOIN dynamic_zone_members
ON character_data.id = dynamic_zone_members.character_id
LEFT JOIN expeditions
ON dynamic_zone_members.dynamic_zone_id = expeditions.dynamic_zone_id
WHERE character_data.name IN ({})
GROUP BY character_data.id
ORDER BY FIELD(character_data.name, {})
),
joined_character_names,
joined_character_names
));
if (results.Success())
{
entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row)
{
CharacterExpedition entry{};
entry.id = std::strtoul(row[0], nullptr, 10);
entry.name = row[1];
entry.expedition_id = row[2] ? std::strtoul(row[2], nullptr, 10) : 0;
entries.emplace_back(std::move(entry));
}
}
return entries;
}
static uint32_t GetIDByMemberID(Database& db, uint32_t character_id)
{
if (character_id == 0)
{
return 0;
}
uint32_t expedition_id = 0;
auto results = db.QueryDatabase(fmt::format(SQL(
SELECT
expeditions.id
FROM expeditions
INNER JOIN dynamic_zone_members
ON expeditions.dynamic_zone_id = dynamic_zone_members.dynamic_zone_id
WHERE
dynamic_zone_members.character_id = {}
),
character_id
));
if (results.Success() && results.RowCount() > 0)
{
auto row = results.begin();
expedition_id = std::strtoul(row[0], nullptr, 10);
}
return expedition_id;
}
};
#endif //EQEMU_EXPEDITIONS_REPOSITORY_H
@@ -45,33 +45,26 @@ public:
// Custom extended repository methods here
static int InsertOrUpdateMany(Database& db,
const std::vector<InstanceListPlayer>& instance_list_player_entries)
static uint32_t InsertOrUpdateMany(Database& db, const std::vector<InstanceListPlayer>& entries)
{
std::vector<std::string> insert_chunks;
for (auto &instance_list_player_entry: instance_list_player_entries)
if (entries.empty())
{
std::vector<std::string> insert_values;
insert_values.push_back(std::to_string(instance_list_player_entry.id));
insert_values.push_back(std::to_string(instance_list_player_entry.charid));
insert_chunks.push_back("(" + Strings::Implode(",", insert_values) + ")");
return 0;
}
std::vector<std::string> insert_values;
std::vector<std::string> values;
values.reserve(entries.size());
auto results = db.QueryDatabase(
fmt::format(
"INSERT INTO {} ({}) VALUES {} ON DUPLICATE KEY UPDATE id = VALUES(id)",
TableName(),
ColumnsRaw(),
Strings::Implode(",", insert_chunks)
)
);
for (const auto& entry : entries)
{
values.push_back(fmt::format("({},{})", entry.id, entry.charid));
}
return (results.Success() ? results.RowsAffected() : 0);
auto results = db.QueryDatabase(fmt::format(
"INSERT INTO {} ({}) VALUES {} ON DUPLICATE KEY UPDATE id = VALUES(id)",
TableName(), ColumnsRaw(), fmt::join(values, ",")));
return results.Success() ? results.RowsAffected() : 0;
}
static bool ReplaceOne(Database& db, InstanceListPlayer e)
+53
View File
@@ -7,6 +7,14 @@
class ItemsRepository: public BaseItemsRepository {
public:
struct Bazaar_Results {
uint32 item_id;
std::string name;
bool stackable;
uint32 icon;
uint32 stats;
};
static std::vector<int32> GetItemIDsBySearchCriteria(
Database& db,
std::string search_string,
@@ -37,6 +45,51 @@ public:
return item_id_list;
}
static std::unordered_map<uint32, Bazaar_Results> GetItemsForBazaarSearch(
Database& db,
const std::vector<std::string> &search_ids,
const std::string &name,
const std::string &field_criteria_items,
const std::string &where_criteria_items,
const uint32 query_limit = 0
)
{
auto query = fmt::format(
"SELECT id, name, stackable, icon, {} "
"FROM items "
"WHERE `name` LIKE '%%{}%%' AND {} AND id IN({}) "
"ORDER BY id ASC",
field_criteria_items,
Strings::Escape(name),
where_criteria_items,
Strings::Implode(",", search_ids)
);
if (query_limit >= 1) {
query += fmt::format(" LIMIT {}", query_limit);
}
std::unordered_map<uint32, Bazaar_Results> item_list;
auto results = db.QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return item_list;
}
item_list.reserve(results.RowCount());
for (auto row : results) {
Bazaar_Results br{};
br.item_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
br.name = row[1] ? row[1] : "";
br.stackable = atoi(row[2]) ? true : false;
br.icon = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
br.stats = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
item_list.emplace(br.item_id, br);
}
return item_list;
}
};
+83 -36
View File
@@ -4,47 +4,94 @@
#include "../database.h"
#include "../strings.h"
#include "base/base_login_accounts_repository.h"
#include "../../loginserver/encryption.h"
#include "../../loginserver/login_types.h"
class LoginAccountsRepository: public BaseLoginAccountsRepository {
class LoginAccountsRepository : public BaseLoginAccountsRepository {
public:
static int64 GetFreeID(Database &db, const std::string &loginserver)
{
auto query = fmt::format(
"SELECT IFNULL(MAX(id), 0) + 1 FROM login_accounts WHERE source_loginserver = '{}'",
Strings::Escape(loginserver)
);
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* LoginAccountsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* LoginAccountsRepository::GetWhereNeverExpires()
* LoginAccountsRepository::GetWhereXAndY()
* LoginAccountsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
auto results = db.QueryDatabase(query);
if (!results.Success() || results.RowCount() != 1) {
return 0;
}
// Custom extended repository methods here
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
static LoginAccountsRepository::LoginAccounts CreateAccountFromContext(
Database &db,
LoginAccountContext c
)
{
auto a = LoginAccountsRepository::NewEntity();
if (!c.password_is_encrypted) {
auto e = EncryptPasswordFromContext(c);
a.account_password = e.password;
}
a.id = c.login_account_id > 0 ? c.login_account_id : GetFreeID(db, c.source_loginserver);
a.account_name = c.username;
a.account_email = !c.email.empty() ? c.email : "local_creation";
a.source_loginserver = c.source_loginserver;
a.last_ip_address = "127.0.0.1";
a.last_login_date = std::time(nullptr);
a.created_at = std::time(nullptr);
LoginAccountsRepository::InsertOne(db, a);
return GetAccountFromContext(db, c).id > 0 ? a : NewEntity();
}
static LoginAccountsRepository::LoginAccounts GetAccountFromContext(
Database &db,
LoginAccountContext c
)
{
std::string where = fmt::format(
"account_name = '{}' AND source_loginserver = '{}'",
Strings::Escape(c.username),
Strings::Escape(c.source_loginserver)
);
if (!c.email.empty()) {
where += fmt::format(" AND account_email = '{}'", Strings::Escape(c.email));
}
if (c.login_account_id > 0) {
where += fmt::format(" AND id = {}", c.login_account_id);
}
where += " LIMIT 1";
auto results = LoginAccountsRepository::GetWhere(db, where);
auto e = LoginAccountsRepository::NewEntity();
if (results.size() == 1) {
e = results.front();
}
return e;
}
static LoginAccounts UpdateAccountPassword(Database &db, LoginAccounts a, std::string password)
{
LoginAccountContext c;
c.username = a.account_name;
c.password = password;
auto e = EncryptPasswordFromContext(c);
a.account_password = e.password;
int success = LoginAccountsRepository::UpdateOne(db, a);
return success ? a : NewEntity();
}
};
#endif //EQEMU_LOGIN_ACCOUNTS_REPOSITORY_H
@@ -5,46 +5,24 @@
#include "../strings.h"
#include "base/base_login_server_admins_repository.h"
class LoginServerAdminsRepository: public BaseLoginServerAdminsRepository {
class LoginServerAdminsRepository : public BaseLoginServerAdminsRepository {
public:
static LoginServerAdmins GetByName(Database &db, std::string account_name)
{
auto admins = GetWhere(
db,
fmt::format(
"account_name = '{}' LIMIT 1",
Strings::Escape(account_name)
)
);
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* LoginServerAdminsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* LoginServerAdminsRepository::GetWhereNeverExpires()
* LoginServerAdminsRepository::GetWhereXAndY()
* LoginServerAdminsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
if (admins.size() == 1) {
return admins.front();
}
return NewEntity();
}
};
#endif //EQEMU_LOGIN_SERVER_ADMINS_REPOSITORY_H
@@ -7,44 +7,27 @@
class LoginWorldServersRepository: public BaseLoginWorldServersRepository {
public:
static LoginWorldServers GetFromWorldContext(Database &db, LoginWorldContext c) {
std::string where = fmt::format(
"short_name = '{}' AND long_name = '{}'",
Strings::Escape(c.short_name),
Strings::Escape(c.long_name)
);
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* LoginWorldServersRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* LoginWorldServersRepository::GetWhereNeverExpires()
* LoginWorldServersRepository::GetWhereXAndY()
* LoginWorldServersRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
if (c.admin_id > 0) {
where += fmt::format(" AND login_server_admin_id = {}", c.admin_id);
}
// Custom extended repository methods here
where += " LIMIT 1";
auto results = GetWhere(db, where);
auto e = NewEntity();
if (results.size() == 1) {
e = results.front();
}
return e;
}
};
#endif //EQEMU_LOGIN_WORLD_SERVERS_REPOSITORY_H

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