Compare commits

...

200 Commits

Author SHA1 Message Date
Alex King 73f5fcd6d7 Update exp.cpp 2023-02-13 00:16:55 -06:00
Valorith 407ceac2bb Remove double tabs 2023-02-13 00:16:55 -06:00
Valorith fea571db40 Use tab character setting 2023-02-13 00:16:55 -06:00
Valorith 1f51a2fceb Indenting adjustments 2023-02-13 00:16:55 -06:00
Valorith 724f4ddfb8 Finalizing formatting 2023-02-13 00:16:55 -06:00
Valorith 3d38cd6235 Indenting 2023-02-13 00:16:55 -06:00
Valorith 19519908a6 Formatting 2023-02-13 00:16:54 -06:00
Valorith 5f044c3d43 Update export naming 2023-02-13 00:16:54 -06:00
Valorith 8cce781340 Adjustment 2023-02-13 00:16:54 -06:00
Valorith c9b3facf03 Additional tweak 2023-02-13 00:16:54 -06:00
Valorith d1a16c2ae8 Formatting 2023-02-13 00:16:54 -06:00
Valorith b61ee86ff3 Tweak 2023-02-13 00:16:54 -06:00
Valorith 97c93ca55a Add XP Events 2023-02-13 00:16:54 -06:00
Aeadoin fc7c30977a [Bots & Mercs] Add Support for TrySympatheticProc (#2866)
* [Bots & Merrcs] Add Support for TrySympatheticProc

* [Bots & Merrcs] Add Support for TrySympatheticProc

* [Bots & Merrcs] Add Support for TrySympatheticProc

* Cleanup

* formatting

* auto
2023-02-13 00:16:18 -06:00
Aeadoin b3fd9dd88a [Crash] Fix Crash in FindType (#2867) 2023-02-13 00:15:40 -06:00
Alex King 4df9661903 [Quest API] Add EVENT_DROP_ITEM_CLIENT to Perl/Lua (#2869)
* [Quest API] Add EVENT_DROP_ITEM_CLIENT to Perl/Lua

- Add `EVENT_DROP_ITEM_CLIENT`, exports `$quantity,` $item_name`, `$item_id`, `$spell_id`, `$slot_id`, and `$item`.

- Add `event_drop_item_client`, exports `e.quantity`, `e.item_name`, `e.item_id`, `e.spell_id`, `e.slot_id`, and `e.item`.

* Update inventory.cpp

* Update inventory.cpp

* Update lua_general.cpp

* Update inventory.cpp
2023-02-13 00:15:19 -06:00
Alex King 8c363320d8 [Quest API] Export target to EVENT_TARGET_CHANGE in Perl/Lua. (#2870)
* [Quest API] Export target to EVENT_TARGET_CHANGE in Perl/Lua.

- Export `$target` to `EVENT_TARGET_CHANGE`.

- Export `e.other` to `event_target_change`.

- Allows operators to not have to grab bot, Client, or NPC's target in Perl with `GetTarget()`.
- Allows operators to not have to grab Client's target in Lua with `GetTarget()`.

* Update mob.cpp

* Update mob.cpp

* Update mob.cpp
2023-02-13 00:03:52 -06:00
Alex King d4afc78982 [Quest API] Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua. (#2871)
* [Quest API] Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua.

- Add `EVENT_DESTROY_ITEM_CLIENT`, exports `$item_id`, `$item_name`, `$quantity`, and `$item`.

- Add `event_destroy_item_client`, exports `e.item_id`, `e.item_name`, `e.quantity`, and `e.item`.

- Allows operators to use player scripts for item destroys.

* Update lua_parser_events.h

* Update inventory.cpp
2023-02-12 23:58:27 -06:00
Aeadoin 24de1d948a [Crash] Fix crash in Mob::CommonDamage when attacker was null (#2872) 2023-02-12 23:53:29 -06:00
Alex King ca0e85b4bc [Quest API] Export $item to EVENT_PLAYER_PICKUP in Perl. (#2875)
* [Quest API] Export $item to EVENT_PLAYER_PICKUP in Perl.

# Notes
- Exports `$item` to `EVENT_PLAYER_PICKUP` in Perl so that you have access to the item itself.

* Optional parsing.

* Update object.cpp

* Update object.cpp
2023-02-12 23:52:47 -06:00
Alex King 5b24d38d1e [Quest API] Export $item to Fishing and Forage Events in Perl (#2876)
* [Quest API] Export $item to Fishing and Forage Events in Perl

# Notes
- Exports `$item` to `EVENT_FISH_SUCCESS` in Perl.
- Exports `$item` to `EVENT_FORAGE_SUCCESS` in Perl.

* Add optional parsing to fish/forage events.

* Update forage.cpp

* Fix missing event param

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-02-12 23:50:21 -06:00
Alex King 4a1d026215 [Quest API] Export $spawned to EVENT_SPAWN_ZONE in Perl (#2877)
* [Quest API] Export $spawned to EVENT_SPAWN_ZONE in Perl

# Notes
- Exports `$spawned` to `EVENT_SPAWN_ZONE` in Perl.
- Allows operators to use the mob reference instead of having to grab it from entity list.

* Optional parsing.
2023-02-12 23:46:01 -06:00
Alex King 5ef8f8c3a8 [Quest API] Export $item and $corpse to EVENT_LOOT and EVENT_LOOT_ZONE in Perl (#2878)
* [Quest API] Export $item and $corpse to EVENT_LOOT and EVENT_LOOT_ZONE in Perl

# Notes
- Exports `$item` and `$corpse` to `EVENT_LOOT` in Perl.
- Exports `$item` and `$corpse` to `EVENT_LOOT_ZONE` in Perl.

* Optional parsing.

* Update corpse.cpp

* Cleanup

* Export changes

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-02-12 23:45:26 -06:00
Alex King 384de31989 [Quest API] (Performance) Check event exists before export and execute EVENT_BOT_CREATE (#2886)
* [Quest API] Optionally parse EVENT_BOT_CREATE

- Optionally parse this event instead of always doing so.

* Cleanup

* Cleanup
2023-02-12 23:40:03 -06:00
Alex King 5be3780a54 [Quest API] (Performance) Check event exists before export and execute EVENT_LEVEL_UP and EVENT_LEVEL_DOWN (#2889)
* [Quest API] Optionally parse EVENT_LEVEL_UP and EVENT_LEVEL_DOWN

- Optionally parses these events instead of always doing so.

* [Quest API] Optionally parse EVENT_LEVEL_UP and EVENT_LEVEL_DOWN

- Optionally parses these events instead of always doing so.
2023-02-12 23:36:45 -06:00
Alex King 21e42714eb [Quest API] (Performance) Check merchant events exist before export and execute (#2893)
* [Quest API] Optionally parse merchant events

- Optionally parse these events instead of always doing so.

* Cleanup
2023-02-12 23:33:32 -06:00
Alex King 3474c00e7a [Quest API] (Performance) Check event EVENT_LANGUAGE_SKILL_UP, EVENT_SKILL_UP, or EVENT_USE_SKILL exist before export and execute (#2894)
* [Quest API] Optionally parse EVENT_LANGUAGE_SKILL_UP, EVENT_SKILL_UP, and EVENT_USE_SKILL

- Optionally parse these events instead of always doing so.

* Cleanup
2023-02-12 23:30:48 -06:00
Alex King 3d6b0e5f74 [Quest API] (Performance) Check event EVENT_COMBINE, EVENT_COMBINE_SUCCESS, EVENT_COMBINE_FAILURE, or EVENT_COMBINE_VALIDATE exist before export and execute (#2896)
* [Quest API] Optionally parse EVENT_COMBINE_SUCCESS and EVENT_COMBINE_FAILURE

- Optionally parse these events instead of always doing so.

* Update tradeskills.cpp

* Update tradeskills.cpp
2023-02-12 23:28:27 -06:00
Alex King 9f619859d1 [Quest API] (Performance) Check spell or cast events exist before export and execute (#2897)
* [Quest API] Optionally parse spell/cast events

# Notes
- Optionally parses `EVENT_CAST`, `EVENT_CAST_BEGIN`, `EVENT_CAST_ON`, `EVENT_SPELL_EFFECT_NPC`, `EVENT_SPELL_EFFECT_CLIENT`, `EVENT_SPELL_EFFECT_BOT`, `EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT`, `EVENT_SPELL_EFFECT_BUFF_TIC_NPC`, `EVENT_SPELL_EFFECT_BUFF_TIC_BOT`, `EVENT_SPELL_FADE`, and `EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE`.

* Cleanup

* PR comment fixes

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-02-12 23:26:17 -06:00
Alex King 805a9c5f59 [Quest API] (Performance) Check event EVENT_DEATH, EVENT_DEATH_COMPLETE, or EVENT_DEATH_ZONE exist before export and execute (#2909)
* [Quest API] Optionally parse EVENT_DEATH and EVENT_DEATH_COMPLETE

- Optionally parse these events instead of always doing so.

* Update attack.cpp

* Update attack.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-02-12 23:15:57 -06:00
Alex King 43329dc583 [Quest API] (Performance) Check event exists before export and execute EVENT_KILLED_MERIT (#2911)
- Optionally parse this event instead of always doing so.
2023-02-12 23:09:34 -06:00
Alex King 66fee56c47 [Quest API] (Performance) Check event exists before export and execute EVENT_DISCOVER_ITEM (#2912)
- Optionally parse this event instead of always doing so.
2023-02-12 23:07:32 -06:00
Alex King efb2ab57aa [Quest API] Optionally parse EVENT_CONNECT and EVENT_DISCONNECT (#2913)
- Optionally parse these events instead of always doing so.
2023-02-12 23:01:48 -06:00
Alex King 0a7d482299 [Quest API] (Performance) Check event EVENT_ENVIRONMENTAL_DAMAGE exists before export and execute (#2899)
* [Quest API] Optionally parse EVENT_ENVIRONMENTAL_DAMAGE

# Notes
- Optionally parses this event instead of always doing so.

* Update client_packet.cpp
2023-02-12 23:00:04 -06:00
Alex King de047fb851 [Quest API] (Performance) Check event EVENT_FEIGN_DEATH exists before export and execute (#2916)
* [Quest API] Optionally parse EVENT_FEIGN_DEATH

# Notes
- Optionally parse this event instead of always doing so.

* Remove unused reference, fix other PR

* Update task_client_state.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-02-12 22:59:14 -06:00
Natedog2012 9836b5cf67 [Bug Fix] Fix for interrupting item casts to no longer lock the client if cast time of item greater than 0 (#2921) 2023-02-12 22:49:59 -06:00
Alex King c64591b8f7 [Quest API] Export $killed_npc to EVENT_NPC_SLAY to Perl (#2879)
# Notes
- Exports `$killed_npc` to `EVENT_NPC_SLAY` to Perl.
- Allows operators to use NPC reference in event instead of just NPC ID.
2023-02-12 22:49:16 -06:00
Alex King 3813162bac [Quest API] (Performance) Check task events exist before export and execute (#2883)
* [Quest API] Optionally parse task events

- Optionally parses these events instead of always doing so.

* Update task_client_state.cpp

* Cleanup

* Update task_client_state.cpp

* [Quest API] Optionally parse task events

- Optionally parses these events instead of always doing so.

* Update task_client_state.cpp

* Cleanup
2023-02-12 22:48:51 -06:00
Alex King 7099e17c7e [Quest API] Export $hate_entity to EVENT_HATE_LIST in Perl (#2885)
# Notes
- Exports `$hate_entity` to `EVENT_HATE_LIST`.
- Allows operators to see which mob is joining/leaving an NPC's hatelist.
2023-02-12 22:44:31 -06:00
Alex King 2c75e8fcd4 [Quest API] Add $target export to EVENT_INSPECT in Perl (#2891)
* [Quest API] Add $target export to EVENT_INSPECT in Perl

# Notes
- Exports `$target` to `EVENT_INSPECT`.
- Allows operators to get information from target directly instead of using entity list.

* Update client_packet.cpp
2023-02-12 22:43:38 -06:00
Alex King e8f01fb6ac [Quest API] Export $item and $augment to augment events in Perl (#2895)
* [Quest API] Export $item and $augment to augment events in Perl

# Notes
- Exports `$item` and `$augment` to `EVENT_AUGMENT_INSERT_CLIENT` in Perl.
- Exports `$item` and `$augment` to `EVENT_AUGMENT_REMOVE_CLIENT` in Perl.
- Allows operators to use item and augment reference instead of just item IDs.

* Cleanup
2023-02-12 22:42:27 -06:00
Alex King fd0764d4cb [Quest API] (Performance) Check event exists before export and execute EVENT_TIMER (#2903)
# Notes
- Parse this event optionally instead of always doing so.
2023-02-12 22:33:33 -06:00
Alex King 71b2bf6a64 [Quest API] (Performance) Check event exists before export and execute EVENT_ENTER_ZONE and EVENT_ZONE (#2900)
# Notes
- Optionally parse these events instead of always doing so.
2023-02-12 22:32:37 -06:00
Alex King 2dcff247c8 [Quest API] Export targets to EVENT_CONSIDER and EVENT_CONSIDER_CORPSE (#2908)
# Perl
- Export `$target` to `EVENT_CONSIDER`.
- Export `$corpse` to `EVENT_CONSIDER_CORPSE`.

# Lua
- Export `e.other` to `EVENT_CONSIDER`.
- Export `e.corpse` to `EVENT_CONSIDER_CORPSE`.

 # Notes
- Allows operators to grab the target or corpse a player is considering.
2023-02-12 22:32:04 -06:00
Alex King 93f19d3971 [Quest API] (Performance) Check event EVENT_AGGRO, EVENT_ATTACK, or EVENT_COMBAT exist before export and execute (#2901)
* [Quest API] Optionally parse EVENT_COMBAT

# Notes
- Optionally parse this event instead of always doing so.

* Optional EVENT_ATTACK

* Update attack.cpp
2023-02-12 22:30:24 -06:00
Alex King bad44f35e2 [Quest API] (Performance) Check event EVENT_PAYLOAD or EVENT_SIGNAL exist before export and execute (#2902)
* [Quest API] Optionally parse EVENT_PAYLOAD and EVENT_SIGNAL

# Notes
- Optionally parse these events instead of always doing so.

* Update bot.cpp
2023-02-12 22:28:50 -06:00
Alex King 4a339d49df [Quest API] (Performance) Check event exists before export and execute EVENT_HP (#2904)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:27:57 -06:00
Alex King 57d0420399 [Quest API] (Performance) Check event EVENT_WAYPOINT_ARRIVE or EVENT_WAYPOINT_DEPART exist before export and execute (#2905)
* [Quest API] Optionally parse EVENT_WAYPOINT_ARRIVE and EVENT_WAYPOINT_DEPART

# Notes
- Optionally parse these events instead of always doing so.

* [Quest API] Optionally parse EVENT_WARP

# Notes
- Optionally parse this event instead of always doing so.

* Revert "[Quest API] Optionally parse EVENT_WARP"

This reverts commit d8acb9883d.
2023-02-12 22:27:15 -06:00
Alex King 90def9b882 [Quest API] (Performance) Check event exists before export and execute EVENT_TRADE (#2906)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:26:21 -06:00
Alex King 84156829a7 [Quest API] (Performance) Check event exists before export and execute EVENT_WARP (#2907)
# Notes
- Parse this event optionally instead of always doing so.
2023-02-12 22:25:42 -06:00
Alex King d210b1e5ff [Quest API] (Performance) Check event EVENT_SLAY exists before export and execute (#2910)
* [Quest API] Optionally parse EVENT_SLAY

# Notes
- Optionally parse this event instead of always doing so.

* Update attack.cpp
2023-02-12 22:24:38 -06:00
Alex King 086538754e [Quest API] (Performance) Check event EVENT_ITEM_TICK or EVENT_WEAPON_PROC exist before export and execute (#2914)
* [Quest API] Optionally parse EVENT_ITEM_TICK

# Notes
- Optionally parse this event instead of always doing so.

* Update mob.cpp
2023-02-12 22:22:22 -06:00
Alex King 241f900dc4 [Quest API] (Performance) Check event exists before export and execute EVENT_DUEL_LOSE and EVENT_DUEL_WIN (#2915)
# Notes
- Optionally parse these events instead of always doing so.
2023-02-12 22:21:21 -06:00
Alex King 604256a223 [Quest API] (Performance) Check event exists before export and execute EVENT_RESPAWN (#2917)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:19:23 -06:00
Alex King 2dffc66c6f [Quest API] (Performance) Check event exists before export and execute EVENT_UNHANDLED_OPCODE (#2918)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:18:57 -06:00
Alex King 1bf24273d2 [Quest API] (Performance) Check event exists before export and execute EVENT_TICK (#2919)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:16:39 -06:00
Alex King c060280417 [Quest API] Optionally parse EVENT_TEST_BUFF (#2920)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:16:17 -06:00
Alex King bc6efd5f74 [Quest API] (Performance) Check equip or scale item events exist before export and execute (#2898)
* [Quest API] Optional parse equip and scale item events

# Notes
- Optionally parse `EVENT_SCALE_CALC`, `EVENT_ITEM_ENTER_ZONE`, `EVENT_UNEQUIP_ITEM_BOT`, `EVENT_EQUIP_ITEM_BOT`, `EVENT_EQUIP_ITEM`, `EVENT_UNEQUIP_ITEM`, `EVENT_EQUIP_ITEM_CLIENT`, `EVENT_UNEQUIP_ITEM_CLIENT`

* Cleanup
2023-02-12 22:15:54 -06:00
Alex King efd6d2f9b1 [Quest API] (Performance) Check event EVENT_AA_BUY or EVENT_AA_GAIN exist before export and execute (#2892)
* [Quest API] Optionally parse EVENT_AA_BUY and EVENT_AA_GAIN

# Notes
- Optionally parse these events instead of always doing so.

* Cleanup
2023-02-12 22:04:54 -06:00
Alex King 9dd4cf71f1 [Quest API] (Performance) Check event exists before export and execute EVENT_GM_COMMAND (#2890)
# Notes
- Optionally parse this event instead of always doing so.
2023-02-12 22:03:51 -06:00
Alex King cfec31457c [Quest API] (Performance) Check event exists before export and execute area events (#2888)
* [Quest API] Optionally parse area events

# Notes
- Optionally parse these events instead of always doing so.

* Update entity.cpp
2023-02-12 22:01:28 -06:00
Alex King 5ac5beb456 [Quest API] (Performance) Check event exists before export and execute EVENT_DESPAWN and EVENT_DESPAWN_ZONE (#2887)
# Notes
- Optionally parse these events instead of always doing so.
2023-02-12 21:59:01 -06:00
Alex King 0e51131d67 [Quest API] (Performance) Check event exists before export and execute EVENT_GROUP_CHANGE (#2884)
* [Quest API] Optionally parse EVENT_GROUP_CHANGE

# Notes
- Optionally parse this event instead of always doing so.

* Update embparser.cpp
2023-02-12 21:56:25 -06:00
Alex King f9a87e26c9 [Quest API] (Performance) Check event exists before export and execute EVENT_AGGRO_SAY, EVENT_SAY, and EVENT_PROXIMITY_SAY (#2882)
* [Quest API] Add optional parsing to EVENT_AGGRO_SAY and EVENT_SAY

# Notes
- Optionally parse these events instead of always doing so.

* Optionally parse EVENT_PROXIMITY_SAY
2023-02-12 21:54:20 -06:00
Alex King 9e16cd8ae8 [Quest API] (Performance) Check event exists before export and execute EVENT_POPUP_RESPONSE (#2881)
# Notes
- Optionally parses this event instead of always doing so.
2023-02-12 21:48:23 -06:00
Alex King 9644f14746 [Quest API] (Performance) Check event exists before export and execute EVENT_CLICK_DOOR and EVENT_CLICK_OBJECT (#2880)
* [Quest API] Add optional parsing to EVENT_CLICK_DOOR.

# Notes
- Optional parses this event instead of always doing so.

* Update client_packet.cpp
2023-02-12 21:47:17 -06:00
Chris Miles d9f545a5ec [Logging] Implement Player Event Logging system (#2833)
* Plumbing

* Batch processing in world

* Cleanup

* Cleanup

* Update player_event_logs.cpp

* Add player zoning event

* Use generics

* Comments

* Add events

* Add more events

* AA_GAIN, AA_PURCHASE, FORAGE_SUCCESS, FORAGE_FAILURE

* FISH_SUCCESS, FISH_FAILURE, ITEM_DESTROY

* Add charges to ITEM_DESTROY

* WENT_ONLINE, WENT_OFFLINE

* LEVEL_GAIN, LEVEL_LOSS

* LOOT_ITEM

* MERCHANT_PURCHASE

* MERCHANT_SELL

* SKILL_UP

* Add events

* Add more events

* TASK_ACCEPT, TASK_COMPLETE, and TASK_UPDATE

* GROUNDSPAWN_PICKUP

* SAY

* REZ_ACCEPTED

* COMBINE_FAILURE and COMBINE_SUCCESS

* DROPPED_ITEM

* DEATH

* SPLIT_MONEY

* TRADER_PURCHASE and TRADER_SELL

* DISCOVER_ITEM

* Convert GM_COMMAND to use new macro

* Convert ZONING event to use macro

* Revert some code changes

* Revert "Revert some code changes"

This reverts commit d53682f997e89a053a660761085913245db91e9d.

* Add cereal generation support to repositories

* TRADE

* Formatting

* Cleanup

* Relocate discord_manager to discord folder

* Discord sending plumbing

* Rename UCS's Database class to UCSDatabase to be more specific and not collide with base Database class for repository usage

* More discord sending plumbing

* More discord message formatting work

* More discord formatting work

* Discord formatting of events

* Format WENT_ONLINE, WENT_OFFLINE

* Add merchant purchase event

* Handle Discord MERCHANT_SELL formatter

* Update player_event_discord_formatter.cpp

* Tweaks

* Implement retention truncation

* Put mutex locking on batch queue, put processor on its own thread

* Process on initial bootup

* Implement optional QS processing, implement keepalive from world to QS

* Reload player event settings when logs are reloaded in game

* Set settings defaults

* Update player_event_logs.cpp

* Update player_event_logs.cpp

* Set retention days on boot

* Update player_event_logs.cpp

* Player Handin Event Testing.

Testing player handin stuff.

* Cleanup.

* Finish NPC Handin.

* set a reference to the client inside of the trade object as well for plugins to process

* Fix for windows _inline

* Bump to cpp20 default, ignore excessive warnings on windows

* Bump FMT to 6.1.2 for cpp20 compat and swap fmt::join for Strings::Join

* Windows compile fixes

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Create 2022_12_19_player_events_tables.sql

* [Formatters] Work on Discord Formatters

* Handin money.

* Format header

* [Formatters] Work on Discord Formatters

* Format

* Format

* [Formatters] More Formatter work, need to test further.

* [Formatters] More Work on Formatters.

* Add missing #endif

* [Formatters] Work on Formatters, fix Bot formatting in ^create help

* NPC Handin Discord Formatter

* Update player_event_logs.cpp

* Discover Item Discord Formatter

* Dropped Item Discord Formatter

* Split Money Discord Formatter

* Trader Discord Formatters

* Cleanup.

* Trade Event Discord Formatter Groundwork

* SAY don't record GM commands

* GM_Command don't record #help

* Update player_event_logs.cpp

* Fill in more event data

* Post rebase fixes

* Post rebase fix

* Discord formatting adjustments

* Add event deprecation or unimplemented tag support

* Trade events

* Add return money and sanity checks.

* Update schema

* Update ucs.cpp

* Update client.cpp

* Update 2022_12_19_player_events_tables.sql

* Implement archive single line

* Replace hackers table and functions with PossibleHack player event

* Replace very old eventlog table since the same events are covered by player event logs

* Update bot_command.cpp

* Record NPC kill events ALL / Named / Raid

* Add BatchEventProcessIntervalSeconds rule

* Naming

* Update CMakeLists.txt

* Update database_schema.h

* Remove logging function and methods

* DB version

* Cleanup SendPlayerHandinEvent

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
Co-authored-by: Aeadoin <109764533+Aeadoin@users.noreply.github.com>
2023-02-12 21:31:01 -06:00
Aeadoin 1cc32d92cf [Bots] Add Lore Check for Augments. (#2874)
* [Bots] Add Lore Check for Augments.

* Add bot name
2023-02-12 16:43:58 -05:00
Aeadoin 924e91cf64 [Crash] Fix Bot Crash in Bot::Bot Constructor. (#2868)
* [Crash] Fix Bot Crash in Bot::Bot Constructor.

* fix another potential crash in bot contructor.
2023-02-12 14:27:29 -05:00
Aeadoin 9825c61a13 [Bots] Add Pet Power Support for Temp Pets. (#2853) 2023-02-11 10:57:02 -05:00
Alex King 5a0a1b1ffd [Quest API] Export $item to EVENT_DISCOVER_ITEM in Perl (#2863)
# Notes
- Exports `$item` to `EVENT_DISCOVER_ITEM`.
2023-02-10 23:56:50 -05:00
Alex King a3bb7e7741 [Quest API] Export $item to Client/Bot Equip Events in Perl (#2860)
* [Quest API] Add $item Export to Client/Bot Equip Events

# Notes
- Adds `$item` export to `EVENT_ITEM_EQUIP_CLIENT`, `EVENT_ITEM_UNEQUIP_CLIENT`, `EVENT_ITEM_EQUIP_BOT`, and `EVENT_UNEQUIP_ITEM_BOT`.

* Update bot.cpp

* Update embparser.cpp
2023-02-10 23:56:36 -05:00
Alex King a1251bdda8 [Quest API] Export $door to EVENT_CLICKDOOR in Perl (#2861)
# Notes
- Exports `$door` object to `EVENT_CLICKDOOR` in Perl so you don't have to grab it from entity list.
2023-02-10 23:56:24 -05:00
Alex King b90082d694 [Quest API] Export $object to EVENT_CLICK_OBJECT in Perl (#2862)
# Notes
- Exports `$object` to `EVENT_CLICK_OBJECT` in Perl so you don't have to grab it from entity list.
2023-02-10 23:34:52 -05:00
Aeadoin a49fa42f35 [Bots] Update ResistSpell to use temp_level_diff client formula (#2851) 2023-02-09 10:36:15 -05:00
Aeadoin 7064a4156f [Bots] Add IsBot() to methods in attack.cpp where applicable. (#2840)
* [Bots] add IsBot() to methods in attack.cpp where applicable.

* Add mercs where applicable

* Cleanup verbose if statements

* typo

* Fix other spots missed.
2023-02-09 10:36:01 -05:00
Aeadoin 106cb45b57 [Crash] Fix potential crash in Mob::CommonDamage (#2848)
out of bounds memory access.
2023-02-09 10:35:51 -05:00
Aeadoin 9a544650ee [Bots] ST_AreaClientOnly spells to land on Bots (#2849) 2023-02-09 10:35:38 -05:00
Aeadoin 032d423add [Bots] Add TotalDominationBonus modifiers. (#2852) 2023-02-09 10:35:26 -05:00
Akkadius 760b30ca0a [Crash] Fix issue where long short names overflow file_name 2023-02-09 01:03:51 -06:00
Chris Miles 6b08ca51cc [Logging] Add raw opcode when emu translated opcode is not found (OP_Unknown) via (C->S) (#2847) 2023-02-07 21:23:24 -06:00
Alex King 268879b414 [Quest API] Add Recipe-based methods to Perl/Lua. (#2844)
* [Quest API] Add Recipe-based methods to Perl/Lua.

# Perl
- Add `quest::get_recipe_component_item_ids(recipe_id)`.
- Add `quest::get_recipe_container_item_ids(recipe_id)`.
- Add `quest::get_recipe_fail_item_ids(recipe_id)`.
- Add `quest::get_recipe_salvage_item_ids(recipe_id)`.
- Add `quest::get_recipe_success_item_ids(recipe_id)`.
- Add `quest::get_recipe_component_count(recipe_id, item_id)`.
- Add `quest::get_recipe_fail_count(recipe_id, item_id)`.
- Add `quest::get_recipe_salvage_count(recipe_id, item_id)`.
- Add `quest::get_recipe_success_count(recipe_id, item_id)`.

# Lua
- Add `eq.get_recipe_component_item_ids(recipe_id)`.
- Add `eq.get_recipe_container_item_ids(recipe_id)`.
- Add `eq.get_recipe_fail_item_ids(recipe_id)`.
- Add `eq.get_recipe_salvage_item_ids(recipe_id)`.
- Add `eq.get_recipe_success_item_ids(recipe_id)`.
- Add `eq.get_recipe_component_count(recipe_id, item_id)`.
- Add `eq.get_recipe_fail_count(recipe_id, item_id)`.
- Add `eq.get_recipe_salvage_count(recipe_id, item_id)`.
- Add `eq.get_recipe_success_count(recipe_id, item_id)`.

# Notes
- Before these methods, you would have to use DBI from Perl or Lua in order to get the components and their counts, these methods allow easy access to these values via the scripting API.
- These should be used sparingly as they're each an individual database hit and could go crazy in a hot path.

* Update eq_constants.h

* Update zonedb.h

* Update tradeskills.cpp

* Reserve.
2023-02-07 21:42:34 -05:00
Alex King 4c6dc960e4 [Bug Fix] Fix CheckNumHitsRemaining() with 1H Blunt (#2846)
# Notes
- CheckNumHitsRemaining() wasn't working when skill ID was `0` (1H Blunt).
2023-02-06 23:41:32 -05:00
Aeadoin cc46b54f7f [Bots] Add Additional HeroicAgi/Dex Modifiers. (#2838)
* [Bots] Add Additional HeroicAgi/Dex Modifiers.

* Typo
2023-02-06 22:31:02 -05:00
Aeadoin 9e3b363d4a [Code] Add IsOfClientBot() virtual method. (#2845) 2023-02-06 22:30:49 -05:00
Aeadoin b0d1dc5f04 [Bots/Mercs] Add 100% Hit chance if sitting while attacked. (#2839)
* [BOT] Add 100% Hit chance if sitting while attacked.

* [BOT] Add 100% Hit chance if sitting while attacked.

* Add Mercs correctly

* Missed usage of IsSitting() in Mob::RollD20
2023-02-06 22:30:33 -05:00
Chris Miles 158396937a [Release] 22.3.0 (#2842)
* [Release] 22.3.0

* Update version.h

* Redirect stderr

* Update should-release to filter non-master

* Update should-release
2023-02-06 20:12:04 -06:00
Aeadoin fb1467284c [Bots] Add Additional HeroicStr modifiers. (#2837) 2023-02-06 21:07:38 -05:00
Aeadoin 14addd4869 [Feature] Add IsOfClientBotMerc() virtual method. (#2843) 2023-02-06 21:03:48 -05:00
Chris Miles 0a114fae9a [Doors] Have NPCs trigger double doors (#2821) 2023-02-06 17:47:03 -06:00
Chris Miles 2b224d42ad [Rules] Fix rule updates that affected bot booting checks (#2841) 2023-02-06 17:31:50 -06:00
Natedog2012 155ec9ac0d [Quest API] Add rule AlternateAugmentationSealer for using a different bagtype (#2831)
* [Quest API] Add rule AlternateAugmentationSealer for using a different bagtype as an alternate augmentation sealer. Use EVENT_COMBINE with UseAugmentContainer

* Default it to be off or bagtype 53 (BagTypeAugmentationSealer)
2023-02-06 17:30:16 -06:00
Chris Miles 25b4b97c41 [DB Updates] Add Windows MySQL path auto detection for users where the path is not found (#2836) 2023-02-06 17:25:34 -06:00
Joel 839f31b24d [Rule] Added rule to bypass level based haste caps (#2835) 2023-02-06 17:25:17 -06:00
Chris Miles 20728c31c4 [Crash] Fix crash in bot command botdyearmor (#2832)
* [Crash] Fix crash in bot command botdyearmor

* Update bot_command.cpp
2023-02-06 17:24:49 -06:00
Chris Miles c6eb12ac16 [Crash] Fix IsUnderwaterOnly crash where npc data references can be stale (#2830)
* [Crash] Fix IsUnderwaterOnly crash where npc data references can be stale

* m_ prefix
2023-02-06 17:24:38 -06:00
Chris Miles 34d21d4056 [Crash] Fix command crash with #npcedit weapon when second weapon not passed ni (#2829) 2023-02-06 17:24:24 -06:00
Chris Miles d369b47ef4 [Tasks] Implement alternate currency rewards (#2827)
* Reward currency on task completion

* Handle reward window

* Tweaks
2023-02-06 17:24:13 -06:00
Chris Miles 404f7cada8 [Pathing] Improvements to handling tight corridors pathing, clipping detection and recovery (#2826) 2023-02-06 17:24:03 -06:00
Chris Miles 823e73336d [Command] #list now searches without case sensitivity (#2825) 2023-02-06 17:23:50 -06:00
Chris Miles 0da6391be3 [Doors] Remove door dev tools spam on client controlled doors (#2824)
* [Doors] Remove door dev tools spam on client controlled doors

* Update client_packet.cpp

* Update client_packet.cpp

* Update ruletypes.h
2023-02-06 17:23:40 -06:00
Chris Miles 0348cb6b8e [Fix] Fix NPC ghosting at safe coordinates (#2823)
* [Fix] Fix NPC ghosting at safe coordinates

* Tweak order

* Handle another case
2023-02-06 17:23:29 -06:00
Vayle b385a4385f [Rules] Add rule to ignore name filter on chat channel creation. (#2820)
* [Rules] Add rule to ignore name filter on chat channel creation.

* Conditional reorder
2023-02-06 17:22:12 -06:00
Chris Miles 6a9228ed6e [Lua] Resolve stoi Exception (#2736)
* [Lua] Resolve stoi Exception

* Change fallback for wp, not really needed for safety

* Change to Strings::ToInt
2023-02-06 17:22:01 -06:00
Vayle 8031bf0bcb [Quest API] Add EVENT_TASKACCEPTED to Player scope (#2822)
* Add EVENT_TASKACCEPTED to player scope

* Formatting
2023-02-05 22:53:37 -05:00
Alex King c1584da9cc [Quest API] Default ScaleNPC to always scale. (#2818)
* [Quest API] Default ScaleNPC to always scale.

# Notes
- ScaleNPC will now always override stats, with the option to override special abilities.

* Update npc_scale_manager.h
2023-02-05 22:52:52 -05:00
Alex King ee6f6f683c [Commands] Remove extraneous else from #weather (#2819)
# Notes
- Condition falls back to sending message and can't turn weather off.
2023-02-01 06:05:32 -05:00
Akkadius 60707a14db [Hotfix] Post revert build fix for https://github.com/EQEmu/Server/commit/54050924d81d1f83268fe01f9c2b36fe10626601 2023-01-31 20:37:13 -06:00
Akkadius 54050924d8 Revert "[Quest API] Cleanup string copies and push_backs. (#2807)"
This reverts commit bcc2e022dc.
2023-01-31 20:30:34 -06:00
Aeadoin f727c9f75a [Bug Fix] Fix does_augment_fit_slot method. (#2817)
* [Bug Fix] DoesAugmentFit finds if an Aug Slot is free, changed overload method to check if Aug fits slot.

* Tweak/add lua
2023-01-31 21:11:12 -05:00
Alex King f410c89815 [Quest API] Add Override Parameters to ScaleNPC() in Perl/Lua. (#2816)
# Perl
- Add `$npc->ScaleNPC(level, always_scale_stats)`.
- Add `$npc->ScaleNPC(level, always_scale_stats, always_scale_special_abilities)`.

# Lua
- Add `npc:ScaleNPC(level, always_scale_stats)`.
- Add `npc:ScaleNPC(level, always_scale_stats, always_scale_special_abilities)`.

# Notes
- Allows operators to not have to set stats to 0 in order for scaling to kick in when scripting.
- Special ability override is separate in case you don't want to override some inherent special abilities the NPC has from a script or otherwise.
2023-01-31 21:11:05 -05:00
Natedog2012 2e575652f6 [Bug fix]#reload static should now properly fill the entity_lists for… (#2815)
* [Bug fix]#reload static should now properly fill the entity_lists for objects / doors / groundspawns
The individual #reload commands WILL still have issues when trying to use #list afterwards!

* Point ReloadDoors, ReloadGroundSpawns, ReloadObjects all to reload static to avoid entity_list data missing
2023-01-31 16:32:25 -06:00
Natedog2012 8e831dce36 [Bug fix]#reload aa will now refresh the AA table properly for every client when changes are made (#2814) 2023-01-30 20:24:02 -06:00
Alex King 040c092795 [Quest API] Add Augment Slot support to does_augment_fit (#2813)
* [Quest API] Add Augment Slot support to does_augment_fit

# Notes
- Allows you to check if the supplied augment ID fits in the specified augment slot of the item instance provided.

* Update item_instance.cpp
2023-01-30 21:18:16 -05:00
Alex King a25952910a [Quest API] Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. (#2810)
* [Quest API] Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua.

# Perl
- Add `EVENT_ITEM_CLICK_CLIENT`.
- Add `EVENT_ITEM_CLICK_CAST_CLIENT`.
- Both events export `$item_id`, `$item_name`, `$slot_id`, and `$spell_id`.

# Lua
- Add `event_item_click_client`.
- Add `event_item_click_cast_client`.
- Both events export `e.item_id`, `e.item_name`, `e.slot_id`, `e.spell_id`, and `e.item`.

# Notes
- Allows operators to handle item clicks in player scripts instead of item-specific scripts.

* Update lua_parser_events.cpp

* Remove optional bool.
2023-01-30 05:01:12 -06:00
Natedog2012 66896a3121 [Quest API] Add GetItemCooldown to return the time remaining on items… (#2811)
* [Quest API] Add GetItemCooldown to return the time remaining on items in seconds

* Change GetItemCooldown to uint32 for timers up to 130 years
2023-01-30 00:04:06 -06:00
Paul Coene 4d2418af9d [Bug Fix] BuffLevelRestrictions were restricting group buffs if mob targeted (#2809) 2023-01-29 18:52:03 -05:00
Chris Miles 265b32f46f [Readme] Update build badges with Drone 2023-01-29 17:06:48 -06:00
Alex King 1cde55c535 [Quest API] Add LDoN Methods to Perl/Lua (#2799)
# Perl
- Add `$npc->GetLDoNLockedSkill()`.
- Add `$npc->GetLDoNTrapType()`.
- Add `$npc->GetLDoNTrapSpellID()`.
- Add `$npc->IsLDoNLocked()`.
- Add `$npc->IsLDoNTrapped()`.
- Add `$npc->IsLDoNTrapDetected()`.
- Add `$npc->SetLDoNLocked(is_locked)`.
- Add `$npc->SetLDoNLockedSkill(skill_value)`.
- Add `$npc->SetLDoNTrapped(is_trapped)`.
- Add `$npc->SetLDoNTrapDetected(is_detected)`.
- Add `$npc->SetLDoNTrapSpellID(spell_id)`.
- Add `$npc->SetLDoNTrapType(trap_type)`.

# Lua
- Add `npc:GetLDoNLockedSkill()`.
- Add `npc:GetLDoNTrapType()`.
- Add `npc:GetLDoNTrapSpellID()`.
- Add `npc:IsLDoNLocked()`.
- Add `npc:IsLDoNTrapped()`.
- Add `npc:IsLDoNTrapDetected()`.
- Add `npc:SetLDoNLocked(is_locked)`.
- Add `npc:SetLDoNLockedSkill(skill_value)`.
- Add `npc:SetLDoNTrapped(is_trapped)`.
- Add `npc:SetLDoNTrapDetected(is_detected)`.
- Add `npc:SetLDoNTrapSpellID(spell_id)`.
- Add `npc:SetLDoNTrapType(trap_type)`.

# Notes
- Adds these methods to allow LDoN traps to be set by a script.
2023-01-29 14:29:31 -06:00
Michael 369b5c2921 [Bug] Fixing % based mob see invis (#2802)
This was preventing anything other than 0 or 1 to be passed, but per the current design, the see_invis can be anything from 0 to MAX 25499, which can give you level 254 invis. See design notes in Mob::GetSeeInvisibleLevelFromNPCStat.
2023-01-29 14:26:55 -06:00
Alex King bcc2e022dc [Quest API] Cleanup string copies and push_backs. (#2807)
# Notes
- Several places use `push_back` instead of `emplace_back`.
- Several places use `std::string` instead of `const std::string&`.
2023-01-29 15:14:49 -05:00
Alex King 0fef46a6c1 [Feature] Add Min/Max Status to Merchants (#2806)
# Notes
- Allows operators to set a minimum and maximum status that an item will show for players.
- Allows operators to have items on a merchant that only a GM can see.
- Some servers may use status for different things, so having a minimum and a maximum will allow for more functionality.
- Default of `min_status` is `0` (Player) and default of `max_status` is `255` (Max).
2023-01-29 15:03:41 -05:00
Alex King b867d40774 [Quest API] Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua. (#2804)
* [Quest API] Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua.

# Perl
- Add `EVENT_DAMAGE_GIVEN`.
- Add `EVENT_DAMAGE_TAKEN`.
- Both events export `$entity_id`, `$damage`, `$spell_id`, `$skill_id`, `$is_damage_shield`, `$is_avoidable`, `$buff_slot`, `$is_buff_tic`, `$special_attack`.

# Lua
- Add `event_damage_given`.
- Add `event_damage_taken`.
- Both events export `e.entity_id`, `e.damage`, `e.spell_id`, `e.skill_id`, `e.is_damage_shield`, `e.is_avoidable`, `e.buff_slot`, `e.is_buff_tic`, `e.special_attack`, and `e.other`.

# Notes
- These events allow operators to have events fire based on damage given or taken, as well as keep better track of a Bot, Client, or NPC's damage per second or otherwise.
- Special Attack is only useful for NPCs, but allows you to see if the attack is Rampage, AERampage, or Chaotic Stab.

* Cleanup.
2023-01-29 14:35:17 -05:00
Aeadoin a489290eba [Bots] Add GetAugmentIDsBySlotID & AddItem with table ref Methods. (#2805)
* [Bots] Add GetAugmentIDsBySlotID & AddItem with table ref Methods.

* Return invalid slots to owner.
2023-01-29 12:49:44 -05:00
Alex King 549d731849 [Bug Fix] Resolve issue with max buff count being 25 in ROF2. (#2800)
# Notes
- This allows ROF2 to properly utilize their max buff count.
- May cause issues with older clients.
2023-01-28 17:40:11 -06:00
Natedog2012 68a34565f9 [Bugfix] Add SetItemCooldown to tell client exact timer of item when clicked and export to perl and lua (#2795)
Items that are on cooldown but client doesn't show.. clicking item will fix the timer in client
2023-01-27 17:31:14 -06:00
Aeadoin c05f951f81 [Bots] Add Override methods for GetMax Buffs/Songs/Total slots (#2801) 2023-01-27 18:00:50 -05:00
Akkadius dc64561b3c [Release] 22.2.0 2023-01-27 01:13:38 -06:00
Akkadius cb2aee2713 [Release] 22.2.0 2023-01-27 01:12:30 -06:00
Chris Miles 0730b6b588 [Crash] Fix crash issue with log formatting during character creation (#2798) 2023-01-26 20:40:58 -06:00
Aeadoin 826550acac [Bots] Add EVENT_UNEQUIP_ITEM_BOT & EVENT_EQUIP_ITEM_BOT (#2796)
* Initial Commit, need to test.

* Add unequip events.

* const auto
2023-01-26 19:49:20 -05:00
Alex King b71b3f5be0 [Bots] ^create and ^viewcombos popup messages fix. (#2797)
# Notes
- These messages were showing weirdly and inconsistently, cleaned them up to show at max 4 per line.
- `^viewcombos` now shows class name and ID in the popup title.
- `^create help` now shows proper class names and IDs instead of `{}`.
2023-01-26 18:44:21 -05:00
Natedog2012 1fe79f430c [Feature] ResetItemCooldown added to lua/perl and fix item re-cast times to show properly (#2793)
* Testing.

* Add ResetItemCooldown and port it over to perl

* This flag needs to be set for updating shared item cooldowns

* Properly set item recast for all item types, on corpses, on looting

* SummonItem properly sets recast timers of summoned items

* Rename variable to avoid confusion and change manifest to be more specific

* Sanity check item_d

* Recast -1 added as RECAST_TYPE_UNLINKED_ITEM
ResetItemCooldown will still remove cooldown of item that we don't have so when we acquire it the cooldown is reset

* change magic numbers

* more magic numbers

* More constants yay

* Remove unneeded export DeleteItemRecastTimer

* Remove duplicate message, this is handled by the client in this part of the code

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2023-01-25 20:09:08 -06:00
Alex King e5dabe0afc [Git] Add CMake Files to .gitignore (#2792)
* [Git] Add CMake Files to GitIgnore

* Update .drone.yml
2023-01-24 18:37:14 -06:00
Alex King 5720ffbcb6 [Release] 22.1.2 (#2791) 2023-01-24 17:18:42 -06:00
Alex King 2b0c778ad1 [Bug Fix] Fix nullptr spell in BCSpells::Load() (#2790)
* [Bug Fix] Fix nullptr spell in BCSpells::Load()

# Notes
- Fix possible `nullptr` where we didn't check if spell was valid before using it.

* Cleanup.
2023-01-24 17:57:12 -05:00
Alex King bf39a0540c [Cleanup] Cleanup #door Command. (#2783)
* [Cleanup] Cleanup #door Command.

# Notes
- Resolves an issue with `.1` versus `0.1`.
- Resolves an issue with updating a pre-existing door.
- Adds `heading` to the update/insert.

* Update doors.cpp
2023-01-24 16:37:21 -06:00
Chris Miles 08c8393988 [CI/CD] Build / Release Pipeline Changes (#2788)
* Test

* Test

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* Kill excessive warnings

* Split

* Remove 7z from build scripts

* Linux

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Test

* Update .drone.yml

* Naming

* Test upload

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Yolo

* Yolo

* Update .drone.yml

* Update .drone.yml

* Copy

* Yolo

* Release without bots

* Update .drone.yml

* Update .drone.yml

* Test pipeline

* Remove debug

* Update .drone.yml

* Filter pipeline stage

* Update .drone.yml

* Test

* Bots release 22.0.5 (Test)

* Release bot test #2

* Check if release

* Update .drone.yml

* Update .drone.yml

* exit 78

* Update .drone.yml

* Update .drone.yml

* Add version checks

* Update .drone.yml

* Update .drone.yml

* Test

* Update build-release.bat

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update build-release.bat

* Update build-release.bat

* Test pipeline

* Update CHANGELOG.md

* Bump

* Update build-release.bat

* Update build-release.bat

* Shuffle

* Take #45354

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* F

* Update windows-build.ps1

* Consolidate

* Run it

* Pop cache back in

* Update linux-build.sh

* Another release test

* Update linux-build.sh

* Update linux-build.sh

* Update CMakeLists.txt

* Trim windows assets

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* [22.1.0] Release

* Crash reporting

* Add version tag injection in the build pipeline

* Update windows-build.ps1

* Test

* Test

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* Kill excessive warnings

* Split

* Remove 7z from build scripts

* Linux

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Test

* Update .drone.yml

* Naming

* Test upload

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Yolo

* Yolo

* Update .drone.yml

* Update .drone.yml

* Copy

* Yolo

* Release without bots

* Update .drone.yml

* Update .drone.yml

* Test pipeline

* Remove debug

* Update .drone.yml

* Filter pipeline stage

* Update .drone.yml

* Test

* Bots release 22.0.5 (Test)

* Release bot test #2

* Check if release

* Update .drone.yml

* Update .drone.yml

* exit 78

* Update .drone.yml

* Update .drone.yml

* Add version checks

* Update .drone.yml

* Update .drone.yml

* Test

* Update build-release.bat

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update build-release.bat

* Update build-release.bat

* Test pipeline

* Update CHANGELOG.md

* Bump

* Update build-release.bat

* Update build-release.bat

* Shuffle

* Take #45354

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* F

* Update windows-build.ps1

* Consolidate

* Run it

* Pop cache back in

* Update linux-build.sh

* Another release test

* Update linux-build.sh

* Update linux-build.sh

* Update CMakeLists.txt

* Trim windows assets

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* Update windows-build.ps1

* [22.1.0] Release

* Crash reporting

* Add version tag injection in the build pipeline

* Update windows-build.ps1

* Full crash report on windows.

* Update endpoint

* [22.1.1] Release

* [skip ci] update .drone.yml

* Filter

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update .drone.yml

* Update CHANGELOG.md

Co-authored-by: KimLS <KimLS@peqtgc.com>
2023-01-24 16:37:04 -06:00
Alex King 8c12f7b431 [Bug Fix] Remove duplicate logic in GetActSpellHealing reducing HOT criticals (#2786)
# Notes
- Removes duplicate critical chance roll in `Mob::GetActSpellHealing`.
- Not sure if this was Live-like or an oversight, but it seems to drastically reduce the possibility of a HOT getting a critical.
- A 1% chance becomes a 0.01% chance being we have to roll twice.
2023-01-24 12:39:46 -06:00
Chris Miles 037be84f38 [Crash] Fix rarer world crash issue where scheduler database was not available (#2789) 2023-01-24 12:38:26 -06:00
Aeadoin 4d355afe9d [Bug Fix] Fix scenario where dereferenced object could be null. (#2784) 2023-01-23 18:40:23 -05:00
Aeadoin 93eddf603b [Bug Fix] Fix botgrouplist to display unique entries. (#2785) 2023-01-23 18:39:55 -05:00
Aeadoin 293f79268d [Bots] Fix Slow Query in QueryNameAvailablity (#2781) 2023-01-22 18:26:57 -05:00
Chris Miles 7e35d5aa79 [AA] Fix AA tables dump (#2769) 2023-01-22 12:57:08 -05:00
Alex King f7e4fba584 [Bug Fix] Fix bots equipping augments. (#2772)
# Notes
- Bots didn't check if the item was an augment before equipping, this stops them from equipping them.
2023-01-22 12:57:00 -05:00
Alex King 01a0f906e1 [Bots] Add Bot Command Reloading (#2773)
# Notes
- Adds `bot_command_init` to `#reload commands` so that operators can reload bot commands if they enable/disable bots while the server is running.
2023-01-22 12:56:55 -05:00
Alex King 0a11eaa092 [Bug Fix] Fix #findaa and GetAAName(). (#2774)
# Notes
- These were not properly checking every possible AA ID.
2023-01-22 12:56:49 -05:00
Alex King d0edb93d62 [Commands] Remove #guildapprove, #guildcreate, and #guildlist Commands (#2775)
# Notes
- Removes `#guildapprove`, `#guildcreate`, and `#guildlist`.
- Removes associated functions, classes, etc. that were only used in these commands.
- These commands are unused and/or covered by the general `#guild` command.
- Approvals don't really seem to be a thing anymore and the variable itself doesn't exist in stock PEQ database anyway.
2023-01-22 12:56:42 -05:00
Alex King 35c3778baf [Commands] Remove #undyeme Command. (#2776)
# Notes
- Removes redundant `#undyeme` command.
- Adds `GetGM()` check to `#undye` so players can't undye other players.
2023-01-22 12:56:36 -05:00
Alex King abb41840f8 [Commands] Cleanup #appearanceeffects Command. (#2777)
# Notes
- Cleanup messages and logic.
2023-01-22 12:56:26 -05:00
Aeadoin cd63047e60 [Bug Fix] Fix Bot Group Loading (#2780)
* [Bots] Fix Bot Groups

* unsigned.
2023-01-22 12:06:13 -05:00
Paul Coene 4fe5522212 [Bug Fix] #scribespells triggered error on mysql keyword rank (#2779) 2023-01-21 18:02:27 -05:00
Akkadius 0ccb18d017 [Hotfix] Remove appveyor fetch bots 2023-01-20 20:56:19 -06:00
Aeadoin e010e41a83 [Bots] Add Virtual Override for Bot::Attack (#2771) 2023-01-20 17:13:40 -05:00
Aeadoin 886f80117c [Cleanup] Merge Client::Attack and Bot::Attack into Mob::Attack (#2756)
* [Cleanup] Merge Client::Attack and Bot::Attack into Mob::Attack (#11)

* Remove #ifdef Bots to go along with KK fix

* Remove method in logging

* remove method from logging

* Fixes

* Rename
2023-01-20 15:52:45 -05:00
Chris Miles 5c095ab87a [Bots] Post pre-processor fixes (#2770)
* Fixes

* Update main.cpp
2023-01-20 13:28:39 -06:00
Akkadius e8ca3f6942 [eqemu_server.pl Swap out binary source 2023-01-20 12:56:37 -06:00
Akkadius 706a06efb6 [Appveyor] Remove bots preprocessor 2023-01-20 12:42:35 -06:00
Alex King 3335cacac1 [Bots] Cleanup and remove preprocessors. (#2757)
* [Bots] Cleanup and remove preprocessors.

- Removes every `#ifdef BOTS` we have and locks bots behind `Bots:AllowBots` rule.
- Bot updates are now done by default similar to regular database updates.
- Modify `CMakeLists.txt`, `.drone.yml`, and `BUILD.md` to match the removal of `EQEMU_ENABLE_BOTS`.

* Cleanup

- Add SQL for enabling bots for servers with bots.
- Add message that tells players/operators bots are disabled.

* Suggested changes.

* Bot injection stuff

* Change SQL to bot SQL.

* Tweaks

* Remove `is_bot`

* Update version.h

* Update main.cpp

* Update database.cpp

* Fix name availability crash

* Remove bots from update script

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-01-20 12:35:33 -06:00
Akkadius 1f0b2a8991 [Hotfix] Make sure we have a proper split size before assuming we can split it 2023-01-20 12:25:49 -06:00
Aeadoin a16f21d6fe [Bots] Add Support for AA bonuses that were missing. (#2764)
* [Bots] Add Support for AA bonuses that were missing.

* Fix GetFocusEffect, add virtual override to Bot to prevent using NPC
2023-01-19 22:45:09 -06:00
Chris Miles 900837f633 [Logging] Improvements to GM Say Logging (#2765) 2023-01-19 22:24:57 -06:00
Chris Miles d3e756287e [Logging] Remove function prefixes (#2766) 2023-01-19 22:24:50 -06:00
Vayle 7d0dd13d17 [Bug Fix] Add omitted function call in UCS (#2768) 2023-01-19 22:24:39 -06:00
Vayle ba5b901c16 [Optimization] Handle channel name filter checks in memory (#2767)
* Handle channel name filter checks in memory

With this commit, name filters are loaded into memory when the server loads and new channels are compared against these memory values VS hitting the database each time.

* Minor formatting tweaks
2023-01-19 21:23:11 -06:00
Akkadius 3424ae2dde [Hotfix] Fix door click crash issue if destination zone doesn't exist 2023-01-19 19:06:58 -06:00
Chris Miles 9aad8ae54c [Logging] Force crash logs to always be on regardless of setting (#2762) 2023-01-19 18:21:44 -06:00
JJ 7cd6b4b8ab [SQL] Update 2023_01_15_merc_data.sql (#2763)
Odd spacing. Someone fell asleep on the keyboard.
2023-01-19 18:20:46 -06:00
Aeadoin 090019cf83 [Bot] Restrict Bot Groups from spawning while Feigned. (#2761) 2023-01-19 16:52:20 -06:00
Chris Miles d93ea9ed86 [Zone Flags] Use database connection, not content connection (#2759) 2023-01-19 15:11:40 -06:00
Chris Miles a7b35594f8 [Fix] Zone Flags Regression (#2760) 2023-01-19 15:11:32 -06:00
Vayle 29473aa7f5 [Rules] Add rule to allow players to permanently save chat channels to database, up to a limit. (#2706)
* Initial code

* Tweak

* Rule description tweak

* More channel work

* More adjustments

* Auto-join saved permanent player channels

* Fix UCS crash if player has no channels to load from table.

* Implemented channel blocking feature

* Update database when player channel's owner or password change

* First round of requested changes.

* Logic tweak to ensure player channels are sets to permanent when appropraite

* name_filter table integration and some refactoring

* Use new `reserved_channel_names` table to block specific channel names.

* Remove some legacy channel block code

* Setup required SQL update to create  `reserved_channel_names`  table.

* Update db_update_manifest.txt

* Update db_update_manifest.txt

* Update chatchannel.cpp

* Code review

* Database to UCSDatabase

* Repository SaveChatChannel

* CurrentPlayerChannelCount repository

* Cleanup name filter

* CreateChannel

* Update websocketpp

* Increment CURRENT_BINARY_DATABASE_VERSION

Set to 9216

* Minor tweaks to blocked channel name checks & other related areas.

- Enforce blocked channel names on channel creation.
- Also enforce blocked channel names on channel join.
- Add channel status check to Debug logging.
- Minor formatting adjustments.
- Add single quotes to column name value in query.

* Minor log change

* Increment DB Version

* Formatting Tweaks

- Made formatting adjustments consistent with KinglyKrab's recommended changes.
- This compiles successfully with these changes, but unable to test the changes until this weekend.

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-01-18 22:42:09 -06:00
Aeadoin 03a27b02ff [Hotfix] Login Server failing to compile on Windows. (#2758) 2023-01-18 21:21:36 -05:00
Akkadius f9ea7ddb62 [Logging] Reset stream so we don't bold the whole line 2023-01-17 21:39:18 -06:00
Chris Miles 40d1c33351 [Logging] Logging Improvements (#2755)
* Console logging improvements

* stderr handling

* Add origination information

* Formatting

* Update zoneserver.cpp

* Update eqemu_logsys.cpp

* Remove semicolon from MySQLQuery log output

* Remove IsRfc5424LogCategory

* Remove no longer used functions

* Remove definition BUILD_LOGGING

* Deprecate categories UCSServer & WorldServer

* Deprecate UCS / World Server / Zone Server categories

* Deprecate Status, QSServer, Normal

* Update login_server.cpp

* Deprecate Emergency, Alert, Critical, Notice

* Deprecate Alert

* Fix terminal color resetting

* Deprecate headless client

* Move LogAIModerate to Detail

* Deprecate moderate logging level for detail

* Update logs.cpp

* Logs list simplify

* Update logs.cpp

* Add discord to log command

* Remove unused headers

* Windows fix

* Error in world when zones fail to load

* Show warning color properly

* Keep loginserver thread log from colliding with other logs during startup

* Deprecate Loginserver category
2023-01-17 21:18:40 -06:00
Michael Cook (mackal) ee2079ec35 [C++20] Arithmetic on different enums is deprecated (#2752)
Just do some casts and add some constants to make life easier
2023-01-17 15:21:01 -06:00
Xackery a90c760186 [Code] Removed vscode setting (#2753) 2023-01-17 15:20:36 -06:00
Alex King fbb36a3e75 [Mercs] Add Mercenary Support (#2745)
* [Mercs] Add Mercenary Support

# Notes
- Adds `--merc-tables` support to database dumper.
- Adds Mercenary-based repositories.
- Adds required SQL `2023_01_15_merc_data.sql` to insert the tables for those who don't already have them.
- Adds optional SQL `2023_01_15_merc_liaisons.sql` to change NPCs to the Mercenary Liaison class optionally.

* Inline.

* Trim tables_to_dump output

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-01-17 16:19:55 -05:00
Aeadoin bd29f1c5bb [Bug Fix] Handle_OP_AugmentItem could cause Zone crash (#2750) 2023-01-17 14:34:28 -05:00
Natedog2012 a99e0a4b2c [Bug Fix] Move EVENT_SPAWN for adding NPCs back to original spot, also add NPCs… (#2749)
* Move EVENT_SPAWN for adding NPCs back to original spot, also add NPCs to npc/mob list before parsing

* Adjust bots EVENT_SPAWN before spawn packet
2023-01-16 22:32:19 -05:00
Aeadoin be03628aa9 [Bug Fix] Fix Group XP not working. (#2748) 2023-01-16 19:10:19 -05:00
Aeadoin f1a6006ee1 [Hotfix] Resolve Zone Crashing when grouped with Bots. (#2747)
* [Hotfix] Resolve Zone Crashing when grouped with Bots.

* Fixed SpawnBotGroupByName as well.

* rename variables
2023-01-16 16:50:38 -05:00
Aeadoin dd40f2a0e6 [Bug Fix] Fix ST_TargetsTarget Spells with Restrictions (#2746) 2023-01-15 17:55:34 -05:00
Aeadoin 7fa421d848 [Bug Fix] HasPet() Zone Crashes (#2744)
* [Bug Fixes] Fix for HasPet() Zone Crashes

* HasPets const

* Remove checking This

* formatting
2023-01-15 17:16:17 -05:00
Alex King 00658632de [Cleanup] Make use of std::abs where possible. (#2739)
# Notes
- Resolves https://github.com/EQEmu/Server/issues/338
2023-01-15 17:02:13 -05:00
Alex King eed45e5250 [Quest API] Add SendPath() to Perl/Lua. (#2740)
* [Quest API] Add SendPath() to Perl/Lua.

# Perl
- Add `$client->SendPath(target)`.

# Lua
- Add `client:SendPath(target)`.

# Notes
- Allows operators to send a path to a target arbitrarily with a script.

* Update client.cpp
2023-01-15 17:02:06 -05:00
Alex King 64c62c4f0a [Feature] Add Rule to Disable Group EXP Modifier. (#2741)
# Notes
- Adds `Character:EnableGroupEXPModifier`, defaults to `true`.
- Adds `Character:GroupMemberEXPModifier`, defaults to `0.2`.
- Adds `Character:FullGroupEXPModifier`, defaults to `2.16`.
- Allows operators to enable or disable the group experience modifier based on number of members.
- Allows operators to change the modifier per member in the group between `2` and `5`.
- Allows operators to change the full group experience modifier.
2023-01-15 17:01:59 -05:00
Paul Coene ca0ae3cb98 [Rule] Add rule for NPC Level Based Buff Restrictions. (#2708)
* [Rule] Add rule for NPC Level Based Buff Restrictions.

* Erroneous whitespace

* Change prefix on log message

* Added log message when GM casts
2023-01-15 15:30:42 -06:00
Chris Miles 9e3539295b [QS] Database class name change (#2743) 2023-01-15 14:37:39 -06:00
Chris Miles 7aa25f17f6 [UCS] Database class name change (#2742) 2023-01-15 14:16:23 -06:00
Chris Miles e1c1d55ca5 [Websocket] Fix cpp20/gcc11 compile failure (#2737) 2023-01-15 11:00:24 -06:00
Aeadoin 403c54362e [Bot/Merc] Cleanup methods, and virtual overrides. (#2734)
* [Bot] Cleanup methods, and virtual overrides.

* Remove Bot::CheckAggroAmount & Bot::CheckHealAggroAmount

* formatting
2023-01-14 23:32:19 -05:00
Alex King a422484307 [Quest API] Add Client Augment Events to Perl/Lua. (#2735)
* [Quest API] Add Client Augment Events to Perl/Lua.

# Perl
- Add `EVENT_AUGMENT_INSERT_CLIENT`.
- Add `EVENT_AUGMENT_REMOVE_CLIENT`.

# Lua
- Add `event_augment_insert_client`.
- Add `event_augment_remove_client`.

# Notes
- Allows operators to use augment insert and augment remove events outside of an item script.
2023-01-14 23:23:48 -05:00
Alex King c41f375129 [Bug Fix] Fix issue with Bot::LoadAndSpawnAllZonedBots. (#2733)
* [Bug Fix] Fix issue with Bot:;LoadAndSpawnAllZonedBots.

# Notes
- Bots could spawn beyond class/global limits due to being stuck in group limbo and spawning when you enter a zone properly.

* Debug messages.

* Remove unspawned bots from group.

* Update bot.cpp

* Update bot.cpp

* Update bot.cpp

* Update bot.cpp

* >= 0
2023-01-14 23:15:26 -05:00
Alex King bd3e8b2afc [Quest API] Add Bot Methods to Lua. (#2731)
# Perl
- Minor cleanup of variable types.

 # Lua
- Add `bot:GetAugmentAt(slot_id, augment_index)`.
- Add `bot:GetItemAt(slot_id)`.
- Add `bot:SendSpellAnim(target_id, spell_id)`.
- Properly implemented `bot:GetItemIDAt(slot_id)`.

# Notes
- `bot:GetItemIDAt` existed in Lua, but didn't have a bind definition, so was non-functional.
- This makes Perl/Lua bot methods 1:1 as Perl had 75 and Lua had 72, they now both have 75.
2023-01-14 09:16:11 -06:00
Alex King f5523b40d2 [Quest API] Add CampAllBots() to Perl/Lua. (#2732)
# Perl
- Add `$client->CampAllBots()`.
- Add `$client->CampAllBots(class_id)`.

# Lua
- Add `client:CampAllBots()`.
- Add `client:CampAllBots(class_id)`.

# Notes
- Adds constants for `NO_CLASS` which is class `0` and uses `RACE_DOUG_0` for any spots that use race ID `0`.
- Cleans up magic number usage of race/class of `0`.
2023-01-14 09:14:50 -06:00
Alex King 095f4fb56c [Quest API] Add SignalAllBotsByOwnerName() to Perl/Lua. (#2730)
# Perl
- Add `$entity_list->SignalAllBotsByOwnerName(owner_name)`.

# Lua
- Add `eq.get_entity_list():SignalAllBotsByOwnerName(owner_name)`.

# Notes
- Adds a way to signal all bots by owner name instead of only character ID.
2023-01-13 04:54:20 -06:00
Alex King f8afadf0a9 [Cleanup] Remove unused basic_functions.h (#2729)
# Notes
- This file is unused and not included in any other files.
2023-01-13 04:52:32 -06:00
Alex King 9c23882d67 [Cleanup] Remove unused maxskill.h. (#2728)
# Notes
- This file is unused, noticed it when looking through source. Nothing calls this method or includes this file.
2023-01-13 04:52:08 -06:00
Aeadoin 3510ba2493 [Bug Fix] Fix Aug Clicks where item has no click effect. (#2725) 2023-01-12 12:46:42 -05:00
322 changed files with 31886 additions and 31752 deletions
-21
View File
@@ -1,21 +0,0 @@
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.101.1/containers/ubuntu-18.04-git
{
"name": "Ubuntu 18.04 EQEMU",
// Moved from dockerfile to image so it builds faster
"image": "eqemu/devcontainer:0.0.2",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["ms-vscode.cpptools", "ms-azuretools.vscode-docker"],
"mounts": ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"],
"remoteEnv": {
"HOST_PROJECT_PATH": "${localWorkspaceFolder}"
}
}
+80 -9
View File
@@ -1,7 +1,8 @@
---
kind: pipeline
type: docker
name: EQEmulator Server Linux CI
name: Build Linux
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
concurrency:
@@ -10,18 +11,88 @@ concurrency:
volumes:
- name: cache
host:
path: /var/lib/cache
path: /var/lib/cache-release
steps:
- name: server-build
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
- name: Build Linux X64
image: akkadius/eqemu-server:v11
environment:
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
commands:
- sudo chown eqemu:eqemu /drone/src/ * -R
- sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O0 -g -DNDEBUG" -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
- curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
- ./bin/tests
- ./utils/scripts/build/linux-build.sh
volumes:
- name: cache
path: /home/eqemu/.ccache/
---
kind: pipeline
type: exec
name: Build Windows
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
concurrency:
limit: 1
platform:
os: windows
arch: amd64
steps:
- name: Build Windows X64
environment:
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
commands:
- .\utils\scripts\build\windows-build.ps1
---
kind: pipeline
type: docker
name: Publish Artifacts to Github
steps:
- name: Upload Artifacts
image: akkadius/eqemu-build-releaser:v3
environment:
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
GH_RELEASE_GITHUB_API_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
commands:
- ./utils/scripts/build/should-release/should-release
- rclone config create remote ftp env_auth true > /dev/null
- |
rclone copy remote: --include "eqemu-server*.zip" .
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
- |
rclone delete remote: --include "eqemu-server*.zip"
trigger:
branch:
- master
event:
- push
depends_on:
- Build Windows
- Build Linux
+12 -1
View File
@@ -59,4 +59,15 @@ bin/
# Clangd Generated Files.
compile_flags.txt
.cache/
.cache/
# vscode generated settings
.vscode/
# Build pipeline
!utils/scripts/build/
!utils/scripts/build/should-release/should-release
!utils/scripts/build/should-release/should-release.exe
# CMake Files
cmake-build-relwithdebinfo/*
-16
View File
@@ -1,16 +0,0 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/mysql"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}
-5
View File
@@ -1,5 +0,0 @@
{
"files.associations": {
"*.ipp": "cpp"
}
}
-164
View File
@@ -1,164 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "make",
"type": "shell",
"command": "cd bin && make",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "make clean",
"type": "shell",
"command": "cd bin && make clean",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "cmake",
"type": "shell",
"command": "mkdir -p bin && cd bin && rm CMakeCache.txt && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' ..",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher":{
"owner": "cpp",
"fileLocation": "relative",
"pattern":[
{
"regexp": "([\\w+|\\\\]*\\.\\w+)\\((\\d+)\\)\\: (warning|error) (.*)$",
"file": 1,
"location": 2,
"severity": 3,
"message": 4
}
]
}
},
{
"label": "download maps",
"type": "shell",
"command": "mkdir -p bin && cd bin && wget https://codeload.github.com/Akkadius/EQEmuMaps/zip/master -O maps.zip && unzip -o maps.zip && rm ./maps -rf && mv EQEmuMaps-master maps && rm maps.zip",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "download quests",
"type": "shell",
"command": "mkdir -p bin && cd bin && cd server && git -C ./quests pull 2> /dev/null || git clone https://github.com/ProjectEQ/projecteqquests.git quests",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "download eqemu_config",
"type": "shell",
"command": "mkdir -p bin && cd bin && wget --no-check-certificate https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/eqemu_config_docker.json -O eqemu_config.json",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "rebuild database (mariadb must be started)",
"type": "shell",
"command": "mkdir -p bin && cd bin && docker run -i --rm --privileged -v ${HOST_PROJECT_PATH}/bin:/src --network=eqemu -it eqemu/server:0.0.3 bash -c './eqemu_server.pl source_peq_db && ./eqemu_server.pl check_db_updates && ./eqemu_server.pl linux_login_server_setup'",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "zone 7000",
"type": "shell",
"command": "docker stop zone7000 | true && docker network create eqemu | true && docker run -i --rm --name zone7000 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu -p 7000:7000/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7000:7000",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "zone 7001",
"type": "shell",
"command": "docker stop zone7001 | true && docker network create eqemu | true && docker run -i --rm --name zone7001 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu -p 7001:7001/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7001:7001",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "loginserver",
"type": "shell",
"command": "docker stop loginserver | true && docker network create eqemu | true && docker run -i --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu --name loginserver -p 5999:5999/udp -p 5998:5998/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./loginserver",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "shared_memory, world",
"type": "shell",
"command": "docker stop sharedmemory | true && docker stop world | true && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --network=eqemu --name sharedmemory eqemu/server:0.0.3 ./shared_memory && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name world -p 9000:9000 -p 9000:9000/udp -p 9001:9001 -p 9080:9080 eqemu/server:0.0.3 gdb -ex run ./world",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "queryserv",
"type": "shell",
"command": "docker stop queryserv | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name queryserv eqemu/server:0.0.3 gdb -ex run ./queryserv",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "mariadb",
"type": "shell",
"command": "docker stop mariadb | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin/db:/bitnami/mariadb -p 3306:3306 -e MARIADB_DATABASE=peq -e MARIADB_USER=eqemu -e MARIADB_PASSWORD=eqemupass -e ALLOW_EMPTY_PASSWORD=yes --name mariadb --network=eqemu bitnami/mariadb:latest",
"group": {
"kind": "test",
"isDefault": true
}
},
{
"label": "ucs",
"type": "shell",
"command": "docker stop ucs | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src -p 7778:7778 --name ucs --network=eqemu eqemu/server:0.0.3 gdb -ex run ./ucs",
"group": {
"kind": "test",
"isDefault": true
}
}
]
}
+2 -2
View File
@@ -40,14 +40,14 @@ Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extra
mkdir build
cd build
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
##### Linux
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
mkdir build
cd build
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON ..
### Building
+747
View File
@@ -0,0 +1,747 @@
## [22.3.0] - 02/06/2023
### Bots
* Add GetAugmentIDsBySlotID & AddItem with table ref Methods. ([#2805](https://github.com/EQEmu/Server/pull/2805)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-29
### Commands
* #list now searches without case sensitivity ([#2825](https://github.com/EQEmu/Server/pull/2825)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
* Remove extraneous else from #weather ([#2819](https://github.com/EQEmu/Server/pull/2819)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
### Crash
* Fix IsUnderwaterOnly crash where npc data references can be stale ([#2830](https://github.com/EQEmu/Server/pull/2830)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
* Fix command crash with #npcedit weapon when second weapon not passed ni ([#2829](https://github.com/EQEmu/Server/pull/2829)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
* Fix crash in bot command botdyearmor ([#2832](https://github.com/EQEmu/Server/pull/2832)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
### DB Updates
* Add Windows MySQL path auto detection for users where the path is not found ([#2836](https://github.com/EQEmu/Server/pull/2836)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
### Doors
* Have NPCs trigger double doors ([#2821](https://github.com/EQEmu/Server/pull/2821)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
* Remove door dev tools spam on client controlled doors ([#2824](https://github.com/EQEmu/Server/pull/2824)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
### Feature
* Add Min/Max Status to Merchants ([#2806](https://github.com/EQEmu/Server/pull/2806)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
### Fixes
* #reload aa will now refresh the AA table properly for every client when changes are made ([#2814](https://github.com/EQEmu/Server/pull/2814)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
* #reload static should now properly fill the entity_lists for… ([#2815](https://github.com/EQEmu/Server/pull/2815)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
* BuffLevelRestrictions were restricting group buffs if mob targeted ([#2809](https://github.com/EQEmu/Server/pull/2809)) ([noudess](https://github.com/noudess)) 2023-01-29
* Fix does_augment_fit_slot method. ([#2817](https://github.com/EQEmu/Server/pull/2817)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-01
* Fix NPC ghosting at safe coordinates ([#2823](https://github.com/EQEmu/Server/pull/2823)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
* Fixing % based mob see invis ([#2802](https://github.com/EQEmu/Server/pull/2802)) ([fryguy503](https://github.com/fryguy503)) 2023-01-29
* Resolve issue with max buff count being 25 in ROF2. ([#2800](https://github.com/EQEmu/Server/pull/2800)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-28
### Hotfix
* Post revert build fix for https://github.com/EQEmu/Server/commit/54050924d81d1f83268fe01f9c2b36fe10626601 ([Akkadius](https://github.com/Akkadius)) 2023-02-01
### Lua
* Resolve stoi Exception ([#2736](https://github.com/EQEmu/Server/pull/2736)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
### Pathing
* Improvements to handling tight corridors pathing, clipping detection and recovery ([#2826](https://github.com/EQEmu/Server/pull/2826)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
### Quest API
* Add Augment Slot support to does_augment_fit ([#2813](https://github.com/EQEmu/Server/pull/2813)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-31
* Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua. ([#2804](https://github.com/EQEmu/Server/pull/2804)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
* Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. ([#2810](https://github.com/EQEmu/Server/pull/2810)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-30
* Add EVENT_TASKACCEPTED to Player scope ([#2822](https://github.com/EQEmu/Server/pull/2822)) ([Valorith](https://github.com/Valorith)) 2023-02-06
* Add GetItemCooldown to return the time remaining on items… ([#2811](https://github.com/EQEmu/Server/pull/2811)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-30
* Add LDoN Methods to Perl/Lua ([#2799](https://github.com/EQEmu/Server/pull/2799)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
* Add Override Parameters to ScaleNPC() in Perl/Lua. ([#2816](https://github.com/EQEmu/Server/pull/2816)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
* Add rule AlternateAugmentationSealer for using a different bagtype ([#2831](https://github.com/EQEmu/Server/pull/2831)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-06
* Default ScaleNPC to always scale. ([#2818](https://github.com/EQEmu/Server/pull/2818)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-06
### Readme
* Update build badges with Drone ([Akkadius](https://github.com/Akkadius)) 2023-01-29
### Rules
* Add rule to ignore name filter on chat channel creation. ([#2820](https://github.com/EQEmu/Server/pull/2820)) ([Valorith](https://github.com/Valorith)) 2023-02-06
* Added rule to bypass level based haste caps ([#2835](https://github.com/EQEmu/Server/pull/2835)) ([jcr4990](https://github.com/jcr4990)) 2023-02-06
* Fix rule updates that affected bot booting checks ([#2841](https://github.com/EQEmu/Server/pull/2841)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
### Tasks
* Implement alternate currency rewards ([#2827](https://github.com/EQEmu/Server/pull/2827)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
## [22.2.0] - 01/27/2023
### Bots
* Add EVENT_UNEQUIP_ITEM_BOT & EVENT_EQUIP_ITEM_BOT ([#2796](https://github.com/EQEmu/Server/pull/2796)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-27
* ^create and ^viewcombos popup messages fix. ([#2797](https://github.com/EQEmu/Server/pull/2797)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-26
### Code Cleanup
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
### Crash
* Fix crash issue with log formatting during character creation ([#2798](https://github.com/EQEmu/Server/pull/2798)) ([Akkadius](https://github.com/Akkadius)) 2023-01-27
### Feature
* ResetItemCooldown added to lua/perl and fix item re-cast times to show properly ([#2793](https://github.com/EQEmu/Server/pull/2793)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-26
### Git
* Add CMake Files to .gitignore ([#2792](https://github.com/EQEmu/Server/pull/2792)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-25
## [22.1.2] - 01/24/2023
### CI/CD
* Build / Release Pipeline Changes ([#2788](https://github.com/EQEmu/Server/pull/2788)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
### Code Cleanup
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
### Crash
* Fix rarer world crash issue where scheduler database was not available ([#2789](https://github.com/EQEmu/Server/pull/2789)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
### Fixes
* Fix nullptr spell in BCSpells::Load() ([#2790](https://github.com/EQEmu/Server/pull/2790)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
* Remove duplicate logic in GetActSpellHealing reducing HOT criticals ([#2786](https://github.com/EQEmu/Server/pull/2786)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
## [22.1.1] - 01/23/2023
### Fixes
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
## [22.1.0] - 01/22/2023
This is a first release using the new build system. Changelog entry representative of last year. Subsequent releases will consist of incremental changes since the last release.
### AA
* Fix AA tables dump ([#2769](https://github.com/EQEmu/Server/pull/2769)) ([Akkadius](https://github.com/Akkadius)) 2023-01-22
### Appveyor
* Remove bots preprocessor ([Akkadius](https://github.com/Akkadius)) 2023-01-20
### Bot/Merc
* Cleanup methods, and virtual overrides. ([#2734](https://github.com/EQEmu/Server/pull/2734)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
### Bots
* Add Bot Command Reloading ([#2773](https://github.com/EQEmu/Server/pull/2773)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
* Add Bot-specific Spell Settings. ([#2553](https://github.com/EQEmu/Server/pull/2553)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Add Buff support for Bards under AI_IdleCastChecks ([#2590](https://github.com/EQEmu/Server/pull/2590)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-28
* Add Data Bucket support to Bot Spell Entries. ([#2505](https://github.com/EQEmu/Server/pull/2505)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
* Add EVENT_TRADE Support to Bots. ([#2560](https://github.com/EQEmu/Server/pull/2560)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
* Add Event_Trade Support for ^inventorygive Command ([#2628](https://github.com/EQEmu/Server/pull/2628)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-11
* Add Expansion Bitmask Quest APIs. ([#2523](https://github.com/EQEmu/Server/pull/2523)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
* Add GetBotOwnerByBotID Method ([#2715](https://github.com/EQEmu/Server/pull/2715)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
* Add Melee Support for Casting, Cleanup Bot Casting Logic ([#2571](https://github.com/EQEmu/Server/pull/2571)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
* Add Quest API Methods ([#2631](https://github.com/EQEmu/Server/pull/2631)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-12
* Add Quest API Support for Limits. ([#2522](https://github.com/EQEmu/Server/pull/2522)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
* Add Rule Allowing Bots to Equip Any Race Items ([#2578](https://github.com/EQEmu/Server/pull/2578)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-26
* Add Support for AA bonuses that were missing. ([#2764](https://github.com/EQEmu/Server/pull/2764)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
* Add Support for Bots to receive Auras, and other AoE Buffs. ([#2586](https://github.com/EQEmu/Server/pull/2586)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
* Add Virtual Override for Bot::Attack ([#2771](https://github.com/EQEmu/Server/pull/2771)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
* Add give/remove saylinks to ^itemuse. ([#2503](https://github.com/EQEmu/Server/pull/2503)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
* Add support for Bot scripting. ([#2515](https://github.com/EQEmu/Server/pull/2515)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
* Apply Spells:IgnoreSpellDmgLvlRestriction to bots ([#2024](https://github.com/EQEmu/Server/pull/2024)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
* Bot::PerformTradeWithClient Cleanup. ([#2084](https://github.com/EQEmu/Server/pull/2084)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
* Cleanup Bot Spell Functions, reduce reliance on NPC Functions/Attributes ([#2495](https://github.com/EQEmu/Server/pull/2495)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-29
* Cleanup Fast Rest Regen ([#2626](https://github.com/EQEmu/Server/pull/2626)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-07
* Cleanup Say Event Parse. ([#2557](https://github.com/EQEmu/Server/pull/2557)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
* Cleanup Spell Settings Commands ([#2607](https://github.com/EQEmu/Server/pull/2607)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
* Cleanup ^inventoryremove, ^inventorylist, and ^list Commands and bot groups. ([#2273](https://github.com/EQEmu/Server/pull/2273)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-03
* Cleanup and remove preprocessors. ([#2757](https://github.com/EQEmu/Server/pull/2757)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-20
* Cleanup various Bot Spell Focus methods ([#2649](https://github.com/EQEmu/Server/pull/2649)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-16
* Convert Load, Save, SaveNew, and Delete to Repositories. ([#2614](https://github.com/EQEmu/Server/pull/2614)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
* Expanded Bot Spell Settings List. ([#2606](https://github.com/EQEmu/Server/pull/2606)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-03
* Fix Bot Spell Type "In Combat Buffs" ([#2711](https://github.com/EQEmu/Server/pull/2711)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-08
* Fix Gender not saving as GetBaseGender on BotSave ([#2639](https://github.com/EQEmu/Server/pull/2639)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
* Fix Slow Query in QueryNameAvailablity ([#2781](https://github.com/EQEmu/Server/pull/2781)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
* Fix ^dyearmor command math. ([#2081](https://github.com/EQEmu/Server/pull/2081)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
* Fix bot spawn when bot id = char_id ([#1984](https://github.com/EQEmu/Server/pull/1984)) ([neckkola](https://github.com/neckkola)) 2022-03-07
* Hotfix for possible crash. ([#2539](https://github.com/EQEmu/Server/pull/2539)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Melee Bot Support for Spell Settings Commands ([#2599](https://github.com/EQEmu/Server/pull/2599)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
* Move Bot Spell Loading process to constructor from calcbotstats() ([#2583](https://github.com/EQEmu/Server/pull/2583)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
* Optimize inventory loading. ([#2588](https://github.com/EQEmu/Server/pull/2588)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-28
* Post pre-processor fixes ([#2770](https://github.com/EQEmu/Server/pull/2770)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
* Resolve incorrect values on Bot Creation ([#2644](https://github.com/EQEmu/Server/pull/2644)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-14
* Restrict Bot Groups from spawning while Feigned. ([#2761](https://github.com/EQEmu/Server/pull/2761)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
* Save Bot Toggle Archer Setting between Loads. ([#2612](https://github.com/EQEmu/Server/pull/2612)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
* Update Bot Heal & Damage methods to more closely match Clients + Bugfixes ([#2045](https://github.com/EQEmu/Server/pull/2045)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-11
* Update Bot Logic to ignore ST_TargetsTarget when buffing ([#2584](https://github.com/EQEmu/Server/pull/2584)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
### C++20
* Arithmetic on different enums is deprecated ([#2752](https://github.com/EQEmu/Server/pull/2752)) ([mackal](https://github.com/mackal)) 2023-01-17
* Enable C++20 + Fixes + FMT 9.1 ([#2664](https://github.com/EQEmu/Server/pull/2664)) ([Akkadius](https://github.com/Akkadius)) 2022-12-21
### Code
* Removed vscode setting ([#2753](https://github.com/EQEmu/Server/pull/2753)) ([xackery](https://github.com/xackery)) 2023-01-17
### Code Cleanup
* Add Validation to varchar number item fields. ([#2241](https://github.com/EQEmu/Server/pull/2241)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
* Cleanup #kick message. ([#2164](https://github.com/EQEmu/Server/pull/2164)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
* Cleanup Haste references and Lua API calls for unsigned to signed. ([#2240](https://github.com/EQEmu/Server/pull/2240)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
* Cleanup code smells and compiler warnings in common/shareddb ([#2270](https://github.com/EQEmu/Server/pull/2270)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
* Cleanup magic numbers ([#2662](https://github.com/EQEmu/Server/pull/2662)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-20
* Cleanup spell and max level bucket logic. ([#2181](https://github.com/EQEmu/Server/pull/2181)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
* Extra Space in NPC::AISpellsList(). ([#2555](https://github.com/EQEmu/Server/pull/2555)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
* Fix unintended copies in zone/zonedb.cpp by changing auto to auto& ([#2271](https://github.com/EQEmu/Server/pull/2271)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
* Make use of std::abs where possible. ([#2739](https://github.com/EQEmu/Server/pull/2739)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
* Merge Client::Attack and Bot::Attack into Mob::Attack ([#2756](https://github.com/EQEmu/Server/pull/2756)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
* Move Client::Undye() to client.cpp from #path Command. ([#2188](https://github.com/EQEmu/Server/pull/2188)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-21
* Possible issues with variable/parameter name equality. ([#2161](https://github.com/EQEmu/Server/pull/2161)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
* Quest API push methods using invalid types. ([#2172](https://github.com/EQEmu/Server/pull/2172)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-16
* Remove Unused EQEMU_DEPOP_INVALIDATES_CACHE ([#2292](https://github.com/EQEmu/Server/pull/2292)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
* Remove this-> in code where its implied ([#2088](https://github.com/EQEmu/Server/pull/2088)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
* Remove unused basic_functions.h ([#2729](https://github.com/EQEmu/Server/pull/2729)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
* Remove unused maxskill.h. ([#2728](https://github.com/EQEmu/Server/pull/2728)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
* Remove unused methods. ([#2171](https://github.com/EQEmu/Server/pull/2171)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
* Remove unusued Max Item ID Constant ([#2528](https://github.com/EQEmu/Server/pull/2528)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-08
* Remove use of bzero since it is deprecated for memset ([#2295](https://github.com/EQEmu/Server/pull/2295)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
* Resharper Warnings ([#2235](https://github.com/EQEmu/Server/pull/2235)) ([Quintinon](https://github.com/Quintinon)) 2022-06-01
* Resolve some warnings in loginserver/world_server.cpp ([#2347](https://github.com/EQEmu/Server/pull/2347)) ([mackal](https://github.com/mackal)) 2022-07-31
* Rework Lua QuestReward to not use try/catch blocks ([#2417](https://github.com/EQEmu/Server/pull/2417)) ([mackal](https://github.com/mackal)) 2022-09-03
* Send eqstr message in AddAAPoints ([#2507](https://github.com/EQEmu/Server/pull/2507)) ([hgtw](https://github.com/hgtw)) 2022-10-29
* Update to EQEmu #2253 to clean up message strings ([#2279](https://github.com/EQEmu/Server/pull/2279)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
* Zone Data Loading Refactor ([#2388](https://github.com/EQEmu/Server/pull/2388)) ([Akkadius](https://github.com/Akkadius)) 2022-09-01
### Commands
* #bind Typo. ([#2196](https://github.com/EQEmu/Server/pull/2196)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
* #ginfo Cleanup. ([#1955](https://github.com/EQEmu/Server/pull/1955)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
* #reload Command Overhaul. ([#2162](https://github.com/EQEmu/Server/pull/2162)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
* #reload level_mods could cause Non-Booted zones to crash. ([#2670](https://github.com/EQEmu/Server/pull/2670)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-24
* Add #bugs Command. ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Add #feature Command. ([#2142](https://github.com/EQEmu/Server/pull/2142)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Add #findcharacter Command. ([#2692](https://github.com/EQEmu/Server/pull/2692)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
* Add #findrecipe and #viewrecipe Commands. ([#2401](https://github.com/EQEmu/Server/pull/2401)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-31
* Add #setanon Command ([#2690](https://github.com/EQEmu/Server/pull/2690)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
* Add #suspendmulti Command. ([#2619](https://github.com/EQEmu/Server/pull/2619)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
* Add BestZ and Region Data to #loc ([#2245](https://github.com/EQEmu/Server/pull/2245)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-05
* Add additional #peqzone functionality. ([#2085](https://github.com/EQEmu/Server/pull/2085)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
* Add max_hp back to #modifynpcstat command. ([#2638](https://github.com/EQEmu/Server/pull/2638)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
* Adding movespeed to #showstats output ([#2596](https://github.com/EQEmu/Server/pull/2596)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
* Bug fix for #logs command. ([#2008](https://github.com/EQEmu/Server/pull/2008)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
* Cleanup #ai Command. ([#1980](https://github.com/EQEmu/Server/pull/1980)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
* Cleanup #appearanceeffects Command. ([#2777](https://github.com/EQEmu/Server/pull/2777)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
* Cleanup #attack Command. ([#2103](https://github.com/EQEmu/Server/pull/2103)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
* Cleanup #ban, #ipban, #flag, #kick, #setlsinfo, and #setpass Commands. ([#2104](https://github.com/EQEmu/Server/pull/2104)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
* Cleanup #chat Command. ([#2581](https://github.com/EQEmu/Server/pull/2581)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Cleanup #corpsefix Command. ([#2197](https://github.com/EQEmu/Server/pull/2197)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Cleanup #cvs Command. ([#2153](https://github.com/EQEmu/Server/pull/2153)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
* Cleanup #date Command. ([#2228](https://github.com/EQEmu/Server/pull/2228)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
* Cleanup #dbspawn2 Command. ([#2493](https://github.com/EQEmu/Server/pull/2493)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
* Cleanup #delacct Command. ([#2567](https://github.com/EQEmu/Server/pull/2567)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Cleanup #depop Command. ([#2536](https://github.com/EQEmu/Server/pull/2536)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Cleanup #depopzone Command. ([#2537](https://github.com/EQEmu/Server/pull/2537)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Cleanup #devtools Command. ([#2538](https://github.com/EQEmu/Server/pull/2538)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Cleanup #doanim Command. ([#2540](https://github.com/EQEmu/Server/pull/2540)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Cleanup #emote Command. ([#2535](https://github.com/EQEmu/Server/pull/2535)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Cleanup #emotesearch and #emoteview Command. ([#2494](https://github.com/EQEmu/Server/pull/2494)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
* Cleanup #emptyinventory Command. ([#2219](https://github.com/EQEmu/Server/pull/2219)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
* Cleanup #findaliases and #help Commands. ([#2204](https://github.com/EQEmu/Server/pull/2204)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Cleanup #findclass and #findrace Commands. ([#2211](https://github.com/EQEmu/Server/pull/2211)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Cleanup #flagedit Command. ([#1968](https://github.com/EQEmu/Server/pull/1968)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #freeze and #unfreeze Commands. ([#2102](https://github.com/EQEmu/Server/pull/2102)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
* Cleanup #gassign Command. ([#2101](https://github.com/EQEmu/Server/pull/2101)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #gearup Command. ([#2589](https://github.com/EQEmu/Server/pull/2589)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Cleanup #getvariable Command. ([#2100](https://github.com/EQEmu/Server/pull/2100)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
* Cleanup #guild Command ([#2693](https://github.com/EQEmu/Server/pull/2693)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-04
* Cleanup #hatelist Command. ([#1976](https://github.com/EQEmu/Server/pull/1976)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #heromodel Command. ([#2566](https://github.com/EQEmu/Server/pull/2566)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Cleanup #kill Command. ([#2195](https://github.com/EQEmu/Server/pull/2195)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
* Cleanup #level Command. ([#2203](https://github.com/EQEmu/Server/pull/2203)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Cleanup #logs Command. ([#1969](https://github.com/EQEmu/Server/pull/1969)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #makepet Command. ([#2105](https://github.com/EQEmu/Server/pull/2105)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #modifynpcstat Command. ([#2499](https://github.com/EQEmu/Server/pull/2499)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
* Cleanup #motd Command. ([#2190](https://github.com/EQEmu/Server/pull/2190)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
* Cleanup #name Command. ([#1977](https://github.com/EQEmu/Server/pull/1977)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #netstats Command. ([#1970](https://github.com/EQEmu/Server/pull/1970)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #npcedit Command. ([#2582](https://github.com/EQEmu/Server/pull/2582)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Cleanup #npcedit, #lastname, #title, and #titlesuffix Commands. ([#2215](https://github.com/EQEmu/Server/pull/2215)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
* Cleanup #npceditmass command. ([#1957](https://github.com/EQEmu/Server/pull/1957)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
* Cleanup #npcemote Command. ([#2106](https://github.com/EQEmu/Server/pull/2106)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #npcloot Command. ([#1974](https://github.com/EQEmu/Server/pull/1974)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
* Cleanup #npcsay and #npcshout Commands. ([#2107](https://github.com/EQEmu/Server/pull/2107)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #npcspecialattk Command. ([#2108](https://github.com/EQEmu/Server/pull/2108)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #npctype_cache Command. ([#2109](https://github.com/EQEmu/Server/pull/2109)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #npctypespawn Command. ([#2110](https://github.com/EQEmu/Server/pull/2110)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #nudge Command. ([#2220](https://github.com/EQEmu/Server/pull/2220)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
* Cleanup #oocmute Command. ([#2191](https://github.com/EQEmu/Server/pull/2191)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Cleanup #opcode Command. ([#2547](https://github.com/EQEmu/Server/pull/2547)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
* Cleanup #profanity Command. ([#2113](https://github.com/EQEmu/Server/pull/2113)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #push Command. ([#2114](https://github.com/EQEmu/Server/pull/2114)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #qglobal Command. ([#2115](https://github.com/EQEmu/Server/pull/2115)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #randomizefeatures Command. ([#2118](https://github.com/EQEmu/Server/pull/2118)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #refreshgroup Command. ([#2119](https://github.com/EQEmu/Server/pull/2119)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadaa Command. ([#2120](https://github.com/EQEmu/Server/pull/2120)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadallrules Command. ([#2121](https://github.com/EQEmu/Server/pull/2121)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadlevelmods Command. ([#2122](https://github.com/EQEmu/Server/pull/2122)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadmerchants Command. ([#2123](https://github.com/EQEmu/Server/pull/2123)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadperlexportsettings Command. ([#2124](https://github.com/EQEmu/Server/pull/2124)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadrulesworld Command. ([#2128](https://github.com/EQEmu/Server/pull/2128)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadstatic Command. ([#2130](https://github.com/EQEmu/Server/pull/2130)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadtitles Command. ([#2125](https://github.com/EQEmu/Server/pull/2125)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadtraps Command. ([#2126](https://github.com/EQEmu/Server/pull/2126)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadworld and #repop Command. ([#2127](https://github.com/EQEmu/Server/pull/2127)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #reloadzps Command. ([#2129](https://github.com/EQEmu/Server/pull/2129)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #resetaa Command. ([#2132](https://github.com/EQEmu/Server/pull/2132)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #resetaa_timer Command. ([#2131](https://github.com/EQEmu/Server/pull/2131)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #resetdisc_timer Command. ([#2133](https://github.com/EQEmu/Server/pull/2133)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #revoke Command. ([#2134](https://github.com/EQEmu/Server/pull/2134)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #roambox Command. ([#2135](https://github.com/EQEmu/Server/pull/2135)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #rules Command. ([#2593](https://github.com/EQEmu/Server/pull/2593)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
* Cleanup #save Command. ([#2136](https://github.com/EQEmu/Server/pull/2136)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #scale Command. ([#2591](https://github.com/EQEmu/Server/pull/2591)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
* Cleanup #scribespell and #scribespells Commands. ([#2534](https://github.com/EQEmu/Server/pull/2534)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Cleanup #sensetrap Command. ([#2137](https://github.com/EQEmu/Server/pull/2137)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #serverinfo Command. ([#2568](https://github.com/EQEmu/Server/pull/2568)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Cleanup #serverrules Command. ([#2139](https://github.com/EQEmu/Server/pull/2139)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #setlanguage Command. ([#2464](https://github.com/EQEmu/Server/pull/2464)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-13
* Cleanup #setskillall Command. ([#1992](https://github.com/EQEmu/Server/pull/1992)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
* Cleanup #shownpcgloballoot and #showzonegloballoot Command. ([#2141](https://github.com/EQEmu/Server/pull/2141)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #showskills Command. ([#1994](https://github.com/EQEmu/Server/pull/1994)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
* Cleanup #spawneditmass Command. ([#2229](https://github.com/EQEmu/Server/pull/2229)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
* Cleanup #spawnfix Command. ([#2143](https://github.com/EQEmu/Server/pull/2143)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #spawnstatus Command. ([#2144](https://github.com/EQEmu/Server/pull/2144)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #summon Command. ([#2145](https://github.com/EQEmu/Server/pull/2145)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
* Cleanup #summonburiedplayercorpse Command. ([#2146](https://github.com/EQEmu/Server/pull/2146)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #suspend Command. ([#2564](https://github.com/EQEmu/Server/pull/2564)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Cleanup #task Command. ([#2071](https://github.com/EQEmu/Server/pull/2071)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-14
* Cleanup #time and #timezone Command. ([#2147](https://github.com/EQEmu/Server/pull/2147)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #timers Command. ([#2562](https://github.com/EQEmu/Server/pull/2562)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Cleanup #trapinfo Command. ([#2148](https://github.com/EQEmu/Server/pull/2148)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #ucs Command. ([#2149](https://github.com/EQEmu/Server/pull/2149)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Cleanup #undye and #undyeme Commands. ([#1966](https://github.com/EQEmu/Server/pull/1966)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #unscribespell Command. ([#1998](https://github.com/EQEmu/Server/pull/1998)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
* Cleanup #untraindisc Command. ([#1996](https://github.com/EQEmu/Server/pull/1996)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
* Cleanup #version Command. ([#1967](https://github.com/EQEmu/Server/pull/1967)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Cleanup #worldwide command. ([#2021](https://github.com/EQEmu/Server/pull/2021)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
* Cleanup #xtargets Command. ([#2545](https://github.com/EQEmu/Server/pull/2545)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
* Cleanup #zone and #zoneinstance Commands. ([#2202](https://github.com/EQEmu/Server/pull/2202)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Command Status Reload and Helper Method ([#2377](https://github.com/EQEmu/Server/pull/2377)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
* Consolidate #lock and #unlock Commands into #serverlock. ([#2193](https://github.com/EQEmu/Server/pull/2193)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
* Fix #copycharacter command crash ([#2446](https://github.com/EQEmu/Server/pull/2446)) ([Akkadius](https://github.com/Akkadius)) 2022-09-25
* Fix #killallnpcs from crashing ([#2037](https://github.com/EQEmu/Server/pull/2037)) ([Akkadius](https://github.com/Akkadius)) 2022-03-07
* Fix Flymode Command Help Prompt ([#2669](https://github.com/EQEmu/Server/pull/2669)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-23
* Fix typos in #ban and #ipban Commands. ([#2209](https://github.com/EQEmu/Server/pull/2209)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
* Make #damage require a target ([#2426](https://github.com/EQEmu/Server/pull/2426)) ([hgtw](https://github.com/hgtw)) 2022-09-05
* Nested Command Aliases ([#2636](https://github.com/EQEmu/Server/pull/2636)) ([Akkadius](https://github.com/Akkadius)) 2022-12-15
* Remove #guildapprove, #guildcreate, and #guildlist Commands ([#2775](https://github.com/EQEmu/Server/pull/2775)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
* Remove #iteminfo Command. ([#2565](https://github.com/EQEmu/Server/pull/2565)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Remove #profiledump and #profilereset Commands. ([#2546](https://github.com/EQEmu/Server/pull/2546)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
* Remove #undyeme Command. ([#2776](https://github.com/EQEmu/Server/pull/2776)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
* Remove unused #bestz and #pf Commands. ([#2112](https://github.com/EQEmu/Server/pull/2112)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Remove unused/broken #deletegraveyard and #setgraveyard Commands. ([#2198](https://github.com/EQEmu/Server/pull/2198)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
### Diawind
* Plus sign markdown fix ([#2727](https://github.com/EQEmu/Server/pull/2727)) ([Akkadius](https://github.com/Akkadius)) 2023-01-12
### Feature
* AA Cap Limit ([#2423](https://github.com/EQEmu/Server/pull/2423)) ([fryguy503](https://github.com/fryguy503)) 2022-10-13
* Add "Keeps Sold Items" Flag to NPCs ([#2671](https://github.com/EQEmu/Server/pull/2671)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
* Add Experience Gain Toggle. ([#2676](https://github.com/EQEmu/Server/pull/2676)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-30
* Add Guild Chat to Console. ([#2387](https://github.com/EQEmu/Server/pull/2387)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
* Add Hate Override for Heals ([#2485](https://github.com/EQEmu/Server/pull/2485)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-14
* Add Rule to Disable Group EXP Modifier. ([#2741](https://github.com/EQEmu/Server/pull/2741)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
* Add Support for "Show Mine Only" Filters ([#2484](https://github.com/EQEmu/Server/pull/2484)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
* Add Type 49545 to Spell Resistrictions ([#2436](https://github.com/EQEmu/Server/pull/2436)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
* Add humanoid and non-wielded restrictions to pick pocket ([#2276](https://github.com/EQEmu/Server/pull/2276)) ([noudess](https://github.com/noudess)) 2022-07-03
* Add player /inspect quest event ([#2508](https://github.com/EQEmu/Server/pull/2508)) ([hgtw](https://github.com/hgtw)) 2022-10-29
* Add special ability to block /open ([#2506](https://github.com/EQEmu/Server/pull/2506)) ([hgtw](https://github.com/hgtw)) 2022-10-29
* Allow Focus Effects to be Filtered out. ([#2447](https://github.com/EQEmu/Server/pull/2447)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
* Allow pets to zone with permanent (buffdurationformula 50) buffs to maintain them through zone transitions ([#2035](https://github.com/EQEmu/Server/pull/2035)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
* Bind Wound and Forage while mounted. ([#2257](https://github.com/EQEmu/Server/pull/2257)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
* Change #scribespells to be aware of spellgroups & ranks ([#2501](https://github.com/EQEmu/Server/pull/2501)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
* Change GetSkillDmgAmt to int32 ([#2364](https://github.com/EQEmu/Server/pull/2364)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-10
* Change Lifetap Emotes to be filterable. ([#2454](https://github.com/EQEmu/Server/pull/2454)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-29
* Change Mana Costs to use Signed Int ([#2384](https://github.com/EQEmu/Server/pull/2384)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-21
* Change mana_used to int32 ([#2321](https://github.com/EQEmu/Server/pull/2321)) ([Aeadoin](https://github.com/Aeadoin)) 2022-07-30
* Client Checksum Verification (Resubmit old 1678) ([#1922](https://github.com/EQEmu/Server/pull/1922)) ([noudess](https://github.com/noudess)) 2022-03-07
* EQ2-style implied targeting for spells. ([#2032](https://github.com/EQEmu/Server/pull/2032)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
* Faction Association ([#2408](https://github.com/EQEmu/Server/pull/2408)) ([mackal](https://github.com/mackal)) 2022-09-03
* GM State Change Persistance ([#2328](https://github.com/EQEmu/Server/pull/2328)) ([fryguy503](https://github.com/fryguy503)) 2022-07-31
* Implement Heroic Strikethrough to NPCs ([#2395](https://github.com/EQEmu/Server/pull/2395)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-31
* Implement OP_CashReward ([#2307](https://github.com/EQEmu/Server/pull/2307)) ([mackal](https://github.com/mackal)) 2022-07-15
* Instance Version Specific Experience Modifiers ([#2376](https://github.com/EQEmu/Server/pull/2376)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
* NPCs with bows and arrows do ranged attacks ([#2322](https://github.com/EQEmu/Server/pull/2322)) ([mackal](https://github.com/mackal)) 2022-07-30
* Soft Delete Bots on Character Soft Delete ([#2467](https://github.com/EQEmu/Server/pull/2467)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
* Spell Ranks will now work with AllowSpellMemorizeFromItem Rule ([#2475](https://github.com/EQEmu/Server/pull/2475)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
* Update HateMod used by SPA 114 to Int32. ([#2428](https://github.com/EQEmu/Server/pull/2428)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-08
### Fixes
* #npcstats command displaying incorrect faction ([#2710](https://github.com/EQEmu/Server/pull/2710)) ([noudess](https://github.com/noudess)) 2023-01-08
* #peqzone no longer bypass Handle_OP_ZoneChange ([#2063](https://github.com/EQEmu/Server/pull/2063)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-19
* #scribespells triggered error on mysql keyword rank ([#2779](https://github.com/EQEmu/Server/pull/2779)) ([noudess](https://github.com/noudess)) 2023-01-21
* #tune command various fixes ([#2046](https://github.com/EQEmu/Server/pull/2046)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-11
* Add Complete Heal Spell back to IsCompleteHealSpell Method ([#2722](https://github.com/EQEmu/Server/pull/2722)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
* Add SE_MakeDrunk to avoid error message. ([#2601](https://github.com/EQEmu/Server/pull/2601)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
* Add omitted function call in UCS ([#2768](https://github.com/EQEmu/Server/pull/2768)) ([Valorith](https://github.com/Valorith)) 2023-01-20
* Add required distance to CoTH before aggro wipe ([#2253](https://github.com/EQEmu/Server/pull/2253)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
* Adjustment for nullptr crash ([#2232](https://github.com/EQEmu/Server/pull/2232)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
* Alleviate some lag with crosszone/worldwide spell casting. ([#2016](https://github.com/EQEmu/Server/pull/2016)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-21
* Allow High Level Spells to be Unmemorized. ([#2641](https://github.com/EQEmu/Server/pull/2641)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
* Allow Songs to be scribed from scrolls ([#2460](https://github.com/EQEmu/Server/pull/2460)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-12
* AltCurrencySelectItemReply_Struct was not handled correctly. ([#2702](https://github.com/EQEmu/Server/pull/2702)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-04
* Any use of TempName left old clean_name. ([#1946](https://github.com/EQEmu/Server/pull/1946)) ([noudess](https://github.com/noudess)) 2022-01-26
* Avoid erase in discord queue range loop ([#2411](https://github.com/EQEmu/Server/pull/2411)) ([hgtw](https://github.com/hgtw)) 2022-09-03
* Bandolier didn't recognize source weapon on cursor ([#2026](https://github.com/EQEmu/Server/pull/2026)) ([noudess](https://github.com/noudess)) 2022-03-07
* Bard Invisible causing display issues. ([#2067](https://github.com/EQEmu/Server/pull/2067)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-01
* Bard update fixes 1 ([#1982](https://github.com/EQEmu/Server/pull/1982)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-09
* Bazaar Search MYSQL Error ([#2252](https://github.com/EQEmu/Server/pull/2252)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
* Blocked spells max spell id increased ([#2207](https://github.com/EQEmu/Server/pull/2207)) ([Isaaru](https://github.com/Isaaru)) 2022-05-25
* Boats should never get FixZ'd ([#2246](https://github.com/EQEmu/Server/pull/2246)) ([noudess](https://github.com/noudess)) 2022-07-02
* Clamp Item Ldon Sell Back Rates. ([#2592](https://github.com/EQEmu/Server/pull/2592)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-30
* Clear title/suffix bug fix. ([#2068](https://github.com/EQEmu/Server/pull/2068)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
* Correct (probably) unintended bitwise AND instead of logical AND ([#2239](https://github.com/EQEmu/Server/pull/2239)) ([Quintinon](https://github.com/Quintinon)) 2022-06-02
* Correct type signed/unsigned int when reading item from database in shareddb ([#2269](https://github.com/EQEmu/Server/pull/2269)) ([Quintinon](https://github.com/Quintinon)) 2022-06-15
* Data Bucket Permanent Duration String ([#2624](https://github.com/EQEmu/Server/pull/2624)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
* Delete NpcType Struct returned by Bot::CreateDefaultNPCTypeStructForBot() when unused ([#2267](https://github.com/EQEmu/Server/pull/2267)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
* Do not allow /open to be used on traps or auras, causes crash ([#1951](https://github.com/EQEmu/Server/pull/1951)) ([KayenEQ](https://github.com/KayenEQ)) 2022-01-30
* Doors::GetSize() Perl Croak Typo. ([#2027](https://github.com/EQEmu/Server/pull/2027)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
* EVENT_ENTER_AREA/EVENT_LEAVE_AREA. ([#2698](https://github.com/EQEmu/Server/pull/2698)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
* Edge case AA reset timer issue fixes ([#1995](https://github.com/EQEmu/Server/pull/1995)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-14
* Fix #door Save ([#2699](https://github.com/EQEmu/Server/pull/2699)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
* Fix #findaa and GetAAName(). ([#2774](https://github.com/EQEmu/Server/pull/2774)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
* Fix #zone 0. ([#2691](https://github.com/EQEmu/Server/pull/2691)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Fix Aug Clicks where item has no click effect. ([#2725](https://github.com/EQEmu/Server/pull/2725)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-12
* Fix Bot "Failed to Load" Messages. ([#2719](https://github.com/EQEmu/Server/pull/2719)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
* Fix Bot Group Loading ([#2780](https://github.com/EQEmu/Server/pull/2780)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
* Fix Bot ^spellsettingsadd command ([#2603](https://github.com/EQEmu/Server/pull/2603)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
* Fix Duplicate Silent Saylink Messages ([#2386](https://github.com/EQEmu/Server/pull/2386)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
* Fix EntityList::GetBotListByCharacterID() ([#2569](https://github.com/EQEmu/Server/pull/2569)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Fix Flag Updating with SetGMStatus() in Lua. ([#2554](https://github.com/EQEmu/Server/pull/2554)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
* Fix Group XP not working. ([#2748](https://github.com/EQEmu/Server/pull/2748)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
* Fix HP Regen Per Second. ([#2206](https://github.com/EQEmu/Server/pull/2206)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-25
* Fix IDFile Crash with spaces or invalid data. ([#2597](https://github.com/EQEmu/Server/pull/2597)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
* Fix IP Exemptions. ([#2189](https://github.com/EQEmu/Server/pull/2189)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
* Fix Instance Repository ([#2598](https://github.com/EQEmu/Server/pull/2598)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
* Fix Legacy Combat Lua Script ([#2226](https://github.com/EQEmu/Server/pull/2226)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
* Fix MovePC in #zone and #zoneinstance Commands. ([#2236](https://github.com/EQEmu/Server/pull/2236)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
* Fix NPC Reference in EVENT_SPAWN ([#2712](https://github.com/EQEmu/Server/pull/2712)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-08
* Fix ST_TargetsTarget Spells with Restrictions ([#2746](https://github.com/EQEmu/Server/pull/2746)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
* Fix Silent Saylinks Sending Message to Others. ([#2389](https://github.com/EQEmu/Server/pull/2389)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
* Fix Spell Bucket and Spell Global Logic Checks. ([#2285](https://github.com/EQEmu/Server/pull/2285)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
* Fix Spellinfo Command to work with SpellIDs above int16 ([#2437](https://github.com/EQEmu/Server/pull/2437)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
* Fix Strings::Money Missing Conditions. ([#2383](https://github.com/EQEmu/Server/pull/2383)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-21
* Fix Swarm Pet Flurry/Rampages Messages ([#2444](https://github.com/EQEmu/Server/pull/2444)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
* Fix bot compile locking client on server enter. ([#2210](https://github.com/EQEmu/Server/pull/2210)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
* Fix bot guild removal. ([#2194](https://github.com/EQEmu/Server/pull/2194)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
* Fix bots equipping augments. ([#2772](https://github.com/EQEmu/Server/pull/2772)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
* Fix case-sensitivity in #suspend Command. ([#2613](https://github.com/EQEmu/Server/pull/2613)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
* Fix duplicate and missing messages due to innate in spells ([#2170](https://github.com/EQEmu/Server/pull/2170)) ([noudess](https://github.com/noudess)) 2022-05-20
* Fix empty spawned merchants ([#2275](https://github.com/EQEmu/Server/pull/2275)) ([hgtw](https://github.com/hgtw)) 2022-06-28
* Fix for Bot command casting ([#1990](https://github.com/EQEmu/Server/pull/1990)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-12
* Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs ([#1986](https://github.com/EQEmu/Server/pull/1986)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
* Fix for being able to skill up on corspe. ([#2058](https://github.com/EQEmu/Server/pull/2058)) ([noudess](https://github.com/noudess)) 2022-03-19
* Fix for castspell command ([#2010](https://github.com/EQEmu/Server/pull/2010)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-18
* Fix issue where #advnpcspawn addspawn does not add spawn sometimes. ([#2247](https://github.com/EQEmu/Server/pull/2247)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
* Fix issue where you can set your title to titles you don't have. ([#1917](https://github.com/EQEmu/Server/pull/1917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-30
* Fix issue with Bot::LoadAndSpawnAllZonedBots. ([#2733](https://github.com/EQEmu/Server/pull/2733)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
* Fix issue with mobs summoning PCs into ceilings ([#1921](https://github.com/EQEmu/Server/pull/1921)) ([noudess](https://github.com/noudess)) 2022-01-30
* Fix loading world shared task state ([#2398](https://github.com/EQEmu/Server/pull/2398)) ([hgtw](https://github.com/hgtw)) 2022-08-28
* Fix luamod GetExperienceForKill return value ([Cole-SoD](https://github.com/Cole-SoD)) 2023-01-12
* Fix memory leak in ucs ([#2409](https://github.com/EQEmu/Server/pull/2409)) ([hgtw](https://github.com/hgtw)) 2022-09-03
* Fix miscellaneous memory leaks related to EQApplicationPacket and it's pBuffer ([#2262](https://github.com/EQEmu/Server/pull/2262)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
* Fix null pointer crash on zones that have not booted a zone yet with #reload commands or anything that calls GetZoneDescription ([#2231](https://github.com/EQEmu/Server/pull/2231)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
* Fix possible crash in ProcessSpecialAbilities. ([#2630](https://github.com/EQEmu/Server/pull/2630)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
* Fix possible crash with zone name methods. ([#2055](https://github.com/EQEmu/Server/pull/2055)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
* Fix possible issue where variables have the same name. ([#2156](https://github.com/EQEmu/Server/pull/2156)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
* Fix quest::updatespawntimer() Perl croak. ([#1947](https://github.com/EQEmu/Server/pull/1947)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-26
* Fix recipient sound (vtell) on non-player races ([#2066](https://github.com/EQEmu/Server/pull/2066)) ([noudess](https://github.com/noudess)) 2022-04-02
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
* Fix stack leaks in Lua events #2254 ([hgtw](https://github.com/hgtw)) 2022-06-09
* Fix trading with bots when in an illusion. ([#2645](https://github.com/EQEmu/Server/pull/2645)) ([nytmyr](https://github.com/nytmyr)) 2022-12-15
* Fix two invalid data accesses in zone/client.cpp ([#2238](https://github.com/EQEmu/Server/pull/2238)) ([Quintinon](https://github.com/Quintinon)) 2022-06-07
* Fixed Spell Logic for Bot Nukes ([#2481](https://github.com/EQEmu/Server/pull/2481)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
* Fixed message on promote/demote permissions check. ([#2700](https://github.com/EQEmu/Server/pull/2700)) ([Valorith](https://github.com/Valorith)) 2023-01-02
* Fixed several instances of incorrect comparision - & executes after == ([#2025](https://github.com/EQEmu/Server/pull/2025)) ([noudess](https://github.com/noudess)) 2022-03-07
* Force NPCs to respect special ability 24 and 50 when set on player pets ([#2059](https://github.com/EQEmu/Server/pull/2059)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-16
* Free return value of ZoneDatabase::LoadTraderItemWithCharges() ([#2264](https://github.com/EQEmu/Server/pull/2264)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
* Hacker_Str was causing sql errors - Non Escaped ([#2251](https://github.com/EQEmu/Server/pull/2251)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
* Handle memory leaks from return value of Client::GetTraderItems() ([#2266](https://github.com/EQEmu/Server/pull/2266)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
* Handle_OP_AugmentItem could cause Zone crash ([#2750](https://github.com/EQEmu/Server/pull/2750)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
* HasPet() Zone Crashes ([#2744](https://github.com/EQEmu/Server/pull/2744)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
* Illusions will now properly display armor to other clients when they zone in. ([#1958](https://github.com/EQEmu/Server/pull/1958)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-04
* Instrument Mods should not affect spells that change model size. ([#2072](https://github.com/EQEmu/Server/pull/2072)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-13
* Invisible will display as dropped now on air pets when they attack. ([#2042](https://github.com/EQEmu/Server/pull/2042)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
* IsDamage test for lifetap was not complete. ([#2213](https://github.com/EQEmu/Server/pull/2213)) ([noudess](https://github.com/noudess)) 2022-05-27
* Limit merchant temp item list to zone and instance ([#2346](https://github.com/EQEmu/Server/pull/2346)) ([mackal](https://github.com/mackal)) 2022-07-31
* Lua GetBlockNextSpell() no return. ([#2151](https://github.com/EQEmu/Server/pull/2151)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Make Perl TakeMoneyFromPP int64 ([#2158](https://github.com/EQEmu/Server/pull/2158)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
* Missing break ([#2031](https://github.com/EQEmu/Server/pull/2031)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-04
* Move EVENT_SPAWN for adding NPCs back to original spot, also add NPCs… ([#2749](https://github.com/EQEmu/Server/pull/2749)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-17
* NPC Constructor was passing hp_regen_per_second out of order to Mob(). ([#2681](https://github.com/EQEmu/Server/pull/2681)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-29
* NPC::CountItem and Corpse::CountItem 0 Charge Item Fix. ([#1959](https://github.com/EQEmu/Server/pull/1959)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-04
* NPC::GetNPCStat has no default return. ([#2150](https://github.com/EQEmu/Server/pull/2150)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* NPCs were getting weapon proc added twice ([#2277](https://github.com/EQEmu/Server/pull/2277)) ([noudess](https://github.com/noudess)) 2022-07-07
* Objects::GetTiltX() and Objects::GetTiltY() Perl Croak Typos. ([#2028](https://github.com/EQEmu/Server/pull/2028)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
* PR 1982 ([#1985](https://github.com/EQEmu/Server/pull/1985)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
* PR 2032 would lock client on casting fail as written ([#2038](https://github.com/EQEmu/Server/pull/2038)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
* Remove StringUtilTest::EscapeStringMemoryTest ([#2310](https://github.com/EQEmu/Server/pull/2310)) ([mackal](https://github.com/mackal)) 2022-07-15
* Remove Unnecessary Attack Log ([#2643](https://github.com/EQEmu/Server/pull/2643)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
* Remove unnecessary log messages. ([#2642](https://github.com/EQEmu/Server/pull/2642)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
* Removed Lua Event Argument Dispatch. ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
* Resolve Warning due to Virtual Mob Method GetInv() ([#2650](https://github.com/EQEmu/Server/pull/2650)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-19
* Resolve XP Calculation Bug introduced w/ recent Rule addition ([#2703](https://github.com/EQEmu/Server/pull/2703)) ([Valorith](https://github.com/Valorith)) 2023-01-07
* Resolve logic error in Raid::QueueClients ([#2404](https://github.com/EQEmu/Server/pull/2404)) ([mackal](https://github.com/mackal)) 2022-09-01
* Resolve subroutine redefinition due to bot methods. ([#2117](https://github.com/EQEmu/Server/pull/2117)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Restore missing messages for lifetap and dmg spells. ([#2057](https://github.com/EQEmu/Server/pull/2057)) ([noudess](https://github.com/noudess)) 2022-04-14
* Shared Memory Faction Association Typo ([#2419](https://github.com/EQEmu/Server/pull/2419)) ([mackal](https://github.com/mackal)) 2022-09-03
* Spell Buckets/Globals SQL Escape. ([#2019](https://github.com/EQEmu/Server/pull/2019)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-26
* Spell Buckets/Globals did not allow string-based values. ([#2043](https://github.com/EQEmu/Server/pull/2043)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-09
* Stop skill ups on Charmed NPCs. ([#2249](https://github.com/EQEmu/Server/pull/2249)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-10
* Summon Companion causing pets to warps away. ([#1972](https://github.com/EQEmu/Server/pull/1972)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-08
* Touch Of Vinitras was ignoring pet DT rule ([#2469](https://github.com/EQEmu/Server/pull/2469)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-03
* Tradeskill Autocombine MinSkill ([#2260](https://github.com/EQEmu/Server/pull/2260)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
* Tradeskill Item 0 Error ([#2256](https://github.com/EQEmu/Server/pull/2256)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
* Zone Flags Regression ([#2760](https://github.com/EQEmu/Server/pull/2760)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
* checking casting_spell_slot before its defined is bad ([#2013](https://github.com/EQEmu/Server/pull/2013)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-20
* manifest for db version 9176 had incorrect field name ([#2062](https://github.com/EQEmu/Server/pull/2062)) ([noudess](https://github.com/noudess)) 2022-03-19
* quest::MovePCInstance() Arguments Fix. ([#2020](https://github.com/EQEmu/Server/pull/2020)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-27
### Hotfix
* Add Bazaar portal discs to SQL ([Akkadius](https://github.com/Akkadius)) 2022-09-05
* Add discord_webhooks to server tables ([Akkadius](https://github.com/Akkadius)) 2022-07-03
* Blocks are nested too deeply. ([#2689](https://github.com/EQEmu/Server/pull/2689)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Cleanup #questerrors Command. ([#2116](https://github.com/EQEmu/Server/pull/2116)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
* Compiling fails on FMT 9.1 with Bots ([#2665](https://github.com/EQEmu/Server/pull/2665)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-21
* Correct database call to point to the content_db connection ([Akkadius](https://github.com/Akkadius)) 2022-06-12
* Corrected misnamed Database Query file for Experience Toggle ([#2683](https://github.com/EQEmu/Server/pull/2683)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-31
* Faction associations file naming / lock consistency ([Akkadius](https://github.com/Akkadius)) 2022-09-05
* Fix DB version merge ([Akkadius](https://github.com/Akkadius)) 2022-05-08
* Fix door click crash issue if destination zone doesn't exist ([Akkadius](https://github.com/Akkadius)) 2023-01-20
* Fix issue with Bot Loading with 0 Health causing buffs to be lost. ([#2552](https://github.com/EQEmu/Server/pull/2552)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-18
* Fix lua mod load path ([Akkadius](https://github.com/Akkadius)) 2022-09-29
* Fix merge issue ([Akkadius](https://github.com/Akkadius)) 2022-07-14
* Fix path load ordering for CLI commands ([Akkadius](https://github.com/Akkadius)) 2022-10-16
* Fix potential race for crash dumps (Linux) ([Akkadius](https://github.com/Akkadius)) 2022-07-31
* Fix regression caused by #2129 ([Akkadius](https://github.com/Akkadius)) 2022-05-09
* Flipped positive / negative values for legacy_combat.lua ([Akkadius](https://github.com/Akkadius)) 2022-06-09
* Force collation on conversion script ([Akkadius](https://github.com/Akkadius)) 2022-09-28
* Instances Repository Fix ([#2576](https://github.com/EQEmu/Server/pull/2576)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
* Login Server failing to compile on Windows. ([#2758](https://github.com/EQEmu/Server/pull/2758)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
* Lua Parser Needs Lua_ItemInst ([#2696](https://github.com/EQEmu/Server/pull/2696)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Make sure we have a proper split size before assuming we can split it ([Akkadius](https://github.com/Akkadius)) 2023-01-20
* Move discord_webhooks to state tables because we don't want webhooks being exported ([Akkadius](https://github.com/Akkadius)) 2022-07-03
* Possible windows compile fix ([Akkadius](https://github.com/Akkadius)) 2022-07-07
* Possible windows compile fix take 2 ([Akkadius](https://github.com/Akkadius)) 2022-07-07
* Remove appveyor fetch bots ([Akkadius](https://github.com/Akkadius)) 2023-01-21
* Remove expansion field from account for those who have it ([#2357](https://github.com/EQEmu/Server/pull/2357)) ([Akkadius](https://github.com/Akkadius)) 2022-08-01
* Resolve Zone Crashing when grouped with Bots. ([#2747](https://github.com/EQEmu/Server/pull/2747)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-16
* Resolve issue with Bot Casting after zoning. ([#2617](https://github.com/EQEmu/Server/pull/2617)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
* Return weather_type_map ([Akkadius](https://github.com/Akkadius)) 2022-10-14
* SQL Update ([Akkadius](https://github.com/Akkadius)) 2022-07-31
* Shared Memory Protection Fixes ([Akkadius](https://github.com/Akkadius)) 2022-07-27
* Windows compile fix take 3 (final) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
* fix manifest ([Akkadius](https://github.com/Akkadius)) 2022-07-16
### Logging
* Add stack trace in code paths that shouldn't occur ([#2453](https://github.com/EQEmu/Server/pull/2453)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
* Cleanup AI Logging Events ([#2615](https://github.com/EQEmu/Server/pull/2615)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
* Fix log messages to final damage values ([#2056](https://github.com/EQEmu/Server/pull/2056)) ([noudess](https://github.com/noudess)) 2022-03-14
* Fix zoning log typo ([#2478](https://github.com/EQEmu/Server/pull/2478)) ([Akkadius](https://github.com/Akkadius)) 2022-10-11
* Force crash logs to always be on regardless of setting ([#2762](https://github.com/EQEmu/Server/pull/2762)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
* Improvements to GM Say Logging ([#2765](https://github.com/EQEmu/Server/pull/2765)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
* Logging Improvements ([#2755](https://github.com/EQEmu/Server/pull/2755)) ([Akkadius](https://github.com/Akkadius)) 2023-01-18
* More AI Logging Cleanup ([#2616](https://github.com/EQEmu/Server/pull/2616)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-10
* Netcode Logging Unify ([#2443](https://github.com/EQEmu/Server/pull/2443)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
* Remove function prefixes ([#2766](https://github.com/EQEmu/Server/pull/2766)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
* Remove loginserver unhandled error ([#2458](https://github.com/EQEmu/Server/pull/2458)) ([Akkadius](https://github.com/Akkadius)) 2022-09-29
* Reset stream so we don't bold the whole line ([Akkadius](https://github.com/Akkadius)) 2023-01-18
* Table Injection - Member Variable Cleanup ([#2281](https://github.com/EQEmu/Server/pull/2281)) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
* Update BUILD_LOGGING=false Blank Aliases ([#2083](https://github.com/EQEmu/Server/pull/2083)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
### Luamod
* Add CalcSpellEffectValue_formula to luamods ([#2721](https://github.com/EQEmu/Server/pull/2721)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-11
### Mercs
* Add Mercenary Support ([#2745](https://github.com/EQEmu/Server/pull/2745)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-17
### Optimization
* Handle channel name filter checks in memory ([#2767](https://github.com/EQEmu/Server/pull/2767)) ([Valorith](https://github.com/Valorith)) 2023-01-20
### QS
* Database class name change ([#2743](https://github.com/EQEmu/Server/pull/2743)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
### Quest API
* Add AddAISpellEffect(spell_effect_id, base_value, limit_value, max_value) and RemoveAISpellEffect(spell_effect_id) to Lua. ([#1981](https://github.com/EQEmu/Server/pull/1981)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-09
* Add AddItem() to Perl/Lua. ([#2054](https://github.com/EQEmu/Server/pull/2054)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
* Add AddPlatinum(), GetCarriedPlatinum() and TakePlatinum() to Perl/Lua. ([#2079](https://github.com/EQEmu/Server/pull/2079)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
* Add Area Damage Methods to Perl/Lua. ([#2549](https://github.com/EQEmu/Server/pull/2549)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
* Add Augment Slot Type/Visible to GetItemStat ([#2686](https://github.com/EQEmu/Server/pull/2686)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Add Bot Methods to Lua. ([#2731](https://github.com/EQEmu/Server/pull/2731)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
* Add Bot::Camp() to Perl/Lua. ([#2718](https://github.com/EQEmu/Server/pull/2718)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
* Add BuffCount() Overloads to Perl/Lua. ([#2679](https://github.com/EQEmu/Server/pull/2679)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-29
* Add CampAllBots() to Perl/Lua. ([#2732](https://github.com/EQEmu/Server/pull/2732)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
* Add Charges/Augment/Attuned Support to Varlink. ([#2685](https://github.com/EQEmu/Server/pull/2685)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Add CheckNameFilter to Perl/Lua. ([#2175](https://github.com/EQEmu/Server/pull/2175)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-20
* Add Client Augment Events to Perl/Lua. ([#2735](https://github.com/EQEmu/Server/pull/2735)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
* Add Client Spell Methods to Perl/Lua. ([#2550](https://github.com/EQEmu/Server/pull/2550)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Add CloneAppearance() to Perl/Lua. ([#2531](https://github.com/EQEmu/Server/pull/2531)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add CopyHateList() to Perl/Lua. ([#2623](https://github.com/EQEmu/Server/pull/2623)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
* Add Corpse::AddItem overloads for Lua ([#2509](https://github.com/EQEmu/Server/pull/2509)) ([hgtw](https://github.com/hgtw)) 2022-10-29
* Add Despawn Events to Perl/Lua. ([#2707](https://github.com/EQEmu/Server/pull/2707)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-07
* Add DoAnim Overloads to Perl/Lua. ([#2627](https://github.com/EQEmu/Server/pull/2627)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
* Add DoAugmentSlotsMatch() to Perl/Lua. ([#2687](https://github.com/EQEmu/Server/pull/2687)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Add DoesAugmentFit() to Perl/Lua. ([#2688](https://github.com/EQEmu/Server/pull/2688)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
* Add Door Methods to Perl/Lua. ([#2724](https://github.com/EQEmu/Server/pull/2724)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-12
* Add EVENT_AA_BUY and EVENT_AA_GAIN to Perl/Lua. ([#2504](https://github.com/EQEmu/Server/pull/2504)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
* Add EVENT_BOT_CREATE to Perl/Lua ([#2713](https://github.com/EQEmu/Server/pull/2713)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-09
* Add EVENT_CAST_ON exports to EVENT_CAST and EVENT_CAST_BEGIN. ([#2051](https://github.com/EQEmu/Server/pull/2051)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
* Add EVENT_EQUIP_ITEM_CLIENT and EVENT_UNEQUIP_ITEM_CLIENT to Perl/Lua. ([#2015](https://github.com/EQEmu/Server/pull/2015)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-23
* Add EVENT_GM_COMMAND to Perl/Lua. ([#2634](https://github.com/EQEmu/Server/pull/2634)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
* Add EVENT_LEVEL_DOWN to Perl/Lua. ([#2620](https://github.com/EQEmu/Server/pull/2620)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
* Add EVENT_PAYLOAD to Perl/Lua. ([#2611](https://github.com/EQEmu/Server/pull/2611)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
* Add EVENT_SKILL_UP & EVENT_LANGUAGE_SKILL_UP to Perl/Lua ([#2076](https://github.com/EQEmu/Server/pull/2076)) ([nytmyr](https://github.com/nytmyr)) 2022-04-25
* Add Entity Variable Methods to Perl/Lua. ([#2609](https://github.com/EQEmu/Server/pull/2609)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
* Add Fling Overloads to Perl/Lua. ([#2622](https://github.com/EQEmu/Server/pull/2622)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
* Add GetAugmentIDsBySlotID() to Perl/Lua. ([#2673](https://github.com/EQEmu/Server/pull/2673)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
* Add GetAverageLevel() to Perl/Lua. ([#2524](https://github.com/EQEmu/Server/pull/2524)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add GetBotItem() and GetBotItemIDBySlot() to Perl/Lua. ([#2350](https://github.com/EQEmu/Server/pull/2350)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-31
* Add GetBotListByCharacterID() to Perl/Lua. ([#2069](https://github.com/EQEmu/Server/pull/2069)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
* Add GetBotListByClientName() Class Overload to Perl/Lua. ([#2577](https://github.com/EQEmu/Server/pull/2577)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
* Add GetBotListByClientName(client_name) to Perl/Lua. ([#2064](https://github.com/EQEmu/Server/pull/2064)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-23
* Add GetEnvironmentalDamageName() to Perl/Lua. ([#1964](https://github.com/EQEmu/Server/pull/1964)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
* Add GetGMStatus() to Perl/Lua. ([#2448](https://github.com/EQEmu/Server/pull/2448)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
* Add GetGuildPublicNote() to Perl/Lua. ([#2608](https://github.com/EQEmu/Server/pull/2608)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
* Add GetHealAmount() and GetSpellDamage() to Perl/Lua. ([#2165](https://github.com/EQEmu/Server/pull/2165)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-11
* Add GetLeader() and GetLeaderName() to Perl/Lua. ([#2701](https://github.com/EQEmu/Server/pull/2701)) ([Valorith](https://github.com/Valorith)) 2023-01-04
* Add GetLowestLevel() to Perl. ([#2517](https://github.com/EQEmu/Server/pull/2517)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
* Add GetRandomBot() to Perl/Lua ([#2543](https://github.com/EQEmu/Server/pull/2543)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
* Add GetRandomClient(), GetRandomMob() and GetRandomNPC() overloads to Perl/Lua. ([#2541](https://github.com/EQEmu/Server/pull/2541)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add GetRandomMob() and GetRandomNPC() to Perl/Lua. ([#2006](https://github.com/EQEmu/Server/pull/2006)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
* Add GetSkillDmgAmt() to Perl. ([#2365](https://github.com/EQEmu/Server/pull/2365)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-10
* Add GetUltimateOwner() to Perl/Lua. ([#2516](https://github.com/EQEmu/Server/pull/2516)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
* Add Goto Player Teleport Methods. ([#2379](https://github.com/EQEmu/Server/pull/2379)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
* Add Group/Raid Overloads to Perl/Lua. ([#2587](https://github.com/EQEmu/Server/pull/2587)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Add Group/Raid overloads to Perl/Lua. ([#2526](https://github.com/EQEmu/Server/pull/2526)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add HasBotSpellEntry() to Perl/Lua. ([#2563](https://github.com/EQEmu/Server/pull/2563)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
* Add Hotzone Methods to Perl/Lua. ([#2558](https://github.com/EQEmu/Server/pull/2558)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Add Instance ID/Version exports to EVENT_ZONE. ([#2502](https://github.com/EQEmu/Server/pull/2502)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
* Add Instance Methods to Perl/Lua. ([#2573](https://github.com/EQEmu/Server/pull/2573)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
* Add IsAttackAllowed() to Perl/Lua. ([#2672](https://github.com/EQEmu/Server/pull/2672)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
* Add IsRaining() and IsSnowing() to Perl/Lua. ([#2477](https://github.com/EQEmu/Server/pull/2477)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-14
* Add IsRareSpawn() to Perl/Lua. ([#2338](https://github.com/EQEmu/Server/pull/2338)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-30
* Add Lua handlers for zone controller events ([#2514](https://github.com/EQEmu/Server/pull/2514)) ([hgtw](https://github.com/hgtw)) 2022-11-05
* Add Marquee methods to Perl/Lua. ([#2544](https://github.com/EQEmu/Server/pull/2544)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
* Add MaxSkills() to Perl/Lua. ([#2621](https://github.com/EQEmu/Server/pull/2621)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
* Add Merchant Events to Perl/Lua. ([#2452](https://github.com/EQEmu/Server/pull/2452)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
* Add Mob Hate Methods to Perl/Lua. ([#2548](https://github.com/EQEmu/Server/pull/2548)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
* Add Overloads to MoveZone Methods in Perl/Lua. ([#2551](https://github.com/EQEmu/Server/pull/2551)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
* Add Owner methods to Perl/Lua. ([#2542](https://github.com/EQEmu/Server/pull/2542)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add Popup methods to Perl/Lua. ([#2533](https://github.com/EQEmu/Server/pull/2533)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add Proximity Range Methods to Perl/Lua. ([#2572](https://github.com/EQEmu/Server/pull/2572)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
* Add RandomizeFeature() overloads to Perl/Lua. ([#2532](https://github.com/EQEmu/Server/pull/2532)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add Recipe Methods ([#2393](https://github.com/EQEmu/Server/pull/2393)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-23
* Add ResetAlternateAdvancementRank() to Perl/Lua. ([#2510](https://github.com/EQEmu/Server/pull/2510)) ([hgtw](https://github.com/hgtw)) 2022-10-29
* Add ResetDecayTimer() to Perl/Lua. ([#2520](https://github.com/EQEmu/Server/pull/2520)) ([hgtw](https://github.com/hgtw)) 2022-11-06
* Add SendGMCommand() to Perl/Lua. ([#2527](https://github.com/EQEmu/Server/pull/2527)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add SendPath() to Perl/Lua. ([#2740](https://github.com/EQEmu/Server/pull/2740)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
* Add SignalAllBotsByOwnerName() to Perl/Lua. ([#2730](https://github.com/EQEmu/Server/pull/2730)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
* Add SplitMoney() with Client splitter to Perl. ([#2525](https://github.com/EQEmu/Server/pull/2525)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
* Add TaskSelector to Perl/Lua. ([#2177](https://github.com/EQEmu/Server/pull/2177)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
* Add Time String to Seconds Method to Perl/Lua. ([#2580](https://github.com/EQEmu/Server/pull/2580)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Add TrackNPC to Perl/Lua. ([#2272](https://github.com/EQEmu/Server/pull/2272)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-29
* Add WearChange Overloads to Perl/Lua. ([#2600](https://github.com/EQEmu/Server/pull/2600)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
* Add Zone Flag Methods to Perl/Lua. ([#2574](https://github.com/EQEmu/Server/pull/2574)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
* Add apis to end shared tasks ([#2521](https://github.com/EQEmu/Server/pull/2521)) ([hgtw](https://github.com/hgtw)) 2022-11-06
* Add caster_id and caster_level export to EVENT_CAST_ON in Perl/Lua. ([#2049](https://github.com/EQEmu/Server/pull/2049)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-11
* Add commify to Perl/Lua. ([#2099](https://github.com/EQEmu/Server/pull/2099)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-03
* Add inventory->CountItemEquippedByID(item_id) and inventory->HasItemEquippedByID(item_id) to Perl/Lua. ([#1963](https://github.com/EQEmu/Server/pull/1963)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-06
* Add missing methods/package.adds to Perl API. ([#2287](https://github.com/EQEmu/Server/pull/2287)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
* Add multiple inventory method short hands to client. ([#2078](https://github.com/EQEmu/Server/pull/2078)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
* Add option to Ignore Mods to CalcEXP ([#2704](https://github.com/EQEmu/Server/pull/2704)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-06
* Adjustment to depop_all function. ([#2595](https://github.com/EQEmu/Server/pull/2595)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
* Allow CreateInstance to be used without a Client initiator. ([#2399](https://github.com/EQEmu/Server/pull/2399)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-28
* Allow EVENT_ZONE to be parsed as non-zero to prevent zoning. ([#2052](https://github.com/EQEmu/Server/pull/2052)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
* Allow scripts to prevent door click ([#2327](https://github.com/EQEmu/Server/pull/2327)) ([hgtw](https://github.com/hgtw)) 2022-07-27
* Cleanup Proximity Events ([#2697](https://github.com/EQEmu/Server/pull/2697)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
* Cleanup Signal Methods in Perl/Lua. ([#2604](https://github.com/EQEmu/Server/pull/2604)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
* Expand Bot quest API functionality. ([#2096](https://github.com/EQEmu/Server/pull/2096)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
* Expand SaveGuardSpot ([#2258](https://github.com/EQEmu/Server/pull/2258)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
* Export corpse in EVENT_DEATH_COMPLETE ([#2519](https://github.com/EQEmu/Server/pull/2519)) ([hgtw](https://github.com/hgtw)) 2022-11-06
* Export killed XYZH to EVENT_DEATH_ZONE in Perl. ([#2050](https://github.com/EQEmu/Server/pull/2050)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
* Fix Lua Door/Object Create Methods. ([#2633](https://github.com/EQEmu/Server/pull/2633)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
* Fix Perl EVENT_HP double parsing in Spire. ([#2585](https://github.com/EQEmu/Server/pull/2585)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
* Fix lua task selector count when over max ([#2353](https://github.com/EQEmu/Server/pull/2353)) ([hgtw](https://github.com/hgtw)) 2022-07-31
* Fix missing arg in perl set_proximity ([#2291](https://github.com/EQEmu/Server/pull/2291)) ([hgtw](https://github.com/hgtw)) 2022-07-09
* Fix parameters in some Perl worldwide methods. ([#2224](https://github.com/EQEmu/Server/pull/2224)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
* Let HasQuestSub check encounters ([#2435](https://github.com/EQEmu/Server/pull/2435)) ([hgtw](https://github.com/hgtw)) 2022-09-20
* Perl Doors Fix. ([#2288](https://github.com/EQEmu/Server/pull/2288)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
* Perl Money Fixes. ([#2098](https://github.com/EQEmu/Server/pull/2098)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
* Send delivered task items in trade events ([#2518](https://github.com/EQEmu/Server/pull/2518)) ([hgtw](https://github.com/hgtw)) 2022-11-06
* Use Floating Point for CameraEffect Intensity ([#2337](https://github.com/EQEmu/Server/pull/2337)) ([hgtw](https://github.com/hgtw)) 2022-07-31
* Use binding library for perl apis ([#2216](https://github.com/EQEmu/Server/pull/2216)) ([hgtw](https://github.com/hgtw)) 2022-07-04
### Rules
* Add Backstab Rules ([#2666](https://github.com/EQEmu/Server/pull/2666)) ([Valorith](https://github.com/Valorith)) 2022-12-21
* Add Frontal Stun Immunity Rules. ([#2217](https://github.com/EQEmu/Server/pull/2217)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
* Add Keep Level on Death ([#2319](https://github.com/EQEmu/Server/pull/2319)) ([trentdm](https://github.com/trentdm)) 2022-07-30
* Add LDoN Loot Count Modifier Rule ([#2694](https://github.com/EQEmu/Server/pull/2694)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
* Add ManaOnDeath and EndurOnDeath ([#2661](https://github.com/EQEmu/Server/pull/2661)) ([fryguy503](https://github.com/fryguy503)) 2022-12-20
* Add Rule to Disable NPC Last Names. ([#2227](https://github.com/EQEmu/Server/pull/2227)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
* Add Rule to Enable Tells with #hideme ([#2358](https://github.com/EQEmu/Server/pull/2358)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-04
* Add Rule to allow Assassinate on non-Humanoid body types. ([#2331](https://github.com/EQEmu/Server/pull/2331)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
* Add Rule to allow Headshots on non-Humanoid body types. ([#2329](https://github.com/EQEmu/Server/pull/2329)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
* Add Rules to disable various item functionalities and cleanup data types. ([#2225](https://github.com/EQEmu/Server/pull/2225)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
* Add Spells:BuffsFadeOnDeath. ([#2200](https://github.com/EQEmu/Server/pull/2200)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Add Spells:IllusionsAlwaysPersist. ([#2199](https://github.com/EQEmu/Server/pull/2199)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
* Add Toggle for Warrior Shielding ([#2496](https://github.com/EQEmu/Server/pull/2496)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-22
* Add adjustment for zone forage. ([#2330](https://github.com/EQEmu/Server/pull/2330)) ([fryguy503](https://github.com/fryguy503)) 2022-07-30
* Add rule for NPC Level Based Buff Restrictions. ([#2708](https://github.com/EQEmu/Server/pull/2708)) ([noudess](https://github.com/noudess)) 2023-01-15
* Add rule to allow players to permanently save chat channels to database, up to a limit. ([#2706](https://github.com/EQEmu/Server/pull/2706)) ([Valorith](https://github.com/Valorith)) 2023-01-19
* Change TradeskillUp Rules to be Floats ([#2674](https://github.com/EQEmu/Server/pull/2674)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-25
* Cleanup all unused rules. ([#2184](https://github.com/EQEmu/Server/pull/2184)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
* Rule Gate Pet Zoning ([#2625](https://github.com/EQEmu/Server/pull/2625)) ([fryguy503](https://github.com/fryguy503)) 2022-12-07
* Rule to allow cap on % XP gain per kill ([#2667](https://github.com/EQEmu/Server/pull/2667)) ([Valorith](https://github.com/Valorith)) 2022-12-25
* Update logic checks everywhere for FVNoDropFlag. ([#2179](https://github.com/EQEmu/Server/pull/2179)) ([Quintinon](https://github.com/Quintinon)) 2022-07-30
### SQL
* Bugs Table Migration (#2602) ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([joligario](https://github.com/joligario)) 2022-12-01
* Update 2023_01_15_merc_data.sql ([#2763](https://github.com/EQEmu/Server/pull/2763)) ([joligario](https://github.com/joligario)) 2023-01-20
### UCS
* Auto Client Reconnection ([#2154](https://github.com/EQEmu/Server/pull/2154)) ([Akkadius](https://github.com/Akkadius)) 2022-05-08
### Websocket
* Fix cpp20/gcc11 compile failure ([#2737](https://github.com/EQEmu/Server/pull/2737)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
### Zone Flags
* Use database connection, not content connection ([#2759](https://github.com/EQEmu/Server/pull/2759)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
+1 -10
View File
@@ -23,6 +23,7 @@ IF(MSVC)
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
ELSE(MSVC)
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC)
@@ -122,7 +123,6 @@ ENDIF()
MESSAGE(STATUS "**************************************************")
#options
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
@@ -176,10 +176,6 @@ IF(EQEMU_COMMANDS_LOGGING)
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
ENDIF(EQEMU_COMMANDS_LOGGING)
IF(EQEMU_ENABLE_BOTS)
ADD_DEFINITIONS(-DBOTS)
ENDIF(EQEMU_ENABLE_BOTS)
#database
IF(MySQL_FOUND AND MariaDB_FOUND)
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
@@ -343,11 +339,6 @@ INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
# silence obnoxious deprecation message
ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
IF(EQEMU_BUILD_LOGGING)
ADD_DEFINITIONS(-DBUILD_LOGGING)
ENDIF()
IF(TLS_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
+3 -3
View File
@@ -1,7 +1,7 @@
# EQEmulator Core Server
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|:---:|:---:|:---:|
|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Build status](https://ci.appveyor.com/api/projects/status/v3utuu0dttm2cqd0?svg=true)](https://ci.appveyor.com/project/KimLS/server) |[![Build status](https://ci.appveyor.com/api/projects/status/scr25kmntx36c1ub?svg=true)](https://ci.appveyor.com/project/KimLS/server-87crp) |
| Drone (Linux x64) | Drone (Windows x64) |
|:---:|:---:|
|[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |
***
-21
View File
@@ -1,21 +0,0 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
configuration: RelWithDebInfo
clone_folder: c:\projects\eqemu
init:
- ps: git config --global core.autocrlf input
cache: c:\tools\vcpkg\installed\
before_build:
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
build:
project: C:\projects\eqemu\build\EQEmu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: >-
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
appveyor PushArtifact build_x64-bots.zip
-21
View File
@@ -1,21 +0,0 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
configuration: RelWithDebInfo
clone_folder: c:\projects\eqemu
init:
- ps: git config --global core.autocrlf input
cache: c:\tools\vcpkg\installed\
before_build:
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=OFF -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
build:
project: C:\projects\eqemu\build\EQEmu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: >-
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
appveyor PushArtifact build_x64-no-bots.zip
+18 -8
View File
@@ -33,9 +33,11 @@ SET(common_sources
eq_stream_proxy.cpp
eqtime.cpp
event_sub.cpp
events/player_event_logs.cpp
events/player_event_discord_formatter.cpp
expedition_lockout_timer.cpp
extprofile.cpp
discord_manager.cpp
discord/discord_manager.cpp
faction.cpp
file.cpp
guild_base.cpp
@@ -182,6 +184,8 @@ SET(repositories
repositories/base/base_char_create_combinations_repository.h
repositories/base/base_char_create_point_allocations_repository.h
repositories/base/base_char_recipe_list_repository.h
repositories/base/base_chatchannels_repository.h
repositories/base/base_chatchannel_reserved_names_repository.h
repositories/base/base_completed_shared_tasks_repository.h
repositories/base/base_completed_shared_task_activity_state_repository.h
repositories/base/base_completed_shared_task_members_repository.h
@@ -196,7 +200,6 @@ SET(repositories
repositories/base/base_dynamic_zones_repository.h
repositories/base/base_dynamic_zone_members_repository.h
repositories/base/base_dynamic_zone_templates_repository.h
repositories/base/base_eventlog_repository.h
repositories/base/base_expeditions_repository.h
repositories/base/base_expedition_lockouts_repository.h
repositories/base/base_faction_association_repository.h
@@ -216,7 +219,6 @@ SET(repositories
repositories/base/base_guilds_repository.h
repositories/base/base_guild_ranks_repository.h
repositories/base/base_guild_relations_repository.h
repositories/base/base_hackers_repository.h
repositories/base/base_horses_repository.h
repositories/base/base_instance_list_repository.h
repositories/base/base_instance_list_player_repository.h
@@ -262,6 +264,8 @@ 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_log_settings_repository.h
repositories/base/base_player_event_logs_repository.h
repositories/base/base_quest_globals_repository.h
repositories/base/base_raid_details_repository.h
repositories/base/base_raid_members_repository.h
@@ -358,6 +362,8 @@ SET(repositories
repositories/char_create_combinations_repository.h
repositories/char_create_point_allocations_repository.h
repositories/char_recipe_list_repository.h
repositories/chatchannels_repository.h
repositories/chatchannel_reserved_names_repository.h
repositories/completed_shared_tasks_repository.h
repositories/completed_shared_task_activity_state_repository.h
repositories/completed_shared_task_members_repository.h
@@ -372,7 +378,6 @@ SET(repositories
repositories/dynamic_zones_repository.h
repositories/dynamic_zone_members_repository.h
repositories/dynamic_zone_templates_repository.h
repositories/eventlog_repository.h
repositories/expeditions_repository.h
repositories/expedition_lockouts_repository.h
repositories/faction_association_repository.h
@@ -392,7 +397,6 @@ SET(repositories
repositories/guilds_repository.h
repositories/guild_ranks_repository.h
repositories/guild_relations_repository.h
repositories/hackers_repository.h
repositories/horses_repository.h
repositories/instance_list_repository.h
repositories/instance_list_player_repository.h
@@ -438,6 +442,8 @@ SET(repositories
repositories/pets_equipmentset_repository.h
repositories/pets_equipmentset_entries_repository.h
repositories/player_titlesets_repository.h
repositories/player_event_log_settings_repository.h
repositories/player_event_logs_repository.h
repositories/quest_globals_repository.h
repositories/raid_details_repository.h
repositories/raid_members_repository.h
@@ -503,7 +509,7 @@ SET(common_headers
dbcore.h
deity.h
discord/discord.h
discord_manager.h
discord/discord_manager.h
dynamic_zone_base.h
emu_constants.h
emu_limits.h
@@ -526,6 +532,9 @@ SET(common_headers
eq_stream_locator.h
eq_stream_proxy.h
eqtime.h
events/player_event_logs.h
events/player_event_discord_formatter.h
events/player_events.h
errmsg.h
event_sub.h
expedition_lockout_timer.h
@@ -604,6 +613,7 @@ SET(common_headers
event/event_loop.h
event/task.h
event/timer.h
json/json_archive_single_line.h
json/json.h
json/json-forwards.h
net/console_server.h
@@ -652,12 +662,12 @@ SET(common_headers
patches/uf_limits.h
patches/uf_ops.h
patches/uf_structs.h
termcolor/rang.hpp
stacktrace/backward.hpp
StackWalker/StackWalker.h
util/memory_stream.h
util/directory.h
util/uuid.h
)
util/uuid.h)
SOURCE_GROUP(Event FILES
event/event_loop.h
+1
View File
@@ -20,6 +20,7 @@
#include "../common/types.h"
#define NO_CLASS 0
#define WARRIOR 1
#define CLERIC 2
#define PALADIN 3
+115 -5
View File
@@ -3,13 +3,96 @@
#include "crash.h"
#include "strings.h"
#include "process/process.h"
#include "http/httplib.h"
#include "http/uri.h"
#include "json/json.h"
#include "version.h"
#include "eqemu_config.h"
#include "serverinfo.h"
#include "rulesys.h"
#include "platform.h"
#include <cstdio>
#include <vector>
#if WINDOWS
#define popen _popen
#endif
void SendCrashReport(const std::string &crash_report)
{
// can configure multiple endpoints if need be
std::vector<std::string> endpoints = {
"http://spire.akkadius.com/api/v1/analytics/server-crash-report",
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
};
auto config = EQEmuConfig::get();
for (auto &e: endpoints) {
uri u(e);
std::string base_url = fmt::format("{}://{}", u.get_scheme(), u.get_host());
if (u.get_port()) {
base_url += fmt::format(":{}", u.get_port());
}
// client
httplib::Client r(base_url);
r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info
auto os = EQ::GetOS();
auto cpus = EQ::GetCPUs();
auto process_id = EQ::GetPID();
auto rss = EQ::GetRSS() / 1048576.0;
auto uptime = static_cast<uint32>(EQ::GetUptime());
// payload
Json::Value p;
p["platform_name"] = GetPlatformName();
p["crash_report"] = crash_report;
p["server_version"] = CURRENT_VERSION;
p["compile_date"] = COMPILE_DATE;
p["compile_time"] = COMPILE_TIME;
p["server_name"] = config->LongName;
p["server_short_name"] = config->ShortName;
p["uptime"] = uptime;
p["os_machine"] = os.machine;
p["os_release"] = os.release;
p["os_version"] = os.version;
p["os_sysname"] = os.sysname;
p["process_id"] = process_id;
p["rss_memory"] = rss;
p["cpus"] = cpus.size();
p["origination_info"] = "";
if (!LogSys.origination_info.zone_short_name.empty()) {
p["origination_info"] = fmt::format(
"{} ({}) instance_id [{}]",
LogSys.origination_info.zone_short_name,
LogSys.origination_info.zone_long_name,
LogSys.origination_info.instance_id
);
}
std::stringstream payload;
payload << p;
if (auto res = r.Post(e, payload.str(), "application/json")) {
if (res->status == 200) {
LogInfo("Sent crash report");
}
else {
LogError("Failed to send crash report to [{}]", e);
}
}
}
}
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
#include "StackWalker.h"
@@ -21,22 +104,30 @@ public:
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
virtual void OnOutput(LPCSTR szText) {
char buffer[4096];
for(int i = 0; i < 4096; ++i) {
if(szText[i] == 0) {
for (int i = 0; i < 4096; ++i) {
if (szText[i] == 0) {
buffer[i] = '\0';
break;
}
if(szText[i] == '\n' || szText[i] == '\r') {
if (szText[i] == '\n' || szText[i] == '\r') {
buffer[i] = ' ';
} else {
}
else {
buffer[i] = szText[i];
}
}
std::string line = buffer;
_lines.push_back(line);
Log(Logs::General, Logs::Crash, buffer);
StackWalker::OnOutput(szText);
}
const std::vector<std::string>& const GetLines() { return _lines; }
private:
std::vector<std::string> _lines;
};
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
@@ -110,7 +201,20 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
{
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
EQEmuStackWalker sw;
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
if (RuleB(Analytics, CrashReporting)) {
std::string crash_report;
auto& lines = sw.GetLines();
for (auto& line : lines) {
crash_report += line;
crash_report += "\n";
}
SendCrashReport(crash_report);
}
}
return EXCEPTION_EXECUTE_HANDLER;
@@ -181,12 +285,18 @@ void print_trace()
}
std::ifstream input(temp_output_file);
std::string crash_report;
for (std::string line; getline(input, line);) {
LogCrash("{}", line);
crash_report += fmt::format("{}\n", line);
}
std::remove(temp_output_file.c_str());
if (RuleB(Analytics, CrashReporting)) {
SendCrashReport(crash_report);
}
exit(1);
}
+28 -64
View File
@@ -71,11 +71,11 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
uint32 errnum= 0;
char errbuf[MYSQL_ERRMSG_SIZE];
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
LogError("[MySQL] Connection [{}] Failed to connect to database: Error [{}]", connection_label, errbuf);
LogError("Connection [{}] Failed to connect to database Error [{}]", connection_label, errbuf);
return false;
}
else {
LogInfo("[MySQL] Connection [{}] database [{}] at [{}]:[{}]", connection_label, database, host,port);
LogInfo("Connected to database [{}] [{}] @ [{}:{}]", connection_label, database, host,port);
return true;
}
}
@@ -391,15 +391,10 @@ bool Database::DeleteCharacter(char *character_name)
}
if (character_id <= 0) {
LogError("[DeleteCharacter] Invalid Character ID [{}]", character_name);
LogError("Invalid Character ID [{}]", character_name);
return false;
}
#ifdef BOTS
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", character_id); // note: only use of GetMobTypeById()
QueryDatabase(query);
#endif
std::string delete_type = "hard-deleted";
if (RuleB(Character, SoftDeletes)) {
delete_type = "soft-deleted";
@@ -418,21 +413,26 @@ bool Database::DeleteCharacter(char *character_name)
QueryDatabase(query);
#ifdef BOTS
query = fmt::format(
SQL(
UPDATE
bot_data
SET
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64)
WHERE
owner_id = '{}'
),
character_id
);
QueryDatabase(query);
LogInfo("[DeleteCharacter] character_name [{}] ({}) bots are being [{}]", character_name, character_id, delete_type);
#endif
if (RuleB(Bots, Enabled)) {
query = fmt::format(
SQL(
UPDATE
bot_data
SET
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64)
WHERE
owner_id = '{}'
),
character_id
);
QueryDatabase(query);
LogInfo(
"[DeleteCharacter] character_name [{}] ({}) bots are being [{}]",
character_name,
character_id,
delete_type
);
}
return true;
}
@@ -444,7 +444,7 @@ bool Database::DeleteCharacter(char *character_name)
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
}
LogInfo("[DeleteCharacter] character_name [{}] ({}) is being [{}]", character_name, character_id, delete_type);
LogInfo("character_name [{}] ({}) is being [{}]", character_name, character_id, delete_type);
return true;
}
@@ -975,6 +975,8 @@ bool Database::LoadVariables() {
varcache.Add(key, value);
}
LogInfo("Loaded [{}] variable(s)", Strings::Commify(std::to_string(results.RowCount())));
return true;
}
@@ -1279,44 +1281,6 @@ bool Database::MoveCharacterToZone(const char *charname, uint32 zone_id)
return results.RowsAffected() != 0;
}
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
return results.RowsAffected() != 0;
}
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
//Utilize the "hacker" table, but also give zone information.
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
auto results = QueryDatabase(query);
if (!results.Success())
{
return false;
}
return results.RowsAffected() != 0;
}
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const std::string &hacked, const char* zone) {
//Utilize the "hacker" table, but also give zone information.
auto query = fmt::format("INSERT INTO hackers(account, name, hacked, zone) values('{}', '{}', '{}', '{}')",
accountname, charactername, hacked, zone);
auto results = QueryDatabase(query);
if (!results.Success())
{
return false;
}
return results.RowsAffected() != 0;
}
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
{
uint16 race_cap = 0;
@@ -2354,7 +2318,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
uri request_uri(url);
LogHTTP(
"[SourceDatabaseTableFromUrl] parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
"parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
url,
request_uri.get_path(),
request_uri.get_host(),
@@ -2408,7 +2372,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
}
catch (std::invalid_argument iae) {
LogError("[SourceDatabaseTableFromUrl] URI parser error [{}]", iae.what());
LogError("URI parser error [{}]", iae.what());
}
}
-3
View File
@@ -108,9 +108,6 @@ public:
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
bool ReserveName(uint32 account_id, char *name);
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
bool SetHackerFlag(const char *accountname, const char *charactername, const char *hacked);
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const char *hacked, const char *zone);
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
bool UpdateName(const char *oldname, const char *newname);
bool CopyCharacter(
const std::string& source_character_name,
+36 -77
View File
@@ -118,109 +118,53 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
);
}
/**
* @return
*/
std::string DatabaseDumpService::GetPlayerTablesList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetPlayerTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(DatabaseSchema::GetPlayerTables(), " ");
}
/**
* @return
*/
std::string DatabaseDumpService::GetBotTablesList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetBotTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(DatabaseSchema::GetBotTables(), " ");
}
std::string DatabaseDumpService::GetMercTablesList()
{
return Strings::Join(DatabaseSchema::GetMercTables(), " ");
}
/**
* @return
*/
std::string DatabaseDumpService::GetLoginTableList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetLoginTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
}
/**
* @return
*/
std::string DatabaseDumpService::GetQueryServTables()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetQueryServerTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
}
/**
* @return
*/
std::string DatabaseDumpService::GetSystemTablesList()
{
std::string tables_list;
auto system_tables = DatabaseSchema::GetServerTables();
auto version_tables = DatabaseSchema::GetVersionTables();
std::vector<std::string> tables = DatabaseSchema::GetServerTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
system_tables.insert(
std::end(system_tables),
std::begin(version_tables),
std::end(version_tables)
);
tables = DatabaseSchema::GetVersionTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(system_tables, " ");
}
/**
* @return
*/
std::string DatabaseDumpService::GetStateTablesList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetStateTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(DatabaseSchema::GetStateTables(), " ");
}
/**
* @return
*/
std::string DatabaseDumpService::GetContentTablesList()
{
std::string tables_list;
std::vector<std::string> tables = DatabaseSchema::GetContentTables();
for (const auto &table : tables) {
tables_list += table + " ";
}
return Strings::Trim(tables_list);
return Strings::Join(DatabaseSchema::GetContentTables(), " ");
}
/**
@@ -306,6 +250,11 @@ void DatabaseDumpService::Dump()
dump_descriptor += "-bots";
}
if (IsDumpMercTables()) {
tables_to_dump += GetMercTablesList() + " ";
dump_descriptor += "-mercs";
}
if (IsDumpSystemTables()) {
tables_to_dump += GetSystemTablesList() + " ";
dump_descriptor += "-system";
@@ -375,7 +324,7 @@ void DatabaseDumpService::Dump()
}
if (!tables_to_dump.empty()) {
LogInfo("Dumping Tables [{}]", tables_to_dump);
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
}
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
@@ -576,3 +525,13 @@ void DatabaseDumpService::SetDumpBotTables(bool dump_bot_tables)
{
DatabaseDumpService::dump_bot_tables = dump_bot_tables;
}
bool DatabaseDumpService::IsDumpMercTables() const
{
return dump_merc_tables;
}
void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
{
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
}
+4
View File
@@ -55,6 +55,8 @@ public:
void SetDumpStateTables(bool dump_state_tables);
bool IsDumpBotTables() const;
void SetDumpBotTables(bool dump_bot_tables);
bool IsDumpMercTables() const;
void SetDumpMercTables(bool dump_bot_tables);
private:
bool dump_all_tables = false;
@@ -70,6 +72,7 @@ private:
bool dump_output_to_console = false;
bool dump_drop_table_syntax_only = false;
bool dump_bot_tables = false;
bool dump_merc_tables = false;
std::string dump_path;
std::string dump_file_name;
@@ -78,6 +81,7 @@ private:
std::string GetBaseMySQLDumpCommand();
std::string GetPlayerTablesList();
std::string GetBotTablesList();
std::string GetMercTablesList();
std::string GetSystemTablesList();
std::string GetStateTablesList();
std::string GetContentTablesList();
+7
View File
@@ -476,6 +476,13 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertPPDeblob();
CheckDatabaseConvertCorpseDeblob();
auto *r = RuleManager::Instance();
r->LoadRules(this, "default", false);
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
LogInfo("Bot tables found but rule not enabled, enabling");
r->SetRule("Bots:Enabled", "true", this, true, true);
}
/* Run EQEmu Server script (Checks for database updates) */
const std::string file = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
+26 -5
View File
@@ -321,18 +321,18 @@ namespace DatabaseSchema {
"discord_webhooks",
"dynamic_zone_members",
"dynamic_zones",
"eventlog",
"expedition_lockouts",
"expeditions",
"gm_ips",
"group_id",
"group_leaders",
"hackers",
"instance_list",
"ip_exemptions",
"item_tick",
"lfguild",
"merc_buffs",
"merchantlist_temp",
"mercs",
"object_contents",
"raid_details",
"raid_leaders",
@@ -341,6 +341,8 @@ namespace DatabaseSchema {
"respawn_times",
"saylink",
"server_scheduled_events",
"player_event_log_settings",
"player_event_logs"
"shared_task_activity_state",
"shared_task_dynamic_zones",
"shared_task_members",
@@ -406,9 +408,28 @@ namespace DatabaseSchema {
"bot_spell_settings",
"bot_spells_entries",
"bot_stances",
"bot_timers",
"vw_bot_character_mobs",
"vw_bot_groups"
"bot_timers"
};
}
static std::vector<std::string> GetMercTables()
{
return {
"merc_armorinfo",
"merc_inventory",
"merc_merchant_entries",
"merc_merchant_template_entries",
"merc_merchant_templates",
"merc_name_types",
"merc_npc_types",
"merc_spell_list_entries",
"merc_spell_lists",
"merc_stance_entries",
"merc_stats",
"merc_subtypes",
"merc_templates",
"merc_types",
"merc_weaponinfo"
};
}
+2 -2
View File
@@ -167,7 +167,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if ((strncasecmp(query, "select", 6) == 0)) {
LogMySQLQuery(
"{0}; -- ({1} row{2} returned) ({3}s)",
"{0} -- ({1} row{2} returned) ({3}s)",
query,
requestResult.RowCount(),
requestResult.RowCount() == 1 ? "" : "s",
@@ -176,7 +176,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
}
else {
LogMySQLQuery(
"{0}; -- ({1} row{2} affected) ({3}s)",
"{0} -- ({1} row{2} affected) ({3}s)",
query,
requestResult.RowsAffected(),
requestResult.RowsAffected() == 1 ? "" : "s",
+91 -11
View File
@@ -1,22 +1,17 @@
#include <cereal/archives/json.hpp>
#include <cereal/archives/binary.hpp>
#include "discord.h"
#include "../http/httplib.h"
#include "../json/json.h"
#include "../strings.h"
#include "../eqemu_logsys.h"
#include "../events/player_event_logs.h"
constexpr int MAX_RETRIES = 10;
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
{
// validate
if (webhook_url.empty()) {
LogDiscord("[webhook_url] is empty");
return;
}
// validate
if (webhook_url.find("http://") == std::string::npos && webhook_url.find("https://") == std::string::npos) {
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
if (!ValidateWebhookUrl(webhook_url)) {
return;
}
@@ -28,7 +23,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
// client
httplib::Client cli(base_url.c_str());
httplib::Client cli(base_url);
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
@@ -46,7 +41,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
int retries = 0;
int retry_timer = 1000;
while (retry) {
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
if (res->status != 200 && res->status != 204) {
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
}
@@ -81,6 +76,74 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
}
}
void Discord::SendPlayerEventMessage(
const PlayerEvent::PlayerEventContainer &e,
const std::string &webhook_url
)
{
if (!ValidateWebhookUrl(webhook_url)) {
return;
}
auto s = Strings::Split(webhook_url, '/');
// url
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
// client
httplib::Client cli(base_url);
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
if (payload.empty()) {
return;
}
bool retry = true;
int retries = 0;
int retry_timer = 1000;
while (retry) {
if (auto res = cli.Post(endpoint, payload, "application/json")) {
if (res->status != 200 && res->status != 204) {
LogError("Code [{}] Error [{}]", res->status, res->body);
}
if (res->status == 429) {
if (!res->body.empty()) {
std::stringstream ss(res->body);
Json::Value response;
try {
ss >> response;
}
catch (std::exception const &ex) {
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
}
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
}
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
}
if (res->status == 204) {
retry = false;
}
if (retries > MAX_RETRIES) {
LogDiscord("Retries exceeded for player event message");
retry = false;
}
retries++;
}
}
}
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
{
if (category_id == Logs::LogCategory::MySQLQuery) {
@@ -89,3 +152,20 @@ std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string
return message + "\n";
}
bool Discord::ValidateWebhookUrl(const std::string &webhook_url)
{
// validate
if (webhook_url.empty()) {
LogDiscord("[webhook_url] is empty");
return false;
}
// validate
if (!Strings::Contains(webhook_url, "http://") && !Strings::Contains(webhook_url, "https://")) {
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
return false;
}
return true;
}
+5
View File
@@ -4,11 +4,16 @@
#include <string>
#include "../types.h"
#include "../http/httplib.h"
#include "../repositories/player_event_logs_repository.h"
#include "../events/player_events.h"
class Discord {
public:
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
static void SendPlayerEventMessage(const PlayerEvent::PlayerEventContainer& e, const std::string &webhook_url);
static bool ValidateWebhookUrl(const std::string &webhook_url);
};
@@ -1,7 +1,6 @@
#include "discord_manager.h"
#include "../common/discord/discord.h"
#include "../common/eqemu_logsys.h"
#include "../common/strings.h"
#include "../../common/discord/discord.h"
#include "../events/player_event_logs.h"
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
{
@@ -55,7 +54,6 @@ void DiscordManager::ProcessMessageQueue()
message = "";
}
}
// final flush
if (!message.empty()) {
Discord::SendWebhookMessage(
@@ -67,3 +65,11 @@ void DiscordManager::ProcessMessageQueue()
webhook_message_queue.clear();
webhook_queue_lock.unlock();
}
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
{
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
if (!w.empty()) {
Discord::SendPlayerEventMessage(e, w);
}
}
@@ -4,12 +4,15 @@
#include <mutex>
#include <map>
#include <vector>
#include "../common/types.h"
#include "../../common/types.h"
#include "../repositories/player_event_logs_repository.h"
#include "../events/player_events.h"
class DiscordManager {
public:
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
void ProcessMessageQueue();
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
private:
std::mutex webhook_queue_lock{};
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
+27 -8
View File
@@ -79,6 +79,8 @@
#define ANIM_DEATH 0x73
#define ANIM_LOOT 0x69
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
typedef enum {
eaStanding = 0,
eaSitting, //1
@@ -1015,15 +1017,32 @@ enum Anonymity : uint8
Roleplaying
};
enum ZoningMessage : int8
{
ZoneNoMessage = 0,
ZoneSuccess = 1,
ZoneNotReady = -1,
ZoneValidPC = -2,
ZoneStoryZone = -3,
ZoneNoExpansion = -6,
enum ZoningMessage : int8 {
ZoneNoMessage = 0,
ZoneSuccess = 1,
ZoneNotReady = -1,
ZoneValidPC = -2,
ZoneStoryZone = -3,
ZoneNoExpansion = -6,
ZoneNoExperience = -7
};
enum class RecipeCountType : uint8
{
Component,
Container,
Fail,
Salvage,
Success
};
#define ALT_CURRENCY_ID_RADIANT 4
#define ALT_CURRENCY_ID_EBON 5
enum ResurrectionActions
{
Decline,
Accept
};
#endif /*COMMON_EQ_CONSTANTS_H*/
+13 -11
View File
@@ -29,7 +29,7 @@
#include "textures.h"
static const uint32 BUFF_COUNT = 25;
static const uint32 BUFF_COUNT = 42;
static const uint32 PET_BUFF_COUNT = 30;
static const uint32 MAX_MERC = 100;
static const uint32 MAX_MERC_GRADES = 10;
@@ -3632,17 +3632,19 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
};
struct MerchantList {
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint8 min_status;
uint8 max_status;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
std::string bucket_name;
std::string bucket_value;
uint8 bucket_comparison;
uint8 bucket_comparison;
};
struct TempMerchantList {
@@ -4545,7 +4547,7 @@ struct ItemVerifyReply_Struct {
struct ItemRecastDelay_Struct {
/*000*/ uint32 recast_delay; // in seconds
/*004*/ uint32 recast_type;
/*008*/ uint32 unknown008;
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
/*012*/
};
+149 -177
View File
@@ -22,21 +22,19 @@
#include "rulesys.h"
#include "platform.h"
#include "strings.h"
#include "misc.h"
#include "discord/discord.h"
#include "repositories/discord_webhooks_repository.h"
#include "repositories/logsys_categories_repository.h"
#include "termcolor/rang.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <time.h>
#include <sys/stat.h>
#include <algorithm>
std::ofstream process_log;
#include <filesystem>
#ifdef _WINDOWS
#include <direct.h>
#include <conio.h>
@@ -52,46 +50,12 @@ std::ofstream process_log;
#endif
/**
* Linux ANSI console color defines
*/
#define LC_RESET "\033[0m"
#define LC_BLACK "\033[30m" /* Black */
#define LC_RED "\033[31m" /* Red */
#define LC_GREEN "\033[32m" /* Green */
#define LC_YELLOW "\033[33m" /* Yellow */
#define LC_BLUE "\033[34m" /* Blue */
#define LC_MAGENTA "\033[35m" /* Magenta */
#define LC_CYAN "\033[36m" /* Cyan */
#define LC_WHITE "\033[37m" /* White */
namespace Console {
enum Color {
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
LightMagenta = 13,
Yellow = 14,
White = 15
};
}
/**
* EQEmuLogSys Constructor
*/
EQEmuLogSys::EQEmuLogSys()
{
m_on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
m_on_log_gmsay_hook = [](uint16 log_type, const char *func, const std::string &) {};
m_on_log_console_hook = [](uint16 log_type, const std::string &) {};
}
@@ -120,14 +84,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* Set Defaults
*/
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
@@ -146,12 +104,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/**
* RFC 5424
*/
log_settings[Logs::Emergency].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Alert].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Critical].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Notice].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
/**
@@ -196,24 +150,6 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
return this;
}
/**
* @param log_category
* @return
*/
bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
{
return (
log_category == Logs::Emergency ||
log_category == Logs::Alert ||
log_category == Logs::Critical ||
log_category == Logs::Error ||
log_category == Logs::Warning ||
log_category == Logs::Notice ||
log_category == Logs::Info ||
log_category == Logs::Debug
);
}
/**
* @param debug_level
* @param log_category
@@ -244,66 +180,6 @@ void EQEmuLogSys::ProcessLogWrite(
}
}
/**
* @param log_category
* @return
*/
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Status:
case Logs::Normal:
return Console::Color::Yellow;
case Logs::MySQLError:
case Logs::Error:
case Logs::QuestErrors:
return Console::Color::LightRed;
case Logs::MySQLQuery:
case Logs::Debug:
return Console::Color::LightGreen;
case Logs::Quests:
return Console::Color::LightCyan;
case Logs::Commands:
case Logs::Mercenaries:
return Console::Color::LightMagenta;
case Logs::Crash:
return Console::Color::LightRed;
default:
return Console::Color::Yellow;
}
}
/**
* @param log_category
* @return
*/
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Status:
case Logs::Normal:
return LC_YELLOW;
case Logs::MySQLError:
case Logs::QuestErrors:
case Logs::Warning:
case Logs::Critical:
case Logs::Error:
return LC_RED;
case Logs::MySQLQuery:
case Logs::Debug:
return LC_GREEN;
case Logs::Quests:
return LC_CYAN;
case Logs::Commands:
case Logs::Mercenaries:
return LC_MAGENTA;
case Logs::Crash:
return LC_RED;
default:
return LC_YELLOW;
}
}
/**
* @param log_category
* @return
@@ -311,9 +187,6 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
{
switch (log_category) {
case Logs::Status:
case Logs::Normal:
return Chat::Yellow;
case Logs::MySQLError:
case Logs::QuestErrors:
case Logs::Error:
@@ -333,28 +206,144 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessConsoleMessage(uint16 log_category, const std::string &message)
void EQEmuLogSys::ProcessConsoleMessage(
uint16 log_category,
const std::string &message,
const char *file,
const char *func,
int line
)
{
#ifdef _WINDOWS
HANDLE console_handle;
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFOEX info = { 0 };
info.cbSize = sizeof(info);
info.dwFontSize.Y = 12; // leave X as zero
info.FontWeight = FW_NORMAL;
wcscpy(info.FaceName, L"Lucida Console");
SetCurrentConsoleFontEx(console_handle, NULL, &info);
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
std::cout << message << "\n";
SetConsoleTextAttribute(console_handle, Console::Color::White);
#else
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
bool is_error = (
log_category == Logs::LogCategory::Error ||
log_category == Logs::LogCategory::MySQLError ||
log_category == Logs::LogCategory::Crash ||
log_category == Logs::LogCategory::QuestErrors
);
bool is_warning = (
log_category == Logs::LogCategory::Warning
);
(!is_error ? std::cout : std::cerr)
<< ""
<< rang::fgB::black
<< rang::style::bold
<< fmt::format("{:>6}", GetPlatformName().substr(0, 6))
<< rang::style::reset
<< rang::fgB::gray
<< " | "
<< ((is_error || is_warning) ? rang::fgB::red : rang::fgB::gray)
<< rang::style::bold
<< fmt::format("{:^10}", fmt::format("{}", Logs::LogCategoryName[log_category]).substr(0, 10))
<< rang::style::reset
<< rang::fgB::gray
<< " | "
<< rang::fgB::gray
<< rang::style::bold
<< fmt::format("{}", func)
<< rang::style::reset
<< rang::fgB::gray
<< " ";
if (RuleB(Logging, PrintFileFunctionAndLine)) {
(!is_error ? std::cout : std::cerr)
<< ""
<< rang::fgB::green
<< rang::style::bold
<< fmt::format("{:}", fmt::format("{}:{}:{}", std::filesystem::path(file).filename().string(), func, line))
<< rang::style::reset
<< " | ";
}
if (log_category == Logs::LogCategory::MySQLQuery) {
auto s = Strings::Split(message, "--");
if (s.size() > 1) {
std::string query = Strings::Trim(s[0]);
std::string meta = Strings::Trim(s[1]);
std::cout <<
rang::fgB::green
<<
query
<<
rang::style::reset;
std::cout <<
rang::fgB::black
<<
" -- "
<<
meta
<<
rang::style::reset;
}
}
else if (Strings::Contains(message, "[")) {
for (auto &e: Strings::Split(message, " ")) {
if (Strings::Contains(e, "[") && Strings::Contains(e, "]")) {
e = Strings::Replace(e, "[", "");
e = Strings::Replace(e, "]", "");
bool is_upper = false;
for (int i = 0; i < strlen(e.c_str()); i++) {
if (isupper(e[i])) {
is_upper = true;
}
}
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::fgB::gray
<< "] "
;
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
}
}
else {
(!is_error ? std::cout : std::cerr)
<< (is_error ? rang::fgB::red : rang::fgB::gray)
<< e
<< " ";
}
}
}
else {
(!is_error ? std::cout : std::cerr)
<< (is_error ? rang::fgB::red : rang::fgB::gray)
<< message
<< " ";
}
if (!origination_info.zone_short_name.empty()) {
(!is_error ? std::cout : std::cerr)
<<
rang::fgB::black
<<
"-- "
<<
fmt::format(
"[{}] ({}) inst_id [{}]",
origination_info.zone_short_name,
origination_info.zone_long_name,
origination_info.instance_id
);
}
(!is_error ? std::cout : std::cerr) << rang::style::reset << std::endl;
m_on_log_console_hook(log_category, message);
}
@@ -368,33 +357,6 @@ constexpr const char *str_end(const char *str)
return *str ? str_end(str + 1) : str;
}
/**
* @param str
* @return
*/
constexpr bool str_slant(const char *str)
{
return *str == '/' ? true : (*str ? str_slant(str + 1) : false);
}
/**
* @param str
* @return
*/
constexpr const char *r_slant(const char *str)
{
return *str == '/' ? (str + 1) : r_slant(str - 1);
}
/**
* @param str
* @return
*/
constexpr const char *base_file_name(const char *str)
{
return str_slant(str) ? r_slant(str_end(str)) : str;
}
/**
* Core logging function
*
@@ -422,7 +384,7 @@ void EQEmuLogSys::Out(
std::string prefix;
if (RuleB(Logging, PrintFileFunctionAndLine)) {
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
prefix = fmt::format("[{0}::{1}:{2}] ", std::filesystem::path(file).filename().string(), func, line);
}
// remove this when we remove all legacy logs
@@ -445,11 +407,14 @@ void EQEmuLogSys::Out(
if (l.log_to_console_enabled) {
EQEmuLogSys::ProcessConsoleMessage(
log_category,
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
output_message,
file,
func,
line
);
}
if (l.log_to_gmsay_enabled) {
m_on_log_gmsay_hook(log_category, output_message);
m_on_log_gmsay_hook(log_category, func, output_message);
}
if (l.log_to_file_enabled) {
EQEmuLogSys::ProcessLogWrite(
@@ -563,6 +528,8 @@ void EQEmuLogSys::SilenceConsoleLogging()
log_settings[log_index].log_to_console = 0;
log_settings[log_index].is_category_enabled = 0;
}
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
}
/**
@@ -667,6 +634,11 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
LogInfo("Loaded [{}] Discord webhooks", webhooks.size());
}
// force override this setting
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_gmsay = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
return this;
}
+63 -62
View File
@@ -39,8 +39,7 @@
namespace Logs {
enum DebugLevel {
General = 1, // 1 - Low-Level general debugging, useful info on single line
Moderate, // 2 - Informational based, used in functions, when particular things load
Detail // 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication
Detail // 2 - Use this for very chatty logging you want to leave in but don't want on by default
};
/**
@@ -54,7 +53,7 @@ namespace Logs {
AI,
Aggro,
Attack,
DeprecatedCS,
DeprecatedCS, // deprecated
Combat,
Commands,
Crash,
@@ -65,36 +64,36 @@ namespace Logs {
Inventory,
Launcher,
Netcode,
Normal,
Normal, // deprecated
Object,
Pathing,
QSServer,
QSServer, // deprecated
Quests,
Rules,
Skills,
Spawns,
Spells,
Status,
Status, // deprecated
TCPConnection,
Tasks,
Tradeskills,
Trading,
Tribute,
UCSServer,
WebInterfaceServer,
WorldServer,
ZoneServer,
UCSServer, // deprecated
WebInterfaceServer, // deprecated
WorldServer, // deprecated
ZoneServer, // deprecated
MySQLError,
MySQLQuery,
Mercenaries,
QuestDebug,
DeprecatedSC,
DeprecatedCSU,
DeprecatedSCD,
DeprecatedCSD,
Loginserver,
DeprecatedSC, // deprecated
DeprecatedCSU, // deprecated
DeprecatedSCD, // deprecated
DeprecatedCSD, // deprecated
Loginserver, // deprecated
ClientLogin,
HeadlessClient,
HeadlessClient, // deprecated
HPUpdate,
FixZ,
Food,
@@ -104,10 +103,10 @@ namespace Logs {
MobAppearance,
Info,
Warning,
Critical,
Emergency,
Alert,
Notice,
Critical, // deprecated
Emergency, // deprecated
Alert, // deprecated
Notice, // deprecated
AIScanClose,
AIYellForHelp,
AICastBeneficialClose,
@@ -160,52 +159,52 @@ namespace Logs {
"Inventory",
"Launcher",
"Netcode",
"Normal",
"Normal (Deprecated)",
"Object",
"Pathing",
"QS Server",
"QS Server (Deprecated)",
"Quests",
"Rules",
"Skills",
"Spawns",
"Spells",
"Status",
"Status (Deprecated)",
"TCP Connection",
"Tasks",
"Tradeskills",
"Trading",
"Tribute",
"UCS Server",
"WebInterface Server",
"World Server",
"Zone Server",
"MySQL Error",
"MySQL Query",
"UCS Server (Deprecated)",
"Web Interface (Deprecated)",
"World Server (Deprecated)",
"Zone Server (Deprecated)",
"QueryErr",
"Query",
"Mercenaries",
"Quest Debug",
"Deprecated",
"Deprecated",
"Deprecated",
"Deprecated",
"Login Server",
"Legacy Packet Logging (Deprecated)",
"Legacy Packet Logging (Deprecated)",
"Legacy Packet Logging (Deprecated)",
"Legacy Packet Logging (Deprecated)",
"Login Server (Deprecated)",
"Client Login",
"Headless Client",
"Headless Client (Deprecated)",
"HP Update",
"FixZ",
"Food",
"Traps",
"NPC Roam Box",
"NPC Scaling",
"Mob Appearance",
"MobAppearance",
"Info",
"Warning",
"Critical",
"Emergency",
"Alert",
"Notice",
"AI Scan Close",
"AI Yell For Help",
"AI Cast Beneficial Close",
"Critical (Deprecated)",
"Emergency (Deprecated)",
"Alert (Deprecated)",
"Notice (Deprecated)",
"AI Scan",
"AI Yell",
"AI CastBeneficial",
"AOE Cast",
"Entity Management",
"Flee",
@@ -222,14 +221,14 @@ namespace Logs {
"DialogueWindow",
"HTTP",
"Saylink",
"ChecksumVerification",
"ChecksumVer",
"CombatRecord",
"Hate",
"Discord",
"Faction",
"Packet-S->C",
"Packet-C->S",
"Packet-S->S",
"Packet S->C",
"Packet C->S",
"Packet S->S",
"Bugs",
"QuestErrors"
};
@@ -345,7 +344,7 @@ public:
// gmsay
uint16 GetGMSayColorFromCategory(uint16 log_category);
EQEmuLogSys *SetGMSayHandler(std::function<void(uint16 log_type, const std::string &)> f)
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)>& f)
{
m_on_log_gmsay_hook = f;
return this;
@@ -376,22 +375,24 @@ public:
private:
// reference to database
Database *m_database;
std::function<void(uint16 log_category, const std::string &)> m_on_log_gmsay_hook;
std::function<void(uint16 log_category, int webhook_id, const std::string &)> m_on_log_discord_hook;
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
bool m_file_logs_enabled = false;
int m_log_platform = 0;
std::string m_platform_file_name;
std::string m_log_path;
Database *m_database;
std::function<void(uint16 log_category, const char *func, const std::string &)> m_on_log_gmsay_hook;
std::function<void(uint16 log_category, int webhook_id, const std::string &)> m_on_log_discord_hook;
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
bool m_file_logs_enabled = false;
int m_log_platform = 0;
std::string m_platform_file_name;
std::string m_log_path;
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
void ProcessConsoleMessage(uint16 log_category, const std::string &message);
void ProcessConsoleMessage(
uint16 log_category,
const std::string &message,
const char *file,
const char *func,
int line
);
void ProcessLogWrite(uint16 log_category, const std::string &message);
bool IsRfc5424LogCategory(uint16 log_category);
void InjectTablesIfNotExist();
};
-551
View File
@@ -21,8 +21,6 @@
#ifndef EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
#ifdef BUILD_LOGGING
#define LogAA(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::AA))\
OutF(LogSys, Logs::General, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -38,11 +36,6 @@
OutF(LogSys, Logs::General, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIModerate(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Moderate, Logs::AI))\
OutF(LogSys, Logs::Moderate, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AI))\
OutF(LogSys, Logs::Detail, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -83,11 +76,6 @@
OutF(LogSys, Logs::General, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCombatModerate(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Moderate, Logs::Combat))\
OutF(LogSys, Logs::Moderate, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCombatDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Combat))\
OutF(LogSys, Logs::Detail, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -213,16 +201,6 @@
OutF(LogSys, Logs::Detail, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQSServer(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::QSServer))\
OutF(LogSys, Logs::General, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQSServerDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::QSServer))\
OutF(LogSys, Logs::Detail, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQuests(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::Quests))\
OutF(LogSys, Logs::General, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -268,11 +246,6 @@
OutF(LogSys, Logs::General, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSpellsModerate(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Moderate, Logs::Spells))\
OutF(LogSys, Logs::Moderate, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSpellsDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Spells))\
OutF(LogSys, Logs::Detail, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -338,46 +311,6 @@
OutF(LogSys, Logs::Detail, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogUCSServer(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::UCSServer))\
OutF(LogSys, Logs::General, Logs::UCSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogUCSServerDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::UCSServer))\
OutF(LogSys, Logs::Detail, Logs::UCSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogWebInterfaceServer(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::WebInterfaceServer))\
OutF(LogSys, Logs::General, Logs::WebInterfaceServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogWebInterfaceServerDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::WebInterfaceServer))\
OutF(LogSys, Logs::Detail, Logs::WebInterfaceServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogWorldServer(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::WorldServer))\
OutF(LogSys, Logs::General, Logs::WorldServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogWorldServerDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::WorldServer))\
OutF(LogSys, Logs::Detail, Logs::WorldServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogZoneServer(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::ZoneServer))\
OutF(LogSys, Logs::General, Logs::ZoneServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogZoneServerDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::ZoneServer))\
OutF(LogSys, Logs::Detail, Logs::ZoneServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMySQLError(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::MySQLError))\
OutF(LogSys, Logs::General, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -449,16 +382,6 @@
OutF(LogSys, Logs::Detail, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHeadlessClient(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::HeadlessClient))\
OutF(LogSys, Logs::General, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHeadlessClientDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::HeadlessClient))\
OutF(LogSys, Logs::Detail, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHPUpdate(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::HPUpdate))\
OutF(LogSys, Logs::General, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -594,11 +517,6 @@
OutF(LogSys, Logs::General, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIScanCloseModerate(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Moderate, Logs::AIScanClose))\
OutF(LogSys, Logs::Moderate, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIScanCloseDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AIScanClose))\
OutF(LogSys, Logs::Detail, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -846,11 +764,6 @@
// manually created
#define LogExpeditionsModerate(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Moderate, Logs::Expeditions))\
OutF(LogSys, Logs::Moderate, Logs::Expeditions, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogBugs(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::Bugs))\
OutF(LogSys, Logs::General, Logs::Bugs, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -881,469 +794,5 @@
OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#else
#define LogEmergency(message, ...) do {\
} while (0)
#define LogAlert(message, ...) do {\
} while (0)
#define LogCritical(message, ...) do {\
} while (0)
#define LogError(message, ...) do {\
} while (0)
#define LogWarning(message, ...) do {\
} while (0)
#define LogNotice(message, ...) do {\
} while (0)
#define LogInfo(message, ...) do {\
} while (0)
#define LogDebug(message, ...) do {\
} while (0)
/**
* Category
*/
#define LogAA(message, ...) do {\
} while (0)
#define LogAADetail(message, ...) do {\
} while (0)
#define LogAI(message, ...) do {\
} while (0)
#define LogAIModerate(message, ...) do {\
} while (0)
#define LogAIDetail(message, ...) do {\
} while (0)
#define LogAggro(message, ...) do {\
} while (0)
#define LogAggroDetail(message, ...) do {\
} while (0)
#define LogAttack(message, ...) do {\
} while (0)
#define LogAttackDetail(message, ...) do {\
} while (0)
#define LogPacketClientServer(message, ...) do {\
} while (0)
#define LogPacketClientServerDetail(message, ...) do {\
} while (0)
#define LogCombat(message, ...) do {\
} while (0)
#define LogCombatModerate(message, ...) do {\
} while (0)
#define LogCombatDetail(message, ...) do {\
} while (0)
#define LogCommands(message, ...) do {\
} while (0)
#define LogCommandsDetail(message, ...) do {\
} while (0)
#define LogCrash(message, ...) do {\
} while (0)
#define LogCrashDetail(message, ...) do {\
} while (0)
#define LogDoors(message, ...) do {\
} while (0)
#define LogDoorsDetail(message, ...) do {\
} while (0)
#define LogGroup(message, ...) do {\
} while (0)
#define LogGroupDetail(message, ...) do {\
} while (0)
#define LogGuilds(message, ...) do {\
} while (0)
#define LogGuildsDetail(message, ...) do {\
} while (0)
#define LogInventory(message, ...) do {\
} while (0)
#define LogInventoryDetail(message, ...) do {\
} while (0)
#define LogLauncher(message, ...) do {\
} while (0)
#define LogLauncherDetail(message, ...) do {\
} while (0)
#define LogNetcode(message, ...) do {\
} while (0)
#define LogNetcodeDetail(message, ...) do {\
} while (0)
#define LogNormal(message, ...) do {\
} while (0)
#define LogNormalDetail(message, ...) do {\
} while (0)
#define LogObject(message, ...) do {\
} while (0)
#define LogObjectDetail(message, ...) do {\
} while (0)
#define LogPathing(message, ...) do {\
} while (0)
#define LogPathingDetail(message, ...) do {\
} while (0)
#define LogQSServer(message, ...) do {\
} while (0)
#define LogQSServerDetail(message, ...) do {\
} while (0)
#define LogQuests(message, ...) do {\
} while (0)
#define LogQuestsDetail(message, ...) do {\
} while (0)
#define LogRules(message, ...) do {\
} while (0)
#define LogRulesDetail(message, ...) do {\
} while (0)
#define LogSkills(message, ...) do {\
} while (0)
#define LogSkillsDetail(message, ...) do {\
} while (0)
#define LogSpawns(message, ...) do {\
} while (0)
#define LogSpawnsDetail(message, ...) do {\
} while (0)
#define LogSpells(message, ...) do {\
} while (0)
#define LogSpellsModerate(message, ...) do {\
} while (0)
#define LogSpellsDetail(message, ...) do {\
} while (0)
#define LogTCPConnection(message, ...) do {\
} while (0)
#define LogTCPConnectionDetail(message, ...) do {\
} while (0)
#define LogTasks(message, ...) do {\
} while (0)
#define LogTasksDetail(message, ...) do {\
} while (0)
#define LogTradeskills(message, ...) do {\
} while (0)
#define LogTradeskillsDetail(message, ...) do {\
} while (0)
#define LogTrading(message, ...) do {\
} while (0)
#define LogTradingDetail(message, ...) do {\
} while (0)
#define LogTribute(message, ...) do {\
} while (0)
#define LogTributeDetail(message, ...) do {\
} while (0)
#define LogMySQLError(message, ...) do {\
} while (0)
#define LogMySQLErrorDetail(message, ...) do {\
} while (0)
#define LogMySQLQuery(message, ...) do {\
} while (0)
#define LogMySQLQueryDetail(message, ...) do {\
} while (0)
#define LogMercenaries(message, ...) do {\
} while (0)
#define LogMercenariesDetail(message, ...) do {\
} while (0)
#define LogQuestDebug(message, ...) do {\
} while (0)
#define LogQuestDebugDetail(message, ...) do {\
} while (0)
#define LogLoginserver(message, ...) do {\
} while (0)
#define LogLoginserverDetail(message, ...) do {\
} while (0)
#define LogClientLogin(message, ...) do {\
} while (0)
#define LogClientLoginDetail(message, ...) do {\
} while (0)
#define LogHeadlessClient(message, ...) do {\
} while (0)
#define LogHeadlessClientDetail(message, ...) do {\
} while (0)
#define LogHPUpdate(message, ...) do {\
} while (0)
#define LogHPUpdateDetail(message, ...) do {\
} while (0)
#define LogFixZ(message, ...) do {\
} while (0)
#define LogFixZDetail(message, ...) do {\
} while (0)
#define LogFood(message, ...) do {\
} while (0)
#define LogFoodDetail(message, ...) do {\
} while (0)
#define LogTraps(message, ...) do {\
} while (0)
#define LogTrapsDetail(message, ...) do {\
} while (0)
#define LogNPCRoamBox(message, ...) do {\
} while (0)
#define LogNPCRoamBoxDetail(message, ...) do {\
} while (0)
#define LogNPCScaling(message, ...) do {\
} while (0)
#define LogNPCScalingDetail(message, ...) do {\
} while (0)
#define LogMobAppearance(message, ...) do {\
} while (0)
#define LogMobAppearanceDetail(message, ...) do {\
} while (0)
#define LogStatus(message, ...) do {\
} while (0)
#define LogStatusDetail(message, ...) do {\
} while (0)
#define LogAIScanClose(message, ...) do {\
} while (0)
#define LogAIScanCloseModerate(message, ...) do {\
} while (0)
#define LogAIScanCloseDetail(message, ...) do {\
} while (0)
#define LogAIYellForHelp(message, ...) do {\
} while (0)
#define LogAIYellForHelpDetail(message, ...) do {\
} while (0)
#define LogAICastBeneficialClose(message, ...) do {\
} while (0)
#define LogAICastBeneficialCloseDetail(message, ...) do {\
} while (0)
#define LogAoeCast(message, ...) do {\
} while (0)
#define LogAoeCastDetail(message, ...) do {\
} while (0)
#define LogEntityManagement(message, ...) do {\
} while (0)
#define LogEntityManagementDetail(message, ...) do {\
} while (0)
#define LogFlee(message, ...) do {\
} while (0)
#define LogFleeDetail(message, ...) do {\
} while (0)
#define LogAura(message, ...) do {\
} while (0)
#define LogAuraDetail(message, ...) do {\
} while (0)
#define LogHotReload(message, ...) do {\
} while (0)
#define LogHotReloadDetail(message, ...) do {\
} while (0)
#define LogMerchants(message, ...) do {\
} while (0)
#define LogMerchantsDetail(message, ...) do {\
} while (0)
#define LogZonePoints(message, ...) do {\
} while (0)
#define LogZonePointsDetail(message, ...) do {\
} while (0)
#define LogExpeditions(message, ...) do {\
} while (0)
#define LogExpeditionsModerate(message, ...) do {\
} while (0)
#define LogExpeditionsDetail(message, ...) do {\
} while (0)
#define LogDynamicZones(message, ...) do {\
} while (0)
#define LogDynamicZonesDetail(message, ...) do {\
} while (0)
#define LogCheatList(message, ...) do {\
} while (0)
#define LogCheatDetail(message, ...) do {\
} while (0)
#define LogClientList(message, ...) do {\
} while (0)
#define LogClientListDetail(message, ...) do {\
} while (0)
#define LogDiaWind(message, ...) do {\
} while (0)
#define LogDiaWindDetail(message, ...) do {\
} while (0)
#define LogHTTP(message, ...) do {\
} while (0)
#define LogHTTPDetail(message, ...) do {\
} while (0)
#define LogSaylink(message, ...) do {\
} while (0)
#define LogSaylinkDetail(message, ...) do {\
} while (0)
#define LogScheduler(message, ...) do {\
} while (0)
#define LogSchedulerDetail(message, ...) do {\
} while (0)
#define LogCheat(message, ...) do {\
} while (0)
#define LogCheatDetail(message, ...) do {\
} while (0)
#define LogLoot(message, ...) do {\
} while (0)
#define LogLootDetail(message, ...) do {\
} while (0)
#define LogFood(message, ...) do {\
} while (0)
#define LogFoodDetail(message, ...) do {\
} while (0)
#define LogChecksumVerification(message, ...) do {\
} while (0)
#define LogChecksumVerificationDetail(message, ...) do {\
} while (0)
#define LogCombatRecord(message, ...) do {\
} while (0)
#define LogCombatRecordDetail(message, ...) do {\
} while (0)
#define LogHate(message, ...) do {\
} while (0)
#define LogHateDetail(message, ...) do {\
} while (0)
#define LogFaction(message, ...) do {\
} while (0)
#define LogFactionDetail(message, ...) do {\
} while (0)
#define LogBugs(message, ...) do {\
} while (0)
#define LogBugsDetail(message, ...) do {\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
} while (0)
#define LogF(debug_level, log_category, message, ...) do {\
} while (0)
#endif
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,214 @@
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
#include <string>
#include "player_events.h"
#include "../repositories/base/base_player_event_logs_repository.h"
#include <cereal/archives/json.hpp>
#include <cereal/types/vector.hpp>
struct DiscordField {
std::string name;
std::string value;
bool is_inline;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(name),
CEREAL_NVP(value),
cereal::make_nvp("inline", is_inline)
);
}
};
struct DiscordAuthor {
std::string name;
std::string icon_url;
std::string url;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(name),
CEREAL_NVP(icon_url),
CEREAL_NVP(url)
);
}
};
struct DiscordEmbed {
std::vector<DiscordField> fields;
std::string title;
std::string description;
std::string timestamp;
DiscordAuthor author;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(fields),
CEREAL_NVP(title),
CEREAL_NVP(description),
CEREAL_NVP(timestamp),
CEREAL_NVP(author)
);
}
};
struct DiscordWebhook {
std::vector<DiscordEmbed> embeds;
std::string content;
std::string avatar_url;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(embeds),
CEREAL_NVP(avatar_url),
CEREAL_NVP(content)
);
}
};
class PlayerEventDiscordFormatter {
public:
static std::string GetCurrentTimestamp();
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
static std::string
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
static void BuildDiscordField(
std::vector<DiscordField> *f,
const std::string &name,
const std::string &value,
bool is_inline = true
);
static void BuildBaseEmbed(
std::vector<DiscordEmbed> *e,
const std::vector<DiscordField> &f,
PlayerEvent::PlayerEventContainer c
);
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
static std::string FormatAAGainedEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::AAGainedEvent &e
);
static std::string FormatAAPurchasedEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::AAPurchasedEvent &e
);
static std::string FormatDeathEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::DeathEvent &e
);
static std::string FormatFishSuccessEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::FishSuccessEvent &e
);
static std::string FormatForageSuccessEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::ForageSuccessEvent &e
);
static std::string FormatDestroyItemEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::DestroyItemEvent &e
);
static std::string FormatDiscoverItemEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::DiscoverItemEvent &e
);
static std::string FormatDroppedItemEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::DroppedItemEvent &e
);
static std::string FormatLevelGainedEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::LevelGainedEvent &e
);
static std::string FormatLevelLostEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::LevelLostEvent &e
);
static std::string FormatLootItemEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::LootItemEvent &e
);
static std::string FormatGroundSpawnPickupEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::GroundSpawnPickupEvent &e
);
static std::string FormatMerchantPurchaseEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::MerchantPurchaseEvent &e
);
static std::string FormatMerchantSellEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::MerchantSellEvent &e
);
static std::string FormatNPCHandinEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::HandinEvent &e
);
static std::string FormatSkillUpEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::SkillUpEvent &e
);
static std::string FormatTaskAcceptEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::TaskAcceptEvent &e
);
static std::string FormatTaskCompleteEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::TaskCompleteEvent &e
);
static std::string FormatTaskUpdateEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::TaskUpdateEvent &e
);
static std::string FormatTradeEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::TradeEvent &e
);
static std::string FormatTraderPurchaseEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::TraderPurchaseEvent &e
);
static std::string FormatTraderSellEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::TraderSellEvent &e
);
static std::string FormatResurrectAcceptEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::ResurrectAcceptEvent &e
);
static std::string FormatSplitMoneyEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::SplitMoneyEvent &e
);
static std::string FormatCombineEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::CombineEvent &e
);
static std::string FormatZoningEvent(
const PlayerEvent::PlayerEventContainer &c,
const PlayerEvent::ZoningEvent &e
);
static DiscordWebhook BuildDiscordWebhook(
const PlayerEvent::PlayerEventContainer &p,
std::vector<DiscordEmbed> &embeds
);
};
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
+703
View File
@@ -0,0 +1,703 @@
#include <cereal/archives/json.hpp>
#include "player_event_logs.h"
#include "player_event_discord_formatter.h"
#include "../platform.h"
#include "../rulesys.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);
ValidateDatabaseConnection();
// initialize settings array
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
m_settings[i].id = i;
m_settings[i].event_name = PlayerEvent::EventName[i];
m_settings[i].event_enabled = 1;
m_settings[i].retention_days = 0;
m_settings[i].discord_webhook_id = 0;
}
SetSettingsDefaults();
// initialize settings from database
auto s = PlayerEventLogSettingsRepository::All(*m_database);
std::vector<int> db{};
db.reserve(s.size());
for (auto &e: s) {
m_settings[e.id] = e;
db.emplace_back(e.id);
}
// insert entries that don't exist in database
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
bool is_deprecated = Strings::Contains(PlayerEvent::EventName[i], "Deprecated");
bool is_implemented = !Strings::Contains(PlayerEvent::EventName[i], "Unimplemented");
// remove when deprecated
if (is_deprecated && is_in_database) {
LogInfo("[Deprecated] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
}
// remove when unimplemented if present
if (!is_implemented && is_in_database) {
LogInfo("[Unimplemented] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
}
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
if (is_missing_in_database && is_implemented && !is_deprecated) {
LogInfo(
"[New] PlayerEvent [{}] ({})",
PlayerEvent::EventName[i],
i
);
auto c = PlayerEventLogSettingsRepository::NewEntity();
c.id = i;
c.event_name = PlayerEvent::EventName[i];
c.event_enabled = m_settings[i].event_enabled;
c.retention_days = m_settings[i].retention_days;
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
}
}
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) {
ProcessRetentionTruncation();
}
}
// set the database object, during initialization
PlayerEventLogs *PlayerEventLogs::SetDatabase(Database *db)
{
m_database = db;
return this;
}
// validates whether the connection is valid or not, used in initialization
bool PlayerEventLogs::ValidateDatabaseConnection()
{
if (!m_database) {
LogError("No database connection");
return false;
}
return true;
}
// determines if the passed in event is enabled or not
// this is used to gate logic or events from firing off
// this is used prior to building the events, we don't want to
// build the events, send them through the stack in a function call
// only to discard them immediately afterwards, very wasteful on resources
// the quest api currently does this
bool PlayerEventLogs::IsEventEnabled(PlayerEvent::EventType event)
{
return m_settings[event].event_enabled ? m_settings[event].event_enabled : false;
}
// this processes any current player events on the queue
void PlayerEventLogs::ProcessBatchQueue()
{
if (m_record_batch_queue.empty()) {
return;
}
BenchTimer benchmark;
// flush many
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
LogInfo(
"Processing batch player event log queue of [{}] took [{}]",
m_record_batch_queue.size(),
benchmark.elapsed()
);
// empty
m_batch_queue_lock.lock();
m_record_batch_queue = {};
m_batch_queue_lock.unlock();
}
// adds a player event to the queue
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
{
m_batch_queue_lock.lock();
m_record_batch_queue.emplace_back(log);
m_batch_queue_lock.unlock();
}
// fills common event data in the SendEvent function
void PlayerEventLogs::FillPlayerEvent(
const PlayerEvent::PlayerEvent &p,
PlayerEventLogsRepository::PlayerEventLogs &n
)
{
n.account_id = p.account_id;
n.character_id = p.character_id;
n.zone_id = p.zone_id;
n.instance_id = p.instance_id;
n.x = p.x;
n.y = p.y;
n.z = p.z;
n.heading = p.heading;
}
// builds the dynamic packet used to ship the player event over the wire
// supports serializing the struct so it can be rebuilt on the other end
std::unique_ptr<ServerPacket>
PlayerEventLogs::BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e)
{
EQ::Net::DynamicPacket dyn_pack;
dyn_pack.PutSerialize(0, e);
auto pack_size = sizeof(ServerSendPlayerEvent_Struct) + dyn_pack.Length();
auto pack = std::make_unique<ServerPacket>(ServerOP_PlayerEvent, static_cast<uint32_t>(pack_size));
auto buf = reinterpret_cast<ServerSendPlayerEvent_Struct *>(pack->pBuffer);
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
return pack;
}
const PlayerEventLogSettingsRepository::PlayerEventLogSettings *PlayerEventLogs::GetSettings() const
{
return m_settings;
}
bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
{
// out of bounds check
if (event_type_id >= PlayerEvent::EventType::MAX) {
return false;
}
// make sure webhook id is set
if (m_settings[event_type_id].discord_webhook_id == 0) {
return false;
}
// ensure there is a matching webhook to begin with
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
return true;
}
return false;
}
std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_type_id)
{
// out of bounds check
if (event_type_id >= PlayerEvent::EventType::MAX) {
return "";
}
// make sure webhook id is set
if (m_settings[event_type_id].discord_webhook_id == 0) {
return "";
}
// ensure there is a matching webhook to begin with
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
}
return "";
}
// GM_COMMAND | [x] Implemented Formatter
// ZONING | [x] Implemented Formatter
// AA_GAIN | [x] Implemented Formatter
// AA_PURCHASE | [x] Implemented Formatter
// FORAGE_SUCCESS | [x] Implemented Formatter
// FORAGE_FAILURE | [x] Implemented Formatter
// FISH_SUCCESS | [x] Implemented Formatter
// FISH_FAILURE | [x] Implemented Formatter
// ITEM_DESTROY | [x] Implemented Formatter
// WENT_ONLINE | [x] Implemented Formatter
// WENT_OFFLINE | [x] Implemented Formatter
// LEVEL_GAIN | [x] Implemented Formatter
// LEVEL_LOSS | [x] Implemented Formatter
// LOOT_ITEM | [x] Implemented Formatter
// MERCHANT_PURCHASE | [x] Implemented Formatter
// MERCHANT_SELL | [x] Implemented Formatter
// GROUP_JOIN | [] Implemented Formatter
// GROUP_LEAVE | [] Implemented Formatter
// RAID_JOIN | [] Implemented Formatter
// RAID_LEAVE | [] Implemented Formatter
// GROUNDSPAWN_PICKUP | [x] Implemented Formatter
// NPC_HANDIN | [x] Implemented Formatter
// SKILL_UP | [x] Implemented Formatter
// TASK_ACCEPT | [x] Implemented Formatter
// TASK_UPDATE | [x] Implemented Formatter
// TASK_COMPLETE | [x] Implemented Formatter
// TRADE | [] Implemented Formatter
// GIVE_ITEM | [] Implemented Formatter
// SAY | [x] Implemented Formatter
// REZ_ACCEPTED | [x] Implemented Formatter
// DEATH | [x] Implemented Formatter
// COMBINE_FAILURE | [x] Implemented Formatter
// COMBINE_SUCCESS | [x] Implemented Formatter
// DROPPED_ITEM | [x] Implemented Formatter
// SPLIT_MONEY | [x] Implemented Formatter
// DZ_JOIN | [] Implemented Formatter
// DZ_LEAVE | [] Implemented Formatter
// TRADER_PURCHASE | [x] Implemented Formatter
// TRADER_SELL | [x] Implemented Formatter
// BANDOLIER_CREATE | [] Implemented Formatter
// BANDOLIER_SWAP | [] Implemented Formatter
// DISCOVER_ITEM | [X] Implemented Formatter
std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e)
{
std::string payload;
switch (e.player_event_log.event_type_id) {
case PlayerEvent::AA_GAIN: {
PlayerEvent::AAGainedEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatAAGainedEvent(e, n);
break;
}
case PlayerEvent::AA_PURCHASE: {
PlayerEvent::AAPurchasedEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatAAPurchasedEvent(e, n);
break;
}
case PlayerEvent::COMBINE_FAILURE:
case PlayerEvent::COMBINE_SUCCESS: {
PlayerEvent::CombineEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatCombineEvent(e, n);
break;
}
case PlayerEvent::DEATH: {
PlayerEvent::DeathEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatDeathEvent(e, n);
break;
}
case PlayerEvent::DISCOVER_ITEM: {
PlayerEvent::DiscoverItemEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatDiscoverItemEvent(e, n);
break;
}
case PlayerEvent::DROPPED_ITEM: {
PlayerEvent::DroppedItemEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
break;
}
case PlayerEvent::FISH_FAILURE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::FISH_SUCCESS: {
PlayerEvent::FishSuccessEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
break;
}
case PlayerEvent::FORAGE_FAILURE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::FORAGE_SUCCESS: {
PlayerEvent::ForageSuccessEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatForageSuccessEvent(e, n);
break;
}
case PlayerEvent::ITEM_DESTROY: {
PlayerEvent::DestroyItemEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatDestroyItemEvent(e, n);
break;
}
case PlayerEvent::LEVEL_GAIN: {
PlayerEvent::LevelGainedEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatLevelGainedEvent(e, n);
break;
}
case PlayerEvent::LEVEL_LOSS: {
PlayerEvent::LevelLostEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatLevelLostEvent(e, n);
break;
}
case PlayerEvent::LOOT_ITEM: {
PlayerEvent::LootItemEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatLootItemEvent(e, n);
break;
}
case PlayerEvent::GROUNDSPAWN_PICKUP: {
PlayerEvent::GroundSpawnPickupEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatGroundSpawnPickupEvent(e, n);
break;
}
case PlayerEvent::NPC_HANDIN: {
PlayerEvent::HandinEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatNPCHandinEvent(e, n);
break;
}
case PlayerEvent::SAY: {
PlayerEvent::SayEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatEventSay(e, n);
break;
}
case PlayerEvent::GM_COMMAND: {
PlayerEvent::GMCommandEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatGMCommand(e, n);
break;
}
case PlayerEvent::SKILL_UP: {
PlayerEvent::SkillUpEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatSkillUpEvent(e, n);
break;
}
case PlayerEvent::SPLIT_MONEY: {
PlayerEvent::SplitMoneyEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatSplitMoneyEvent(e, n);
break;
}
case PlayerEvent::TASK_ACCEPT: {
PlayerEvent::TaskAcceptEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatTaskAcceptEvent(e, n);
break;
}
case PlayerEvent::TASK_COMPLETE: {
PlayerEvent::TaskCompleteEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatTaskCompleteEvent(e, n);
break;
}
case PlayerEvent::TASK_UPDATE: {
PlayerEvent::TaskUpdateEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatTaskUpdateEvent(e, n);
break;
}
case PlayerEvent::TRADE: {
PlayerEvent::TradeEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatTradeEvent(e, n);
break;
}
case PlayerEvent::TRADER_PURCHASE: {
PlayerEvent::TraderPurchaseEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatTraderPurchaseEvent(e, n);
break;
}
case PlayerEvent::TRADER_SELL: {
PlayerEvent::TraderSellEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatTraderSellEvent(e, n);
break;
}
case PlayerEvent::REZ_ACCEPTED: {
PlayerEvent::ResurrectAcceptEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
break;
}
case PlayerEvent::WENT_ONLINE:
case PlayerEvent::WENT_OFFLINE: {
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
break;
}
case PlayerEvent::MERCHANT_PURCHASE: {
PlayerEvent::MerchantPurchaseEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatMerchantPurchaseEvent(e, n);
break;
}
case PlayerEvent::MERCHANT_SELL: {
PlayerEvent::MerchantSellEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatMerchantSellEvent(e, n);
break;
}
case PlayerEvent::ZONING: {
PlayerEvent::ZoningEvent n{};
std::stringstream ss;
{
ss << e.player_event_log.event_data;
cereal::JSONInputArchive ar(ss);
n.serialize(ar);
}
payload = PlayerEventDiscordFormatter::FormatZoningEvent(e, n);
break;
}
default: {
LogInfo(
"Player event [{}] ({}) Discord formatter not implemented",
e.player_event_log.event_type_name,
e.player_event_log.event_type_id
);
}
}
return payload;
}
// general process function, used in world or UCS depending on rule Logging:PlayerEventsQSProcess
void PlayerEventLogs::Process()
{
if (m_process_batch_events_timer.Check()) {
ProcessBatchQueue();
}
if (m_process_retention_truncation_timer.Check()) {
ProcessRetentionTruncation();
}
}
void PlayerEventLogs::ProcessRetentionTruncation()
{
LogInfo("Running truncation");
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
)
);
if (deleted_count > 0) {
LogInfo(
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
deleted_count,
PlayerEvent::EventName[i],
i,
m_settings[i].retention_days
);
}
}
}
}
void PlayerEventLogs::ReloadSettings()
{
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
m_settings[e.id] = e;
}
}
const int32_t RETENTION_DAYS_DEFAULT = 7;
void PlayerEventLogs::SetSettingsDefaults()
{
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
m_settings[PlayerEvent::ZONING].event_enabled = 1;
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
m_settings[PlayerEvent::TRADE].event_enabled = 1;
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
m_settings[PlayerEvent::SAY].event_enabled = 0;
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
m_settings[PlayerEvent::DEATH].event_enabled = 1;
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 1;
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
}
}
+85
View File
@@ -0,0 +1,85 @@
#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>
class PlayerEventLogs {
public:
void Init();
void ReloadSettings();
PlayerEventLogs *SetDatabase(Database *db);
bool ValidateDatabaseConnection();
bool IsEventEnabled(PlayerEvent::EventType event);
void Process();
// batch queue
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
// main event record generic function
// can ingest any struct event types
template<typename T>
std::unique_ptr<ServerPacket> RecordEvent(
PlayerEvent::EventType t,
const PlayerEvent::PlayerEvent &p,
T e
)
{
auto n = PlayerEventLogsRepository::NewEntity();
FillPlayerEvent(p, n);
n.event_type_id = t;
std::stringstream ss;
{
cereal::JSONOutputArchiveSingleLine ar(ss);
e.serialize(ar);
}
n.event_type_name = PlayerEvent::EventName[t];
n.event_data = Strings::Contains(ss.str(), "noop") ? "{}" : ss.str();
n.created_at = std::time(nullptr);
auto c = PlayerEvent::PlayerEventContainer{
.player_event = p,
.player_event_log = n
};
return BuildPlayerEventPacket(c);
}
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
bool IsEventDiscordEnabled(int32_t event_type_id);
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
private:
Database *m_database; // reference to database
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
// batch queue is used to record events in batch
std::vector<PlayerEventLogsRepository::PlayerEventLogs> m_record_batch_queue{};
static void FillPlayerEvent(const PlayerEvent::PlayerEvent &p, PlayerEventLogsRepository::PlayerEventLogs &n);
static std::unique_ptr<ServerPacket>
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
// timers
Timer m_process_batch_events_timer; // events processing timer
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
// processing
std::mutex m_batch_queue_lock{};
void ProcessBatchQueue();
void ProcessRetentionTruncation();
void SetSettingsDefaults();
};
extern PlayerEventLogs player_event_logs;
#endif //EQEMU_PLAYER_EVENT_LOGS_H
+935
View File
@@ -0,0 +1,935 @@
#ifndef EQEMU_PLAYER_EVENTS_H
#define EQEMU_PLAYER_EVENTS_H
#include <string>
#include <cereal/cereal.hpp>
#include "../types.h"
#include "../repositories/player_event_logs_repository.h"
namespace PlayerEvent {
enum EventType {
GM_COMMAND = 1,
ZONING,
AA_GAIN,
AA_PURCHASE,
FORAGE_SUCCESS,
FORAGE_FAILURE,
FISH_SUCCESS,
FISH_FAILURE,
ITEM_DESTROY,
WENT_ONLINE,
WENT_OFFLINE,
LEVEL_GAIN,
LEVEL_LOSS,
LOOT_ITEM,
MERCHANT_PURCHASE,
MERCHANT_SELL,
GROUP_JOIN, // unimplemented
GROUP_LEAVE, // unimplemented
RAID_JOIN, // unimplemented
RAID_LEAVE, // unimplemented
GROUNDSPAWN_PICKUP,
NPC_HANDIN,
SKILL_UP,
TASK_ACCEPT,
TASK_UPDATE,
TASK_COMPLETE,
TRADE,
GIVE_ITEM, // unimplemented
SAY,
REZ_ACCEPTED,
DEATH,
COMBINE_FAILURE,
COMBINE_SUCCESS,
DROPPED_ITEM,
SPLIT_MONEY,
DZ_JOIN, // unimplemented
DZ_LEAVE, // unimplemented
TRADER_PURCHASE,
TRADER_SELL,
BANDOLIER_CREATE, // unimplemented
BANDOLIER_SWAP, // unimplemented
DISCOVER_ITEM,
POSSIBLE_HACK,
KILLED_NPC,
KILLED_NAMED_NPC,
KILLED_RAID_NPC,
MAX // dont remove
};
// Don't ever remove items, even if they are deprecated
// If event is deprecated just tag (Deprecated) in the name
// If event is unimplemented just tag (Unimplemented) in the name
// Events don't get saved to the database if unimplemented or deprecated
// Events tagged as deprecated will get automatically removed
static const char *EventName[PlayerEvent::MAX] = {
"None",
"GM Command",
"Zoning",
"AA Gain",
"AA Purchase",
"Forage Success",
"Forage Failure",
"Fish Success",
"Fish Failure",
"Item Destroy",
"Went Online",
"Went Offline",
"Level Gain",
"Level Loss",
"Loot Item",
"Merchant Purchase",
"Merchant Sell",
"Group Join (Unimplemented)",
"Group Leave (Unimplemented)",
"Raid Join (Unimplemented)",
"Raid Leave (Unimplemented)",
"Groundspawn Pickup",
"NPC Handin",
"Skill Up",
"Task Accept",
"Task Update",
"Task Complete",
"Trade",
"Given Item (Unimplemented)",
"Say",
"Rez Accepted",
"Death",
"Combine Failure",
"Combine Success",
"Dropped Item",
"Split Money",
"DZ Join (Unimplemented)",
"DZ Leave (Unimplemented)",
"Trader Purchase",
"Trader Sell",
"Bandolier Create (Unimplemented)",
"Bandolier Swap (Unimplemented)",
"Discover Item",
"Possible Hack",
"Killed NPC",
"Killed Named NPC",
"Killed Raid NPC"
};
// Generic struct used by all events
struct PlayerEvent {
int64 account_id;
std::string account_name;
int64 character_id;
std::string character_name;
int64 guild_id;
std::string guild_name;
int zone_id;
std::string zone_short_name;
std::string zone_long_name;
int instance_id;
float x;
float y;
float z;
float heading;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(account_id),
CEREAL_NVP(account_name),
CEREAL_NVP(character_id),
CEREAL_NVP(character_name),
CEREAL_NVP(guild_id),
CEREAL_NVP(guild_name),
CEREAL_NVP(zone_id),
CEREAL_NVP(zone_short_name),
CEREAL_NVP(zone_long_name),
CEREAL_NVP(instance_id),
CEREAL_NVP(x),
CEREAL_NVP(y),
CEREAL_NVP(z),
CEREAL_NVP(heading)
);
}
};
// contains metadata in use for things like log/discord formatters
// along with the actual event to be persisted
struct PlayerEventContainer {
PlayerEvent player_event;
PlayerEventLogsRepository::PlayerEventLogs player_event_log;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(player_event),
CEREAL_NVP(player_event_log)
);
}
};
// used in events with no extra data
struct EmptyEvent {
std::string noop; // noop, gets discard upstream
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(noop)
);
}
};
// 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)
);
}
};
// used in Trade event
class TradeItemEntry {
public:
uint16 slot;
uint32 item_id;
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)
{
ar(
CEREAL_NVP(slot),
CEREAL_NVP(item_id),
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)
);
}
};
/**
* Events
*/
struct Money {
int32 platinum;
int32 gold;
int32 silver;
int32 copper;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(platinum),
CEREAL_NVP(gold),
CEREAL_NVP(silver),
CEREAL_NVP(copper)
);
}
};
struct TradeEvent {
uint32 character_1_id;
std::string character_1_name;
uint32 character_2_id;
std::string character_2_name;
Money character_1_give_money;
Money character_2_give_money;
std::vector<TradeItemEntry> character_1_give_items;
std::vector<TradeItemEntry> character_2_give_items;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(character_1_id),
CEREAL_NVP(character_1_name),
CEREAL_NVP(character_2_id),
CEREAL_NVP(character_2_name),
CEREAL_NVP(character_1_give_money),
CEREAL_NVP(character_2_give_money),
CEREAL_NVP(character_1_give_items),
CEREAL_NVP(character_2_give_items)
);
}
};
struct GMCommandEvent {
std::string message;
std::string target;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(message),
CEREAL_NVP(target)
);
}
};
struct ZoningEvent {
std::string from_zone_long_name;
std::string from_zone_short_name;
int32 from_zone_id;
int32 from_instance_id;
int32 from_instance_version;
std::string to_zone_long_name;
std::string to_zone_short_name;
int32 to_zone_id;
int32 to_instance_id;
int32 to_instance_version;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(from_zone_long_name),
CEREAL_NVP(from_zone_short_name),
CEREAL_NVP(from_zone_id),
CEREAL_NVP(from_instance_id),
CEREAL_NVP(from_instance_version),
CEREAL_NVP(to_zone_long_name),
CEREAL_NVP(to_zone_short_name),
CEREAL_NVP(to_zone_id),
CEREAL_NVP(to_instance_id),
CEREAL_NVP(to_instance_version)
);
}
};
struct AAGainedEvent {
uint32 aa_gained;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(CEREAL_NVP(aa_gained));
}
};
struct AAPurchasedEvent {
int32 aa_id;
int32 aa_cost;
int32 aa_previous_id;
int32 aa_next_id;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(aa_id),
CEREAL_NVP(aa_cost),
CEREAL_NVP(aa_previous_id),
CEREAL_NVP(aa_next_id)
);
}
};
struct ForageSuccessEvent {
uint32 item_id;
std::string item_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name)
);
}
};
struct FishSuccessEvent {
uint32 item_id;
std::string item_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name)
);
}
};
struct DestroyItemEvent {
uint32 item_id;
std::string item_name;
int16 charges;
std::string reason;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(reason),
CEREAL_NVP(charges)
);
}
};
struct LevelGainedEvent {
uint32 from_level;
uint8 to_level;
int levels_gained;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(from_level),
CEREAL_NVP(to_level),
CEREAL_NVP(levels_gained)
);
}
};
struct LevelLostEvent {
uint32 from_level;
uint8 to_level;
int levels_lost;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(from_level),
CEREAL_NVP(to_level),
CEREAL_NVP(levels_lost)
);
}
};
struct LootItemEvent {
uint32 item_id;
std::string item_name;
int16 charges;
uint32 npc_id;
std::string corpse_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(charges),
CEREAL_NVP(npc_id),
CEREAL_NVP(corpse_name)
);
}
};
struct MerchantPurchaseEvent {
uint32 npc_id;
std::string merchant_name;
uint32 merchant_type;
uint32 item_id;
std::string item_name;
int16 charges;
uint32 cost;
uint32 alternate_currency_id;
uint64 player_money_balance;
uint64 player_currency_balance;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(npc_id),
CEREAL_NVP(merchant_name),
CEREAL_NVP(merchant_type),
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(charges),
CEREAL_NVP(cost),
CEREAL_NVP(alternate_currency_id),
CEREAL_NVP(player_money_balance),
CEREAL_NVP(player_currency_balance)
);
}
};
struct MerchantSellEvent {
uint32 npc_id;
std::string merchant_name;
uint32 merchant_type;
uint32 item_id;
std::string item_name;
int16 charges;
uint32 cost;
uint32 alternate_currency_id;
uint64 player_money_balance;
uint64 player_currency_balance;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(npc_id),
CEREAL_NVP(merchant_name),
CEREAL_NVP(merchant_type),
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(charges),
CEREAL_NVP(cost),
CEREAL_NVP(alternate_currency_id),
CEREAL_NVP(player_money_balance),
CEREAL_NVP(player_currency_balance)
);
}
};
struct SkillUpEvent {
uint32 skill_id;
int value;
int16 max_skill;
std::string against_who;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(skill_id),
CEREAL_NVP(value),
CEREAL_NVP(max_skill),
CEREAL_NVP(against_who)
);
}
};
struct TaskAcceptEvent {
uint32 npc_id;
std::string npc_name;
uint32 task_id;
std::string task_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(npc_id),
CEREAL_NVP(npc_name),
CEREAL_NVP(task_id),
CEREAL_NVP(task_name)
);
}
};
struct TaskUpdateEvent {
uint32 task_id;
std::string task_name;
uint32 activity_id;
uint32 done_count;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(task_id),
CEREAL_NVP(task_name),
CEREAL_NVP(activity_id),
CEREAL_NVP(done_count)
);
}
};
struct TaskCompleteEvent {
uint32 task_id;
std::string task_name;
uint32 activity_id;
uint32 done_count;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(task_id),
CEREAL_NVP(task_name),
CEREAL_NVP(activity_id),
CEREAL_NVP(done_count)
);
}
};
struct GroundSpawnPickupEvent {
uint32 item_id;
std::string item_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name)
);
}
};
struct SayEvent {
std::string message;
std::string target;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(message),
CEREAL_NVP(target)
);
}
};
struct ResurrectAcceptEvent {
std::string resurrecter_name;
std::string spell_name;
uint32 spell_id;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(resurrecter_name),
CEREAL_NVP(spell_name),
CEREAL_NVP(spell_id)
);
}
};
struct CombineEvent {
uint32 recipe_id;
std::string recipe_name;
uint32 made_count;
uint32 tradeskill_id;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(recipe_id),
CEREAL_NVP(recipe_name),
CEREAL_NVP(made_count),
CEREAL_NVP(tradeskill_id)
);
}
};
struct DroppedItemEvent {
uint32 item_id;
std::string item_name;
int16 slot_id;
uint32 charges;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(slot_id),
CEREAL_NVP(charges)
);
}
};
struct DeathEvent {
uint32 killer_id;
std::string killer_name;
int64 damage;
uint32 spell_id;
std::string spell_name;
int skill_id;
std::string skill_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(killer_id),
CEREAL_NVP(killer_name),
CEREAL_NVP(damage),
CEREAL_NVP(spell_id),
CEREAL_NVP(spell_name),
CEREAL_NVP(skill_id),
CEREAL_NVP(skill_name)
);
}
};
struct SplitMoneyEvent {
uint32 copper;
uint32 silver;
uint32 gold;
uint32 platinum;
uint64 player_money_balance;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(copper),
CEREAL_NVP(silver),
CEREAL_NVP(gold),
CEREAL_NVP(platinum),
CEREAL_NVP(player_money_balance)
);
}
};
struct TraderPurchaseEvent {
uint32 item_id;
std::string item_name;
uint32 trader_id;
std::string trader_name;
uint32 price;
uint32 charges;
uint32 total_cost;
uint64 player_money_balance;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(trader_id),
CEREAL_NVP(trader_name),
CEREAL_NVP(price),
CEREAL_NVP(charges),
CEREAL_NVP(total_cost),
CEREAL_NVP(player_money_balance)
);
}
};
struct TraderSellEvent {
uint32 item_id;
std::string item_name;
uint32 buyer_id;
std::string buyer_name;
uint32 price;
uint32 charges;
uint32 total_cost;
uint64 player_money_balance;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(buyer_id),
CEREAL_NVP(buyer_name),
CEREAL_NVP(price),
CEREAL_NVP(charges),
CEREAL_NVP(total_cost),
CEREAL_NVP(player_money_balance)
);
}
};
struct DiscoverItemEvent {
uint32 item_id;
std::string item_name;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name)
);
}
};
class HandinEntry {
public:
uint32 item_id;
std::string item_name;
uint16 charges;
bool attuned;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(charges),
CEREAL_NVP(attuned)
);
}
};
class HandinMoney {
public:
uint32 copper;
uint32 silver;
uint32 gold;
uint32 platinum;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(copper),
CEREAL_NVP(silver),
CEREAL_NVP(gold),
CEREAL_NVP(platinum)
);
}
};
struct HandinEvent {
uint32 npc_id;
std::string npc_name;
std::vector<HandinEntry> handin_items;
HandinMoney handin_money;
std::vector<HandinEntry> return_items;
HandinMoney return_money;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(npc_id),
CEREAL_NVP(npc_name),
CEREAL_NVP(handin_items),
CEREAL_NVP(handin_money),
CEREAL_NVP(return_items),
CEREAL_NVP(return_money)
);
}
};
struct PossibleHackEvent {
std::string message;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(message)
);
}
};
struct KilledNPCEvent {
uint32 npc_id;
std::string npc_name;
uint32 combat_time_seconds;
uint64 total_damage_per_second_taken;
uint64 total_heal_per_second_taken;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(npc_id),
CEREAL_NVP(npc_name),
CEREAL_NVP(combat_time_seconds),
CEREAL_NVP(total_damage_per_second_taken),
CEREAL_NVP(total_heal_per_second_taken)
);
}
};
}
#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()\
);\
}\
} 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()\
);\
}\
} while (0)
+5 -17
View File
@@ -63,7 +63,9 @@ bool BaseGuildManager::LoadGuilds() {
for (auto row=results.begin();row!=results.end();++row)
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
query = "SELECT guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
query = "SELECT guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
results = m_db->QueryDatabase(query);
if (!results.Success())
@@ -864,20 +866,11 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
return(true);
}
//factored out so I dont have to copy this crap.
#ifdef BOTS
#define GuildMemberBaseQuery \
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
" g.`banker`, g.`public_note`, g.`alt`" \
" FROM `vw_bot_character_mobs` AS c LEFT JOIN `vw_guild_members` AS g ON c.`id` = g.`char_id` AND c.`mob_type` = g.`mob_type` "
#else
#define GuildMemberBaseQuery \
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
" g.`banker`, g.`public_note`, g.`alt` " \
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
#endif
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
//fields from `characer_`
into.char_id = atoi(row[0]);
@@ -967,13 +960,8 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
}
//load up the rank info for each guild.
std::string query;
#ifdef BOTS
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C' AND c.deleted_at IS NULL", char_id);
#else
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
#endif
auto results = m_db->QueryDatabase(query);
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
auto results = m_db->QueryDatabase(query);
if (!results.Success()) {
return false;
}
+3 -1
View File
@@ -26,6 +26,8 @@
#include "item_instance.h"
#include "classes.h"
#include "races.h"
#include <list>
#include <vector>
@@ -130,7 +132,7 @@ namespace EQ
// Swap items in inventory
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = 0, uint8 class_id = 0, uint16 deity_id = 0, uint8 level = 0);
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = RACE_DOUG_0, uint8 class_id = NO_CLASS, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
// Remove item from inventory
bool DeleteItem(int16 slot_id, int16 quantity = 0);
+1 -1
View File
@@ -198,7 +198,7 @@ std::string IpUtil::DNSLookupSync(const std::string &addr, int port)
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() > 1500) {
LogInfo(
"[DNSLookupSync] Deadline exceeded [{}]",
"Deadline exceeded [{}]",
1500
);
running = false;
+26 -12
View File
@@ -358,15 +358,27 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
}
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
{
if (!m_item || !m_item->IsClassCommon())
return false;
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) {
if (
(
!GetItem(slot) &&
m_item->AugSlotVisible[slot]
) &&
augment_type == -1 ||
(
m_item->AugSlotType[slot] &&
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
)
) {
return true;
}
return false;
return false;
}
// Retrieve item inside container
@@ -534,10 +546,11 @@ bool EQ::ItemInstance::IsNoneEmptyContainer()
}
// Retrieve augment inside item
EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 slot) const
EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
{
if (m_item && m_item->IsClassCommon())
return GetItem(slot);
if (m_item && m_item->IsClassCommon()) {
return GetItem(augment_index);
}
return nullptr;
}
@@ -663,12 +676,13 @@ bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *C
return false;
}
uint32 EQ::ItemInstance::GetAugmentItemID(uint8 slot) const
uint32 EQ::ItemInstance::GetAugmentItemID(uint8 augment_index) const
{
if (!m_item || !m_item->IsClassCommon())
if (!m_item || !m_item->IsClassCommon()) {
return 0;
}
return GetItemID(slot);
return GetItemID(augment_index);
}
// Add an augment to the item
@@ -1249,7 +1263,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bool augments) const
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
{
int race = 0;
int race = RACE_DOUG_0;
const auto item = GetItem();
if (item) {
race = item->BaneDmgRace;
+4 -4
View File
@@ -101,8 +101,8 @@ namespace EQ
//
bool IsAugmentable() const;
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augtype) const;
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
int8 AvailableAugmentSlot(int32 augment_type) const;
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
@@ -127,8 +127,8 @@ namespace EQ
//
// Augments
//
ItemInstance* GetAugment(uint8 slot) const;
uint32 GetAugmentItemID(uint8 slot) const;
ItemInstance* GetAugment(uint8 augment_index) const;
uint32 GetAugmentItemID(uint8 augment_index) const;
void PutAugment(uint8 slot, const ItemInstance& inst);
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
void DeleteAugment(uint8 slot);
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -665,7 +665,7 @@ namespace RoF
ENCODE(OP_DeleteCharge)
{
Log(Logs::Moderate, Logs::Netcode, "RoF::ENCODE(OP_DeleteCharge)");
Log(Logs::Detail, Logs::Netcode, "RoF::ENCODE(OP_DeleteCharge)");
ENCODE_FORWARD(OP_MoveItem);
}
@@ -1593,7 +1593,7 @@ namespace RoF
ENCODE_LENGTH_EXACT(LootingItem_Struct);
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF::ENCODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "RoF::ENCODE(OP_LootItem)");
OUT(lootee);
OUT(looter);
@@ -1751,7 +1751,7 @@ namespace RoF
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF::ENCODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "RoF::ENCODE(OP_MoveItem)");
eq->from_slot = ServerToRoFSlot(emu->from_slot);
eq->to_slot = ServerToRoFSlot(emu->to_slot);
@@ -3831,7 +3831,7 @@ namespace RoF
}
float SpawnSize = emu->size;
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
)
{
@@ -3965,7 +3965,7 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
)
{
@@ -4822,7 +4822,7 @@ namespace RoF
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF::DECODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "RoF::DECODE(OP_LootItem)");
IN(lootee);
IN(looter);
@@ -4837,7 +4837,7 @@ namespace RoF
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF::DECODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "RoF::DECODE(OP_MoveItem)");
emu->from_slot = RoFToServerSlot(eq->from_slot);
emu->to_slot = RoFToServerSlot(eq->to_slot);
+7 -7
View File
@@ -716,7 +716,7 @@ namespace RoF2
ENCODE(OP_DeleteCharge)
{
Log(Logs::Moderate, Logs::Netcode, "RoF2::ENCODE(OP_DeleteCharge)");
Log(Logs::Detail, Logs::Netcode, "RoF2::ENCODE(OP_DeleteCharge)");
ENCODE_FORWARD(OP_MoveItem);
}
@@ -1644,7 +1644,7 @@ namespace RoF2
ENCODE_LENGTH_EXACT(LootingItem_Struct);
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF2::ENCODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "RoF2::ENCODE(OP_LootItem)");
OUT(lootee);
OUT(looter);
@@ -1802,7 +1802,7 @@ namespace RoF2
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF2::ENCODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "RoF2::ENCODE(OP_MoveItem)");
eq->from_slot = ServerToRoF2Slot(emu->from_slot);
eq->to_slot = ServerToRoF2Slot(emu->to_slot);
@@ -3967,7 +3967,7 @@ namespace RoF2
}
float SpawnSize = emu->size;
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
)
{
@@ -4172,7 +4172,7 @@ namespace RoF2
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // These do something with OP_WeaponEquip1
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // ^
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
)
{
@@ -5023,7 +5023,7 @@ namespace RoF2
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF2::DECODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "RoF2::DECODE(OP_LootItem)");
IN(lootee);
IN(looter);
@@ -5038,7 +5038,7 @@ namespace RoF2
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "RoF2::DECODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "RoF2::DECODE(OP_MoveItem)");
emu->from_slot = RoF2ToServerSlot(eq->from_slot);
emu->to_slot = RoF2ToServerSlot(eq->to_slot);
+8 -8
View File
@@ -458,7 +458,7 @@ namespace SoD
ENCODE(OP_DeleteCharge)
{
Log(Logs::Moderate, Logs::Netcode, "SoD::ENCODE(OP_DeleteCharge)");
Log(Logs::Detail, Logs::Netcode, "SoD::ENCODE(OP_DeleteCharge)");
ENCODE_FORWARD(OP_MoveItem);
}
@@ -1128,7 +1128,7 @@ namespace SoD
ENCODE_LENGTH_EXACT(LootingItem_Struct);
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoD::ENCODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "SoD::ENCODE(OP_LootItem)");
OUT(lootee);
OUT(looter);
@@ -1277,7 +1277,7 @@ namespace SoD
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoD::ENCODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "SoD::ENCODE(OP_MoveItem)");
eq->from_slot = ServerToSoDSlot(emu->from_slot);
eq->to_slot = ServerToSoDSlot(emu->to_slot);
@@ -2467,7 +2467,7 @@ namespace SoD
}
float SpawnSize = emu->size;
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
)
{
@@ -2666,7 +2666,7 @@ namespace SoD
Buffer += sizeof(structs::Spawn_Struct_Position);
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
)
{
@@ -2693,7 +2693,7 @@ namespace SoD
}
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
)
{
@@ -3226,7 +3226,7 @@ namespace SoD
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoD::DECODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "SoD::DECODE(OP_LootItem)");
IN(lootee);
IN(looter);
@@ -3241,7 +3241,7 @@ namespace SoD
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoD::DECODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "SoD::DECODE(OP_MoveItem)");
emu->from_slot = SoDToServerSlot(eq->from_slot);
emu->to_slot = SoDToServerSlot(eq->to_slot);
+5 -5
View File
@@ -436,7 +436,7 @@ namespace SoF
ENCODE(OP_DeleteCharge)
{
Log(Logs::Moderate, Logs::Netcode, "SoF::ENCODE(OP_DeleteCharge)");
Log(Logs::Detail, Logs::Netcode, "SoF::ENCODE(OP_DeleteCharge)");
ENCODE_FORWARD(OP_MoveItem);
}
@@ -923,7 +923,7 @@ namespace SoF
ENCODE_LENGTH_EXACT(LootingItem_Struct);
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoF::ENCODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "SoF::ENCODE(OP_LootItem)");
OUT(lootee);
OUT(looter);
@@ -954,7 +954,7 @@ namespace SoF
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoF::ENCODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "SoF::ENCODE(OP_MoveItem)");
eq->from_slot = ServerToSoFSlot(emu->from_slot);
eq->to_slot = ServerToSoFSlot(emu->to_slot);
@@ -2631,7 +2631,7 @@ namespace SoF
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoF::DECODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "SoF::DECODE(OP_LootItem)");
IN(lootee);
IN(looter);
@@ -2646,7 +2646,7 @@ namespace SoF
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "SoF::DECODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "SoF::DECODE(OP_MoveItem)");
emu->from_slot = SoFToServerSlot(eq->from_slot);
emu->to_slot = SoFToServerSlot(eq->to_slot);
+5 -5
View File
@@ -380,7 +380,7 @@ namespace Titanium
ENCODE(OP_DeleteCharge)
{
Log(Logs::Moderate, Logs::Netcode, "Titanium::ENCODE(OP_DeleteCharge)");
Log(Logs::Detail, Logs::Netcode, "Titanium::ENCODE(OP_DeleteCharge)");
ENCODE_FORWARD(OP_MoveItem);
}
@@ -890,7 +890,7 @@ namespace Titanium
ENCODE_LENGTH_EXACT(LootingItem_Struct);
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "Titanium::ENCODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "Titanium::ENCODE(OP_LootItem)");
OUT(lootee);
OUT(looter);
@@ -934,7 +934,7 @@ namespace Titanium
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "Titanium::ENCODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "Titanium::ENCODE(OP_MoveItem)");
eq->from_slot = ServerToTitaniumSlot(emu->from_slot);
eq->to_slot = ServerToTitaniumSlot(emu->to_slot);
@@ -2178,7 +2178,7 @@ namespace Titanium
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "Titanium::DECODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "Titanium::DECODE(OP_LootItem)");
IN(lootee);
IN(looter);
@@ -2193,7 +2193,7 @@ namespace Titanium
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "Titanium::DECODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "Titanium::DECODE(OP_MoveItem)");
emu->from_slot = TitaniumToServerSlot(eq->from_slot);
emu->to_slot = TitaniumToServerSlot(eq->to_slot);
+8 -8
View File
@@ -579,7 +579,7 @@ namespace UF
ENCODE(OP_DeleteCharge)
{
Log(Logs::Moderate, Logs::Netcode, "UF::ENCODE(OP_DeleteCharge)");
Log(Logs::Detail, Logs::Netcode, "UF::ENCODE(OP_DeleteCharge)");
ENCODE_FORWARD(OP_MoveItem);
}
@@ -1349,7 +1349,7 @@ namespace UF
ENCODE_LENGTH_EXACT(LootingItem_Struct);
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "UF::ENCODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "UF::ENCODE(OP_LootItem)");
OUT(lootee);
OUT(looter);
@@ -1502,7 +1502,7 @@ namespace UF
ENCODE_LENGTH_EXACT(MoveItem_Struct);
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "UF::ENCODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "UF::ENCODE(OP_MoveItem)");
eq->from_slot = ServerToUFSlot(emu->from_slot);
eq->to_slot = ServerToUFSlot(emu->to_slot);
@@ -2739,7 +2739,7 @@ namespace UF
}
float SpawnSize = emu->size;
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
)
{
@@ -2942,7 +2942,7 @@ namespace UF
Buffer += sizeof(structs::Spawn_Struct_Position);
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
)
{
@@ -2978,7 +2978,7 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
}
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
)
{
@@ -3584,7 +3584,7 @@ namespace UF
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "UF::DECODE(OP_LootItem)");
Log(Logs::Detail, Logs::Netcode, "UF::DECODE(OP_LootItem)");
IN(lootee);
IN(looter);
@@ -3599,7 +3599,7 @@ namespace UF
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
Log(Logs::Moderate, Logs::Netcode, "UF::DECODE(OP_MoveItem)");
Log(Logs::Detail, Logs::Netcode, "UF::DECODE(OP_MoveItem)");
emu->from_slot = UFToServerSlot(eq->from_slot);
emu->to_slot = UFToServerSlot(eq->to_slot);
+18 -11
View File
@@ -20,12 +20,19 @@ void PathManager::LoadPaths()
{
m_server_path = File::FindEqemuConfigPath();
std::filesystem::current_path(m_server_path);
if (!m_server_path.empty()) {
std::filesystem::current_path(m_server_path);
}
LogInfo("[PathManager] server [{}]", m_server_path);
if (m_server_path.empty()) {
LogInfo("Failed to load server path");
return;
}
LogInfo("server [{}]", m_server_path);
if (!EQEmuConfig::LoadConfig()) {
LogError("[PathManager] Failed to load eqemu config");
LogError("Failed to load eqemu config");
return;
}
@@ -77,14 +84,14 @@ void PathManager::LoadPaths()
m_log_path = fs::relative(fs::path{m_server_path + "/" + c->LogDir}).string();
}
LogInfo("[PathManager] logs [{}]", m_log_path);
LogInfo("[PathManager] lua mods [{}]", m_lua_mods_path);
LogInfo("[PathManager] lua_modules [{}]", m_lua_modules_path);
LogInfo("[PathManager] maps [{}]", m_maps_path);
LogInfo("[PathManager] patches [{}]", m_patch_path);
LogInfo("[PathManager] plugins [{}]", m_plugins_path);
LogInfo("[PathManager] quests [{}]", m_quests_path);
LogInfo("[PathManager] shared_memory [{}]", m_shared_memory_path);
LogInfo("logs path [{}]", m_log_path);
LogInfo("lua mods path [{}]", m_lua_mods_path);
LogInfo("lua_modules path [{}]", m_lua_modules_path);
LogInfo("maps path [{}]", m_maps_path);
LogInfo("patches path [{}]", m_patch_path);
LogInfo("plugins path [{}]", m_plugins_path);
LogInfo("quests path [{}]", m_quests_path);
LogInfo("shared_memory path [{}]", m_shared_memory_path);
}
const std::string &PathManager::GetServerPath() const
+19 -16
View File
@@ -22,26 +22,31 @@
EQEmuExePlatform exe_platform = ExePlatformNone;
void RegisterExecutablePlatform(EQEmuExePlatform p) {
void RegisterExecutablePlatform(EQEmuExePlatform p)
{
exe_platform = p;
}
const EQEmuExePlatform& GetExecutablePlatform() {
const EQEmuExePlatform &GetExecutablePlatform()
{
return exe_platform;
}
/**
* @return
*/
int GetExecutablePlatformInt(){
int GetExecutablePlatformInt()
{
return exe_platform;
}
/**
* Returns platform name by string
*
* @return
*/
bool IsWorld()
{
return exe_platform == EQEmuExePlatform::ExePlatformWorld;
}
bool IsQueryServ()
{
return exe_platform == EQEmuExePlatform::ExePlatformQueryServ;
}
std::string GetPlatformName()
{
switch (GetExecutablePlatformInt()) {
@@ -55,14 +60,12 @@ std::string GetPlatformName()
return "UCS";
case EQEmuExePlatform::ExePlatformLogin:
return "Login";
case EQEmuExePlatform::ExePlatformSocket_Server:
return "SocketServer";
case EQEmuExePlatform::ExePlatformSharedMemory:
return "SharedMemory";
return "SharedMem";
case EQEmuExePlatform::ExePlatformClientImport:
return "ClientImport";
return "Import";
case EQEmuExePlatform::ExePlatformClientExport:
return "ClientExport";
return "Export";
case EQEmuExePlatform::ExePlatformLaunch:
return "Launch";
case EQEmuExePlatform::ExePlatformHC:
+2
View File
@@ -44,5 +44,7 @@ void RegisterExecutablePlatform(EQEmuExePlatform p);
const EQEmuExePlatform& GetExecutablePlatform();
int GetExecutablePlatformInt();
std::string GetPlatformName();
bool IsWorld();
bool IsQueryServ();
#endif
+3
View File
@@ -18,6 +18,7 @@
*/
#include "profanity_manager.h"
#include "eqemu_logsys.h"
#include "dbcore.h"
#include "strings.h"
@@ -235,6 +236,8 @@ bool EQ::ProfanityManager::load_database_entries(DBcore *db) {
}
}
LogInfo("Loaded [{}] profanity entries", Strings::Commify(profanity_list.size()));
return true;
}
@@ -9,22 +9,19 @@
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_HACKERS_REPOSITORY_H
#define EQEMU_BASE_HACKERS_REPOSITORY_H
#ifndef EQEMU_BASE_CHATCHANNEL_RESERVED_NAMES_REPOSITORY_H
#define EQEMU_BASE_CHATCHANNEL_RESERVED_NAMES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseHackersRepository {
class BaseChatchannelReservedNamesRepository {
public:
struct Hackers {
struct ChatchannelReservedNames {
int32_t id;
std::string account;
std::string name;
std::string hacked;
std::string zone;
std::string date;
};
static std::string PrimaryKey()
@@ -36,11 +33,7 @@ public:
{
return {
"id",
"account",
"name",
"hacked",
"zone",
"date",
};
}
@@ -48,11 +41,7 @@ public:
{
return {
"id",
"account",
"name",
"hacked",
"zone",
"date",
};
}
@@ -68,7 +57,7 @@ public:
static std::string TableName()
{
return std::string("hackers");
return std::string("chatchannel_reserved_names");
}
static std::string BaseSelect()
@@ -89,57 +78,50 @@ public:
);
}
static Hackers NewEntity()
static ChatchannelReservedNames NewEntity()
{
Hackers e{};
ChatchannelReservedNames e{};
e.id = 0;
e.account = "";
e.name = "";
e.hacked = "";
e.zone = "";
e.date = std::time(nullptr);
e.id = 0;
e.name = "";
return e;
}
static Hackers GetHackers(
const std::vector<Hackers> &hackerss,
int hackers_id
static ChatchannelReservedNames GetChatchannelReservedNames(
const std::vector<ChatchannelReservedNames> &chatchannel_reserved_namess,
int chatchannel_reserved_names_id
)
{
for (auto &hackers : hackerss) {
if (hackers.id == hackers_id) {
return hackers;
for (auto &chatchannel_reserved_names : chatchannel_reserved_namess) {
if (chatchannel_reserved_names.id == chatchannel_reserved_names_id) {
return chatchannel_reserved_names;
}
}
return NewEntity();
}
static Hackers FindOne(
static ChatchannelReservedNames FindOne(
Database& db,
int hackers_id
int chatchannel_reserved_names_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
hackers_id
PrimaryKey(),
chatchannel_reserved_names_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Hackers e{};
ChatchannelReservedNames e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.account = row[1] ? row[1] : "";
e.name = row[2] ? row[2] : "";
e.hacked = row[3] ? row[3] : "";
e.zone = row[4] ? row[4] : "";
e.date = row[5] ? row[5] : "";
e.id = static_cast<int32_t>(atoi(row[0]));
e.name = row[1] ? row[1] : "";
return e;
}
@@ -149,7 +131,7 @@ public:
static int DeleteOne(
Database& db,
int hackers_id
int chatchannel_reserved_names_id
)
{
auto results = db.QueryDatabase(
@@ -157,7 +139,7 @@ public:
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
hackers_id
chatchannel_reserved_names_id
)
);
@@ -166,18 +148,14 @@ public:
static int UpdateOne(
Database& db,
const Hackers &e
const ChatchannelReservedNames &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.account) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.hacked) + "'");
v.push_back(columns[4] + " = '" + Strings::Escape(e.zone) + "'");
v.push_back(columns[5] + " = '" + Strings::Escape(e.date) + "'");
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -192,19 +170,15 @@ public:
return (results.Success() ? results.RowsAffected() : 0);
}
static Hackers InsertOne(
static ChatchannelReservedNames InsertOne(
Database& db,
Hackers e
ChatchannelReservedNames e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.account) + "'");
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.hacked) + "'");
v.push_back("'" + Strings::Escape(e.zone) + "'");
v.push_back("'" + Strings::Escape(e.date) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -226,7 +200,7 @@ public:
static int InsertMany(
Database& db,
const std::vector<Hackers> &entries
const std::vector<ChatchannelReservedNames> &entries
)
{
std::vector<std::string> insert_chunks;
@@ -235,11 +209,7 @@ public:
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.account) + "'");
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.hacked) + "'");
v.push_back("'" + Strings::Escape(e.zone) + "'");
v.push_back("'" + Strings::Escape(e.date) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -257,9 +227,9 @@ public:
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<Hackers> All(Database& db)
static std::vector<ChatchannelReservedNames> All(Database& db)
{
std::vector<Hackers> all_entries;
std::vector<ChatchannelReservedNames> all_entries;
auto results = db.QueryDatabase(
fmt::format(
@@ -271,14 +241,10 @@ public:
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Hackers e{};
ChatchannelReservedNames e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.account = row[1] ? row[1] : "";
e.name = row[2] ? row[2] : "";
e.hacked = row[3] ? row[3] : "";
e.zone = row[4] ? row[4] : "";
e.date = row[5] ? row[5] : "";
e.id = static_cast<int32_t>(atoi(row[0]));
e.name = row[1] ? row[1] : "";
all_entries.push_back(e);
}
@@ -286,9 +252,9 @@ public:
return all_entries;
}
static std::vector<Hackers> GetWhere(Database& db, const std::string &where_filter)
static std::vector<ChatchannelReservedNames> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<Hackers> all_entries;
std::vector<ChatchannelReservedNames> all_entries;
auto results = db.QueryDatabase(
fmt::format(
@@ -301,14 +267,10 @@ public:
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Hackers e{};
ChatchannelReservedNames e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.account = row[1] ? row[1] : "";
e.name = row[2] ? row[2] : "";
e.hacked = row[3] ? row[3] : "";
e.zone = row[4] ? row[4] : "";
e.date = row[5] ? row[5] : "";
e.id = static_cast<int32_t>(atoi(row[0]));
e.name = row[1] ? row[1] : "";
all_entries.push_back(e);
}
@@ -369,4 +331,4 @@ public:
};
#endif //EQEMU_BASE_HACKERS_REPOSITORY_H
#endif //EQEMU_BASE_CHATCHANNEL_RESERVED_NAMES_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_CHATCHANNELS_REPOSITORY_H
#define EQEMU_BASE_CHATCHANNELS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseChatchannelsRepository {
public:
struct Chatchannels {
int32_t id;
std::string name;
std::string owner;
std::string password;
int32_t minstatus;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"name",
"owner",
"password",
"minstatus",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"name",
"owner",
"password",
"minstatus",
};
}
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("chatchannels");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static Chatchannels NewEntity()
{
Chatchannels e{};
e.id = 0;
e.name = "";
e.owner = "";
e.password = "";
e.minstatus = 0;
return e;
}
static Chatchannels GetChatchannels(
const std::vector<Chatchannels> &chatchannelss,
int chatchannels_id
)
{
for (auto &chatchannels : chatchannelss) {
if (chatchannels.id == chatchannels_id) {
return chatchannels;
}
}
return NewEntity();
}
static Chatchannels FindOne(
Database& db,
int chatchannels_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
chatchannels_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Chatchannels e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.name = row[1] ? row[1] : "";
e.owner = row[2] ? row[2] : "";
e.password = row[3] ? row[3] : "";
e.minstatus = static_cast<int32_t>(atoi(row[4]));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int chatchannels_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
chatchannels_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const Chatchannels &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.owner) + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.password) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.minstatus));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static Chatchannels InsertOne(
Database& db,
Chatchannels e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.owner) + "'");
v.push_back("'" + Strings::Escape(e.password) + "'");
v.push_back(std::to_string(e.minstatus));
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<Chatchannels> &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.name) + "'");
v.push_back("'" + Strings::Escape(e.owner) + "'");
v.push_back("'" + Strings::Escape(e.password) + "'");
v.push_back(std::to_string(e.minstatus));
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<Chatchannels> All(Database& db)
{
std::vector<Chatchannels> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Chatchannels e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.name = row[1] ? row[1] : "";
e.owner = row[2] ? row[2] : "";
e.password = row[3] ? row[3] : "";
e.minstatus = static_cast<int32_t>(atoi(row[4]));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<Chatchannels> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<Chatchannels> 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) {
Chatchannels e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.name = row[1] ? row[1] : "";
e.owner = row[2] ? row[2] : "";
e.password = row[3] ? row[3] : "";
e.minstatus = static_cast<int32_t>(atoi(row[4]));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_CHATCHANNELS_REPOSITORY_H
@@ -1,412 +0,0 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_EVENTLOG_REPOSITORY_H
#define EQEMU_BASE_EVENTLOG_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseEventlogRepository {
public:
struct Eventlog {
uint32_t id;
std::string accountname;
uint32_t accountid;
int32_t status;
std::string charname;
std::string target;
std::string time;
std::string descriptiontype;
std::string description;
int32_t event_nid;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"accountname",
"accountid",
"status",
"charname",
"target",
"time",
"descriptiontype",
"description",
"event_nid",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"accountname",
"accountid",
"status",
"charname",
"target",
"time",
"descriptiontype",
"description",
"event_nid",
};
}
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("eventlog");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static Eventlog NewEntity()
{
Eventlog e{};
e.id = 0;
e.accountname = "";
e.accountid = 0;
e.status = 0;
e.charname = "";
e.target = "None";
e.time = std::time(nullptr);
e.descriptiontype = "";
e.description = "";
e.event_nid = 0;
return e;
}
static Eventlog GetEventlog(
const std::vector<Eventlog> &eventlogs,
int eventlog_id
)
{
for (auto &eventlog : eventlogs) {
if (eventlog.id == eventlog_id) {
return eventlog;
}
}
return NewEntity();
}
static Eventlog FindOne(
Database& db,
int eventlog_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
BaseSelect(),
eventlog_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Eventlog e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.accountname = row[1] ? row[1] : "";
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.status = static_cast<int32_t>(atoi(row[3]));
e.charname = row[4] ? row[4] : "";
e.target = row[5] ? row[5] : "";
e.time = row[6] ? row[6] : "";
e.descriptiontype = row[7] ? row[7] : "";
e.description = row[8] ? row[8] : "";
e.event_nid = static_cast<int32_t>(atoi(row[9]));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int eventlog_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
eventlog_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const Eventlog &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.accountname) + "'");
v.push_back(columns[2] + " = " + std::to_string(e.accountid));
v.push_back(columns[3] + " = " + std::to_string(e.status));
v.push_back(columns[4] + " = '" + Strings::Escape(e.charname) + "'");
v.push_back(columns[5] + " = '" + Strings::Escape(e.target) + "'");
v.push_back(columns[6] + " = '" + Strings::Escape(e.time) + "'");
v.push_back(columns[7] + " = '" + Strings::Escape(e.descriptiontype) + "'");
v.push_back(columns[8] + " = '" + Strings::Escape(e.description) + "'");
v.push_back(columns[9] + " = " + std::to_string(e.event_nid));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static Eventlog InsertOne(
Database& db,
Eventlog e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.accountname) + "'");
v.push_back(std::to_string(e.accountid));
v.push_back(std::to_string(e.status));
v.push_back("'" + Strings::Escape(e.charname) + "'");
v.push_back("'" + Strings::Escape(e.target) + "'");
v.push_back("'" + Strings::Escape(e.time) + "'");
v.push_back("'" + Strings::Escape(e.descriptiontype) + "'");
v.push_back("'" + Strings::Escape(e.description) + "'");
v.push_back(std::to_string(e.event_nid));
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<Eventlog> &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.accountname) + "'");
v.push_back(std::to_string(e.accountid));
v.push_back(std::to_string(e.status));
v.push_back("'" + Strings::Escape(e.charname) + "'");
v.push_back("'" + Strings::Escape(e.target) + "'");
v.push_back("'" + Strings::Escape(e.time) + "'");
v.push_back("'" + Strings::Escape(e.descriptiontype) + "'");
v.push_back("'" + Strings::Escape(e.description) + "'");
v.push_back(std::to_string(e.event_nid));
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<Eventlog> All(Database& db)
{
std::vector<Eventlog> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Eventlog e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.accountname = row[1] ? row[1] : "";
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.status = static_cast<int32_t>(atoi(row[3]));
e.charname = row[4] ? row[4] : "";
e.target = row[5] ? row[5] : "";
e.time = row[6] ? row[6] : "";
e.descriptiontype = row[7] ? row[7] : "";
e.description = row[8] ? row[8] : "";
e.event_nid = static_cast<int32_t>(atoi(row[9]));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<Eventlog> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<Eventlog> 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) {
Eventlog e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.accountname = row[1] ? row[1] : "";
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.status = static_cast<int32_t>(atoi(row[3]));
e.charname = row[4] ? row[4] : "";
e.target = row[5] ? row[5] : "";
e.time = row[6] ? row[6] : "";
e.descriptiontype = row[7] ? row[7] : "";
e.description = row[8] ? row[8] : "";
e.event_nid = static_cast<int32_t>(atoi(row[9]));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_EVENTLOG_REPOSITORY_H
@@ -0,0 +1,414 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_ARMORINFO_REPOSITORY_H
#define EQEMU_BASE_MERC_ARMORINFO_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercArmorinfoRepository {
public:
struct MercArmorinfo {
int32_t id;
uint32_t merc_npc_type_id;
uint8_t minlevel;
uint8_t maxlevel;
uint8_t texture;
uint8_t helmtexture;
uint32_t armortint_id;
uint8_t armortint_red;
uint8_t armortint_green;
uint8_t armortint_blue;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"merc_npc_type_id",
"minlevel",
"maxlevel",
"texture",
"helmtexture",
"armortint_id",
"armortint_red",
"armortint_green",
"armortint_blue",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"merc_npc_type_id",
"minlevel",
"maxlevel",
"texture",
"helmtexture",
"armortint_id",
"armortint_red",
"armortint_green",
"armortint_blue",
};
}
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("merc_armorinfo");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercArmorinfo NewEntity()
{
MercArmorinfo e{};
e.id = 0;
e.merc_npc_type_id = 0;
e.minlevel = 1;
e.maxlevel = 255;
e.texture = 0;
e.helmtexture = 0;
e.armortint_id = 0;
e.armortint_red = 0;
e.armortint_green = 0;
e.armortint_blue = 0;
return e;
}
static MercArmorinfo GetMercArmorinfo(
const std::vector<MercArmorinfo> &merc_armorinfos,
int merc_armorinfo_id
)
{
for (auto &merc_armorinfo : merc_armorinfos) {
if (merc_armorinfo.id == merc_armorinfo_id) {
return merc_armorinfo;
}
}
return NewEntity();
}
static MercArmorinfo FindOne(
Database& db,
int merc_armorinfo_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_armorinfo_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercArmorinfo e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.minlevel = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.texture = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.helmtexture = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.armortint_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
e.armortint_red = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[9], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_armorinfo_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_armorinfo_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercArmorinfo &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_npc_type_id));
v.push_back(columns[2] + " = " + std::to_string(e.minlevel));
v.push_back(columns[3] + " = " + std::to_string(e.maxlevel));
v.push_back(columns[4] + " = " + std::to_string(e.texture));
v.push_back(columns[5] + " = " + std::to_string(e.helmtexture));
v.push_back(columns[6] + " = " + std::to_string(e.armortint_id));
v.push_back(columns[7] + " = " + std::to_string(e.armortint_red));
v.push_back(columns[8] + " = " + std::to_string(e.armortint_green));
v.push_back(columns[9] + " = " + std::to_string(e.armortint_blue));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercArmorinfo InsertOne(
Database& db,
MercArmorinfo e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
v.push_back(std::to_string(e.texture));
v.push_back(std::to_string(e.helmtexture));
v.push_back(std::to_string(e.armortint_id));
v.push_back(std::to_string(e.armortint_red));
v.push_back(std::to_string(e.armortint_green));
v.push_back(std::to_string(e.armortint_blue));
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<MercArmorinfo> &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.merc_npc_type_id));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
v.push_back(std::to_string(e.texture));
v.push_back(std::to_string(e.helmtexture));
v.push_back(std::to_string(e.armortint_id));
v.push_back(std::to_string(e.armortint_red));
v.push_back(std::to_string(e.armortint_green));
v.push_back(std::to_string(e.armortint_blue));
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<MercArmorinfo> All(Database& db)
{
std::vector<MercArmorinfo> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercArmorinfo e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.minlevel = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.texture = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.helmtexture = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.armortint_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
e.armortint_red = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[9], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercArmorinfo> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercArmorinfo> 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) {
MercArmorinfo e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.minlevel = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.texture = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.helmtexture = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.armortint_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
e.armortint_red = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[9], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_ARMORINFO_REPOSITORY_H
@@ -0,0 +1,504 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_BUFFS_REPOSITORY_H
#define EQEMU_BASE_MERC_BUFFS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercBuffsRepository {
public:
struct MercBuffs {
uint32_t MercBuffId;
uint32_t MercId;
uint32_t SpellId;
uint32_t CasterLevel;
uint32_t DurationFormula;
int32_t TicsRemaining;
uint32_t PoisonCounters;
uint32_t DiseaseCounters;
uint32_t CurseCounters;
uint32_t CorruptionCounters;
uint32_t HitCount;
uint32_t MeleeRune;
uint32_t MagicRune;
int32_t dot_rune;
int32_t caston_x;
int8_t Persistent;
int32_t caston_y;
int32_t caston_z;
int32_t ExtraDIChance;
};
static std::string PrimaryKey()
{
return std::string("MercBuffId");
}
static std::vector<std::string> Columns()
{
return {
"MercBuffId",
"MercId",
"SpellId",
"CasterLevel",
"DurationFormula",
"TicsRemaining",
"PoisonCounters",
"DiseaseCounters",
"CurseCounters",
"CorruptionCounters",
"HitCount",
"MeleeRune",
"MagicRune",
"dot_rune",
"caston_x",
"Persistent",
"caston_y",
"caston_z",
"ExtraDIChance",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"MercBuffId",
"MercId",
"SpellId",
"CasterLevel",
"DurationFormula",
"TicsRemaining",
"PoisonCounters",
"DiseaseCounters",
"CurseCounters",
"CorruptionCounters",
"HitCount",
"MeleeRune",
"MagicRune",
"dot_rune",
"caston_x",
"Persistent",
"caston_y",
"caston_z",
"ExtraDIChance",
};
}
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("merc_buffs");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercBuffs NewEntity()
{
MercBuffs e{};
e.MercBuffId = 0;
e.MercId = 0;
e.SpellId = 0;
e.CasterLevel = 0;
e.DurationFormula = 0;
e.TicsRemaining = 0;
e.PoisonCounters = 0;
e.DiseaseCounters = 0;
e.CurseCounters = 0;
e.CorruptionCounters = 0;
e.HitCount = 0;
e.MeleeRune = 0;
e.MagicRune = 0;
e.dot_rune = 0;
e.caston_x = 0;
e.Persistent = 0;
e.caston_y = 0;
e.caston_z = 0;
e.ExtraDIChance = 0;
return e;
}
static MercBuffs GetMercBuffs(
const std::vector<MercBuffs> &merc_buffss,
int merc_buffs_id
)
{
for (auto &merc_buffs : merc_buffss) {
if (merc_buffs.MercBuffId == merc_buffs_id) {
return merc_buffs;
}
}
return NewEntity();
}
static MercBuffs FindOne(
Database& db,
int merc_buffs_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_buffs_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercBuffs e{};
e.MercBuffId = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.MercId = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.SpellId = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.CasterLevel = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.DurationFormula = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.TicsRemaining = static_cast<int32_t>(atoi(row[5]));
e.PoisonCounters = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
e.DiseaseCounters = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.CurseCounters = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
e.CorruptionCounters = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
e.HitCount = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
e.MeleeRune = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.MagicRune = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.dot_rune = static_cast<int32_t>(atoi(row[13]));
e.caston_x = static_cast<int32_t>(atoi(row[14]));
e.Persistent = static_cast<int8_t>(atoi(row[15]));
e.caston_y = static_cast<int32_t>(atoi(row[16]));
e.caston_z = static_cast<int32_t>(atoi(row[17]));
e.ExtraDIChance = static_cast<int32_t>(atoi(row[18]));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_buffs_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_buffs_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercBuffs &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.MercId));
v.push_back(columns[2] + " = " + std::to_string(e.SpellId));
v.push_back(columns[3] + " = " + std::to_string(e.CasterLevel));
v.push_back(columns[4] + " = " + std::to_string(e.DurationFormula));
v.push_back(columns[5] + " = " + std::to_string(e.TicsRemaining));
v.push_back(columns[6] + " = " + std::to_string(e.PoisonCounters));
v.push_back(columns[7] + " = " + std::to_string(e.DiseaseCounters));
v.push_back(columns[8] + " = " + std::to_string(e.CurseCounters));
v.push_back(columns[9] + " = " + std::to_string(e.CorruptionCounters));
v.push_back(columns[10] + " = " + std::to_string(e.HitCount));
v.push_back(columns[11] + " = " + std::to_string(e.MeleeRune));
v.push_back(columns[12] + " = " + std::to_string(e.MagicRune));
v.push_back(columns[13] + " = " + std::to_string(e.dot_rune));
v.push_back(columns[14] + " = " + std::to_string(e.caston_x));
v.push_back(columns[15] + " = " + std::to_string(e.Persistent));
v.push_back(columns[16] + " = " + std::to_string(e.caston_y));
v.push_back(columns[17] + " = " + std::to_string(e.caston_z));
v.push_back(columns[18] + " = " + std::to_string(e.ExtraDIChance));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.MercBuffId
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercBuffs InsertOne(
Database& db,
MercBuffs e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.MercBuffId));
v.push_back(std::to_string(e.MercId));
v.push_back(std::to_string(e.SpellId));
v.push_back(std::to_string(e.CasterLevel));
v.push_back(std::to_string(e.DurationFormula));
v.push_back(std::to_string(e.TicsRemaining));
v.push_back(std::to_string(e.PoisonCounters));
v.push_back(std::to_string(e.DiseaseCounters));
v.push_back(std::to_string(e.CurseCounters));
v.push_back(std::to_string(e.CorruptionCounters));
v.push_back(std::to_string(e.HitCount));
v.push_back(std::to_string(e.MeleeRune));
v.push_back(std::to_string(e.MagicRune));
v.push_back(std::to_string(e.dot_rune));
v.push_back(std::to_string(e.caston_x));
v.push_back(std::to_string(e.Persistent));
v.push_back(std::to_string(e.caston_y));
v.push_back(std::to_string(e.caston_z));
v.push_back(std::to_string(e.ExtraDIChance));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.MercBuffId = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercBuffs> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.MercBuffId));
v.push_back(std::to_string(e.MercId));
v.push_back(std::to_string(e.SpellId));
v.push_back(std::to_string(e.CasterLevel));
v.push_back(std::to_string(e.DurationFormula));
v.push_back(std::to_string(e.TicsRemaining));
v.push_back(std::to_string(e.PoisonCounters));
v.push_back(std::to_string(e.DiseaseCounters));
v.push_back(std::to_string(e.CurseCounters));
v.push_back(std::to_string(e.CorruptionCounters));
v.push_back(std::to_string(e.HitCount));
v.push_back(std::to_string(e.MeleeRune));
v.push_back(std::to_string(e.MagicRune));
v.push_back(std::to_string(e.dot_rune));
v.push_back(std::to_string(e.caston_x));
v.push_back(std::to_string(e.Persistent));
v.push_back(std::to_string(e.caston_y));
v.push_back(std::to_string(e.caston_z));
v.push_back(std::to_string(e.ExtraDIChance));
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<MercBuffs> All(Database& db)
{
std::vector<MercBuffs> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercBuffs e{};
e.MercBuffId = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.MercId = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.SpellId = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.CasterLevel = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.DurationFormula = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.TicsRemaining = static_cast<int32_t>(atoi(row[5]));
e.PoisonCounters = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
e.DiseaseCounters = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.CurseCounters = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
e.CorruptionCounters = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
e.HitCount = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
e.MeleeRune = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.MagicRune = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.dot_rune = static_cast<int32_t>(atoi(row[13]));
e.caston_x = static_cast<int32_t>(atoi(row[14]));
e.Persistent = static_cast<int8_t>(atoi(row[15]));
e.caston_y = static_cast<int32_t>(atoi(row[16]));
e.caston_z = static_cast<int32_t>(atoi(row[17]));
e.ExtraDIChance = static_cast<int32_t>(atoi(row[18]));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercBuffs> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercBuffs> 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) {
MercBuffs e{};
e.MercBuffId = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.MercId = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.SpellId = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.CasterLevel = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.DurationFormula = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.TicsRemaining = static_cast<int32_t>(atoi(row[5]));
e.PoisonCounters = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
e.DiseaseCounters = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.CurseCounters = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
e.CorruptionCounters = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
e.HitCount = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
e.MeleeRune = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.MagicRune = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.dot_rune = static_cast<int32_t>(atoi(row[13]));
e.caston_x = static_cast<int32_t>(atoi(row[14]));
e.Persistent = static_cast<int8_t>(atoi(row[15]));
e.caston_y = static_cast<int32_t>(atoi(row[16]));
e.caston_z = static_cast<int32_t>(atoi(row[17]));
e.ExtraDIChance = static_cast<int32_t>(atoi(row[18]));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_BUFFS_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_INVENTORY_REPOSITORY_H
#define EQEMU_BASE_MERC_INVENTORY_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercInventoryRepository {
public:
struct MercInventory {
uint32_t merc_inventory_id;
uint32_t merc_subtype_id;
uint32_t item_id;
uint32_t min_level;
uint32_t max_level;
};
static std::string PrimaryKey()
{
return std::string("merc_inventory_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_inventory_id",
"merc_subtype_id",
"item_id",
"min_level",
"max_level",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_inventory_id",
"merc_subtype_id",
"item_id",
"min_level",
"max_level",
};
}
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("merc_inventory");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercInventory NewEntity()
{
MercInventory e{};
e.merc_inventory_id = 0;
e.merc_subtype_id = 0;
e.item_id = 0;
e.min_level = 0;
e.max_level = 0;
return e;
}
static MercInventory GetMercInventory(
const std::vector<MercInventory> &merc_inventorys,
int merc_inventory_id
)
{
for (auto &merc_inventory : merc_inventorys) {
if (merc_inventory.merc_inventory_id == merc_inventory_id) {
return merc_inventory;
}
}
return NewEntity();
}
static MercInventory FindOne(
Database& db,
int merc_inventory_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_inventory_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercInventory e{};
e.merc_inventory_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.item_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.min_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.max_level = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_inventory_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_inventory_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercInventory &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_subtype_id));
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
v.push_back(columns[3] + " = " + std::to_string(e.min_level));
v.push_back(columns[4] + " = " + std::to_string(e.max_level));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_inventory_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercInventory InsertOne(
Database& db,
MercInventory e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_inventory_id));
v.push_back(std::to_string(e.merc_subtype_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.min_level));
v.push_back(std::to_string(e.max_level));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_inventory_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercInventory> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_inventory_id));
v.push_back(std::to_string(e.merc_subtype_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.min_level));
v.push_back(std::to_string(e.max_level));
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<MercInventory> All(Database& db)
{
std::vector<MercInventory> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercInventory e{};
e.merc_inventory_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.item_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.min_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.max_level = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercInventory> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercInventory> 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) {
MercInventory e{};
e.merc_inventory_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.item_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.min_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.max_level = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_INVENTORY_REPOSITORY_H
@@ -0,0 +1,344 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_MERCHANT_ENTRIES_REPOSITORY_H
#define EQEMU_BASE_MERC_MERCHANT_ENTRIES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercMerchantEntriesRepository {
public:
struct MercMerchantEntries {
uint32_t merc_merchant_entry_id;
uint32_t merc_merchant_template_id;
uint32_t merchant_id;
};
static std::string PrimaryKey()
{
return std::string("merc_merchant_entry_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_merchant_entry_id",
"merc_merchant_template_id",
"merchant_id",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_merchant_entry_id",
"merc_merchant_template_id",
"merchant_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("merc_merchant_entries");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercMerchantEntries NewEntity()
{
MercMerchantEntries e{};
e.merc_merchant_entry_id = 0;
e.merc_merchant_template_id = 0;
e.merchant_id = 0;
return e;
}
static MercMerchantEntries GetMercMerchantEntries(
const std::vector<MercMerchantEntries> &merc_merchant_entriess,
int merc_merchant_entries_id
)
{
for (auto &merc_merchant_entries : merc_merchant_entriess) {
if (merc_merchant_entries.merc_merchant_entry_id == merc_merchant_entries_id) {
return merc_merchant_entries;
}
}
return NewEntity();
}
static MercMerchantEntries FindOne(
Database& db,
int merc_merchant_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_merchant_entries_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercMerchantEntries e{};
e.merc_merchant_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merchant_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_merchant_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_merchant_entries_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercMerchantEntries &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_merchant_template_id));
v.push_back(columns[2] + " = " + std::to_string(e.merchant_id));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_merchant_entry_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercMerchantEntries InsertOne(
Database& db,
MercMerchantEntries e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_merchant_entry_id));
v.push_back(std::to_string(e.merc_merchant_template_id));
v.push_back(std::to_string(e.merchant_id));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_merchant_entry_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercMerchantEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_merchant_entry_id));
v.push_back(std::to_string(e.merc_merchant_template_id));
v.push_back(std::to_string(e.merchant_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<MercMerchantEntries> All(Database& db)
{
std::vector<MercMerchantEntries> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercMerchantEntries e{};
e.merc_merchant_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merchant_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercMerchantEntries> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercMerchantEntries> 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) {
MercMerchantEntries e{};
e.merc_merchant_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merchant_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_MERCHANT_ENTRIES_REPOSITORY_H
@@ -0,0 +1,344 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_MERCHANT_TEMPLATE_ENTRIES_REPOSITORY_H
#define EQEMU_BASE_MERC_MERCHANT_TEMPLATE_ENTRIES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercMerchantTemplateEntriesRepository {
public:
struct MercMerchantTemplateEntries {
uint32_t merc_merchant_template_entry_id;
uint32_t merc_merchant_template_id;
uint32_t merc_template_id;
};
static std::string PrimaryKey()
{
return std::string("merc_merchant_template_entry_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_merchant_template_entry_id",
"merc_merchant_template_id",
"merc_template_id",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_merchant_template_entry_id",
"merc_merchant_template_id",
"merc_template_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("merc_merchant_template_entries");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercMerchantTemplateEntries NewEntity()
{
MercMerchantTemplateEntries e{};
e.merc_merchant_template_entry_id = 0;
e.merc_merchant_template_id = 0;
e.merc_template_id = 0;
return e;
}
static MercMerchantTemplateEntries GetMercMerchantTemplateEntries(
const std::vector<MercMerchantTemplateEntries> &merc_merchant_template_entriess,
int merc_merchant_template_entries_id
)
{
for (auto &merc_merchant_template_entries : merc_merchant_template_entriess) {
if (merc_merchant_template_entries.merc_merchant_template_entry_id == merc_merchant_template_entries_id) {
return merc_merchant_template_entries;
}
}
return NewEntity();
}
static MercMerchantTemplateEntries FindOne(
Database& db,
int merc_merchant_template_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_merchant_template_entries_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercMerchantTemplateEntries e{};
e.merc_merchant_template_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merc_template_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_merchant_template_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_merchant_template_entries_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercMerchantTemplateEntries &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_merchant_template_id));
v.push_back(columns[2] + " = " + std::to_string(e.merc_template_id));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_merchant_template_entry_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercMerchantTemplateEntries InsertOne(
Database& db,
MercMerchantTemplateEntries e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_merchant_template_entry_id));
v.push_back(std::to_string(e.merc_merchant_template_id));
v.push_back(std::to_string(e.merc_template_id));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_merchant_template_entry_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercMerchantTemplateEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_merchant_template_entry_id));
v.push_back(std::to_string(e.merc_merchant_template_id));
v.push_back(std::to_string(e.merc_template_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<MercMerchantTemplateEntries> All(Database& db)
{
std::vector<MercMerchantTemplateEntries> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercMerchantTemplateEntries e{};
e.merc_merchant_template_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merc_template_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercMerchantTemplateEntries> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercMerchantTemplateEntries> 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) {
MercMerchantTemplateEntries e{};
e.merc_merchant_template_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merc_template_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_MERCHANT_TEMPLATE_ENTRIES_REPOSITORY_H
@@ -0,0 +1,344 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_MERCHANT_TEMPLATES_REPOSITORY_H
#define EQEMU_BASE_MERC_MERCHANT_TEMPLATES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercMerchantTemplatesRepository {
public:
struct MercMerchantTemplates {
uint32_t merc_merchant_template_id;
std::string name;
std::string qglobal;
};
static std::string PrimaryKey()
{
return std::string("merc_merchant_template_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_merchant_template_id",
"name",
"qglobal",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_merchant_template_id",
"name",
"qglobal",
};
}
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("merc_merchant_templates");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercMerchantTemplates NewEntity()
{
MercMerchantTemplates e{};
e.merc_merchant_template_id = 0;
e.name = "";
e.qglobal = "";
return e;
}
static MercMerchantTemplates GetMercMerchantTemplates(
const std::vector<MercMerchantTemplates> &merc_merchant_templatess,
int merc_merchant_templates_id
)
{
for (auto &merc_merchant_templates : merc_merchant_templatess) {
if (merc_merchant_templates.merc_merchant_template_id == merc_merchant_templates_id) {
return merc_merchant_templates;
}
}
return NewEntity();
}
static MercMerchantTemplates FindOne(
Database& db,
int merc_merchant_templates_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_merchant_templates_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercMerchantTemplates e{};
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.name = row[1] ? row[1] : "";
e.qglobal = row[2] ? row[2] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_merchant_templates_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_merchant_templates_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercMerchantTemplates &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.qglobal) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_merchant_template_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercMerchantTemplates InsertOne(
Database& db,
MercMerchantTemplates e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_merchant_template_id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.qglobal) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_merchant_template_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercMerchantTemplates> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_merchant_template_id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.qglobal) + "'");
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<MercMerchantTemplates> All(Database& db)
{
std::vector<MercMerchantTemplates> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercMerchantTemplates e{};
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.name = row[1] ? row[1] : "";
e.qglobal = row[2] ? row[2] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercMerchantTemplates> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercMerchantTemplates> 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) {
MercMerchantTemplates e{};
e.merc_merchant_template_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.name = row[1] ? row[1] : "";
e.qglobal = row[2] ? row[2] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_MERCHANT_TEMPLATES_REPOSITORY_H
@@ -0,0 +1,355 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_NAME_TYPES_REPOSITORY_H
#define EQEMU_BASE_MERC_NAME_TYPES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercNameTypesRepository {
public:
struct MercNameTypes {
uint32_t name_type_id;
uint32_t class_id;
std::string prefix;
std::string suffix;
};
static std::string PrimaryKey()
{
return std::string("name_type_id");
}
static std::vector<std::string> Columns()
{
return {
"name_type_id",
"class_id",
"prefix",
"suffix",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"name_type_id",
"class_id",
"prefix",
"suffix",
};
}
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("merc_name_types");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercNameTypes NewEntity()
{
MercNameTypes e{};
e.name_type_id = 0;
e.class_id = 0;
e.prefix = "";
e.suffix = "";
return e;
}
static MercNameTypes GetMercNameTypes(
const std::vector<MercNameTypes> &merc_name_typess,
int merc_name_types_id
)
{
for (auto &merc_name_types : merc_name_typess) {
if (merc_name_types.name_type_id == merc_name_types_id) {
return merc_name_types;
}
}
return NewEntity();
}
static MercNameTypes FindOne(
Database& db,
int merc_name_types_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_name_types_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercNameTypes e{};
e.name_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.prefix = row[2] ? row[2] : "";
e.suffix = row[3] ? row[3] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_name_types_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_name_types_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercNameTypes &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.name_type_id));
v.push_back(columns[1] + " = " + std::to_string(e.class_id));
v.push_back(columns[2] + " = '" + Strings::Escape(e.prefix) + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.suffix) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.name_type_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercNameTypes InsertOne(
Database& db,
MercNameTypes e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.name_type_id));
v.push_back(std::to_string(e.class_id));
v.push_back("'" + Strings::Escape(e.prefix) + "'");
v.push_back("'" + Strings::Escape(e.suffix) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.name_type_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercNameTypes> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.name_type_id));
v.push_back(std::to_string(e.class_id));
v.push_back("'" + Strings::Escape(e.prefix) + "'");
v.push_back("'" + Strings::Escape(e.suffix) + "'");
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<MercNameTypes> All(Database& db)
{
std::vector<MercNameTypes> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercNameTypes e{};
e.name_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.prefix = row[2] ? row[2] : "";
e.suffix = row[3] ? row[3] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercNameTypes> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercNameTypes> 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) {
MercNameTypes e{};
e.name_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.prefix = row[2] ? row[2] : "";
e.suffix = row[3] ? row[3] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_NAME_TYPES_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_NPC_TYPES_REPOSITORY_H
#define EQEMU_BASE_MERC_NPC_TYPES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercNpcTypesRepository {
public:
struct MercNpcTypes {
uint32_t merc_npc_type_id;
uint8_t proficiency_id;
uint8_t tier_id;
uint32_t class_id;
std::string name;
};
static std::string PrimaryKey()
{
return std::string("merc_npc_type_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_npc_type_id",
"proficiency_id",
"tier_id",
"class_id",
"name",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_npc_type_id",
"proficiency_id",
"tier_id",
"class_id",
"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("merc_npc_types");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercNpcTypes NewEntity()
{
MercNpcTypes e{};
e.merc_npc_type_id = 0;
e.proficiency_id = 0;
e.tier_id = 0;
e.class_id = 0;
e.name = "";
return e;
}
static MercNpcTypes GetMercNpcTypes(
const std::vector<MercNpcTypes> &merc_npc_typess,
int merc_npc_types_id
)
{
for (auto &merc_npc_types : merc_npc_typess) {
if (merc_npc_types.merc_npc_type_id == merc_npc_types_id) {
return merc_npc_types;
}
}
return NewEntity();
}
static MercNpcTypes FindOne(
Database& db,
int merc_npc_types_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_npc_types_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercNpcTypes e{};
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[1], nullptr, 10));
e.tier_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.name = row[4] ? row[4] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_npc_types_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_npc_types_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercNpcTypes &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.proficiency_id));
v.push_back(columns[2] + " = " + std::to_string(e.tier_id));
v.push_back(columns[3] + " = " + std::to_string(e.class_id));
v.push_back(columns[4] + " = '" + Strings::Escape(e.name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_npc_type_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercNpcTypes InsertOne(
Database& db,
MercNpcTypes e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back(std::to_string(e.tier_id));
v.push_back(std::to_string(e.class_id));
v.push_back("'" + Strings::Escape(e.name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_npc_type_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercNpcTypes> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back(std::to_string(e.tier_id));
v.push_back(std::to_string(e.class_id));
v.push_back("'" + Strings::Escape(e.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<MercNpcTypes> All(Database& db)
{
std::vector<MercNpcTypes> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercNpcTypes e{};
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[1], nullptr, 10));
e.tier_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.name = row[4] ? row[4] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercNpcTypes> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercNpcTypes> 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) {
MercNpcTypes e{};
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[1], nullptr, 10));
e.tier_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.name = row[4] ? row[4] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_NPC_TYPES_REPOSITORY_H
@@ -0,0 +1,404 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_SPELL_LIST_ENTRIES_REPOSITORY_H
#define EQEMU_BASE_MERC_SPELL_LIST_ENTRIES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercSpellListEntriesRepository {
public:
struct MercSpellListEntries {
uint32_t merc_spell_list_entry_id;
uint32_t merc_spell_list_id;
uint32_t spell_id;
uint32_t spell_type;
uint8_t stance_id;
uint8_t minlevel;
uint8_t maxlevel;
int8_t slot;
uint8_t procChance;
};
static std::string PrimaryKey()
{
return std::string("merc_spell_list_entry_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_spell_list_entry_id",
"merc_spell_list_id",
"spell_id",
"spell_type",
"stance_id",
"minlevel",
"maxlevel",
"slot",
"procChance",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_spell_list_entry_id",
"merc_spell_list_id",
"spell_id",
"spell_type",
"stance_id",
"minlevel",
"maxlevel",
"slot",
"procChance",
};
}
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("merc_spell_list_entries");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercSpellListEntries NewEntity()
{
MercSpellListEntries e{};
e.merc_spell_list_entry_id = 0;
e.merc_spell_list_id = 0;
e.spell_id = 0;
e.spell_type = 0;
e.stance_id = 0;
e.minlevel = 1;
e.maxlevel = 255;
e.slot = -1;
e.procChance = 0;
return e;
}
static MercSpellListEntries GetMercSpellListEntries(
const std::vector<MercSpellListEntries> &merc_spell_list_entriess,
int merc_spell_list_entries_id
)
{
for (auto &merc_spell_list_entries : merc_spell_list_entriess) {
if (merc_spell_list_entries.merc_spell_list_entry_id == merc_spell_list_entries_id) {
return merc_spell_list_entries;
}
}
return NewEntity();
}
static MercSpellListEntries FindOne(
Database& db,
int merc_spell_list_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_spell_list_entries_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercSpellListEntries e{};
e.merc_spell_list_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_spell_list_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.spell_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.spell_type = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.stance_id = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.minlevel = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.slot = static_cast<int8_t>(atoi(row[7]));
e.procChance = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_spell_list_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_spell_list_entries_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercSpellListEntries &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_spell_list_id));
v.push_back(columns[2] + " = " + std::to_string(e.spell_id));
v.push_back(columns[3] + " = " + std::to_string(e.spell_type));
v.push_back(columns[4] + " = " + std::to_string(e.stance_id));
v.push_back(columns[5] + " = " + std::to_string(e.minlevel));
v.push_back(columns[6] + " = " + std::to_string(e.maxlevel));
v.push_back(columns[7] + " = " + std::to_string(e.slot));
v.push_back(columns[8] + " = " + std::to_string(e.procChance));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_spell_list_entry_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercSpellListEntries InsertOne(
Database& db,
MercSpellListEntries e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_spell_list_entry_id));
v.push_back(std::to_string(e.merc_spell_list_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.spell_type));
v.push_back(std::to_string(e.stance_id));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.procChance));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_spell_list_entry_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercSpellListEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_spell_list_entry_id));
v.push_back(std::to_string(e.merc_spell_list_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.spell_type));
v.push_back(std::to_string(e.stance_id));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
v.push_back(std::to_string(e.slot));
v.push_back(std::to_string(e.procChance));
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<MercSpellListEntries> All(Database& db)
{
std::vector<MercSpellListEntries> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercSpellListEntries e{};
e.merc_spell_list_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_spell_list_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.spell_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.spell_type = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.stance_id = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.minlevel = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.slot = static_cast<int8_t>(atoi(row[7]));
e.procChance = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercSpellListEntries> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercSpellListEntries> 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) {
MercSpellListEntries e{};
e.merc_spell_list_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_spell_list_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.spell_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.spell_type = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.stance_id = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.minlevel = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.slot = static_cast<int8_t>(atoi(row[7]));
e.procChance = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_SPELL_LIST_ENTRIES_REPOSITORY_H
@@ -0,0 +1,354 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_SPELL_LISTS_REPOSITORY_H
#define EQEMU_BASE_MERC_SPELL_LISTS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercSpellListsRepository {
public:
struct MercSpellLists {
uint32_t merc_spell_list_id;
uint32_t class_id;
uint8_t proficiency_id;
std::string name;
};
static std::string PrimaryKey()
{
return std::string("merc_spell_list_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_spell_list_id",
"class_id",
"proficiency_id",
"name",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_spell_list_id",
"class_id",
"proficiency_id",
"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("merc_spell_lists");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercSpellLists NewEntity()
{
MercSpellLists e{};
e.merc_spell_list_id = 0;
e.class_id = 0;
e.proficiency_id = 0;
e.name = "";
return e;
}
static MercSpellLists GetMercSpellLists(
const std::vector<MercSpellLists> &merc_spell_listss,
int merc_spell_lists_id
)
{
for (auto &merc_spell_lists : merc_spell_listss) {
if (merc_spell_lists.merc_spell_list_id == merc_spell_lists_id) {
return merc_spell_lists;
}
}
return NewEntity();
}
static MercSpellLists FindOne(
Database& db,
int merc_spell_lists_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_spell_lists_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercSpellLists e{};
e.merc_spell_list_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.name = row[3] ? row[3] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_spell_lists_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_spell_lists_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercSpellLists &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.class_id));
v.push_back(columns[2] + " = " + std::to_string(e.proficiency_id));
v.push_back(columns[3] + " = '" + Strings::Escape(e.name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_spell_list_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercSpellLists InsertOne(
Database& db,
MercSpellLists e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_spell_list_id));
v.push_back(std::to_string(e.class_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back("'" + Strings::Escape(e.name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_spell_list_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercSpellLists> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_spell_list_id));
v.push_back(std::to_string(e.class_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back("'" + Strings::Escape(e.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<MercSpellLists> All(Database& db)
{
std::vector<MercSpellLists> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercSpellLists e{};
e.merc_spell_list_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.name = row[3] ? row[3] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercSpellLists> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercSpellLists> 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) {
MercSpellLists e{};
e.merc_spell_list_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.name = row[3] ? row[3] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_SPELL_LISTS_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_STANCE_ENTRIES_REPOSITORY_H
#define EQEMU_BASE_MERC_STANCE_ENTRIES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercStanceEntriesRepository {
public:
struct MercStanceEntries {
uint32_t merc_stance_entry_id;
uint32_t class_id;
uint8_t proficiency_id;
uint8_t stance_id;
int8_t isdefault;
};
static std::string PrimaryKey()
{
return std::string("merc_stance_entry_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_stance_entry_id",
"class_id",
"proficiency_id",
"stance_id",
"isdefault",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_stance_entry_id",
"class_id",
"proficiency_id",
"stance_id",
"isdefault",
};
}
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("merc_stance_entries");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercStanceEntries NewEntity()
{
MercStanceEntries e{};
e.merc_stance_entry_id = 0;
e.class_id = 0;
e.proficiency_id = 0;
e.stance_id = 0;
e.isdefault = 0;
return e;
}
static MercStanceEntries GetMercStanceEntries(
const std::vector<MercStanceEntries> &merc_stance_entriess,
int merc_stance_entries_id
)
{
for (auto &merc_stance_entries : merc_stance_entriess) {
if (merc_stance_entries.merc_stance_entry_id == merc_stance_entries_id) {
return merc_stance_entries;
}
}
return NewEntity();
}
static MercStanceEntries FindOne(
Database& db,
int merc_stance_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_stance_entries_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercStanceEntries e{};
e.merc_stance_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.stance_id = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.isdefault = static_cast<int8_t>(atoi(row[4]));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_stance_entries_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_stance_entries_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercStanceEntries &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.class_id));
v.push_back(columns[2] + " = " + std::to_string(e.proficiency_id));
v.push_back(columns[3] + " = " + std::to_string(e.stance_id));
v.push_back(columns[4] + " = " + std::to_string(e.isdefault));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_stance_entry_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercStanceEntries InsertOne(
Database& db,
MercStanceEntries e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_stance_entry_id));
v.push_back(std::to_string(e.class_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back(std::to_string(e.stance_id));
v.push_back(std::to_string(e.isdefault));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_stance_entry_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercStanceEntries> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_stance_entry_id));
v.push_back(std::to_string(e.class_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back(std::to_string(e.stance_id));
v.push_back(std::to_string(e.isdefault));
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<MercStanceEntries> All(Database& db)
{
std::vector<MercStanceEntries> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercStanceEntries e{};
e.merc_stance_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.stance_id = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.isdefault = static_cast<int8_t>(atoi(row[4]));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercStanceEntries> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercStanceEntries> 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) {
MercStanceEntries e{};
e.merc_stance_entry_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.stance_id = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.isdefault = static_cast<int8_t>(atoi(row[4]));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_STANCE_ENTRIES_REPOSITORY_H
@@ -0,0 +1,645 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_STATS_REPOSITORY_H
#define EQEMU_BASE_MERC_STATS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercStatsRepository {
public:
struct MercStats {
uint32_t merc_npc_type_id;
uint8_t clientlevel;
uint8_t level;
int32_t hp;
int32_t mana;
int16_t AC;
int32_t ATK;
uint32_t STR;
uint32_t STA;
uint32_t DEX;
uint32_t AGI;
uint32_t _INT;
uint32_t WIS;
uint32_t CHA;
int16_t MR;
int16_t CR;
int16_t DR;
int16_t FR;
int16_t PR;
int16_t Corrup;
uint32_t mindmg;
uint32_t maxdmg;
int16_t attack_count;
int8_t attack_speed;
uint8_t attack_delay;
std::string special_abilities;
int32_t Accuracy;
uint32_t hp_regen_rate;
uint32_t mana_regen_rate;
float runspeed;
int32_t statscale;
float spellscale;
float healscale;
};
static std::string PrimaryKey()
{
return std::string("merc_npc_type_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_npc_type_id",
"clientlevel",
"level",
"hp",
"mana",
"AC",
"ATK",
"STR",
"STA",
"DEX",
"AGI",
"_INT",
"WIS",
"CHA",
"MR",
"CR",
"DR",
"FR",
"PR",
"Corrup",
"mindmg",
"maxdmg",
"attack_count",
"attack_speed",
"attack_delay",
"special_abilities",
"Accuracy",
"hp_regen_rate",
"mana_regen_rate",
"runspeed",
"statscale",
"spellscale",
"healscale",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_npc_type_id",
"clientlevel",
"level",
"hp",
"mana",
"AC",
"ATK",
"STR",
"STA",
"DEX",
"AGI",
"_INT",
"WIS",
"CHA",
"MR",
"CR",
"DR",
"FR",
"PR",
"Corrup",
"mindmg",
"maxdmg",
"attack_count",
"attack_speed",
"attack_delay",
"special_abilities",
"Accuracy",
"hp_regen_rate",
"mana_regen_rate",
"runspeed",
"statscale",
"spellscale",
"healscale",
};
}
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("merc_stats");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercStats NewEntity()
{
MercStats e{};
e.merc_npc_type_id = 0;
e.clientlevel = 1;
e.level = 1;
e.hp = 1;
e.mana = 0;
e.AC = 1;
e.ATK = 1;
e.STR = 75;
e.STA = 75;
e.DEX = 75;
e.AGI = 75;
e._INT = 80;
e.WIS = 80;
e.CHA = 75;
e.MR = 15;
e.CR = 15;
e.DR = 15;
e.FR = 15;
e.PR = 15;
e.Corrup = 15;
e.mindmg = 1;
e.maxdmg = 1;
e.attack_count = 0;
e.attack_speed = 0;
e.attack_delay = 30;
e.special_abilities = "";
e.Accuracy = 0;
e.hp_regen_rate = 1;
e.mana_regen_rate = 1;
e.runspeed = 0;
e.statscale = 100;
e.spellscale = 100;
e.healscale = 100;
return e;
}
static MercStats GetMercStats(
const std::vector<MercStats> &merc_statss,
int merc_stats_id
)
{
for (auto &merc_stats : merc_statss) {
if (merc_stats.merc_npc_type_id == merc_stats_id) {
return merc_stats;
}
}
return NewEntity();
}
static MercStats FindOne(
Database& db,
int merc_stats_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_stats_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercStats e{};
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.clientlevel = static_cast<uint8_t>(strtoul(row[1], nullptr, 10));
e.level = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.hp = static_cast<int32_t>(atoi(row[3]));
e.mana = static_cast<int32_t>(atoi(row[4]));
e.AC = static_cast<int16_t>(atoi(row[5]));
e.ATK = static_cast<int32_t>(atoi(row[6]));
e.STR = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.STA = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
e.DEX = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
e.AGI = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
e._INT = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.WIS = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.CHA = static_cast<uint32_t>(strtoul(row[13], nullptr, 10));
e.MR = static_cast<int16_t>(atoi(row[14]));
e.CR = static_cast<int16_t>(atoi(row[15]));
e.DR = static_cast<int16_t>(atoi(row[16]));
e.FR = static_cast<int16_t>(atoi(row[17]));
e.PR = static_cast<int16_t>(atoi(row[18]));
e.Corrup = static_cast<int16_t>(atoi(row[19]));
e.mindmg = static_cast<uint32_t>(strtoul(row[20], nullptr, 10));
e.maxdmg = static_cast<uint32_t>(strtoul(row[21], nullptr, 10));
e.attack_count = static_cast<int16_t>(atoi(row[22]));
e.attack_speed = static_cast<int8_t>(atoi(row[23]));
e.attack_delay = static_cast<uint8_t>(strtoul(row[24], nullptr, 10));
e.special_abilities = row[25] ? row[25] : "";
e.Accuracy = static_cast<int32_t>(atoi(row[26]));
e.hp_regen_rate = static_cast<uint32_t>(strtoul(row[27], nullptr, 10));
e.mana_regen_rate = static_cast<uint32_t>(strtoul(row[28], nullptr, 10));
e.runspeed = strtof(row[29], nullptr);
e.statscale = static_cast<int32_t>(atoi(row[30]));
e.spellscale = strtof(row[31], nullptr);
e.healscale = strtof(row[32], nullptr);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_stats_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_stats_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercStats &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.merc_npc_type_id));
v.push_back(columns[1] + " = " + std::to_string(e.clientlevel));
v.push_back(columns[2] + " = " + std::to_string(e.level));
v.push_back(columns[3] + " = " + std::to_string(e.hp));
v.push_back(columns[4] + " = " + std::to_string(e.mana));
v.push_back(columns[5] + " = " + std::to_string(e.AC));
v.push_back(columns[6] + " = " + std::to_string(e.ATK));
v.push_back(columns[7] + " = " + std::to_string(e.STR));
v.push_back(columns[8] + " = " + std::to_string(e.STA));
v.push_back(columns[9] + " = " + std::to_string(e.DEX));
v.push_back(columns[10] + " = " + std::to_string(e.AGI));
v.push_back(columns[11] + " = " + std::to_string(e._INT));
v.push_back(columns[12] + " = " + std::to_string(e.WIS));
v.push_back(columns[13] + " = " + std::to_string(e.CHA));
v.push_back(columns[14] + " = " + std::to_string(e.MR));
v.push_back(columns[15] + " = " + std::to_string(e.CR));
v.push_back(columns[16] + " = " + std::to_string(e.DR));
v.push_back(columns[17] + " = " + std::to_string(e.FR));
v.push_back(columns[18] + " = " + std::to_string(e.PR));
v.push_back(columns[19] + " = " + std::to_string(e.Corrup));
v.push_back(columns[20] + " = " + std::to_string(e.mindmg));
v.push_back(columns[21] + " = " + std::to_string(e.maxdmg));
v.push_back(columns[22] + " = " + std::to_string(e.attack_count));
v.push_back(columns[23] + " = " + std::to_string(e.attack_speed));
v.push_back(columns[24] + " = " + std::to_string(e.attack_delay));
v.push_back(columns[25] + " = '" + Strings::Escape(e.special_abilities) + "'");
v.push_back(columns[26] + " = " + std::to_string(e.Accuracy));
v.push_back(columns[27] + " = " + std::to_string(e.hp_regen_rate));
v.push_back(columns[28] + " = " + std::to_string(e.mana_regen_rate));
v.push_back(columns[29] + " = " + std::to_string(e.runspeed));
v.push_back(columns[30] + " = " + std::to_string(e.statscale));
v.push_back(columns[31] + " = " + std::to_string(e.spellscale));
v.push_back(columns[32] + " = " + std::to_string(e.healscale));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_npc_type_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercStats InsertOne(
Database& db,
MercStats e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back(std::to_string(e.clientlevel));
v.push_back(std::to_string(e.level));
v.push_back(std::to_string(e.hp));
v.push_back(std::to_string(e.mana));
v.push_back(std::to_string(e.AC));
v.push_back(std::to_string(e.ATK));
v.push_back(std::to_string(e.STR));
v.push_back(std::to_string(e.STA));
v.push_back(std::to_string(e.DEX));
v.push_back(std::to_string(e.AGI));
v.push_back(std::to_string(e._INT));
v.push_back(std::to_string(e.WIS));
v.push_back(std::to_string(e.CHA));
v.push_back(std::to_string(e.MR));
v.push_back(std::to_string(e.CR));
v.push_back(std::to_string(e.DR));
v.push_back(std::to_string(e.FR));
v.push_back(std::to_string(e.PR));
v.push_back(std::to_string(e.Corrup));
v.push_back(std::to_string(e.mindmg));
v.push_back(std::to_string(e.maxdmg));
v.push_back(std::to_string(e.attack_count));
v.push_back(std::to_string(e.attack_speed));
v.push_back(std::to_string(e.attack_delay));
v.push_back("'" + Strings::Escape(e.special_abilities) + "'");
v.push_back(std::to_string(e.Accuracy));
v.push_back(std::to_string(e.hp_regen_rate));
v.push_back(std::to_string(e.mana_regen_rate));
v.push_back(std::to_string(e.runspeed));
v.push_back(std::to_string(e.statscale));
v.push_back(std::to_string(e.spellscale));
v.push_back(std::to_string(e.healscale));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_npc_type_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercStats> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back(std::to_string(e.clientlevel));
v.push_back(std::to_string(e.level));
v.push_back(std::to_string(e.hp));
v.push_back(std::to_string(e.mana));
v.push_back(std::to_string(e.AC));
v.push_back(std::to_string(e.ATK));
v.push_back(std::to_string(e.STR));
v.push_back(std::to_string(e.STA));
v.push_back(std::to_string(e.DEX));
v.push_back(std::to_string(e.AGI));
v.push_back(std::to_string(e._INT));
v.push_back(std::to_string(e.WIS));
v.push_back(std::to_string(e.CHA));
v.push_back(std::to_string(e.MR));
v.push_back(std::to_string(e.CR));
v.push_back(std::to_string(e.DR));
v.push_back(std::to_string(e.FR));
v.push_back(std::to_string(e.PR));
v.push_back(std::to_string(e.Corrup));
v.push_back(std::to_string(e.mindmg));
v.push_back(std::to_string(e.maxdmg));
v.push_back(std::to_string(e.attack_count));
v.push_back(std::to_string(e.attack_speed));
v.push_back(std::to_string(e.attack_delay));
v.push_back("'" + Strings::Escape(e.special_abilities) + "'");
v.push_back(std::to_string(e.Accuracy));
v.push_back(std::to_string(e.hp_regen_rate));
v.push_back(std::to_string(e.mana_regen_rate));
v.push_back(std::to_string(e.runspeed));
v.push_back(std::to_string(e.statscale));
v.push_back(std::to_string(e.spellscale));
v.push_back(std::to_string(e.healscale));
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<MercStats> All(Database& db)
{
std::vector<MercStats> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercStats e{};
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.clientlevel = static_cast<uint8_t>(strtoul(row[1], nullptr, 10));
e.level = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.hp = static_cast<int32_t>(atoi(row[3]));
e.mana = static_cast<int32_t>(atoi(row[4]));
e.AC = static_cast<int16_t>(atoi(row[5]));
e.ATK = static_cast<int32_t>(atoi(row[6]));
e.STR = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.STA = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
e.DEX = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
e.AGI = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
e._INT = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.WIS = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.CHA = static_cast<uint32_t>(strtoul(row[13], nullptr, 10));
e.MR = static_cast<int16_t>(atoi(row[14]));
e.CR = static_cast<int16_t>(atoi(row[15]));
e.DR = static_cast<int16_t>(atoi(row[16]));
e.FR = static_cast<int16_t>(atoi(row[17]));
e.PR = static_cast<int16_t>(atoi(row[18]));
e.Corrup = static_cast<int16_t>(atoi(row[19]));
e.mindmg = static_cast<uint32_t>(strtoul(row[20], nullptr, 10));
e.maxdmg = static_cast<uint32_t>(strtoul(row[21], nullptr, 10));
e.attack_count = static_cast<int16_t>(atoi(row[22]));
e.attack_speed = static_cast<int8_t>(atoi(row[23]));
e.attack_delay = static_cast<uint8_t>(strtoul(row[24], nullptr, 10));
e.special_abilities = row[25] ? row[25] : "";
e.Accuracy = static_cast<int32_t>(atoi(row[26]));
e.hp_regen_rate = static_cast<uint32_t>(strtoul(row[27], nullptr, 10));
e.mana_regen_rate = static_cast<uint32_t>(strtoul(row[28], nullptr, 10));
e.runspeed = strtof(row[29], nullptr);
e.statscale = static_cast<int32_t>(atoi(row[30]));
e.spellscale = strtof(row[31], nullptr);
e.healscale = strtof(row[32], nullptr);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercStats> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercStats> 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) {
MercStats e{};
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.clientlevel = static_cast<uint8_t>(strtoul(row[1], nullptr, 10));
e.level = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.hp = static_cast<int32_t>(atoi(row[3]));
e.mana = static_cast<int32_t>(atoi(row[4]));
e.AC = static_cast<int16_t>(atoi(row[5]));
e.ATK = static_cast<int32_t>(atoi(row[6]));
e.STR = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.STA = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
e.DEX = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
e.AGI = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
e._INT = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.WIS = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.CHA = static_cast<uint32_t>(strtoul(row[13], nullptr, 10));
e.MR = static_cast<int16_t>(atoi(row[14]));
e.CR = static_cast<int16_t>(atoi(row[15]));
e.DR = static_cast<int16_t>(atoi(row[16]));
e.FR = static_cast<int16_t>(atoi(row[17]));
e.PR = static_cast<int16_t>(atoi(row[18]));
e.Corrup = static_cast<int16_t>(atoi(row[19]));
e.mindmg = static_cast<uint32_t>(strtoul(row[20], nullptr, 10));
e.maxdmg = static_cast<uint32_t>(strtoul(row[21], nullptr, 10));
e.attack_count = static_cast<int16_t>(atoi(row[22]));
e.attack_speed = static_cast<int8_t>(atoi(row[23]));
e.attack_delay = static_cast<uint8_t>(strtoul(row[24], nullptr, 10));
e.special_abilities = row[25] ? row[25] : "";
e.Accuracy = static_cast<int32_t>(atoi(row[26]));
e.hp_regen_rate = static_cast<uint32_t>(strtoul(row[27], nullptr, 10));
e.mana_regen_rate = static_cast<uint32_t>(strtoul(row[28], nullptr, 10));
e.runspeed = strtof(row[29], nullptr);
e.statscale = static_cast<int32_t>(atoi(row[30]));
e.spellscale = strtof(row[31], nullptr);
e.healscale = strtof(row[32], nullptr);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_STATS_REPOSITORY_H
@@ -0,0 +1,354 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_SUBTYPES_REPOSITORY_H
#define EQEMU_BASE_MERC_SUBTYPES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercSubtypesRepository {
public:
struct MercSubtypes {
uint32_t merc_subtype_id;
uint32_t class_id;
uint8_t tier_id;
uint8_t confidence_id;
};
static std::string PrimaryKey()
{
return std::string("merc_subtype_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_subtype_id",
"class_id",
"tier_id",
"confidence_id",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_subtype_id",
"class_id",
"tier_id",
"confidence_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("merc_subtypes");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercSubtypes NewEntity()
{
MercSubtypes e{};
e.merc_subtype_id = 0;
e.class_id = 0;
e.tier_id = 0;
e.confidence_id = 0;
return e;
}
static MercSubtypes GetMercSubtypes(
const std::vector<MercSubtypes> &merc_subtypess,
int merc_subtypes_id
)
{
for (auto &merc_subtypes : merc_subtypess) {
if (merc_subtypes.merc_subtype_id == merc_subtypes_id) {
return merc_subtypes;
}
}
return NewEntity();
}
static MercSubtypes FindOne(
Database& db,
int merc_subtypes_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_subtypes_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercSubtypes e{};
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.confidence_id = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_subtypes_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_subtypes_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercSubtypes &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.class_id));
v.push_back(columns[2] + " = " + std::to_string(e.tier_id));
v.push_back(columns[3] + " = " + std::to_string(e.confidence_id));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_subtype_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercSubtypes InsertOne(
Database& db,
MercSubtypes e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_subtype_id));
v.push_back(std::to_string(e.class_id));
v.push_back(std::to_string(e.tier_id));
v.push_back(std::to_string(e.confidence_id));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_subtype_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercSubtypes> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_subtype_id));
v.push_back(std::to_string(e.class_id));
v.push_back(std::to_string(e.tier_id));
v.push_back(std::to_string(e.confidence_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<MercSubtypes> All(Database& db)
{
std::vector<MercSubtypes> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercSubtypes e{};
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.confidence_id = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercSubtypes> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercSubtypes> 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) {
MercSubtypes e{};
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.class_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.tier_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.confidence_id = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_SUBTYPES_REPOSITORY_H
@@ -0,0 +1,384 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_TEMPLATES_REPOSITORY_H
#define EQEMU_BASE_MERC_TEMPLATES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercTemplatesRepository {
public:
struct MercTemplates {
uint32_t merc_template_id;
uint32_t merc_type_id;
uint32_t merc_subtype_id;
uint32_t merc_npc_type_id;
std::string dbstring;
int8_t name_type_id;
uint32_t clientversion;
};
static std::string PrimaryKey()
{
return std::string("merc_template_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_template_id",
"merc_type_id",
"merc_subtype_id",
"merc_npc_type_id",
"dbstring",
"name_type_id",
"clientversion",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_template_id",
"merc_type_id",
"merc_subtype_id",
"merc_npc_type_id",
"dbstring",
"name_type_id",
"clientversion",
};
}
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("merc_templates");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercTemplates NewEntity()
{
MercTemplates e{};
e.merc_template_id = 0;
e.merc_type_id = 0;
e.merc_subtype_id = 0;
e.merc_npc_type_id = 0;
e.dbstring = "";
e.name_type_id = 0;
e.clientversion = 0;
return e;
}
static MercTemplates GetMercTemplates(
const std::vector<MercTemplates> &merc_templatess,
int merc_templates_id
)
{
for (auto &merc_templates : merc_templatess) {
if (merc_templates.merc_template_id == merc_templates_id) {
return merc_templates;
}
}
return NewEntity();
}
static MercTemplates FindOne(
Database& db,
int merc_templates_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_templates_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercTemplates e{};
e.merc_template_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_type_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.dbstring = row[4] ? row[4] : "";
e.name_type_id = static_cast<int8_t>(atoi(row[5]));
e.clientversion = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_templates_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_templates_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercTemplates &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_type_id));
v.push_back(columns[2] + " = " + std::to_string(e.merc_subtype_id));
v.push_back(columns[3] + " = " + std::to_string(e.merc_npc_type_id));
v.push_back(columns[4] + " = '" + Strings::Escape(e.dbstring) + "'");
v.push_back(columns[5] + " = " + std::to_string(e.name_type_id));
v.push_back(columns[6] + " = " + std::to_string(e.clientversion));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_template_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercTemplates InsertOne(
Database& db,
MercTemplates e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_template_id));
v.push_back(std::to_string(e.merc_type_id));
v.push_back(std::to_string(e.merc_subtype_id));
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back("'" + Strings::Escape(e.dbstring) + "'");
v.push_back(std::to_string(e.name_type_id));
v.push_back(std::to_string(e.clientversion));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_template_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercTemplates> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_template_id));
v.push_back(std::to_string(e.merc_type_id));
v.push_back(std::to_string(e.merc_subtype_id));
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back("'" + Strings::Escape(e.dbstring) + "'");
v.push_back(std::to_string(e.name_type_id));
v.push_back(std::to_string(e.clientversion));
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<MercTemplates> All(Database& db)
{
std::vector<MercTemplates> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercTemplates e{};
e.merc_template_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_type_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.dbstring = row[4] ? row[4] : "";
e.name_type_id = static_cast<int8_t>(atoi(row[5]));
e.clientversion = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercTemplates> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercTemplates> 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) {
MercTemplates e{};
e.merc_template_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.merc_type_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.merc_subtype_id = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.merc_npc_type_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.dbstring = row[4] ? row[4] : "";
e.name_type_id = static_cast<int8_t>(atoi(row[5]));
e.clientversion = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_TEMPLATES_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_TYPES_REPOSITORY_H
#define EQEMU_BASE_MERC_TYPES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercTypesRepository {
public:
struct MercTypes {
uint32_t merc_type_id;
uint32_t race_id;
uint8_t proficiency_id;
std::string dbstring;
uint32_t clientversion;
};
static std::string PrimaryKey()
{
return std::string("merc_type_id");
}
static std::vector<std::string> Columns()
{
return {
"merc_type_id",
"race_id",
"proficiency_id",
"dbstring",
"clientversion",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"merc_type_id",
"race_id",
"proficiency_id",
"dbstring",
"clientversion",
};
}
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("merc_types");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercTypes NewEntity()
{
MercTypes e{};
e.merc_type_id = 0;
e.race_id = 0;
e.proficiency_id = 0;
e.dbstring = "";
e.clientversion = 0;
return e;
}
static MercTypes GetMercTypes(
const std::vector<MercTypes> &merc_typess,
int merc_types_id
)
{
for (auto &merc_types : merc_typess) {
if (merc_types.merc_type_id == merc_types_id) {
return merc_types;
}
}
return NewEntity();
}
static MercTypes FindOne(
Database& db,
int merc_types_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_types_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercTypes e{};
e.merc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.race_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.dbstring = row[3] ? row[3] : "";
e.clientversion = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_types_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_types_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercTypes &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.race_id));
v.push_back(columns[2] + " = " + std::to_string(e.proficiency_id));
v.push_back(columns[3] + " = '" + Strings::Escape(e.dbstring) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.clientversion));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.merc_type_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercTypes InsertOne(
Database& db,
MercTypes e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_type_id));
v.push_back(std::to_string(e.race_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back("'" + Strings::Escape(e.dbstring) + "'");
v.push_back(std::to_string(e.clientversion));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.merc_type_id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<MercTypes> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.merc_type_id));
v.push_back(std::to_string(e.race_id));
v.push_back(std::to_string(e.proficiency_id));
v.push_back("'" + Strings::Escape(e.dbstring) + "'");
v.push_back(std::to_string(e.clientversion));
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<MercTypes> All(Database& db)
{
std::vector<MercTypes> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercTypes e{};
e.merc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.race_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.dbstring = row[3] ? row[3] : "";
e.clientversion = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercTypes> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercTypes> 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) {
MercTypes e{};
e.merc_type_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.race_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.proficiency_id = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.dbstring = row[3] ? row[3] : "";
e.clientversion = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_TYPES_REPOSITORY_H
@@ -0,0 +1,394 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERC_WEAPONINFO_REPOSITORY_H
#define EQEMU_BASE_MERC_WEAPONINFO_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercWeaponinfoRepository {
public:
struct MercWeaponinfo {
int32_t id;
int32_t merc_npc_type_id;
uint8_t minlevel;
uint8_t maxlevel;
int32_t d_melee_texture1;
int32_t d_melee_texture2;
uint8_t prim_melee_type;
uint8_t sec_melee_type;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"merc_npc_type_id",
"minlevel",
"maxlevel",
"d_melee_texture1",
"d_melee_texture2",
"prim_melee_type",
"sec_melee_type",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"merc_npc_type_id",
"minlevel",
"maxlevel",
"d_melee_texture1",
"d_melee_texture2",
"prim_melee_type",
"sec_melee_type",
};
}
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("merc_weaponinfo");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static MercWeaponinfo NewEntity()
{
MercWeaponinfo e{};
e.id = 0;
e.merc_npc_type_id = 0;
e.minlevel = 0;
e.maxlevel = 0;
e.d_melee_texture1 = 0;
e.d_melee_texture2 = 0;
e.prim_melee_type = 28;
e.sec_melee_type = 28;
return e;
}
static MercWeaponinfo GetMercWeaponinfo(
const std::vector<MercWeaponinfo> &merc_weaponinfos,
int merc_weaponinfo_id
)
{
for (auto &merc_weaponinfo : merc_weaponinfos) {
if (merc_weaponinfo.id == merc_weaponinfo_id) {
return merc_weaponinfo;
}
}
return NewEntity();
}
static MercWeaponinfo FindOne(
Database& db,
int merc_weaponinfo_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merc_weaponinfo_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
MercWeaponinfo e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.merc_npc_type_id = static_cast<int32_t>(atoi(row[1]));
e.minlevel = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[4]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[5]));
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int merc_weaponinfo_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
merc_weaponinfo_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const MercWeaponinfo &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.merc_npc_type_id));
v.push_back(columns[2] + " = " + std::to_string(e.minlevel));
v.push_back(columns[3] + " = " + std::to_string(e.maxlevel));
v.push_back(columns[4] + " = " + std::to_string(e.d_melee_texture1));
v.push_back(columns[5] + " = " + std::to_string(e.d_melee_texture2));
v.push_back(columns[6] + " = " + std::to_string(e.prim_melee_type));
v.push_back(columns[7] + " = " + std::to_string(e.sec_melee_type));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static MercWeaponinfo InsertOne(
Database& db,
MercWeaponinfo e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.merc_npc_type_id));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
v.push_back(std::to_string(e.d_melee_texture1));
v.push_back(std::to_string(e.d_melee_texture2));
v.push_back(std::to_string(e.prim_melee_type));
v.push_back(std::to_string(e.sec_melee_type));
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<MercWeaponinfo> &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.merc_npc_type_id));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
v.push_back(std::to_string(e.d_melee_texture1));
v.push_back(std::to_string(e.d_melee_texture2));
v.push_back(std::to_string(e.prim_melee_type));
v.push_back(std::to_string(e.sec_melee_type));
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<MercWeaponinfo> All(Database& db)
{
std::vector<MercWeaponinfo> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
MercWeaponinfo e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.merc_npc_type_id = static_cast<int32_t>(atoi(row[1]));
e.minlevel = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[4]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[5]));
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<MercWeaponinfo> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<MercWeaponinfo> 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) {
MercWeaponinfo e{};
e.id = static_cast<int32_t>(atoi(row[0]));
e.merc_npc_type_id = static_cast<int32_t>(atoi(row[1]));
e.minlevel = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.maxlevel = static_cast<uint8_t>(strtoul(row[3], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[4]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[5]));
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERC_WEAPONINFO_REPOSITORY_H
@@ -16,6 +16,7 @@
#include "../../strings.h"
#include <ctime>
class BaseMerchantlistRepository {
public:
struct Merchantlist {
@@ -24,6 +25,8 @@ public:
int32_t item;
int16_t faction_required;
uint8_t level_required;
uint8_t min_status;
uint8_t max_status;
uint16_t alt_currency_cost;
int32_t classes_required;
int32_t probability;
@@ -49,6 +52,8 @@ public:
"item",
"faction_required",
"level_required",
"min_status",
"max_status",
"alt_currency_cost",
"classes_required",
"probability",
@@ -70,6 +75,8 @@ public:
"item",
"faction_required",
"level_required",
"min_status",
"max_status",
"alt_currency_cost",
"classes_required",
"probability",
@@ -125,6 +132,8 @@ public:
e.item = 0;
e.faction_required = -100;
e.level_required = 0;
e.min_status = 0;
e.max_status = 255;
e.alt_currency_cost = 0;
e.classes_required = 65535;
e.probability = 100;
@@ -160,8 +169,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
merchantlist_id
)
);
@@ -175,16 +185,18 @@ public:
e.item = static_cast<int32_t>(atoi(row[2]));
e.faction_required = static_cast<int16_t>(atoi(row[3]));
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.classes_required = static_cast<int32_t>(atoi(row[6]));
e.probability = static_cast<int32_t>(atoi(row[7]));
e.bucket_name = row[8] ? row[8] : "";
e.bucket_value = row[9] ? row[9] : "";
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
e.content_flags = row[13] ? row[13] : "";
e.content_flags_disabled = row[14] ? row[14] : "";
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
e.classes_required = static_cast<int32_t>(atoi(row[8]));
e.probability = static_cast<int32_t>(atoi(row[9]));
e.bucket_name = row[10] ? row[10] : "";
e.bucket_value = row[11] ? row[11] : "";
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
e.content_flags = row[15] ? row[15] : "";
e.content_flags_disabled = row[16] ? row[16] : "";
return e;
}
@@ -223,16 +235,18 @@ public:
v.push_back(columns[2] + " = " + std::to_string(e.item));
v.push_back(columns[3] + " = " + std::to_string(e.faction_required));
v.push_back(columns[4] + " = " + std::to_string(e.level_required));
v.push_back(columns[5] + " = " + std::to_string(e.alt_currency_cost));
v.push_back(columns[6] + " = " + std::to_string(e.classes_required));
v.push_back(columns[7] + " = " + std::to_string(e.probability));
v.push_back(columns[8] + " = '" + Strings::Escape(e.bucket_name) + "'");
v.push_back(columns[9] + " = '" + Strings::Escape(e.bucket_value) + "'");
v.push_back(columns[10] + " = " + std::to_string(e.bucket_comparison));
v.push_back(columns[11] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[12] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[13] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[14] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
v.push_back(columns[5] + " = " + std::to_string(e.min_status));
v.push_back(columns[6] + " = " + std::to_string(e.max_status));
v.push_back(columns[7] + " = " + std::to_string(e.alt_currency_cost));
v.push_back(columns[8] + " = " + std::to_string(e.classes_required));
v.push_back(columns[9] + " = " + std::to_string(e.probability));
v.push_back(columns[10] + " = '" + Strings::Escape(e.bucket_name) + "'");
v.push_back(columns[11] + " = '" + Strings::Escape(e.bucket_value) + "'");
v.push_back(columns[12] + " = " + std::to_string(e.bucket_comparison));
v.push_back(columns[13] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[14] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[15] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[16] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -259,6 +273,8 @@ public:
v.push_back(std::to_string(e.item));
v.push_back(std::to_string(e.faction_required));
v.push_back(std::to_string(e.level_required));
v.push_back(std::to_string(e.min_status));
v.push_back(std::to_string(e.max_status));
v.push_back(std::to_string(e.alt_currency_cost));
v.push_back(std::to_string(e.classes_required));
v.push_back(std::to_string(e.probability));
@@ -303,6 +319,8 @@ public:
v.push_back(std::to_string(e.item));
v.push_back(std::to_string(e.faction_required));
v.push_back(std::to_string(e.level_required));
v.push_back(std::to_string(e.min_status));
v.push_back(std::to_string(e.max_status));
v.push_back(std::to_string(e.alt_currency_cost));
v.push_back(std::to_string(e.classes_required));
v.push_back(std::to_string(e.probability));
@@ -351,16 +369,18 @@ public:
e.item = static_cast<int32_t>(atoi(row[2]));
e.faction_required = static_cast<int16_t>(atoi(row[3]));
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.classes_required = static_cast<int32_t>(atoi(row[6]));
e.probability = static_cast<int32_t>(atoi(row[7]));
e.bucket_name = row[8] ? row[8] : "";
e.bucket_value = row[9] ? row[9] : "";
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
e.content_flags = row[13] ? row[13] : "";
e.content_flags_disabled = row[14] ? row[14] : "";
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
e.classes_required = static_cast<int32_t>(atoi(row[8]));
e.probability = static_cast<int32_t>(atoi(row[9]));
e.bucket_name = row[10] ? row[10] : "";
e.bucket_value = row[11] ? row[11] : "";
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
e.content_flags = row[15] ? row[15] : "";
e.content_flags_disabled = row[16] ? row[16] : "";
all_entries.push_back(e);
}
@@ -390,16 +410,18 @@ public:
e.item = static_cast<int32_t>(atoi(row[2]));
e.faction_required = static_cast<int16_t>(atoi(row[3]));
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.classes_required = static_cast<int32_t>(atoi(row[6]));
e.probability = static_cast<int32_t>(atoi(row[7]));
e.bucket_name = row[8] ? row[8] : "";
e.bucket_value = row[9] ? row[9] : "";
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
e.content_flags = row[13] ? row[13] : "";
e.content_flags_disabled = row[14] ? row[14] : "";
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
e.classes_required = static_cast<int32_t>(atoi(row[8]));
e.probability = static_cast<int32_t>(atoi(row[9]));
e.bucket_name = row[10] ? row[10] : "";
e.bucket_value = row[11] ? row[11] : "";
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
e.content_flags = row[15] ? row[15] : "";
e.content_flags_disabled = row[16] ? row[16] : "";
all_entries.push_back(e);
}
@@ -0,0 +1,554 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_MERCS_REPOSITORY_H
#define EQEMU_BASE_MERCS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseMercsRepository {
public:
struct Mercs {
uint32_t MercID;
uint32_t OwnerCharacterID;
uint8_t Slot;
std::string Name;
uint32_t TemplateID;
uint32_t SuspendedTime;
uint8_t IsSuspended;
uint32_t TimerRemaining;
uint8_t Gender;
float MercSize;
uint8_t StanceID;
uint32_t HP;
uint32_t Mana;
uint32_t Endurance;
uint32_t Face;
uint32_t LuclinHairStyle;
uint32_t LuclinHairColor;
uint32_t LuclinEyeColor;
uint32_t LuclinEyeColor2;
uint32_t LuclinBeardColor;
uint32_t LuclinBeard;
uint32_t DrakkinHeritage;
uint32_t DrakkinTattoo;
uint32_t DrakkinDetails;
};
static std::string PrimaryKey()
{
return std::string("MercID");
}
static std::vector<std::string> Columns()
{
return {
"MercID",
"OwnerCharacterID",
"Slot",
"Name",
"TemplateID",
"SuspendedTime",
"IsSuspended",
"TimerRemaining",
"Gender",
"MercSize",
"StanceID",
"HP",
"Mana",
"Endurance",
"Face",
"LuclinHairStyle",
"LuclinHairColor",
"LuclinEyeColor",
"LuclinEyeColor2",
"LuclinBeardColor",
"LuclinBeard",
"DrakkinHeritage",
"DrakkinTattoo",
"DrakkinDetails",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"MercID",
"OwnerCharacterID",
"Slot",
"Name",
"TemplateID",
"SuspendedTime",
"IsSuspended",
"TimerRemaining",
"Gender",
"MercSize",
"StanceID",
"HP",
"Mana",
"Endurance",
"Face",
"LuclinHairStyle",
"LuclinHairColor",
"LuclinEyeColor",
"LuclinEyeColor2",
"LuclinBeardColor",
"LuclinBeard",
"DrakkinHeritage",
"DrakkinTattoo",
"DrakkinDetails",
};
}
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("mercs");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static Mercs NewEntity()
{
Mercs e{};
e.MercID = 0;
e.OwnerCharacterID = 0;
e.Slot = 0;
e.Name = "";
e.TemplateID = 0;
e.SuspendedTime = 0;
e.IsSuspended = 0;
e.TimerRemaining = 0;
e.Gender = 0;
e.MercSize = 5;
e.StanceID = 0;
e.HP = 0;
e.Mana = 0;
e.Endurance = 0;
e.Face = 1;
e.LuclinHairStyle = 1;
e.LuclinHairColor = 1;
e.LuclinEyeColor = 1;
e.LuclinEyeColor2 = 1;
e.LuclinBeardColor = 1;
e.LuclinBeard = 0;
e.DrakkinHeritage = 0;
e.DrakkinTattoo = 0;
e.DrakkinDetails = 0;
return e;
}
static Mercs GetMercs(
const std::vector<Mercs> &mercss,
int mercs_id
)
{
for (auto &mercs : mercss) {
if (mercs.MercID == mercs_id) {
return mercs;
}
}
return NewEntity();
}
static Mercs FindOne(
Database& db,
int mercs_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
mercs_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
Mercs e{};
e.MercID = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.OwnerCharacterID = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.Slot = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.Name = row[3] ? row[3] : "";
e.TemplateID = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.SuspendedTime = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.IsSuspended = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.TimerRemaining = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.Gender = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
e.MercSize = strtof(row[9], nullptr);
e.StanceID = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.HP = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.Mana = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.Endurance = static_cast<uint32_t>(strtoul(row[13], nullptr, 10));
e.Face = static_cast<uint32_t>(strtoul(row[14], nullptr, 10));
e.LuclinHairStyle = static_cast<uint32_t>(strtoul(row[15], nullptr, 10));
e.LuclinHairColor = static_cast<uint32_t>(strtoul(row[16], nullptr, 10));
e.LuclinEyeColor = static_cast<uint32_t>(strtoul(row[17], nullptr, 10));
e.LuclinEyeColor2 = static_cast<uint32_t>(strtoul(row[18], nullptr, 10));
e.LuclinBeardColor = static_cast<uint32_t>(strtoul(row[19], nullptr, 10));
e.LuclinBeard = static_cast<uint32_t>(strtoul(row[20], nullptr, 10));
e.DrakkinHeritage = static_cast<uint32_t>(strtoul(row[21], nullptr, 10));
e.DrakkinTattoo = static_cast<uint32_t>(strtoul(row[22], nullptr, 10));
e.DrakkinDetails = static_cast<uint32_t>(strtoul(row[23], nullptr, 10));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int mercs_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
mercs_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const Mercs &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.OwnerCharacterID));
v.push_back(columns[2] + " = " + std::to_string(e.Slot));
v.push_back(columns[3] + " = '" + Strings::Escape(e.Name) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.TemplateID));
v.push_back(columns[5] + " = " + std::to_string(e.SuspendedTime));
v.push_back(columns[6] + " = " + std::to_string(e.IsSuspended));
v.push_back(columns[7] + " = " + std::to_string(e.TimerRemaining));
v.push_back(columns[8] + " = " + std::to_string(e.Gender));
v.push_back(columns[9] + " = " + std::to_string(e.MercSize));
v.push_back(columns[10] + " = " + std::to_string(e.StanceID));
v.push_back(columns[11] + " = " + std::to_string(e.HP));
v.push_back(columns[12] + " = " + std::to_string(e.Mana));
v.push_back(columns[13] + " = " + std::to_string(e.Endurance));
v.push_back(columns[14] + " = " + std::to_string(e.Face));
v.push_back(columns[15] + " = " + std::to_string(e.LuclinHairStyle));
v.push_back(columns[16] + " = " + std::to_string(e.LuclinHairColor));
v.push_back(columns[17] + " = " + std::to_string(e.LuclinEyeColor));
v.push_back(columns[18] + " = " + std::to_string(e.LuclinEyeColor2));
v.push_back(columns[19] + " = " + std::to_string(e.LuclinBeardColor));
v.push_back(columns[20] + " = " + std::to_string(e.LuclinBeard));
v.push_back(columns[21] + " = " + std::to_string(e.DrakkinHeritage));
v.push_back(columns[22] + " = " + std::to_string(e.DrakkinTattoo));
v.push_back(columns[23] + " = " + std::to_string(e.DrakkinDetails));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.MercID
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static Mercs InsertOne(
Database& db,
Mercs e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.MercID));
v.push_back(std::to_string(e.OwnerCharacterID));
v.push_back(std::to_string(e.Slot));
v.push_back("'" + Strings::Escape(e.Name) + "'");
v.push_back(std::to_string(e.TemplateID));
v.push_back(std::to_string(e.SuspendedTime));
v.push_back(std::to_string(e.IsSuspended));
v.push_back(std::to_string(e.TimerRemaining));
v.push_back(std::to_string(e.Gender));
v.push_back(std::to_string(e.MercSize));
v.push_back(std::to_string(e.StanceID));
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(std::to_string(e.Face));
v.push_back(std::to_string(e.LuclinHairStyle));
v.push_back(std::to_string(e.LuclinHairColor));
v.push_back(std::to_string(e.LuclinEyeColor));
v.push_back(std::to_string(e.LuclinEyeColor2));
v.push_back(std::to_string(e.LuclinBeardColor));
v.push_back(std::to_string(e.LuclinBeard));
v.push_back(std::to_string(e.DrakkinHeritage));
v.push_back(std::to_string(e.DrakkinTattoo));
v.push_back(std::to_string(e.DrakkinDetails));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.MercID = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<Mercs> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.MercID));
v.push_back(std::to_string(e.OwnerCharacterID));
v.push_back(std::to_string(e.Slot));
v.push_back("'" + Strings::Escape(e.Name) + "'");
v.push_back(std::to_string(e.TemplateID));
v.push_back(std::to_string(e.SuspendedTime));
v.push_back(std::to_string(e.IsSuspended));
v.push_back(std::to_string(e.TimerRemaining));
v.push_back(std::to_string(e.Gender));
v.push_back(std::to_string(e.MercSize));
v.push_back(std::to_string(e.StanceID));
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(std::to_string(e.Face));
v.push_back(std::to_string(e.LuclinHairStyle));
v.push_back(std::to_string(e.LuclinHairColor));
v.push_back(std::to_string(e.LuclinEyeColor));
v.push_back(std::to_string(e.LuclinEyeColor2));
v.push_back(std::to_string(e.LuclinBeardColor));
v.push_back(std::to_string(e.LuclinBeard));
v.push_back(std::to_string(e.DrakkinHeritage));
v.push_back(std::to_string(e.DrakkinTattoo));
v.push_back(std::to_string(e.DrakkinDetails));
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<Mercs> All(Database& db)
{
std::vector<Mercs> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
Mercs e{};
e.MercID = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.OwnerCharacterID = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.Slot = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.Name = row[3] ? row[3] : "";
e.TemplateID = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.SuspendedTime = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.IsSuspended = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.TimerRemaining = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.Gender = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
e.MercSize = strtof(row[9], nullptr);
e.StanceID = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.HP = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.Mana = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.Endurance = static_cast<uint32_t>(strtoul(row[13], nullptr, 10));
e.Face = static_cast<uint32_t>(strtoul(row[14], nullptr, 10));
e.LuclinHairStyle = static_cast<uint32_t>(strtoul(row[15], nullptr, 10));
e.LuclinHairColor = static_cast<uint32_t>(strtoul(row[16], nullptr, 10));
e.LuclinEyeColor = static_cast<uint32_t>(strtoul(row[17], nullptr, 10));
e.LuclinEyeColor2 = static_cast<uint32_t>(strtoul(row[18], nullptr, 10));
e.LuclinBeardColor = static_cast<uint32_t>(strtoul(row[19], nullptr, 10));
e.LuclinBeard = static_cast<uint32_t>(strtoul(row[20], nullptr, 10));
e.DrakkinHeritage = static_cast<uint32_t>(strtoul(row[21], nullptr, 10));
e.DrakkinTattoo = static_cast<uint32_t>(strtoul(row[22], nullptr, 10));
e.DrakkinDetails = static_cast<uint32_t>(strtoul(row[23], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<Mercs> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<Mercs> 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) {
Mercs e{};
e.MercID = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.OwnerCharacterID = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.Slot = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
e.Name = row[3] ? row[3] : "";
e.TemplateID = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
e.SuspendedTime = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.IsSuspended = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.TimerRemaining = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
e.Gender = static_cast<uint8_t>(strtoul(row[8], nullptr, 10));
e.MercSize = strtof(row[9], nullptr);
e.StanceID = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
e.HP = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
e.Mana = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
e.Endurance = static_cast<uint32_t>(strtoul(row[13], nullptr, 10));
e.Face = static_cast<uint32_t>(strtoul(row[14], nullptr, 10));
e.LuclinHairStyle = static_cast<uint32_t>(strtoul(row[15], nullptr, 10));
e.LuclinHairColor = static_cast<uint32_t>(strtoul(row[16], nullptr, 10));
e.LuclinEyeColor = static_cast<uint32_t>(strtoul(row[17], nullptr, 10));
e.LuclinEyeColor2 = static_cast<uint32_t>(strtoul(row[18], nullptr, 10));
e.LuclinBeardColor = static_cast<uint32_t>(strtoul(row[19], nullptr, 10));
e.LuclinBeard = static_cast<uint32_t>(strtoul(row[20], nullptr, 10));
e.DrakkinHeritage = static_cast<uint32_t>(strtoul(row[21], nullptr, 10));
e.DrakkinTattoo = static_cast<uint32_t>(strtoul(row[22], nullptr, 10));
e.DrakkinDetails = static_cast<uint32_t>(strtoul(row[23], nullptr, 10));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_MERCS_REPOSITORY_H
@@ -0,0 +1,364 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BasePlayerEventLogSettingsRepository {
public:
struct PlayerEventLogSettings {
int64_t id;
std::string event_name;
int8_t event_enabled;
int32_t retention_days;
int32_t discord_webhook_id;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"event_name",
"event_enabled",
"retention_days",
"discord_webhook_id",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"event_name",
"event_enabled",
"retention_days",
"discord_webhook_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_log_settings");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventLogSettings NewEntity()
{
PlayerEventLogSettings e{};
e.id = 0;
e.event_name = "";
e.event_enabled = 0;
e.retention_days = 0;
e.discord_webhook_id = 0;
return e;
}
static PlayerEventLogSettings GetPlayerEventLogSettings(
const std::vector<PlayerEventLogSettings> &player_event_log_settingss,
int player_event_log_settings_id
)
{
for (auto &player_event_log_settings : player_event_log_settingss) {
if (player_event_log_settings.id == player_event_log_settings_id) {
return player_event_log_settings;
}
}
return NewEntity();
}
static PlayerEventLogSettings FindOne(
Database& db,
int player_event_log_settings_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_log_settings_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventLogSettings e{};
e.id = strtoll(row[0], nullptr, 10);
e.event_name = row[1] ? row[1] : "";
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
e.retention_days = static_cast<int32_t>(atoi(row[3]));
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_log_settings_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_log_settings_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventLogSettings &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.id));
v.push_back(columns[1] + " = '" + Strings::Escape(e.event_name) + "'");
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));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventLogSettings InsertOne(
Database& db,
PlayerEventLogSettings e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.event_name) + "'");
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));
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<PlayerEventLogSettings> &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.event_name) + "'");
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));
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<PlayerEventLogSettings> All(Database& db)
{
std::vector<PlayerEventLogSettings> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventLogSettings e{};
e.id = strtoll(row[0], nullptr, 10);
e.event_name = row[1] ? row[1] : "";
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
e.retention_days = static_cast<int32_t>(atoi(row[3]));
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventLogSettings> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventLogSettings> 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) {
PlayerEventLogSettings e{};
e.id = strtoll(row[0], nullptr, 10);
e.event_name = row[1] ? row[1] : "";
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
e.retention_days = static_cast<int32_t>(atoi(row[3]));
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
@@ -0,0 +1,465 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
#define EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
#include <cereal/cereal.hpp>
class BasePlayerEventLogsRepository {
public:
struct PlayerEventLogs {
int64_t id;
int64_t account_id;
int64_t character_id;
int32_t zone_id;
int32_t instance_id;
float x;
float y;
float z;
float heading;
int32_t event_type_id;
std::string event_type_name;
std::string event_data;
time_t created_at;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(id),
CEREAL_NVP(account_id),
CEREAL_NVP(character_id),
CEREAL_NVP(zone_id),
CEREAL_NVP(instance_id),
CEREAL_NVP(x),
CEREAL_NVP(y),
CEREAL_NVP(z),
CEREAL_NVP(heading),
CEREAL_NVP(event_type_id),
CEREAL_NVP(event_type_name),
CEREAL_NVP(event_data),
CEREAL_NVP(created_at)
);
}
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"account_id",
"character_id",
"zone_id",
"instance_id",
"x",
"y",
"z",
"heading",
"event_type_id",
"event_type_name",
"event_data",
"created_at",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"account_id",
"character_id",
"zone_id",
"instance_id",
"x",
"y",
"z",
"heading",
"event_type_id",
"event_type_name",
"event_data",
"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_logs");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static PlayerEventLogs NewEntity()
{
PlayerEventLogs e{};
e.id = 0;
e.account_id = 0;
e.character_id = 0;
e.zone_id = 0;
e.instance_id = 0;
e.x = 0;
e.y = 0;
e.z = 0;
e.heading = 0;
e.event_type_id = 0;
e.event_type_name = "";
e.event_data = "";
e.created_at = 0;
return e;
}
static PlayerEventLogs GetPlayerEventLogs(
const std::vector<PlayerEventLogs> &player_event_logss,
int player_event_logs_id
)
{
for (auto &player_event_logs : player_event_logss) {
if (player_event_logs.id == player_event_logs_id) {
return player_event_logs;
}
}
return NewEntity();
}
static PlayerEventLogs FindOne(
Database& db,
int player_event_logs_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
player_event_logs_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
PlayerEventLogs e{};
e.id = strtoll(row[0], nullptr, 10);
e.account_id = strtoll(row[1], nullptr, 10);
e.character_id = strtoll(row[2], nullptr, 10);
e.zone_id = static_cast<int32_t>(atoi(row[3]));
e.instance_id = static_cast<int32_t>(atoi(row[4]));
e.x = strtof(row[5], nullptr);
e.y = strtof(row[6], nullptr);
e.z = strtof(row[7], nullptr);
e.heading = strtof(row[8], nullptr);
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
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);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int player_event_logs_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
player_event_logs_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const PlayerEventLogs &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.account_id));
v.push_back(columns[2] + " = " + std::to_string(e.character_id));
v.push_back(columns[3] + " = " + std::to_string(e.zone_id));
v.push_back(columns[4] + " = " + std::to_string(e.instance_id));
v.push_back(columns[5] + " = " + std::to_string(e.x));
v.push_back(columns[6] + " = " + std::to_string(e.y));
v.push_back(columns[7] + " = " + std::to_string(e.z));
v.push_back(columns[8] + " = " + std::to_string(e.heading));
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") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static PlayerEventLogs InsertOne(
Database& db,
PlayerEventLogs e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.account_id));
v.push_back(std::to_string(e.character_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.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.event_type_id));
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
v.push_back("'" + Strings::Escape(e.event_data) + "'");
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<PlayerEventLogs> &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.account_id));
v.push_back(std::to_string(e.character_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.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.event_type_id));
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
v.push_back("'" + Strings::Escape(e.event_data) + "'");
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<PlayerEventLogs> All(Database& db)
{
std::vector<PlayerEventLogs> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerEventLogs e{};
e.id = strtoll(row[0], nullptr, 10);
e.account_id = strtoll(row[1], nullptr, 10);
e.character_id = strtoll(row[2], nullptr, 10);
e.zone_id = static_cast<int32_t>(atoi(row[3]));
e.instance_id = static_cast<int32_t>(atoi(row[4]));
e.x = strtof(row[5], nullptr);
e.y = strtof(row[6], nullptr);
e.z = strtof(row[7], nullptr);
e.heading = strtof(row[8], nullptr);
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
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);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<PlayerEventLogs> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<PlayerEventLogs> 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) {
PlayerEventLogs e{};
e.id = strtoll(row[0], nullptr, 10);
e.account_id = strtoll(row[1], nullptr, 10);
e.character_id = strtoll(row[2], nullptr, 10);
e.zone_id = static_cast<int32_t>(atoi(row[3]));
e.instance_id = static_cast<int32_t>(atoi(row[4]));
e.x = strtof(row[5], nullptr);
e.y = strtof(row[6], nullptr);
e.z = strtof(row[7], nullptr);
e.heading = strtof(row[8], nullptr);
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
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);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
@@ -5,6 +5,8 @@
#include "../strings.h"
#include "base/base_character_data_repository.h"
class CharacterDataRepository: public BaseCharacterDataRepository {
public:
@@ -44,7 +46,6 @@ public:
*/
// Custom extended repository methods here
};
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_CHATCHANNEL_RESERVED_NAMES_REPOSITORY_H
#define EQEMU_CHATCHANNEL_RESERVED_NAMES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_chatchannel_reserved_names_repository.h"
class ChatchannelReservedNamesRepository: public BaseChatchannelReservedNamesRepository {
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
*
* ChatchannelReservedNamesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* ChatchannelReservedNamesRepository::GetWhereNeverExpires()
* ChatchannelReservedNamesRepository::GetWhereXAndY()
* ChatchannelReservedNamesRepository::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_CHATCHANNEL_RESERVED_NAMES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_CHATCHANNELS_REPOSITORY_H
#define EQEMU_CHATCHANNELS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_chatchannels_repository.h"
class ChatchannelsRepository: public BaseChatchannelsRepository {
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
*
* ChatchannelsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* ChatchannelsRepository::GetWhereNeverExpires()
* ChatchannelsRepository::GetWhereXAndY()
* ChatchannelsRepository::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_CHATCHANNELS_REPOSITORY_H
@@ -172,7 +172,7 @@ public:
DELETE FROM {}
WHERE dynamic_zone_id IN ({});
),
TableName(), fmt::join(dynamic_zone_ids, ",")
TableName(), Strings::Join(dynamic_zone_ids, ",")
));
}
}
@@ -75,7 +75,7 @@ public:
FROM expedition_lockouts
WHERE expedition_id IN ({})
),
fmt::join(expedition_ids, ",")
Strings::Join(expedition_ids, ",")
));
all_entries.reserve(results.RowCount());
+1 -1
View File
@@ -62,7 +62,7 @@ public:
std::vector<CharacterExpedition> entries;
auto joined_character_names = fmt::format("'{}'", fmt::join(character_names, "','"));
auto joined_character_names = fmt::format("'{}'", Strings::Join(character_names, "','"));
auto results = db.QueryDatabase(fmt::format(SQL(
SELECT
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_ARMORINFO_REPOSITORY_H
#define EQEMU_MERC_ARMORINFO_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_armorinfo_repository.h"
class MercArmorinfoRepository: public BaseMercArmorinfoRepository {
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
*
* MercArmorinfoRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercArmorinfoRepository::GetWhereNeverExpires()
* MercArmorinfoRepository::GetWhereXAndY()
* MercArmorinfoRepository::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_MERC_ARMORINFO_REPOSITORY_H
@@ -1,11 +1,11 @@
#ifndef EQEMU_EVENTLOG_REPOSITORY_H
#define EQEMU_EVENTLOG_REPOSITORY_H
#ifndef EQEMU_MERC_BUFFS_REPOSITORY_H
#define EQEMU_MERC_BUFFS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_eventlog_repository.h"
#include "base/base_merc_buffs_repository.h"
class EventlogRepository: public BaseEventlogRepository {
class MercBuffsRepository: public BaseMercBuffsRepository {
public:
/**
@@ -32,10 +32,10 @@ public:
*
* Example custom methods in a repository
*
* EventlogRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* EventlogRepository::GetWhereNeverExpires()
* EventlogRepository::GetWhereXAndY()
* EventlogRepository::DeleteWhereXAndY()
* MercBuffsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercBuffsRepository::GetWhereNeverExpires()
* MercBuffsRepository::GetWhereXAndY()
* MercBuffsRepository::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
@@ -47,4 +47,4 @@ public:
};
#endif //EQEMU_EVENTLOG_REPOSITORY_H
#endif //EQEMU_MERC_BUFFS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_INVENTORY_REPOSITORY_H
#define EQEMU_MERC_INVENTORY_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_inventory_repository.h"
class MercInventoryRepository: public BaseMercInventoryRepository {
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
*
* MercInventoryRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercInventoryRepository::GetWhereNeverExpires()
* MercInventoryRepository::GetWhereXAndY()
* MercInventoryRepository::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_MERC_INVENTORY_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_MERCHANT_ENTRIES_REPOSITORY_H
#define EQEMU_MERC_MERCHANT_ENTRIES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_merchant_entries_repository.h"
class MercMerchantEntriesRepository: public BaseMercMerchantEntriesRepository {
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
*
* MercMerchantEntriesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercMerchantEntriesRepository::GetWhereNeverExpires()
* MercMerchantEntriesRepository::GetWhereXAndY()
* MercMerchantEntriesRepository::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_MERC_MERCHANT_ENTRIES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_MERCHANT_TEMPLATE_ENTRIES_REPOSITORY_H
#define EQEMU_MERC_MERCHANT_TEMPLATE_ENTRIES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_merchant_template_entries_repository.h"
class MercMerchantTemplateEntriesRepository: public BaseMercMerchantTemplateEntriesRepository {
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
*
* MercMerchantTemplateEntriesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercMerchantTemplateEntriesRepository::GetWhereNeverExpires()
* MercMerchantTemplateEntriesRepository::GetWhereXAndY()
* MercMerchantTemplateEntriesRepository::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_MERC_MERCHANT_TEMPLATE_ENTRIES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_MERCHANT_TEMPLATES_REPOSITORY_H
#define EQEMU_MERC_MERCHANT_TEMPLATES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_merchant_templates_repository.h"
class MercMerchantTemplatesRepository: public BaseMercMerchantTemplatesRepository {
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
*
* MercMerchantTemplatesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercMerchantTemplatesRepository::GetWhereNeverExpires()
* MercMerchantTemplatesRepository::GetWhereXAndY()
* MercMerchantTemplatesRepository::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_MERC_MERCHANT_TEMPLATES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_NAME_TYPES_REPOSITORY_H
#define EQEMU_MERC_NAME_TYPES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_name_types_repository.h"
class MercNameTypesRepository: public BaseMercNameTypesRepository {
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
*
* MercNameTypesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercNameTypesRepository::GetWhereNeverExpires()
* MercNameTypesRepository::GetWhereXAndY()
* MercNameTypesRepository::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_MERC_NAME_TYPES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_NPC_TYPES_REPOSITORY_H
#define EQEMU_MERC_NPC_TYPES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_npc_types_repository.h"
class MercNpcTypesRepository: public BaseMercNpcTypesRepository {
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
*
* MercNpcTypesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercNpcTypesRepository::GetWhereNeverExpires()
* MercNpcTypesRepository::GetWhereXAndY()
* MercNpcTypesRepository::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_MERC_NPC_TYPES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_SPELL_LIST_ENTRIES_REPOSITORY_H
#define EQEMU_MERC_SPELL_LIST_ENTRIES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_spell_list_entries_repository.h"
class MercSpellListEntriesRepository: public BaseMercSpellListEntriesRepository {
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
*
* MercSpellListEntriesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercSpellListEntriesRepository::GetWhereNeverExpires()
* MercSpellListEntriesRepository::GetWhereXAndY()
* MercSpellListEntriesRepository::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_MERC_SPELL_LIST_ENTRIES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_SPELL_LISTS_REPOSITORY_H
#define EQEMU_MERC_SPELL_LISTS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_spell_lists_repository.h"
class MercSpellListsRepository: public BaseMercSpellListsRepository {
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
*
* MercSpellListsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercSpellListsRepository::GetWhereNeverExpires()
* MercSpellListsRepository::GetWhereXAndY()
* MercSpellListsRepository::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_MERC_SPELL_LISTS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_STANCE_ENTRIES_REPOSITORY_H
#define EQEMU_MERC_STANCE_ENTRIES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_stance_entries_repository.h"
class MercStanceEntriesRepository: public BaseMercStanceEntriesRepository {
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
*
* MercStanceEntriesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercStanceEntriesRepository::GetWhereNeverExpires()
* MercStanceEntriesRepository::GetWhereXAndY()
* MercStanceEntriesRepository::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_MERC_STANCE_ENTRIES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_STATS_REPOSITORY_H
#define EQEMU_MERC_STATS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_stats_repository.h"
class MercStatsRepository: public BaseMercStatsRepository {
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
*
* MercStatsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercStatsRepository::GetWhereNeverExpires()
* MercStatsRepository::GetWhereXAndY()
* MercStatsRepository::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_MERC_STATS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_SUBTYPES_REPOSITORY_H
#define EQEMU_MERC_SUBTYPES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_subtypes_repository.h"
class MercSubtypesRepository: public BaseMercSubtypesRepository {
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
*
* MercSubtypesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercSubtypesRepository::GetWhereNeverExpires()
* MercSubtypesRepository::GetWhereXAndY()
* MercSubtypesRepository::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_MERC_SUBTYPES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_TEMPLATES_REPOSITORY_H
#define EQEMU_MERC_TEMPLATES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_templates_repository.h"
class MercTemplatesRepository: public BaseMercTemplatesRepository {
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
*
* MercTemplatesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercTemplatesRepository::GetWhereNeverExpires()
* MercTemplatesRepository::GetWhereXAndY()
* MercTemplatesRepository::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_MERC_TEMPLATES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_TYPES_REPOSITORY_H
#define EQEMU_MERC_TYPES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_types_repository.h"
class MercTypesRepository: public BaseMercTypesRepository {
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
*
* MercTypesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercTypesRepository::GetWhereNeverExpires()
* MercTypesRepository::GetWhereXAndY()
* MercTypesRepository::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_MERC_TYPES_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_MERC_WEAPONINFO_REPOSITORY_H
#define EQEMU_MERC_WEAPONINFO_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_merc_weaponinfo_repository.h"
class MercWeaponinfoRepository: public BaseMercWeaponinfoRepository {
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
*
* MercWeaponinfoRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercWeaponinfoRepository::GetWhereNeverExpires()
* MercWeaponinfoRepository::GetWhereXAndY()
* MercWeaponinfoRepository::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_MERC_WEAPONINFO_REPOSITORY_H
@@ -1,11 +1,11 @@
#ifndef EQEMU_HACKERS_REPOSITORY_H
#define EQEMU_HACKERS_REPOSITORY_H
#ifndef EQEMU_MERCS_REPOSITORY_H
#define EQEMU_MERCS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_hackers_repository.h"
#include "base/base_mercs_repository.h"
class HackersRepository: public BaseHackersRepository {
class MercsRepository: public BaseMercsRepository {
public:
/**
@@ -32,10 +32,10 @@ public:
*
* Example custom methods in a repository
*
* HackersRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* HackersRepository::GetWhereNeverExpires()
* HackersRepository::GetWhereXAndY()
* HackersRepository::DeleteWhereXAndY()
* MercsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* MercsRepository::GetWhereNeverExpires()
* MercsRepository::GetWhereXAndY()
* MercsRepository::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
@@ -47,4 +47,4 @@ public:
};
#endif //EQEMU_HACKERS_REPOSITORY_H
#endif //EQEMU_MERCS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
#define EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_player_event_log_settings_repository.h"
class PlayerEventLogSettingsRepository: public BasePlayerEventLogSettingsRepository {
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
*
* PlayerEventLogSettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* PlayerEventLogSettingsRepository::GetWhereNeverExpires()
* PlayerEventLogSettingsRepository::GetWhereXAndY()
* PlayerEventLogSettingsRepository::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_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
#define EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_player_event_logs_repository.h"
class PlayerEventLogsRepository: public BasePlayerEventLogsRepository {
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
*
* PlayerEventLogsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* PlayerEventLogsRepository::GetWhereNeverExpires()
* PlayerEventLogsRepository::GetWhereXAndY()
* PlayerEventLogsRepository::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_PLAYER_EVENT_LOGS_REPOSITORY_H

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