mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-23 13:12:28 +00:00
Compare commits
403 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9477ff72ac | |||
| 6d8e80b1e5 | |||
| ebeaef598b | |||
| 60b65da7f2 | |||
| 100e6698ea | |||
| 2bd94ab7a2 | |||
| 4c8d68c24b | |||
| 1755678b1f | |||
| 39e2763968 | |||
| f7780b0247 | |||
| c0fe0f11f7 | |||
| a1f1f11940 | |||
| 4c5013e09e | |||
| 838ffbd8c7 | |||
| 42b41d973c | |||
| e7761133a9 | |||
| 93f2bea96e | |||
| ded82ac6d6 | |||
| 6ef182edfd | |||
| e466ca1c6d | |||
| fa5a3155fe | |||
| a20d333f9d | |||
| 853739b538 | |||
| 6094ec9c7b | |||
| 9da1d6b397 | |||
| 8ea7299a57 | |||
| 0811a899d1 | |||
| fad9599642 | |||
| 62711b13d8 | |||
| 2702485206 | |||
| 0aadb891a1 | |||
| d812310c5b | |||
| 1420983700 | |||
| d25cc35f1b | |||
| ed7f395612 | |||
| 8dceb20dd8 | |||
| 6929d180ca | |||
| 011a66a75e | |||
| 07120563a2 | |||
| cc985cbcd5 | |||
| 97caa79472 | |||
| cfa575c756 | |||
| 85063249b4 | |||
| 04d6f8feea | |||
| dfc1bf0381 | |||
| 2237c3a056 | |||
| 4af191c593 | |||
| 0a3972deb9 | |||
| 9d2f258390 | |||
| 0b452f4ec1 | |||
| fef629e1df | |||
| a5a51fbe44 | |||
| 47db92cdb6 | |||
| 690301e80d | |||
| 1887e48b76 | |||
| af2691eb12 | |||
| 2df4289588 | |||
| 49d4d0acc3 | |||
| 5a663910a5 | |||
| b027edd21e | |||
| 0bbfcf7adc | |||
| 7962a0bd38 | |||
| 4d9b51df0a | |||
| 508ecec6ea | |||
| f0c6fa2a26 | |||
| ad6dbb7beb | |||
| 6ddbb41617 | |||
| 8a558f6a29 | |||
| 0585be0360 | |||
| 6927baef7f | |||
| 52d64781b5 | |||
| 0667fe435f | |||
| 9959070f24 | |||
| 2a91f08845 | |||
| adc64005f1 | |||
| 605480f1c4 | |||
| 3b95601c62 | |||
| a4f2ed28f1 | |||
| e19b969541 | |||
| 4241556f75 | |||
| 961332b40c | |||
| a1a861e0c4 | |||
| 4bbb1aa92f | |||
| 1212ccefef | |||
| c203fec9b4 | |||
| 16ab1839e8 | |||
| f5e4c6a127 | |||
| 166c87c931 | |||
| 345dd442dd | |||
| 565baec675 | |||
| 9884c442e9 | |||
| ad0b5d6a1c | |||
| b82b32e1d2 | |||
| 2fb72e5729 | |||
| 3791bc788f | |||
| 833fa55fdf | |||
| 4fc3c27715 | |||
| cea3ad6a42 | |||
| d8926cd5f3 | |||
| efb03164c7 | |||
| 455eb2e6d9 | |||
| b5b0e53da2 | |||
| 68cb94b39c | |||
| 3d95b6c184 | |||
| 7db7631308 | |||
| f053cd3b56 | |||
| cf27f2bc88 | |||
| 79918ebaba | |||
| 2a648507f2 | |||
| f395ee0508 | |||
| 7166fcc650 | |||
| ae8e58ddc5 | |||
| 26e72c6857 | |||
| df1d740ae6 | |||
| d7e810232a | |||
| 9b992167f0 | |||
| 65d4533568 | |||
| eb545a18a4 | |||
| f2f0228aa4 | |||
| 06337fe762 | |||
| 604c7ad4ab | |||
| bab16771aa | |||
| d3a414a048 | |||
| e85a8db8c4 | |||
| 12cc3c90ea | |||
| 9c656bc498 | |||
| bc337979bb | |||
| a64425ebe6 | |||
| ca933fce45 | |||
| 9c3498b431 | |||
| d7e09a1f3b | |||
| 1652e7a976 | |||
| 37dda9bf41 | |||
| a2b78ff4e6 | |||
| 79a3ce8d7e | |||
| d857fb3c48 | |||
| 2b4cd292e4 | |||
| 3b7cfa6454 | |||
| c5fa7e28c8 | |||
| 5d133a2b47 | |||
| 7122ac33b2 | |||
| c47644ea46 | |||
| a61f951d0e | |||
| 4357b8c731 | |||
| 9cbe25f712 | |||
| c14a17e4de | |||
| ab04a4c6df | |||
| c0cf9bb5aa | |||
| b5d23389ee | |||
| dc35ab5251 | |||
| 9cbfd5c8f0 | |||
| 5631a0711f | |||
| 00e02b61ca | |||
| 108397b138 | |||
| 9a07142a9b | |||
| 919a92bda3 | |||
| 140aba9f69 | |||
| c3d41e08f4 | |||
| 5d6a1aad50 | |||
| af91b2b41c | |||
| 2660aa79ab | |||
| 730738faf9 | |||
| 2bb7bba724 | |||
| e93081dde0 | |||
| 3a46bf7383 | |||
| aa6421afdf | |||
| 6a7eaae122 | |||
| 714b474d2c | |||
| e24d82f0fe | |||
| 33a375677e | |||
| 8fce86c396 | |||
| 68b40f0239 | |||
| 2dc2bac456 | |||
| 00a8a0cf88 | |||
| 5a466da96c | |||
| de4f5ae491 | |||
| fb20d92166 | |||
| 6cff433d23 | |||
| 2da7ddad57 | |||
| 55161e18c8 | |||
| 063d4fbd1a | |||
| c25cb0cc23 | |||
| ddac326239 | |||
| 14fe396510 | |||
| c968a0acdc | |||
| 8c4cd34e01 | |||
| 0dbcf83a11 | |||
| a75648f73f | |||
| 6c2886a71d | |||
| 1d96ddb60d | |||
| c30074be66 | |||
| b5652e6010 | |||
| 202d2ed496 | |||
| 81cee49ea1 | |||
| 2d61cd2b9a | |||
| b06505b80a | |||
| 4c2f9a4423 | |||
| fb3159b657 | |||
| 8ebf5bbb78 | |||
| d2aae4d79c | |||
| f9dc9da42b | |||
| 3f3bbe98b5 | |||
| 59537ae977 | |||
| ee45a28efe | |||
| 70ce81fb0a | |||
| e06d28ad20 | |||
| d57489781c | |||
| 21d65c73b7 | |||
| 8f6d606f53 | |||
| f25e37d0c5 | |||
| e55f9b9d27 | |||
| b01486d767 | |||
| 50ce99ce3e | |||
| 4854201b2a | |||
| c81d05940a | |||
| 47be17e2af | |||
| 809b3b6099 | |||
| f06c7e8834 | |||
| 096448d23c | |||
| e55fb1cafd | |||
| d4962bb2ab | |||
| 98e56bdfe9 | |||
| 5c1be3643e | |||
| c2fa61b3a2 | |||
| 01a1186e63 | |||
| 7427318213 | |||
| d3c3d7b384 | |||
| e9e8143778 | |||
| bc71997518 | |||
| 4a9a9fa197 | |||
| ee14aed8de | |||
| 2717fcc339 | |||
| dc28c8d485 | |||
| a633784f78 | |||
| 5519c3e781 | |||
| 9401323708 | |||
| 251993c61b | |||
| 728ce0c519 | |||
| 6a80bcecc7 | |||
| 6324e3687a | |||
| d16ac99033 | |||
| e12368f002 | |||
| a13fa07e68 | |||
| 7873ad3771 | |||
| dfadc237e5 | |||
| a1f2764978 | |||
| 927d379e75 | |||
| a1f154749c | |||
| 42a2e19e73 | |||
| c56b2e3e03 | |||
| b05f1d3218 | |||
| a004924112 | |||
| 8d986c95cd | |||
| ef7a3cae17 | |||
| 050aba65b6 | |||
| 9154c90418 | |||
| d558f9ece2 | |||
| 327dacdbe1 | |||
| f2ff4245c0 | |||
| 3ceb743195 | |||
| 021f04c17d | |||
| f7e2dbdce6 | |||
| 2a679f1002 | |||
| 8c9849ec73 | |||
| 10086ce97c | |||
| 223ae22f73 | |||
| 4330494f57 | |||
| 64ae7e4529 | |||
| 58c3e267e1 | |||
| 598483a1a4 | |||
| c1122022b9 | |||
| f2c4babd8d | |||
| 5249b065d3 | |||
| 9312261444 | |||
| 85054fedf8 | |||
| 6d7beb1796 | |||
| 66e377fd4a | |||
| 67c4c26f70 | |||
| b1c8e3890a | |||
| d6e06a19a7 | |||
| 4092b3a2cb | |||
| f4f0619618 | |||
| 71ca7f9b39 | |||
| 5fcc83b4b6 | |||
| 1f25639dd3 | |||
| 2a176835b1 | |||
| fff3e77a6e | |||
| 6efb9ec228 | |||
| a663c822e8 | |||
| cf49b2fe49 | |||
| b45e0e80b5 | |||
| 3200145d01 | |||
| 53563b9720 | |||
| 1e22baf267 | |||
| d99c3145ad | |||
| 57243c6799 | |||
| 1100668f21 | |||
| 0cf454dc29 | |||
| 75391d96f4 | |||
| 81b07a5aa0 | |||
| 774aa99b29 | |||
| 756e835144 | |||
| c5c575b028 | |||
| 152e99444c | |||
| 795df5c597 | |||
| 18eff726d0 | |||
| f06a37a009 | |||
| ae53efc52c | |||
| 548eb65e1d | |||
| fede8760d4 | |||
| 6faa202b57 | |||
| c406710623 | |||
| 662c4012db | |||
| 849e7b910d | |||
| 8e33755f02 | |||
| dfaa929778 | |||
| 306b06745f | |||
| 108fc82ee0 | |||
| 577f61b082 | |||
| a01cf0718d | |||
| 90412ba61b | |||
| 5cbc380c62 | |||
| 6c289a7c71 | |||
| 57335b188f | |||
| 056e429100 | |||
| f548aeddb2 | |||
| 4ff9faa4e6 | |||
| 17fc350d46 | |||
| b18bc66b42 | |||
| 324bfd448e | |||
| 75560ee830 | |||
| 50db7637aa | |||
| 67fdc75df3 | |||
| 9993022418 | |||
| bd95ed44fd | |||
| 65fd323eab | |||
| 290c58741e | |||
| 39d0772a01 | |||
| 622fe50479 | |||
| f41a219309 | |||
| 23bc3c7fd6 | |||
| 3144ac1a28 | |||
| a5106420e8 | |||
| 5a42c4f667 | |||
| a3107cc54d | |||
| f0152cef66 | |||
| 21755a9f9e | |||
| b329515a07 | |||
| ff4b117cfa | |||
| e305ba852b | |||
| b8c91cf4f9 | |||
| cd82bd8472 | |||
| 20bed20f47 | |||
| c93054421f | |||
| b7a1fc6644 | |||
| 6bfb8fca2e | |||
| 9d6a7ad743 | |||
| 076b88be9a | |||
| 84a779c4df | |||
| 3fb479e612 | |||
| c1f4ee0e65 | |||
| 32f7dc3d1b | |||
| fa55fd1664 | |||
| c44c0d4efa | |||
| 50c63b95db | |||
| 612029de6e | |||
| dbc6346fe8 | |||
| 93a4153a4b | |||
| 434f270f68 | |||
| 5ba33b88bd | |||
| ce1de9997b | |||
| 8814ab26cd | |||
| 8c23eee42a | |||
| 5475615448 | |||
| 4a5559022f | |||
| 5be2041085 | |||
| 9f4d60ec36 | |||
| c64a2aec94 | |||
| 0e582eda82 | |||
| 7eff6ada87 | |||
| 291997d35b | |||
| ac4572bf79 | |||
| f0a9578b6a | |||
| baa824d8fb | |||
| b19d3ac8a2 | |||
| 6a393bf0c3 | |||
| 09a5551de1 | |||
| 6e2e035d66 | |||
| ac5922bb32 | |||
| ecf2a369cc | |||
| 95b306599f | |||
| 497d20512a | |||
| db916e946e | |||
| 958549b407 | |||
| 71ebf1b2d4 | |||
| e19b8d3056 | |||
| 8b1d64a043 | |||
| 576f99f292 | |||
| e3761cf2a3 | |||
| ad1764b464 | |||
| 1c9ea57a4e | |||
| 03c158b674 | |||
| 39b5374e92 |
+1
-1
@@ -15,7 +15,7 @@ volumes:
|
||||
|
||||
steps:
|
||||
- name: Build Linux X64
|
||||
image: akkadius/eqemu-server:v11
|
||||
image: akkadius/eqemu-server:v13
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
|
||||
+985
@@ -1,3 +1,988 @@
|
||||
## [22.34.2] - 11/23/2023
|
||||
|
||||
### Admin
|
||||
|
||||
* Update date in changelog ([#3698](https://github.com/EQEmu/Server/pull/3698)) @joligario 2023-11-19
|
||||
|
||||
### Code
|
||||
|
||||
* Fix typo in #giveitem ([#3704](https://github.com/EQEmu/Server/pull/3704)) @Kinglykrab 2023-11-22
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add "IgnoreLevelBasedHasteCaps" rule to GetHaste() ([#3705](https://github.com/EQEmu/Server/pull/3705)) @jcr4990 2023-11-23
|
||||
* Fix bots/Mercenaries being removed from hatelist ([#3708](https://github.com/EQEmu/Server/pull/3708)) @Kinglykrab 2023-11-23
|
||||
* Fix some spell types failing IsValidSpellRange check ([#3707](https://github.com/EQEmu/Server/pull/3707)) @nytmyr 2023-11-23
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Update ticket login table structure ([#3703](https://github.com/EQEmu/Server/pull/3703)) @KimLS 2023-11-22
|
||||
|
||||
## [22.34.1] - 11/20/2023
|
||||
|
||||
### EQTime
|
||||
|
||||
Hotfix for world not spamming save messages by setting to detail level logging @Akkadius 2023-11-20
|
||||
|
||||
## [22.34.0] - 11/19/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add ownerraid, byclass and byrace actionables and fix group-based arguments for raids. ([#3680](https://github.com/EQEmu/Server/pull/3680)) @nytmyr 2023-11-19
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup #giveitem and #summonitem ([#3692](https://github.com/EQEmu/Server/pull/3692)) @Kinglykrab 2023-11-19
|
||||
* Cleanup #show currencies Command ([#3693](https://github.com/EQEmu/Server/pull/3693)) @Kinglykrab 2023-11-19
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #show aa_points Command ([#3695](https://github.com/EQEmu/Server/pull/3695)) @Kinglykrab 2023-11-19
|
||||
|
||||
### Database
|
||||
|
||||
* Pull pet power from content database ([#3689](https://github.com/EQEmu/Server/pull/3689)) @joligario 2023-11-18
|
||||
|
||||
### GM Commands
|
||||
|
||||
* Add `#takeplatinum` ([#3690](https://github.com/EQEmu/Server/pull/3690)) @joligario 2023-11-19
|
||||
* Remove duplicate comment ([#3691](https://github.com/EQEmu/Server/pull/3691)) @joligario 2023-11-19
|
||||
|
||||
### Illusions
|
||||
|
||||
* RandomizeFeastures erased texture. ([#3686](https://github.com/EQEmu/Server/pull/3686)) @noudess 2023-11-12
|
||||
|
||||
### Spawn
|
||||
|
||||
* (imported from takp) Added min_time and max_time to spawnentry. This will prevent a NPC from… ([#3685](https://github.com/EQEmu/Server/pull/3685)) @regneq 2023-11-18
|
||||
|
||||
## [22.33.0] - 11/11/2023
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Comment to Item Data/Quest API ([#3669](https://github.com/EQEmu/Server/pull/3669)) @Kinglykrab 2023-11-07
|
||||
|
||||
### Spawn2
|
||||
|
||||
* Fix edge case with instances not copying disabled spawn state ([#3688](https://github.com/EQEmu/Server/pull/3688)) @Akkadius 2023-11-12
|
||||
|
||||
## [22.32.1] - 11/6/2023
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Adjust spawn2_disabled migration to copy data over
|
||||
|
||||
## [22.32.0] - 11/6/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Fix invalid races from being created ([#3681](https://github.com/EQEmu/Server/pull/3681)) @nytmyr 2023-11-06
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix crash on CentOS when forming a raid with PCs or BOTs ([#3676](https://github.com/EQEmu/Server/pull/3676)) @neckkola 2023-11-06
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add IsTGBCompatibleSpell() to package.add ([#3675](https://github.com/EQEmu/Server/pull/3675)) @Kinglykrab 2023-11-04
|
||||
* Fix Perl__worldwideremovetask package ([#3670](https://github.com/EQEmu/Server/pull/3670)) @Kinglykrab 2023-11-04
|
||||
* Revert " Fix Killed XYZH support in EVENT_DEATH in Perl. " (#3682) ([#3591](https://github.com/EQEmu/Server/pull/3591)) @fryguy503 2023-11-06
|
||||
CRASH
|
||||
|
||||
### GCC
|
||||
|
||||
* Compatibility fix for GCC 13 ([#3677](https://github.com/EQEmu/Server/pull/3677)) @joligario 2023-11-05
|
||||
|
||||
### Parser
|
||||
|
||||
* Cleanup Spire Parsing for crosszonemoveplayerbycharid ([#3674](https://github.com/EQEmu/Server/pull/3674)) @Kinglykrab 2023-11-04
|
||||
* Cleanup Spire Parsing for crosszonemoveplayerbyexpeditionid ([#3671](https://github.com/EQEmu/Server/pull/3671)) @Kinglykrab 2023-11-04
|
||||
* Cleanup Spire Parsing for crosszonemoveplayerbygroupid ([#3673](https://github.com/EQEmu/Server/pull/3673)) @Kinglykrab 2023-11-04
|
||||
* Cleanup Spire Parsing for crosszonemoveplayerbyguildid ([#3672](https://github.com/EQEmu/Server/pull/3672)) @Kinglykrab 2023-11-04
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetBaseRaceName() to Perl and Lua ([#3668](https://github.com/EQEmu/Server/pull/3668)) @joligario 2023-11-01
|
||||
* Add details to Lua event dispatch errors ([#3679](https://github.com/EQEmu/Server/pull/3679)) @hgtw 2023-11-06
|
||||
|
||||
### Spawn
|
||||
|
||||
* Split spawn2 enabled into its own state table ([#3664](https://github.com/EQEmu/Server/pull/3664)) @Akkadius 2023-11-06
|
||||
|
||||
### Spells
|
||||
|
||||
* Added IsNightTime() for Dance of the Fireflies ([#3667](https://github.com/EQEmu/Server/pull/3667)) @regneq 2023-11-04
|
||||
|
||||
## [22.31.3] - 10/31/2023
|
||||
|
||||
### Bug
|
||||
|
||||
* Force raids off content database ([#3665](https://github.com/EQEmu/Server/pull/3665)) @joligario 2023-10-31
|
||||
|
||||
### Crash
|
||||
|
||||
* Revert " Fix spell in AESpell related to beacons " ([#3659](https://github.com/EQEmu/Server/pull/3659)) @Akkadius 2023-10-31
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix issue with blocked spells not loading properly @Akkadius 2023-10-31
|
||||
|
||||
### Logs
|
||||
|
||||
* Convert Loot Messages to Error Logs ([#3663](https://github.com/EQEmu/Server/pull/3663)) @Kinglykrab 2023-10-31
|
||||
|
||||
## [22.31.2] - 10/31/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Hotfix issue with beacon spells crashing @Akkadius 2023-10-31
|
||||
|
||||
## [22.31.1] - 10/31/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Hotfix issue with blocked spells not loading properly @Akkadius 2023-10-31
|
||||
|
||||
## [22.31.0] - 10/29/2023
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix crash when client pointer does not exist during #hotfix ([#3661](https://github.com/EQEmu/Server/pull/3661)) @Akkadius 2023-10-29
|
||||
* Fix spell in AESpell related to beacons ([#3659](https://github.com/EQEmu/Server/pull/3659)) @Akkadius 2023-10-29
|
||||
|
||||
### Database
|
||||
|
||||
* Add id to variables table ([#3658](https://github.com/EQEmu/Server/pull/3658)) @Akkadius 2023-10-29
|
||||
|
||||
### Linux
|
||||
|
||||
* Add symbols to release builds ([#3660](https://github.com/EQEmu/Server/pull/3660)) @Akkadius 2023-10-29
|
||||
|
||||
### Perl
|
||||
|
||||
* Revert " Reload perl quests on zone bootup " ([#3648](https://github.com/EQEmu/Server/pull/3648)) @Akkadius 2023-10-26
|
||||
|
||||
### Trading
|
||||
|
||||
* Fix part 3 of Issue 932. ([#3654](https://github.com/EQEmu/Server/pull/3654)) @noudess 2023-10-29
|
||||
|
||||
## [22.30.2] - 10/26/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
Revert Perl regression in #3648 causing scripts to not reliably initialize on zone bootup. @Akkadius 2023-10-26
|
||||
|
||||
## [22.30.1] - 10/24/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix empty InsertMany in bot starting items. ([#3653](https://github.com/EQEmu/Server/pull/3653)) @Kinglykrab 2023-10-24
|
||||
|
||||
## [22.30.0] - 10/23/2023
|
||||
|
||||
### API
|
||||
|
||||
* Implement Zone Sidecar ([#3635](https://github.com/EQEmu/Server/pull/3635)) @Akkadius 2023-10-24
|
||||
|
||||
### Commands
|
||||
|
||||
* Move #suspend from content database ([#3651](https://github.com/EQEmu/Server/pull/3651)) @joligario 2023-10-24
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix Bot Starting Items SQL ([#3649](https://github.com/EQEmu/Server/pull/3649)) @Kinglykrab 2023-10-23
|
||||
|
||||
### Perl
|
||||
|
||||
* Implement eqemu-perl for Linux ([#3652](https://github.com/EQEmu/Server/pull/3652)) @Akkadius 2023-10-24
|
||||
* Reload perl quests on zone bootup ([#3648](https://github.com/EQEmu/Server/pull/3648)) @hgtw 2023-10-24
|
||||
|
||||
### Pets
|
||||
|
||||
* Disallow effect of alliance line when cast on pets. ([#3650](https://github.com/EQEmu/Server/pull/3650)) @noudess 2023-10-24
|
||||
|
||||
## [22.29.1] - 10/21/2023
|
||||
|
||||
### DB
|
||||
|
||||
* Fix manifest for blocked spells ([#3646](https://github.com/EQEmu/Server/pull/3646)) @joligario 2023-10-21
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix issue with subcommand settings not working ([#3643](https://github.com/EQEmu/Server/pull/3643)) @Kinglykrab 2023-10-21
|
||||
* Hotfix command without hotfix name ([#3644](https://github.com/EQEmu/Server/pull/3644)) @joligario 2023-10-21
|
||||
* Verifying mail keys when none exist ([#3645](https://github.com/EQEmu/Server/pull/3645)) @joligario 2023-10-21
|
||||
|
||||
## [22.29.0] - 10/20/2023
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Expansion and Content Flag support to Blocked Spells ([#3638](https://github.com/EQEmu/Server/pull/3638)) @Kinglykrab 2023-10-20
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix crash when checking Bot Group/Raid membership ([#3641](https://github.com/EQEmu/Server/pull/3641)) @Aeadoin 2023-10-20
|
||||
|
||||
### Perl
|
||||
|
||||
* Static linker fix on Linux ([#3642](https://github.com/EQEmu/Server/pull/3642)) @Akkadius 2023-10-20
|
||||
|
||||
### Rules
|
||||
|
||||
* Add rule to configure max number of procs per round Combat:MaxProcs ([#3640](https://github.com/EQEmu/Server/pull/3640)) @Akkadius 2023-10-20
|
||||
|
||||
## [22.28.1] - 10/20/2023
|
||||
|
||||
### Build
|
||||
|
||||
* Perl Linux build fix
|
||||
|
||||
## [22.28.0] - 10/15/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Adjust Bot Movement Speed ([#3615](https://github.com/EQEmu/Server/pull/3615)) @Kinglykrab 2023-10-14
|
||||
* Fix bot removal on zone, regression from #3611 ([#3631](https://github.com/EQEmu/Server/pull/3631)) @Akkadius 2023-10-16
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix Crash with #summon ([#3618](https://github.com/EQEmu/Server/pull/3618)) @Kinglykrab 2023-10-14
|
||||
* Fix crash in Mob::ShowBuffs ([#3632](https://github.com/EQEmu/Server/pull/3632)) @Akkadius 2023-10-16
|
||||
* Resolve crash when assigning empty raid note. ([#3628](https://github.com/EQEmu/Server/pull/3628)) @Aeadoin 2023-10-15
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Extra Kick Classes ([#3613](https://github.com/EQEmu/Server/pull/3613)) @Kinglykrab 2023-10-11
|
||||
* Add Immune to Assassinate Special Ability ([#3622](https://github.com/EQEmu/Server/pull/3622)) @Kinglykrab 2023-10-14
|
||||
* Add Immune to Headshot Special Ability ([#3624](https://github.com/EQEmu/Server/pull/3624)) @Kinglykrab 2023-10-14
|
||||
* Update Raid Functions for Titanium and Underfoot ([#3524](https://github.com/EQEmu/Server/pull/3524)) @neckkola 2023-10-14
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix #cast defaulting to cast time ([#3617](https://github.com/EQEmu/Server/pull/3617)) @Kinglykrab 2023-10-14
|
||||
|
||||
### Parser Fix
|
||||
|
||||
* Fix SendIllusion Spire parsing ([#3623](https://github.com/EQEmu/Server/pull/3623)) @Kinglykrab 2023-10-14
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GrantAllAAPoints() to Perl/Lua and Modify #grantaa ([#3616](https://github.com/EQEmu/Server/pull/3616)) @Kinglykrab 2023-10-14
|
||||
* Add target ID and spell exports to events ([#3620](https://github.com/EQEmu/Server/pull/3620)) @Kinglykrab 2023-10-15
|
||||
|
||||
### Scripts
|
||||
|
||||
* Update 13th Floor importer ([#3630](https://github.com/EQEmu/Server/pull/3630)) @joligario 2023-10-16
|
||||
* Update 13th Floor script for legacy research tome bagtypes ([#3621](https://github.com/EQEmu/Server/pull/3621)) @joligario 2023-10-14
|
||||
|
||||
## [22.27.0] - 10/07/2023
|
||||
|
||||
### Crash
|
||||
|
||||
* Bot member zoned crash fix ([#3607](https://github.com/EQEmu/Server/pull/3607)) @Akkadius 2023-10-07
|
||||
* Fix #summon crash ([#3608](https://github.com/EQEmu/Server/pull/3608)) @Akkadius 2023-10-07
|
||||
* Fix CanUseAlternateAdvancementRank crash ([#3609](https://github.com/EQEmu/Server/pull/3609)) @Akkadius 2023-10-07
|
||||
* Fix crash in #movechar ([#3612](https://github.com/EQEmu/Server/pull/3612)) @Akkadius 2023-10-07
|
||||
* Fix crash in CastSpell Quest API input cast ([#3610](https://github.com/EQEmu/Server/pull/3610)) @Akkadius 2023-10-07
|
||||
* Fix dangling pointer crash observed in SendHPPacketsFrom ([#3611](https://github.com/EQEmu/Server/pull/3611)) @Akkadius 2023-10-07
|
||||
* Fix rarer crash with File::Makedir ([#3606](https://github.com/EQEmu/Server/pull/3606)) @Akkadius 2023-10-07
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-18
|
||||
* Ensure Linux builds report failures @Akkadius 2023-10-03
|
||||
* Fix #show group_info Popup ([#3605](https://github.com/EQEmu/Server/pull/3605)) @Kinglykrab 2023-10-04
|
||||
* Fix swarm pet names to use '_' instead of ' ' ([#3601](https://github.com/EQEmu/Server/pull/3601)) @noudess 2023-09-19
|
||||
* Invis vs. Undead/Animal Breaks Charm for Pets ([#3587](https://github.com/EQEmu/Server/pull/3587)) @crdunwel 2023-09-19
|
||||
|
||||
### Logs
|
||||
|
||||
* Change pathing log messages from Error to Pathing. ([#3604](https://github.com/EQEmu/Server/pull/3604)) @joligario 2023-09-29
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Caster ID Parameter to FindBuff in Perl/Lua ([#3590](https://github.com/EQEmu/Server/pull/3590)) @Kinglykrab 2023-09-29
|
||||
|
||||
## [22.26.2] - 09/18/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix an issue with schema versioning for the AA update
|
||||
|
||||
## [22.26.1] - 09/17/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-17
|
||||
|
||||
## [22.26.0] - 09/17/2023
|
||||
|
||||
### Bug
|
||||
|
||||
* Additional Wild Ramp param was causing an overflow it appears at least on local testing. ([#3589](https://github.com/EQEmu/Server/pull/3589)) @fryguy503 2023-09-11
|
||||
|
||||
### Commands
|
||||
|
||||
* npc_edit faction and #setfaction duplicate and incorrect. ([#3577](https://github.com/EQEmu/Server/pull/3577)) @noudess 2023-09-03
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Defensive Proc Rules for Level Gap Penalty ([#3580](https://github.com/EQEmu/Server/pull/3580)) @Kinglykrab 2023-09-17
|
||||
* Add opcodes for Cast and Scribe book buttons ([#3578](https://github.com/EQEmu/Server/pull/3578)) @hgtw 2023-09-17
|
||||
* Cleanup Group Split Money Logic ([#3583](https://github.com/EQEmu/Server/pull/3583)) @crdunwel 2023-09-17
|
||||
|
||||
### Fixes
|
||||
|
||||
* AA System Fixes ([#3572](https://github.com/EQEmu/Server/pull/3572)) @KimLS 2023-09-17
|
||||
* Check for Song Skill Increase on Bard Pulse ([#3586](https://github.com/EQEmu/Server/pull/3586)) @crdunwel 2023-09-17
|
||||
* Fix #set faction/#setfaction Command ([#3575](https://github.com/EQEmu/Server/pull/3575)) @Kinglykrab 2023-09-02
|
||||
* Fix Killed XYZH support in EVENT_DEATH in Perl. ([#3591](https://github.com/EQEmu/Server/pull/3591)) @Kinglykrab 2023-09-17
|
||||
* Fix entity ID on death with #castspell ([#3592](https://github.com/EQEmu/Server/pull/3592)) @Kinglykrab 2023-09-17
|
||||
* Zoning logging edge case safety @Akkadius 2023-08-29
|
||||
|
||||
### Logging
|
||||
|
||||
* Add logging to track down Wild Ramp issue ([#3588](https://github.com/EQEmu/Server/pull/3588)) @fryguy503 2023-09-11
|
||||
|
||||
### Messages
|
||||
|
||||
* Remove duplicate message on tracking begin ([#3574](https://github.com/EQEmu/Server/pull/3574)) @noudess 2023-09-11
|
||||
* Swarm pet normal damage messages were missing ([#3594](https://github.com/EQEmu/Server/pull/3594)) @noudess 2023-09-17
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add ApplySpell() and SetBuffDuration() overloads to Perl/Lua ([#3576](https://github.com/EQEmu/Server/pull/3576)) @Kinglykrab 2023-09-17
|
||||
* Add XYZ/XYZH Overloads to Cross Zone Move Methods ([#3581](https://github.com/EQEmu/Server/pull/3581)) @Kinglykrab 2023-09-17
|
||||
|
||||
## [22.25.0] - 08/28/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add Support for Mana Pool AA Bonuses. ([#3571](https://github.com/EQEmu/Server/pull/3571)) @Aeadoin 2023-08-21
|
||||
* Remove In-Game Command References to Bot Groups ([#3545](https://github.com/EQEmu/Server/pull/3545)) @Aeadoin 2023-08-13
|
||||
|
||||
### Bug
|
||||
|
||||
* Escape item name in trader audit. ([#3540](https://github.com/EQEmu/Server/pull/3540)) @fryguy503 2023-08-13
|
||||
|
||||
### CMake
|
||||
|
||||
* Add cmake option to re-enable MSVC warnings ([#3537](https://github.com/EQEmu/Server/pull/3537)) @hgtw 2023-08-13
|
||||
* Define perlbind option for all targets ([#3538](https://github.com/EQEmu/Server/pull/3538)) @hgtw 2023-08-13
|
||||
|
||||
### Charm
|
||||
|
||||
* Fix to update target windows on charm on/off ([#3549](https://github.com/EQEmu/Server/pull/3549)) @noudess 2023-08-20
|
||||
|
||||
### Combat Messages
|
||||
|
||||
* Fix issue where pet proc damage was not showing up ([#3551](https://github.com/EQEmu/Server/pull/3551)) @noudess 2023-08-24
|
||||
|
||||
### Database
|
||||
|
||||
* Change primary key entry to NOT NULL ([#3559](https://github.com/EQEmu/Server/pull/3559)) @joligario 2023-08-20
|
||||
* Extend dumper CLI utility to export static instance data ([#3562](https://github.com/EQEmu/Server/pull/3562)) @Akkadius 2023-08-20
|
||||
|
||||
### Expansions
|
||||
|
||||
* Expansion settings tweaks ([#3556](https://github.com/EQEmu/Server/pull/3556)) @Akkadius 2023-08-20
|
||||
|
||||
### Feature
|
||||
|
||||
* Add adjustability for AERampage Range. ([#3548](https://github.com/EQEmu/Server/pull/3548)) @fryguy503 2023-08-20
|
||||
* Change #reload zone to reload zone headers globally. ([#3557](https://github.com/EQEmu/Server/pull/3557)) @Kinglykrab 2023-08-20
|
||||
* Change money type to all lower case as EQ live money shares and split has it that way. ([#3550](https://github.com/EQEmu/Server/pull/3550)) @regneq 2023-08-18
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add character_stats_record to player tables @Akkadius 2023-08-11
|
||||
* Bots no longer drop group on death, and raid fixes. ([#3542](https://github.com/EQEmu/Server/pull/3542)) @Aeadoin 2023-08-13
|
||||
* Bots will now load AAs properly when spawned. ([#3544](https://github.com/EQEmu/Server/pull/3544)) @Aeadoin 2023-08-13
|
||||
* Clearing target window on CHARM wear off had a side effect ([#3570](https://github.com/EQEmu/Server/pull/3570)) @noudess 2023-08-21
|
||||
* Fix #motd/#set motd Command ([#3558](https://github.com/EQEmu/Server/pull/3558)) @Kinglykrab 2023-08-20
|
||||
* Fix Bot::CheckDataBucket to work with Owner Buckets. ([#3552](https://github.com/EQEmu/Server/pull/3552)) @Aeadoin 2023-08-18
|
||||
* Fix to zoning logging exception @Akkadius 2023-08-29
|
||||
* Instance GetUnusedInstanceID crash fox @Akkadius 2023-08-21
|
||||
* Minor adjustment to formula calc position to fix modifier bug. ([#3565](https://github.com/EQEmu/Server/pull/3565)) @Valorith 2023-08-21
|
||||
|
||||
### Instances
|
||||
|
||||
* Honor reserved instances ([#3563](https://github.com/EQEmu/Server/pull/3563)) @joligario 2023-08-21
|
||||
* Refine id selection ([#3568](https://github.com/EQEmu/Server/pull/3568)) @joligario 2023-08-29
|
||||
|
||||
### Logging
|
||||
|
||||
* Add detailed zoning logging ([#3555](https://github.com/EQEmu/Server/pull/3555)) @Akkadius 2023-08-20
|
||||
|
||||
### Quest API
|
||||
|
||||
* Reload content flags globally when a content flag is set ([#3564](https://github.com/EQEmu/Server/pull/3564)) @Akkadius 2023-08-21
|
||||
|
||||
### Rules
|
||||
|
||||
* Add FinalRaidExpMultiplier Rule ([#3554](https://github.com/EQEmu/Server/pull/3554)) @Valorith 2023-08-20
|
||||
* Add a rule to adjust the randomization range for Wizard\Caster Merc innate critical ratio. ([#3543](https://github.com/EQEmu/Server/pull/3543)) @catapultam-habeo 2023-08-13
|
||||
* Add rule to restrict hand in of quest items to quest flagged NPCs. ([#3536](https://github.com/EQEmu/Server/pull/3536)) @Valorith 2023-08-13
|
||||
* Add rule to toggle pets accepting quest items ([#3533](https://github.com/EQEmu/Server/pull/3533)) @Valorith 2023-08-06
|
||||
* Also reload rules in world when #reload rules invoked ([#3566](https://github.com/EQEmu/Server/pull/3566)) @Akkadius 2023-08-21
|
||||
* Correct explanation of Bots:ManaRegen ([#3569](https://github.com/EQEmu/Server/pull/3569)) @Aeadoin 2023-08-21
|
||||
|
||||
### Spawns
|
||||
|
||||
* Fixes a rarer issue where spawn2 is not being properly content filtered @Akkadius 2023-08-13
|
||||
|
||||
## [22.24.0] - 08/05/2023
|
||||
|
||||
### Character
|
||||
|
||||
* Record character stats to `character_stats_record` table ([#3522](https://github.com/EQEmu/Server/pull/3522)) @Akkadius 2023-08-05
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup #view zone_loot Command ([#3523](https://github.com/EQEmu/Server/pull/3523)) @Kinglykrab 2023-08-02
|
||||
* Remove Strings::Commify from all identifier values ([#3528](https://github.com/EQEmu/Server/pull/3528)) @Kinglykrab 2023-08-02
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Support for Drakkin Heritage Illusions ([#3521](https://github.com/EQEmu/Server/pull/3521)) @Kinglykrab 2023-08-01
|
||||
|
||||
### Fixes
|
||||
|
||||
* Bug fix for raid mark NPC across zones ([#3525](https://github.com/EQEmu/Server/pull/3525)) @neckkola 2023-08-05
|
||||
* Bugs table should not target content database ([#3535](https://github.com/EQEmu/Server/pull/3535)) @Akkadius 2023-08-05
|
||||
* Fix +/- 0.1 XYZ Door Manipulation ([#3527](https://github.com/EQEmu/Server/pull/3527)) @Kinglykrab 2023-08-02
|
||||
* Fix issue with mob scanning when trying to use EVENT_SPAWN ([#3529](https://github.com/EQEmu/Server/pull/3529)) @Akkadius 2023-08-04
|
||||
|
||||
### Quest API
|
||||
|
||||
* Adjust GetCloseMobList calls internally ([#3530](https://github.com/EQEmu/Server/pull/3530)) @Akkadius 2023-08-04
|
||||
|
||||
## [22.23.0] - 07/31/2023
|
||||
|
||||
### Databuckets
|
||||
|
||||
* Improvements to distributed cache, reload commands ([#3519](https://github.com/EQEmu/Server/pull/3519)) @Akkadius 2023-08-01
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix #gm top level alias for #set gm ([#3517](https://github.com/EQEmu/Server/pull/3517)) @Kinglykrab 2023-07-30
|
||||
* Fix Appearance Issues ([#3520](https://github.com/EQEmu/Server/pull/3520)) @Kinglykrab 2023-08-01
|
||||
* Fix NPC Cast Events not parsing properly. ([#3518](https://github.com/EQEmu/Server/pull/3518)) @Kinglykrab 2023-08-01
|
||||
|
||||
### Scaling/Bug Fix
|
||||
|
||||
* Scaling where min and max damage was bugged ([#3514](https://github.com/EQEmu/Server/pull/3514)) @noudess 2023-08-01
|
||||
|
||||
## [22.22.1] - 07/30/2023
|
||||
|
||||
### Database
|
||||
|
||||
* Hotfix: Add command_subsettings to server tables @Akkadius 2023-07-29
|
||||
|
||||
### Doors
|
||||
|
||||
* Add door blacklist ([#3516](https://github.com/EQEmu/Server/pull/3516)) @Akkadius 2023-07-30
|
||||
|
||||
## [22.22.0] - 07/27/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Fix casing in corpse money and decay time. ([#3511](https://github.com/EQEmu/Server/pull/3511)) @Kinglykrab 2023-07-23
|
||||
|
||||
### Crash Fix
|
||||
|
||||
* Guard against Spells:MaxTotalSlotsPET being set above client allowed maximum. ([#3507](https://github.com/EQEmu/Server/pull/3507)) @Valorith 2023-07-22
|
||||
|
||||
### Data Buckets
|
||||
|
||||
* Distributed Databucket Caching ([#3500](https://github.com/EQEmu/Server/pull/3500)) @Kinglykrab 2023-07-24
|
||||
|
||||
### Database
|
||||
|
||||
* Fix console output in database:dump --dump-output-to-console @Akkadius 2023-07-25
|
||||
|
||||
### Fixes
|
||||
|
||||
* Escape search string in #find item ([#3510](https://github.com/EQEmu/Server/pull/3510)) @Kinglykrab 2023-07-22
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetMobTypeIdentifier() to Perl/Lua ([#3512](https://github.com/EQEmu/Server/pull/3512)) @Kinglykrab 2023-07-28
|
||||
|
||||
### Saylink
|
||||
|
||||
* Fix cases where saylinks were not being cached ([#3508](https://github.com/EQEmu/Server/pull/3508)) @Akkadius 2023-07-20
|
||||
|
||||
## [22.21.2] - 07/19/2023
|
||||
|
||||
### Databuckets
|
||||
|
||||
* Fix rarer same bucket name scoping overlap issue ([#3509](https://github.com/EQEmu/Server/pull/3509)) @Akkadius 2023-07-20
|
||||
|
||||
## [22.21.1] - 07/18/2023
|
||||
|
||||
### Bug
|
||||
|
||||
* Show Petition and Show Petition_Info fix ([#3503](https://github.com/EQEmu/Server/pull/3503)) @fryguy503 2023-07-18
|
||||
|
||||
### Code
|
||||
|
||||
* Remove arbitrary teleport blocking in Tutorial and Load zones ([#3506](https://github.com/EQEmu/Server/pull/3506)) @Valorith 2023-07-19
|
||||
|
||||
### Databuckets
|
||||
|
||||
* Fix issue with expired databuckets not being expired and returned properly ([#3504](https://github.com/EQEmu/Server/pull/3504)) @Akkadius 2023-07-18
|
||||
|
||||
### Fixes
|
||||
|
||||
* #set title_suffix Argument Position ([#3505](https://github.com/EQEmu/Server/pull/3505)) @Kinglykrab 2023-07-18
|
||||
|
||||
## [22.21.0] - 07/18/2023
|
||||
|
||||
### Data Buckets
|
||||
|
||||
* Implement scoped data buckets ([#3498](https://github.com/EQEmu/Server/pull/3498)) @Akkadius 2023-07-16
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix rule check and add rule for pickpocket command ([#3492](https://github.com/EQEmu/Server/pull/3492)) @tuday2 2023-07-16
|
||||
|
||||
### Pathing
|
||||
|
||||
* Improvements to roambox logic, pathing ([#3502](https://github.com/EQEmu/Server/pull/3502)) @Akkadius 2023-07-18
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add SetLDoNPoints() to Perl/Lua ([#3496](https://github.com/EQEmu/Server/pull/3496)) @Kinglykrab 2023-07-16
|
||||
|
||||
### Z Clipping
|
||||
|
||||
* Don't issue zclip adjustments when NPC is not moving ([#3499](https://github.com/EQEmu/Server/pull/3499)) @Akkadius 2023-07-16
|
||||
|
||||
## [22.20.1] - 07/15/2023
|
||||
|
||||
### Database
|
||||
|
||||
* Fix database manifest entry for #3443 @neckkola 2023-07-15
|
||||
|
||||
## [22.20.0] - 07/15/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Remove orphaned commands related to botgroup ([#3489](https://github.com/EQEmu/Server/pull/3489)) @tuday2 2023-07-09
|
||||
|
||||
### Commands
|
||||
|
||||
* Consolidate #set-like commands into a singular #set command ([#3486](https://github.com/EQEmu/Server/pull/3486)) @Kinglykrab 2023-07-15
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Support for item textures higher than 65,535 ([#3494](https://github.com/EQEmu/Server/pull/3494)) @Kinglykrab 2023-07-14
|
||||
* Update raid features ([#3443](https://github.com/EQEmu/Server/pull/3443)) @neckkola 2023-07-13
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix Tradeskill Combines with augmented items ([#3490](https://github.com/EQEmu/Server/pull/3490)) @Kinglykrab 2023-07-15
|
||||
* Fix charmed pets to follow when charmed. ([#3488](https://github.com/EQEmu/Server/pull/3488)) @noudess 2023-07-08
|
||||
* Update bot naming check and add more explanation ([#3491](https://github.com/EQEmu/Server/pull/3491)) @tuday2 2023-07-13
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Mob/Entity type check methods to Perl/Lua ([#3493](https://github.com/EQEmu/Server/pull/3493)) @Kinglykrab 2023-07-13
|
||||
|
||||
## [22.19.0] - 07/08/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add Pickpocket Command ([#3484](https://github.com/EQEmu/Server/pull/3484)) @tuday2 2023-07-08
|
||||
|
||||
### Code
|
||||
|
||||
* Move #find item summon links to front ([#3483](https://github.com/EQEmu/Server/pull/3483)) @Kinglykrab 2023-07-05
|
||||
* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #itemsearch alias to #find aliases ([#3485](https://github.com/EQEmu/Server/pull/3485)) @Kinglykrab 2023-07-08
|
||||
* Consolidate #show commands into a singular #show command ([#3478](https://github.com/EQEmu/Server/pull/3478)) @Kinglykrab 2023-07-08
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Skills:TrivialTradeskillCombinesNoFail Rule ([#3481](https://github.com/EQEmu/Server/pull/3481)) @JasXSL 2023-07-05
|
||||
|
||||
## [22.18.0] - 07/04/2023
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #emotesearch to #find command ([#3480](https://github.com/EQEmu/Server/pull/3480)) @Kinglykrab 2023-07-04
|
||||
* Cleanup #copycharacter Command ([#3479](https://github.com/EQEmu/Server/pull/3479)) @Kinglykrab 2023-07-04
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add chatchannel_reserved_names to a new manifest ([#3482](https://github.com/EQEmu/Server/pull/3482)) @Kinglykrab 2023-07-04
|
||||
* Fix issue in zone store of returning reference to local variable ([#3477](https://github.com/EQEmu/Server/pull/3477)) @Kinglykrab 2023-07-04
|
||||
|
||||
## [22.17.0] - 07/03/2023
|
||||
|
||||
### Cleanup/Feature
|
||||
|
||||
* Add support for bots to #showstats/#mystats ([#3427](https://github.com/EQEmu/Server/pull/3427)) @Kinglykrab 2023-07-01
|
||||
|
||||
### Code
|
||||
|
||||
* Remove LoadItemDBFieldNames() from common/misc.cpp and common/misc.h ([#3473](https://github.com/EQEmu/Server/pull/3473)) @Kinglykrab 2023-07-04
|
||||
* Remove handle_npc_single_npc from zone/lua_parser_events.cpp and zone/lua_parser_events.h ([#3467](https://github.com/EQEmu/Server/pull/3467)) @Kinglykrab 2023-07-03
|
||||
|
||||
### Database
|
||||
|
||||
* Set multi statements off when returning early ([#3462](https://github.com/EQEmu/Server/pull/3462)) @Akkadius 2023-07-01
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Strings::BeginsWith() and Strings::EndsWith() ([#3471](https://github.com/EQEmu/Server/pull/3471)) @Kinglykrab 2023-07-03
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add check for underscores in botcreate command ([#3458](https://github.com/EQEmu/Server/pull/3458)) @tuday2 2023-06-29
|
||||
* EVENT_LANGUAGE_SKILL_UP in Lua was using EVENT_SKILL_UP logic ([#3466](https://github.com/EQEmu/Server/pull/3466)) @Kinglykrab 2023-07-03
|
||||
* Fix _PutItem having a slot_id of -1 on mobs with no items ([#3474](https://github.com/EQEmu/Server/pull/3474)) @Kinglykrab 2023-07-04
|
||||
* Fix data type of GetAggroCount() ([#3470](https://github.com/EQEmu/Server/pull/3470)) @Kinglykrab 2023-07-03
|
||||
|
||||
### Logging
|
||||
|
||||
* Fix logging crash when % are sent through query logs ([#3461](https://github.com/EQEmu/Server/pull/3461)) @Akkadius 2023-07-01
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add ClearAccountFlag() and GetAccountFlags() to Perl/Lua ([#3469](https://github.com/EQEmu/Server/pull/3469)) @Kinglykrab 2023-07-03
|
||||
* Add GetClassAbbreviation() and GetRaceAbbreviation() to Perl/Lua ([#3463](https://github.com/EQEmu/Server/pull/3463)) @Kinglykrab 2023-07-02
|
||||
* Add GetClassPlural() and GetRacePlural() to Perl/Lua ([#3468](https://github.com/EQEmu/Server/pull/3468)) @Kinglykrab 2023-07-03
|
||||
* Add GetCloseMobList() and CalculateDistance() overload to Perl/Lua ([#3455](https://github.com/EQEmu/Server/pull/3455)) @Kinglykrab 2023-07-02
|
||||
* Add Hate Entry Methods to Perl ([#3459](https://github.com/EQEmu/Server/pull/3459)) @Kinglykrab 2023-07-02
|
||||
* Add ItemData Class to Perl ([#3465](https://github.com/EQEmu/Server/pull/3465)) @Kinglykrab 2023-07-02
|
||||
* Add Spawn2 Class to Perl ([#3456](https://github.com/EQEmu/Server/pull/3456)) @Kinglykrab 2023-07-02
|
||||
* Add StatBonuses Class to Perl ([#3460](https://github.com/EQEmu/Server/pull/3460)) @Kinglykrab 2023-07-02
|
||||
* Add missing Item Methods to Perl/Lua. ([#3464](https://github.com/EQEmu/Server/pull/3464)) @Kinglykrab 2023-07-02
|
||||
|
||||
## [22.16.0] - 06/27/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19
|
||||
* Delete common/worldconn.cpp ([#3436](https://github.com/EQEmu/Server/pull/3436)) @Kinglykrab 2023-06-24
|
||||
* Remove DatabaseCastAccepted() from zone/npc.cpp and zone/npc.h ([#3449](https://github.com/EQEmu/Server/pull/3449)) @Kinglykrab 2023-06-24
|
||||
* Remove GetACAvoid() from zone/merc.h ([#3447](https://github.com/EQEmu/Server/pull/3447)) @Kinglykrab 2023-06-25
|
||||
* Remove GetACMit() from zone/merc.h ([#3446](https://github.com/EQEmu/Server/pull/3446)) @Kinglykrab 2023-06-24
|
||||
* Remove _ClearWaypints() from zone/npc.h ([#3445](https://github.com/EQEmu/Server/pull/3445)) @Kinglykrab 2023-06-24
|
||||
* Remove acmod() from zone/merc.h ([#3448](https://github.com/EQEmu/Server/pull/3448)) @Kinglykrab 2023-06-24
|
||||
* Remove command_packetprofile from zone/command.h ([#3432](https://github.com/EQEmu/Server/pull/3432)) @Kinglykrab 2023-06-24
|
||||
* Remove command_showpetspell in zone/command.h ([#3430](https://github.com/EQEmu/Server/pull/3430)) @Kinglykrab 2023-06-24
|
||||
* Remove command_unlock from zone/command.h ([#3431](https://github.com/EQEmu/Server/pull/3431)) @Kinglykrab 2023-06-24
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #finddeity Command ([#3435](https://github.com/EQEmu/Server/pull/3435)) @Kinglykrab 2023-06-26
|
||||
* Add #findlanguage Command ([#3434](https://github.com/EQEmu/Server/pull/3434)) @Kinglykrab 2023-06-25
|
||||
* Add #showspells Command ([#3429](https://github.com/EQEmu/Server/pull/3429)) @Kinglykrab 2023-06-24
|
||||
* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19
|
||||
* Cleanup #showbuffs Command ([#3439](https://github.com/EQEmu/Server/pull/3439)) @Kinglykrab 2023-06-26
|
||||
* Cleanup #shownpcgloballoot and #showzonegloballoot Commands ([#3440](https://github.com/EQEmu/Server/pull/3440)) @Kinglykrab 2023-06-24
|
||||
* Cleanup #viewcurrencies Command ([#3441](https://github.com/EQEmu/Server/pull/3441)) @Kinglykrab 2023-06-25
|
||||
* Consolidate #findX commands to a singular #find Command ([#3452](https://github.com/EQEmu/Server/pull/3452)) @Kinglykrab 2023-06-28
|
||||
* Consolidate #merchant_close_shop and #merchant_open_shop to #merchantshop ([#3433](https://github.com/EQEmu/Server/pull/3433)) @Kinglykrab 2023-06-24
|
||||
* Delete #showbonusstats Command ([#3437](https://github.com/EQEmu/Server/pull/3437)) @Kinglykrab 2023-06-24
|
||||
* Delete #spellinfo Command ([#3438](https://github.com/EQEmu/Server/pull/3438)) @Kinglykrab 2023-06-24
|
||||
|
||||
### Database
|
||||
|
||||
* Fix database version checking edge case issue ([#3428](https://github.com/EQEmu/Server/pull/3428)) @Akkadius 2023-06-22
|
||||
* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19
|
||||
* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix NPC Item Stat Bonuses ([#3444](https://github.com/EQEmu/Server/pull/3444)) @Kinglykrab 2023-06-26
|
||||
* Fix error in 023_01_21_bots_raid_members.sql ([#3453](https://github.com/EQEmu/Server/pull/3453)) @mibastian 2023-06-28
|
||||
* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19
|
||||
* Merchant Open Flag set only for regular Merchants ([#3454](https://github.com/EQEmu/Server/pull/3454)) @Kinglykrab 2023-06-27
|
||||
|
||||
### Readme
|
||||
|
||||
* Update new location of database updates ([#3424](https://github.com/EQEmu/Server/pull/3424)) @joligario 2023-06-19
|
||||
|
||||
### Rules
|
||||
|
||||
* Add ClientPetsUserOwnerNameInLastName rule ([#3442](https://github.com/EQEmu/Server/pull/3442)) @Kinglykrab 2023-06-25
|
||||
|
||||
## [22.15.3] - 06/19/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix improper condition in Water LOS checks ([#3426](https://github.com/EQEmu/Server/pull/3426)) @Kinglykrab 2023-06-19
|
||||
|
||||
## [22.15.2] - 06/19/2023
|
||||
|
||||
### Database
|
||||
|
||||
* Fix multi-statement error reporting ([#3425](https://github.com/EQEmu/Server/pull/3425)) @Akkadius 2023-06-19
|
||||
|
||||
## [22.15.1] - 06/19/2023
|
||||
|
||||
### Schema
|
||||
|
||||
* Add `chatchannel_reserved_names` table to `database_schema.h`
|
||||
|
||||
## [22.15.0] - 06/19/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Default skill type to Hand to Hand in #npcedit meleetype ([#3422](https://github.com/EQEmu/Server/pull/3422)) @Kinglykrab 2023-06-19
|
||||
|
||||
### Commands
|
||||
|
||||
* Add missing subcommands to #npcedit ([#3423](https://github.com/EQEmu/Server/pull/3423)) @Kinglykrab 2023-06-19
|
||||
|
||||
### Database
|
||||
|
||||
* Implement native database migrations in server ([#2857](https://github.com/EQEmu/Server/pull/2857)) @Akkadius 2023-06-19
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix possible crash with #npcedit weapon ([#3421](https://github.com/EQEmu/Server/pull/3421)) @Kinglykrab 2023-06-19
|
||||
|
||||
## [22.14.1] - 06/18/2023
|
||||
|
||||
### Backups
|
||||
|
||||
* Move world database:dump to use MySQL credentials file ([#3410](https://github.com/EQEmu/Server/pull/3410)) @Akkadius 2023-06-17
|
||||
|
||||
### Binaries
|
||||
|
||||
* Add support for static linking (portable) binaries ([#3417](https://github.com/EQEmu/Server/pull/3417)) @Akkadius 2023-06-18
|
||||
|
||||
### CI
|
||||
|
||||
* Build static linux binaries ([#3419](https://github.com/EQEmu/Server/pull/3419)) @Akkadius 2023-06-18
|
||||
|
||||
### CLI
|
||||
|
||||
* Add `bots:enable` and `bots:disable` commands ([#3415](https://github.com/EQEmu/Server/pull/3415)) @Akkadius 2023-06-17
|
||||
* Add `mercs:enable` and `mercs:disable` commands ([#3416](https://github.com/EQEmu/Server/pull/3416)) @Akkadius 2023-06-18
|
||||
* Console menu validation fixes ([#3413](https://github.com/EQEmu/Server/pull/3413)) @Akkadius 2023-06-17
|
||||
|
||||
### Database
|
||||
|
||||
* Add query multi statement execution support ([#3414](https://github.com/EQEmu/Server/pull/3414)) @Akkadius 2023-06-17
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Water Line of Sight Checks ([#3408](https://github.com/EQEmu/Server/pull/3408)) @nytmyr 2023-06-17
|
||||
|
||||
### Logging
|
||||
|
||||
* Logging improvements, console silencing, terminal coloring ([#3412](https://github.com/EQEmu/Server/pull/3412)) @Akkadius 2023-06-17
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add convert_money_to_string() to Perl/Lua ([#3418](https://github.com/EQEmu/Server/pull/3418)) @Kinglykrab 2023-06-18
|
||||
|
||||
### Strings
|
||||
|
||||
* Add more test cases for string utils ([#3411](https://github.com/EQEmu/Server/pull/3411)) @Akkadius 2023-06-17
|
||||
|
||||
### Targeting
|
||||
|
||||
* Fix bug when using /tar on invalid target ([#3407](https://github.com/EQEmu/Server/pull/3407)) @noudess 2023-06-17
|
||||
|
||||
### Telnet
|
||||
|
||||
* Add cross zone/world wide cast and move functionality to Telnet ([#3409](https://github.com/EQEmu/Server/pull/3409)) @Kinglykrab 2023-06-17
|
||||
|
||||
## [22.13.1] - 06/13/2023
|
||||
|
||||
### Targeting
|
||||
|
||||
* Revert #3383 ([#3405](https://github.com/EQEmu/Server/pull/3405)) @noudess 2023-06-13
|
||||
|
||||
## [22.13.0] - 06/12/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Add GMFind_Struct to packet structures ([#3402](https://github.com/EQEmu/Server/pull/3402)) @Kinglykrab 2023-06-12
|
||||
* Remove CHECK_LOS_STEP from zone/common.h ([#3398](https://github.com/EQEmu/Server/pull/3398)) @Kinglykrab 2023-06-12
|
||||
* Remove CheckCoordLosNoZLeaps() from zone/entity.cpp and zone/entity.h ([#3384](https://github.com/EQEmu/Server/pull/3384)) @Kinglykrab 2023-06-12
|
||||
* Remove CountTempPets() from zone/entity.cpp and zone/entity.h ([#3390](https://github.com/EQEmu/Server/pull/3390)) @Kinglykrab 2023-06-12
|
||||
* Remove Evade() from zone/entity.cpp and zone/entity.h ([#3394](https://github.com/EQEmu/Server/pull/3394)) @Kinglykrab 2023-06-12
|
||||
* Remove GateAllClients() from zone/entity.cpp and zone/entity.h ([#3391](https://github.com/EQEmu/Server/pull/3391)) @Kinglykrab 2023-06-12
|
||||
* Remove GetClient(ip, port) from zone/entity.h ([#3386](https://github.com/EQEmu/Server/pull/3386)) @Kinglykrab 2023-06-12
|
||||
* Remove GetClientCount() from zone/entity.cpp and zone/entity.h ([#3392](https://github.com/EQEmu/Server/pull/3392)) @Kinglykrab 2023-06-12
|
||||
* Remove GetGroupByBot(), GetRaidByMob(), and GetRaidByLeaderName() from zone/entity.cpp and zone/entity.h ([#3387](https://github.com/EQEmu/Server/pull/3387)) @Kinglykrab 2023-06-12
|
||||
* Remove InteractiveChat() and TakenAction() from zone/npc.h ([#3382](https://github.com/EQEmu/Server/pull/3382)) @Kinglykrab 2023-06-12
|
||||
* Remove LimitCheckBoth() from zone/entity.cpp and zone/entity.h ([#3393](https://github.com/EQEmu/Server/pull/3393)) @Kinglykrab 2023-06-12
|
||||
* Remove NPC::AddCash() from npc.cpp/npc.h ([#3380](https://github.com/EQEmu/Server/pull/3380)) @Kinglykrab 2023-06-09
|
||||
* Remove RemoveMob() and RemoveRaid() from zone/entity.cpp and zone/entity.h ([#3389](https://github.com/EQEmu/Server/pull/3389)) @Kinglykrab 2023-06-12
|
||||
* Remove SPECIALIZE_MANA_REDUCE from zone/common.h ([#3400](https://github.com/EQEmu/Server/pull/3400)) @Kinglykrab 2023-06-12
|
||||
* Remove SendAATimer() from zone/entity.h ([#3388](https://github.com/EQEmu/Server/pull/3388)) @Kinglykrab 2023-06-12
|
||||
* Remove WriteEntityIDs() from zone/entity.cpp and zone/entity.h ([#3395](https://github.com/EQEmu/Server/pull/3395)) @Kinglykrab 2023-06-12
|
||||
* Remove _BECOMENPCPET() and _NPCPET() from zone/common.h ([#3399](https://github.com/EQEmu/Server/pull/3399)) @Kinglykrab 2023-06-12
|
||||
* Remove pDBAsyncWorkID from zone/entity.h ([#3385](https://github.com/EQEmu/Server/pull/3385)) @Kinglykrab 2023-06-12
|
||||
* Remove struct DynamicZoneSafeReturn from zone/entity.h ([#3396](https://github.com/EQEmu/Server/pull/3396)) @Kinglykrab 2023-06-12
|
||||
* Remove struct TradeEntity from zone/common.h ([#3397](https://github.com/EQEmu/Server/pull/3397)) @Kinglykrab 2023-06-12
|
||||
|
||||
### Commands
|
||||
|
||||
* Assign #opcode to a #reload alias ([#3401](https://github.com/EQEmu/Server/pull/3401)) @Kinglykrab 2023-06-12
|
||||
|
||||
### Illusions
|
||||
|
||||
* RandomizeFeatures and SetGender were killing db texture ([#3376](https://github.com/EQEmu/Server/pull/3376)) @noudess 2023-06-06
|
||||
|
||||
### Logging
|
||||
|
||||
* Fixed statements that logged incorrect data ([#3381](https://github.com/EQEmu/Server/pull/3381)) @noudess 2023-06-07
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetEXPForLevel() to Perl/Lua ([#3403](https://github.com/EQEmu/Server/pull/3403)) @Kinglykrab 2023-06-12
|
||||
* Add SendChannelMessage() to Perl/Lua ([#3378](https://github.com/EQEmu/Server/pull/3378)) @Kinglykrab 2023-06-04
|
||||
* Add several spell methods to Perl/Lua ([#3379](https://github.com/EQEmu/Server/pull/3379)) @Kinglykrab 2023-06-12
|
||||
|
||||
### Targeting
|
||||
|
||||
* /tar <bad target> should not untarget existing target ([#3383](https://github.com/EQEmu/Server/pull/3383)) @noudess 2023-06-12
|
||||
|
||||
## [22.12.0] - 05/29/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup #setskill and #setskillall Commands ([#3367](https://github.com/EQEmu/Server/pull/3367)) @Kinglykrab 2023-05-25
|
||||
* Delete message.h ([#3348](https://github.com/EQEmu/Server/pull/3348)) @Kinglykrab 2023-05-17
|
||||
* Fix #spawn command NPCs having 0 health ([#3371](https://github.com/EQEmu/Server/pull/3371)) @Kinglykrab 2023-05-21
|
||||
* Remove CalcPetHp from spdat.h ([#3364](https://github.com/EQEmu/Server/pull/3364)) @Kinglykrab 2023-05-25
|
||||
* Remove CountNPC() and QueueManaged() from entity.cpp/entity.h ([#3346](https://github.com/EQEmu/Server/pull/3346)) @Kinglykrab 2023-05-17
|
||||
* Remove DumpMerchantList() from zone.cpp/zone.h ([#3343](https://github.com/EQEmu/Server/pull/3343)) @Kinglykrab 2023-05-17
|
||||
* Remove GetDamageReceived() and GetHealReceived() from combat_record.cpp/combat_record.h ([#3358](https://github.com/EQEmu/Server/pull/3358)) @Kinglykrab 2023-05-17
|
||||
* Remove GetEscapingEntOnHateList() from hate_list.cpp/hate_list.h ([#3353](https://github.com/EQEmu/Server/pull/3353)) @Kinglykrab 2023-05-17
|
||||
* Remove GetMaxRank() from aa_ability.cpp/aa_ability.h ([#3347](https://github.com/EQEmu/Server/pull/3347)) @Kinglykrab 2023-05-25
|
||||
* Remove IsEntityInFrenzyMode() from hate_list.cpp/hate_list.h ([#3352](https://github.com/EQEmu/Server/pull/3352)) @Kinglykrab 2023-05-17
|
||||
* Remove IsRaid() from raids.h ([#3361](https://github.com/EQEmu/Server/pull/3361)) @Kinglykrab 2023-05-25
|
||||
* Remove LoadSpawn2() and PopulateZoneSpawnListClose() from spawn2.cpp/zonedb.h ([#3344](https://github.com/EQEmu/Server/pull/3344)) @Kinglykrab 2023-05-25
|
||||
* Remove SetGraveyard() from zone.cpp/zone.h ([#3354](https://github.com/EQEmu/Server/pull/3354)) @Kinglykrab 2023-05-17
|
||||
* Remove SetTradeCash() from trading.cpp/common.h ([#3356](https://github.com/EQEmu/Server/pull/3356)) @Kinglykrab 2023-05-17
|
||||
* Remove TraderUpdate() from trading.cpp/client.h ([#3357](https://github.com/EQEmu/Server/pull/3357)) @Kinglykrab 2023-05-17
|
||||
* Remove TypeToSkill() from tradeskills.cpp/object.h ([#3355](https://github.com/EQEmu/Server/pull/3355)) @Kinglykrab 2023-05-17
|
||||
* Remove Z_AGGRO from spdat.h ([#3365](https://github.com/EQEmu/Server/pull/3365)) @Kinglykrab 2023-05-25
|
||||
* Remove numMembers from raids.h ([#3362](https://github.com/EQEmu/Server/pull/3362)) @Kinglykrab 2023-05-25
|
||||
* Set GetAugmentType() to int again ([#3335](https://github.com/EQEmu/Server/pull/3335)) @Kinglykrab 2023-05-08
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #findcurrency Command ([#3368](https://github.com/EQEmu/Server/pull/3368)) @Kinglykrab 2023-05-25
|
||||
* Add entity variable command ([#3345](https://github.com/EQEmu/Server/pull/3345)) @Kinglykrab 2023-05-25
|
||||
* Cleanup #setanim ([#3350](https://github.com/EQEmu/Server/pull/3350)) @Kinglykrab 2023-05-25
|
||||
|
||||
### Feature
|
||||
|
||||
* Intoxication setter/getter for source, getter for Perl/Lua ([#3330](https://github.com/EQEmu/Server/pull/3330)) @JasXSL 2023-05-03
|
||||
|
||||
### Fixes
|
||||
|
||||
* #augmentitem bypasses augment restrictions ([#3332](https://github.com/EQEmu/Server/pull/3332)) @Kinglykrab 2023-05-07
|
||||
* Fix Heroic INT/WIS Bonuses ([#3341](https://github.com/EQEmu/Server/pull/3341)) @RekkasGit 2023-05-15
|
||||
* Fix duplicate messages in #npcedit ([#3372](https://github.com/EQEmu/Server/pull/3372)) @Kinglykrab 2023-05-21
|
||||
* Fix issue with Group Pointers/Member roles ([#3374](https://github.com/EQEmu/Server/pull/3374)) @Aeadoin 2023-05-25
|
||||
* Fix mob item bonus calc ([#3334](https://github.com/EQEmu/Server/pull/3334)) @Akkadius 2023-05-07
|
||||
* Fix typos in #zheader ([#3370](https://github.com/EQEmu/Server/pull/3370)) @Kinglykrab 2023-05-21
|
||||
* Mob scaling issue with min dmg set to zero while max dmg is not ([#3351](https://github.com/EQEmu/Server/pull/3351)) @RekkasGit 2023-05-20
|
||||
* NPC Armor Upgrade to a slot not handled correctly ([#3366](https://github.com/EQEmu/Server/pull/3366)) @noudess 2023-05-20
|
||||
* ReloadQuests() on Zone::Init() to avoid cached global quests/plugins ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Kinglykrab 2023-05-07
|
||||
* Revert " ReloadQuests() on Zone::Init() to avoid cached global quests/plugins " ([#3333](https://github.com/EQEmu/Server/pull/3333)) @Akkadius 2023-05-08
|
||||
|
||||
### Memory Leak
|
||||
|
||||
* Fix large memory leak introduced in CalcItemBonuses ([#3331](https://github.com/EQEmu/Server/pull/3331)) @Akkadius 2023-05-07
|
||||
|
||||
### Messages
|
||||
|
||||
* Remove duplicate heal message for healing yourself ([#3329](https://github.com/EQEmu/Server/pull/3329)) @noudess 2023-05-03
|
||||
|
||||
### Performance
|
||||
|
||||
* Character bind is now bulk saved ([#3338](https://github.com/EQEmu/Server/pull/3338)) @Akkadius 2023-05-09
|
||||
* Character buffs now save in bulk ([#3336](https://github.com/EQEmu/Server/pull/3336)) @Akkadius 2023-05-09
|
||||
* Character pet bulk saving ([#3337](https://github.com/EQEmu/Server/pull/3337)) @Akkadius 2023-05-09
|
||||
* Character tribute is now bulk saved ([#3340](https://github.com/EQEmu/Server/pull/3340)) @Kinglykrab 2023-05-25
|
||||
* Mail key is now cached during player load ([#3339](https://github.com/EQEmu/Server/pull/3339)) @Akkadius 2023-05-09
|
||||
|
||||
### Pets
|
||||
|
||||
* Fix saving inconsistencies with pets ([#3375](https://github.com/EQEmu/Server/pull/3375)) @Akkadius 2023-05-25
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetHateListClosest(), GetHateListClosestBot(), GetHateListClosestClient(), and GetHateListClosestNPC() methods/overloads to Perl/Lua ([#3359](https://github.com/EQEmu/Server/pull/3359)) @RekkasGit 2023-05-16
|
||||
* Add GetPet() to Perl ([#3309](https://github.com/EQEmu/Server/pull/3309)) @Kinglykrab 2023-05-08
|
||||
* Add Memorize and Scribe Spell Events to Perl/Lua ([#3363](https://github.com/EQEmu/Server/pull/3363)) @Kinglykrab 2023-05-25
|
||||
* Add zone data methods to Perl/Lua ([#3342](https://github.com/EQEmu/Server/pull/3342)) @Kinglykrab 2023-05-24
|
||||
* Cleanup The Darkened Sea Quest Methods Names ([#3369](https://github.com/EQEmu/Server/pull/3369)) @Kinglykrab 2023-05-21
|
||||
|
||||
### Rules
|
||||
|
||||
* Add World:MaximumQuestErrors Rule ([#3349](https://github.com/EQEmu/Server/pull/3349)) @Kinglykrab 2023-05-21
|
||||
* ResurrectionEffectBlock to prevent/allow/move buffs. ([#3288](https://github.com/EQEmu/Server/pull/3288)) @nytmyr 2023-05-08
|
||||
|
||||
## [22.11.0] - 04/29/2023
|
||||
|
||||
### Code
|
||||
|
||||
* Add check for owner in quest::pausetimer() ([#3304](https://github.com/EQEmu/Server/pull/3304)) @Kinglykrab 2023-04-23
|
||||
* Add check for owner in quest::resumetimer() ([#3305](https://github.com/EQEmu/Server/pull/3305)) @Kinglykrab 2023-04-23
|
||||
* Add initiator/owner checks to various methods in questmgr.cpp ([#3306](https://github.com/EQEmu/Server/pull/3306)) @Kinglykrab 2023-04-23
|
||||
* Fix possible nullptr in quest::addloot() ([#3303](https://github.com/EQEmu/Server/pull/3303)) @Kinglykrab 2023-04-23
|
||||
* Remove GetClassHPFactor() from zone/client_mods.cpp and zone/client.h ([#3313](https://github.com/EQEmu/Server/pull/3313)) @Kinglykrab 2023-04-30
|
||||
* Remove GetClassHPFactor() from zone/merc.h ([#3314](https://github.com/EQEmu/Server/pull/3314)) @Kinglykrab 2023-04-30
|
||||
* Remove pDontCastBefore_casting_spell from zone/npc.h ([#3311](https://github.com/EQEmu/Server/pull/3311)) @Kinglykrab 2023-04-30
|
||||
* Remove unused code in zone/pets.cpp ([#3310](https://github.com/EQEmu/Server/pull/3310)) @Kinglykrab 2023-04-30
|
||||
* Remove unused methods in zone/bot.cpp and zone/bot.h ([#3315](https://github.com/EQEmu/Server/pull/3315)) @Kinglykrab 2023-04-30
|
||||
* Remove unused methods in zone/client.cpp and zone/client.h ([#3312](https://github.com/EQEmu/Server/pull/3312)) @Kinglykrab 2023-04-30
|
||||
* Remove unused variable in common/crash.cpp ([#3308](https://github.com/EQEmu/Server/pull/3308)) @Kinglykrab 2023-04-30
|
||||
* Use default ctor/dtor in oriented_bounding_box.h ([#3307](https://github.com/EQEmu/Server/pull/3307)) @Kinglykrab 2023-04-30
|
||||
* quest::createBot() unnecessary check against nullptr ([#3302](https://github.com/EQEmu/Server/pull/3302)) @Kinglykrab 2023-04-23
|
||||
* quest::setallskill() had always true condition. ([#3301](https://github.com/EQEmu/Server/pull/3301)) @Kinglykrab 2023-04-30
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix UCS crash that occurs during log reloading ([#3324](https://github.com/EQEmu/Server/pull/3324)) @Akkadius 2023-04-30
|
||||
* Fix possible dereference of nullptr in Client::CalcHPRegen ([#3316](https://github.com/EQEmu/Server/pull/3316)) @Aeadoin 2023-04-23
|
||||
* Fix possible nullptr in Client::GetCharMaxLevelFromQGlobal() ([#3317](https://github.com/EQEmu/Server/pull/3317)) @Kinglykrab 2023-04-23
|
||||
|
||||
### Discord
|
||||
|
||||
* Add Discord webhook callback processing to world ([#3322](https://github.com/EQEmu/Server/pull/3322)) @Akkadius 2023-04-30
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix issue with NPCs no longer using some armor. ([#3318](https://github.com/EQEmu/Server/pull/3318)) @noudess 2023-04-24
|
||||
* Fix issue with spawning Mercs ([#3327](https://github.com/EQEmu/Server/pull/3327)) @Aeadoin 2023-04-29
|
||||
* Possible issues with SummonItem in Client::QuestReward() methods ([#3325](https://github.com/EQEmu/Server/pull/3325)) @Kinglykrab 2023-04-27
|
||||
|
||||
### Maps
|
||||
|
||||
* Update download with faster releases link ([#3321](https://github.com/EQEmu/Server/pull/3321)) @Akkadius 2023-04-30
|
||||
|
||||
### Messages
|
||||
|
||||
* Remove duplicate you have lost a level message ([#3323](https://github.com/EQEmu/Server/pull/3323)) @noudess 2023-04-25
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetDefaultRaceSize() overloads to Perl/Lua ([#3320](https://github.com/EQEmu/Server/pull/3320)) @Kinglykrab 2023-04-30
|
||||
* Add HasSpellEffect() to Perl/Lua ([#3319](https://github.com/EQEmu/Server/pull/3319)) @Kinglykrab 2023-04-30
|
||||
|
||||
## [22.10.0] - 04/22/2023
|
||||
|
||||
### Backups
|
||||
|
||||
+34
-1
@@ -16,6 +16,20 @@ SET(CMAKE_CXX_STANDARD 20)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
||||
|
||||
IF (EQEMU_BUILD_STATIC)
|
||||
SET(BUILD_SHARED_LIBS OFF)
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
||||
MESSAGE(STATUS "Building with static linking")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
||||
IF (UNIX)
|
||||
SET(PERL_LIBRARY "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/libperl.so")
|
||||
SET(PERL_INCLUDE_PATH "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/")
|
||||
SET(PERL_EXECUTABLE "/opt/eqemu-perl/bin/perl")
|
||||
ENDIF ()
|
||||
ENDIF (EQEMU_BUILD_STATIC)
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
@@ -23,7 +37,11 @@ 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")
|
||||
|
||||
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
||||
IF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||
ELSE(MSVC)
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
@@ -120,6 +138,13 @@ ELSE()
|
||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
|
||||
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
|
||||
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
|
||||
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
|
||||
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
|
||||
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
|
||||
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#options
|
||||
@@ -307,6 +332,10 @@ ELSE()
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
ENDIF()
|
||||
|
||||
IF (EQEMU_BUILD_STATIC)
|
||||
SET(ZLIB_LIBRARY_LIBS libz.a)
|
||||
ENDIF(EQEMU_BUILD_STATIC)
|
||||
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Library Usage *")
|
||||
@@ -371,6 +400,10 @@ IF(PERL_LIBRARY_ENABLED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
||||
IF (UNIX AND EQEMU_BUILD_STATIC)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
+10
-1
@@ -15,6 +15,9 @@ SET(common_sources
|
||||
database.cpp
|
||||
database_conversions.cpp
|
||||
database_instances.cpp
|
||||
database/database_update_manifest.cpp
|
||||
database/database_update_manifest_bots.cpp
|
||||
database/database_update.cpp
|
||||
dbcore.cpp
|
||||
deity.cpp
|
||||
dynamic_zone_base.cpp
|
||||
@@ -67,6 +70,7 @@ SET(common_sources
|
||||
perl_eqdb.cpp
|
||||
perl_eqdb_res.cpp
|
||||
process/process.cpp
|
||||
process.cpp
|
||||
proc_launcher.cpp
|
||||
profanity_manager.cpp
|
||||
ptimer.cpp
|
||||
@@ -87,6 +91,7 @@ SET(common_sources
|
||||
timer.cpp
|
||||
unix.cpp
|
||||
platform.cpp
|
||||
json/json.hpp
|
||||
json/jsoncpp.cpp
|
||||
zone_store.cpp
|
||||
net/console_server.cpp
|
||||
@@ -506,6 +511,7 @@ SET(common_headers
|
||||
data_verification.h
|
||||
database.h
|
||||
database_schema.h
|
||||
database/database_update.h
|
||||
dbcore.h
|
||||
deity.h
|
||||
discord/discord.h
|
||||
@@ -579,12 +585,14 @@ SET(common_headers
|
||||
path_manager.cpp
|
||||
platform.h
|
||||
process/process.h
|
||||
process.h
|
||||
proc_launcher.h
|
||||
profanity_manager.h
|
||||
profiler.h
|
||||
ptimer.h
|
||||
queue.h
|
||||
races.h
|
||||
raid.h
|
||||
random.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
@@ -666,7 +674,8 @@ SET(common_headers
|
||||
StackWalker/StackWalker.h
|
||||
util/memory_stream.h
|
||||
util/directory.h
|
||||
util/uuid.h)
|
||||
util/uuid.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/classes.h"
|
||||
#include "data_verification.h"
|
||||
|
||||
const char *GetClassIDName(uint8 class_id, uint8 level)
|
||||
{
|
||||
@@ -630,6 +631,20 @@ bool IsINTCasterClass(uint8 class_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHeroicINTCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case NECROMANCER:
|
||||
case WIZARD:
|
||||
case MAGICIAN:
|
||||
case ENCHANTER:
|
||||
case SHADOWKNIGHT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsWISCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
@@ -642,6 +657,21 @@ bool IsWISCasterClass(uint8 class_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHeroicWISCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case CLERIC:
|
||||
case DRUID:
|
||||
case SHAMAN:
|
||||
case PALADIN:
|
||||
case BEASTLORD:
|
||||
case RANGER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPlateClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
@@ -721,3 +751,51 @@ uint8 ClassArmorType(uint8 class_id)
|
||||
return ARMOR_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string GetPlayerClassAbbreviation(uint8 class_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) {
|
||||
return std::string("UNK");
|
||||
}
|
||||
|
||||
switch (class_id) {
|
||||
case WARRIOR:
|
||||
return "WAR";
|
||||
case CLERIC:
|
||||
return "CLR";
|
||||
case PALADIN:
|
||||
return "PAL";
|
||||
case RANGER:
|
||||
return "RNG";
|
||||
case SHADOWKNIGHT:
|
||||
return "SHD";
|
||||
case DRUID:
|
||||
return "DRU";
|
||||
case MONK:
|
||||
return "MNK";
|
||||
case BARD:
|
||||
return "BRD";
|
||||
case ROGUE:
|
||||
return "ROG";
|
||||
case SHAMAN:
|
||||
return "SHM";
|
||||
case NECROMANCER:
|
||||
return "NEC";
|
||||
case WIZARD:
|
||||
return "WIZ";
|
||||
case MAGICIAN:
|
||||
return "MAG";
|
||||
case ENCHANTER:
|
||||
return "ENC";
|
||||
case BEASTLORD:
|
||||
return "BST";
|
||||
case BERSERKER:
|
||||
return "BER";
|
||||
}
|
||||
|
||||
return std::string("UNK");
|
||||
}
|
||||
|
||||
bool IsPlayerClass(uint8 class_id) {
|
||||
return EQ::ValueWithin(class_id, WARRIOR, BERSERKER);
|
||||
}
|
||||
|
||||
+6
-1
@@ -19,6 +19,7 @@
|
||||
#define CLASSES_CH
|
||||
|
||||
#include "../common/types.h"
|
||||
#include <string>
|
||||
|
||||
#define NO_CLASS 0
|
||||
#define WARRIOR 1
|
||||
@@ -127,6 +128,9 @@
|
||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
||||
|
||||
bool IsPlayerClass(uint8 class_id);
|
||||
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
||||
|
||||
uint32 GetPlayerClassValue(uint8 class_id);
|
||||
uint32 GetPlayerClassBit(uint8 class_id);
|
||||
|
||||
@@ -140,7 +144,8 @@ bool IsHybridClass(uint8 class_id);
|
||||
bool IsCasterClass(uint8 class_id);
|
||||
bool IsINTCasterClass(uint8 class_id);
|
||||
bool IsWISCasterClass(uint8 class_id);
|
||||
|
||||
bool IsHeroicINTCasterClass(uint8 class_id);
|
||||
bool IsHeroicWISCasterClass(uint8 class_id);
|
||||
bool IsPlateClass(uint8 class_id);
|
||||
bool IsChainClass(uint8 class_id);
|
||||
bool IsLeatherClass(uint8 class_id);
|
||||
|
||||
@@ -39,15 +39,15 @@ namespace EQEmuCommand {
|
||||
{
|
||||
if (cmd[{"-d", "--debug"}]) {
|
||||
std::cout << "Positional args:\n";
|
||||
for (auto &pos_arg : cmd.pos_args())
|
||||
for (auto &pos_arg: cmd.pos_args())
|
||||
std::cout << '\t' << pos_arg << std::endl;
|
||||
|
||||
std::cout << "\nFlags:\n";
|
||||
for (auto &flag : cmd.flags())
|
||||
for (auto &flag: cmd.flags())
|
||||
std::cout << '\t' << flag << std::endl;
|
||||
|
||||
std::cout << "\nParameters:\n";
|
||||
for (auto ¶m : cmd.params())
|
||||
for (auto ¶m: cmd.params())
|
||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -69,22 +69,22 @@ namespace EQEmuCommand {
|
||||
{
|
||||
bool arguments_filled = true;
|
||||
|
||||
int index = 2;
|
||||
for (auto &arg : arguments) {
|
||||
int index = 2;
|
||||
for (auto &arg: arguments) {
|
||||
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
||||
arguments_filled = false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
|
||||
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
|
||||
std::string arguments_string;
|
||||
for (auto &arg : arguments) {
|
||||
for (auto &arg: arguments) {
|
||||
arguments_string += " " + arg;
|
||||
}
|
||||
|
||||
std::string options_string;
|
||||
for (auto &opt : options) {
|
||||
for (auto &opt: options) {
|
||||
options_string += " " + opt + "\n";
|
||||
}
|
||||
|
||||
@@ -124,14 +124,6 @@ namespace EQEmuCommand {
|
||||
)
|
||||
{
|
||||
std::string description;
|
||||
bool ran_command = false;
|
||||
for (auto &it: in_function_map) {
|
||||
if (it.first == argv[1]) {
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
ran_command = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
std::cout << std::endl;
|
||||
std::cout <<
|
||||
@@ -142,9 +134,7 @@ namespace EQEmuCommand {
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
|
||||
/**
|
||||
* Get max command length for padding length
|
||||
*/
|
||||
// Get max command length for padding length
|
||||
int max_command_length = 0;
|
||||
|
||||
for (auto &it: in_function_map) {
|
||||
@@ -155,18 +145,14 @@ namespace EQEmuCommand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display command menu
|
||||
*/
|
||||
// Display command menu
|
||||
std::string command_section;
|
||||
for (auto &it: in_function_map) {
|
||||
description.clear();
|
||||
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
|
||||
/**
|
||||
* Print section header
|
||||
*/
|
||||
// Print section header
|
||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
||||
|
||||
if (command_prefix.find("test") != std::string::npos) {
|
||||
@@ -178,9 +164,7 @@ namespace EQEmuCommand {
|
||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print commands
|
||||
*/
|
||||
// Print commands
|
||||
std::stringstream command;
|
||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
||||
@@ -191,6 +175,15 @@ namespace EQEmuCommand {
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
bool ran_command = false;
|
||||
|
||||
for (auto &it: in_function_map) {
|
||||
if (it.first == argv[1]) {
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
ran_command = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ran_command) {
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@ void SendCrashReport(const std::string &crash_report)
|
||||
r.set_connection_timeout(1, 0);
|
||||
r.set_read_timeout(1, 0);
|
||||
r.set_write_timeout(1, 0);
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// os info
|
||||
auto os = EQ::GetOS();
|
||||
|
||||
+83
-23
@@ -2097,37 +2097,45 @@ void Database::ClearInvSnapshots(bool from_now) {
|
||||
|
||||
struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
||||
{
|
||||
|
||||
TimeOfDay_Struct eqTime;
|
||||
std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1");
|
||||
TimeOfDay_Struct t{};
|
||||
std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1");
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success() || results.RowCount() == 0){
|
||||
if (!results.Success() || results.RowCount() == 0) {
|
||||
LogInfo("Loading EQ time of day failed. Using defaults");
|
||||
eqTime.minute = 0;
|
||||
eqTime.hour = 9;
|
||||
eqTime.day = 1;
|
||||
eqTime.month = 1;
|
||||
eqTime.year = 3100;
|
||||
t.minute = 0;
|
||||
t.hour = 9;
|
||||
t.day = 1;
|
||||
t.month = 1;
|
||||
t.year = 3100;
|
||||
realtime = time(nullptr);
|
||||
}
|
||||
else{
|
||||
auto row = results.begin();
|
||||
|
||||
eqTime.minute = Strings::ToUnsignedInt(row[0]);
|
||||
eqTime.hour = Strings::ToUnsignedInt(row[1]);
|
||||
eqTime.day = Strings::ToUnsignedInt(row[2]);
|
||||
eqTime.month = Strings::ToUnsignedInt(row[3]);
|
||||
eqTime.year = Strings::ToUnsignedInt(row[4]);
|
||||
realtime = Strings::ToBigInt(row[5]);
|
||||
return t;
|
||||
}
|
||||
|
||||
return eqTime;
|
||||
auto row = results.begin();
|
||||
|
||||
uint8 hour = Strings::ToUnsignedInt(row[1]);
|
||||
time_t realtime_ = Strings::ToBigInt(row[5]);
|
||||
if (RuleI(World, BootHour) > 0 && RuleI(World, BootHour) <= 24) {
|
||||
hour = RuleI(World, BootHour);
|
||||
realtime_ = time(nullptr);
|
||||
}
|
||||
|
||||
t.minute = Strings::ToUnsignedInt(row[0]);
|
||||
t.hour = hour;
|
||||
t.day = Strings::ToUnsignedInt(row[2]);
|
||||
t.month = Strings::ToUnsignedInt(row[3]);
|
||||
t.year = Strings::ToUnsignedInt(row[4]);
|
||||
realtime = realtime_;
|
||||
|
||||
LogEqTime("Setting hour to [{}]", hour);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year)
|
||||
{
|
||||
std::string query = StringFormat("UPDATE eqtime set minute = %d, hour = %d, day = %d, month = %d, year = %d, realtime = %d limit 1", minute, hour, day, month, year, time(0));
|
||||
std::string query = StringFormat("UPDATE eqtime set minute = %d, hour = %d, day = %d, month = %d, year = %d, realtime = %d limit 1", minute, hour, day, month, year, time(nullptr));
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return results.Success();
|
||||
@@ -2347,7 +2355,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
||||
);
|
||||
|
||||
if (!DoesTableExist(table_name)) {
|
||||
LogMySQLQuery("Table [{}] does not exist. Downloading from Github and installing...", table_name);
|
||||
LogMySQLQuery("Table [{}] does not exist. Downloading and installing...", table_name);
|
||||
|
||||
// http get request
|
||||
httplib::Client cli(
|
||||
@@ -2355,7 +2363,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
||||
"{}://{}",
|
||||
request_uri.get_scheme(),
|
||||
request_uri.get_host()
|
||||
).c_str()
|
||||
)
|
||||
);
|
||||
|
||||
cli.set_connection_timeout(0, 60000000); // 60 sec
|
||||
@@ -2408,3 +2416,55 @@ uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
|
||||
|
||||
return !zones.empty() ? zones[0].min_status : 0;
|
||||
}
|
||||
|
||||
void Database::SourceSqlFromUrl(std::string url)
|
||||
{
|
||||
try {
|
||||
uri request_uri(url);
|
||||
|
||||
LogHTTPDetail(
|
||||
"parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
|
||||
url,
|
||||
request_uri.get_path(),
|
||||
request_uri.get_host(),
|
||||
request_uri.get_query(),
|
||||
request_uri.get_scheme(),
|
||||
request_uri.get_port()
|
||||
);
|
||||
|
||||
LogInfo("Downloading and installing from [{}]", url);
|
||||
|
||||
// http get request
|
||||
httplib::Client cli(
|
||||
fmt::format(
|
||||
"{}://{}",
|
||||
request_uri.get_scheme(),
|
||||
request_uri.get_host()
|
||||
)
|
||||
);
|
||||
|
||||
cli.set_connection_timeout(0, 60000000); // 60 sec
|
||||
cli.set_read_timeout(60, 0); // 60 seconds
|
||||
cli.set_write_timeout(60, 0); // 60 seconds
|
||||
|
||||
if (auto res = cli.Get(request_uri.get_path())) {
|
||||
if (res->status == 200) {
|
||||
auto results = QueryDatabaseMulti(res->body);
|
||||
if (!results.ErrorMessage().empty()) {
|
||||
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (res->status == 404) {
|
||||
LogError("Error retrieving URL [{}]", url);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogError("Error retrieving URL [{}]", url);
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::invalid_argument iae) {
|
||||
LogError("URI parser error [{}]", iae.what());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ public:
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
|
||||
void SourceSqlFromUrl(std::string url);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ std::string DatabaseDumpService::GetMySQLVersion()
|
||||
return Strings::Trim(version_output);
|
||||
}
|
||||
|
||||
const std::string CREDENTIALS_FILE = "login.my.cnf";
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@@ -101,21 +103,15 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
||||
auto config = EQEmuConfig::get();
|
||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||
return fmt::format(
|
||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||
config->ContentDbUsername,
|
||||
config->ContentDbPassword,
|
||||
config->ContentDbHost,
|
||||
config->ContentDbPort,
|
||||
"mysqldump --defaults-extra-file={} {}",
|
||||
CREDENTIALS_FILE,
|
||||
config->ContentDbName
|
||||
);
|
||||
};
|
||||
|
||||
return fmt::format(
|
||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||
config->DatabaseUsername,
|
||||
config->DatabasePassword,
|
||||
config->DatabaseHost,
|
||||
config->DatabasePort,
|
||||
"mysqldump --defaults-extra-file={} {}",
|
||||
CREDENTIALS_FILE,
|
||||
config->DatabaseDB
|
||||
);
|
||||
}
|
||||
@@ -283,6 +279,11 @@ void DatabaseDumpService::DatabaseDump()
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDumpStaticInstanceData()) {
|
||||
tables_to_dump += "instance_list";
|
||||
options += " --no-create-info --where=\"instance_list.is_global > 0 and instance_list.never_expires > 0\"";
|
||||
}
|
||||
|
||||
if (!dump_descriptor.empty()) {
|
||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
||||
}
|
||||
@@ -309,6 +310,8 @@ void DatabaseDumpService::DatabaseDump()
|
||||
if (tables_to_dump.empty()) {
|
||||
std::cerr << "No tables were specified" << std::endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const auto execute_command = fmt::format(
|
||||
@@ -319,13 +322,16 @@ void DatabaseDumpService::DatabaseDump()
|
||||
pipe_file
|
||||
);
|
||||
|
||||
BuildCredentialsFile();
|
||||
std::string execution_result = Process::execute(execute_command);
|
||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||
std::cout << execution_result;
|
||||
}
|
||||
}
|
||||
|
||||
LogSys.EnableConsoleLogging();
|
||||
if (!IsDumpOutputToConsole()) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
}
|
||||
|
||||
if (!pipe_file.empty()) {
|
||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||
@@ -350,10 +356,9 @@ void DatabaseDumpService::DatabaseDump()
|
||||
}
|
||||
|
||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
||||
if (HasCompressionBinary()) {
|
||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsTarAvailable()) {
|
||||
Process::execute(
|
||||
@@ -387,6 +392,8 @@ void DatabaseDumpService::DatabaseDump()
|
||||
}
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
|
||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||
@@ -566,4 +573,51 @@ void DatabaseDumpService::RemoveSqlBackup()
|
||||
if (File::Exists(file)) {
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
}
|
||||
|
||||
void DatabaseDumpService::BuildCredentialsFile()
|
||||
{
|
||||
auto config = EQEmuConfig::get();
|
||||
std::ofstream out(CREDENTIALS_FILE);
|
||||
if (out.is_open()) {
|
||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||
out << "[mysqldump]" << std::endl;
|
||||
out << "user=" << config->ContentDbUsername << std::endl;
|
||||
out << "password=" << config->ContentDbPassword << std::endl;
|
||||
out << "host=" << config->ContentDbHost << std::endl;
|
||||
out << "port=" << config->ContentDbPort << std::endl;
|
||||
out << "default-character-set=utf8" << std::endl;
|
||||
}
|
||||
else {
|
||||
out << "[mysqldump]" << std::endl;
|
||||
out << "user=" << config->DatabaseUsername << std::endl;
|
||||
out << "password=" << config->DatabasePassword << std::endl;
|
||||
out << "host=" << config->DatabaseHost << std::endl;
|
||||
out << "port=" << config->DatabasePort << std::endl;
|
||||
out << "default-character-set=utf8" << std::endl;
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
else {
|
||||
LogError("Failed to open credentials file for writing");
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseDumpService::RemoveCredentialsFile()
|
||||
{
|
||||
if (File::Exists(CREDENTIALS_FILE)) {
|
||||
std::filesystem::remove(CREDENTIALS_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpStaticInstanceData()
|
||||
{
|
||||
return dump_static_instance_data;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpStaticInstanceData(bool b)
|
||||
{
|
||||
dump_static_instance_data = b;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
bool IsDumpMercTables() const;
|
||||
void SetDumpMercTables(bool dump_bot_tables);
|
||||
|
||||
void SetDumpStaticInstanceData(bool b);
|
||||
bool IsDumpStaticInstanceData();
|
||||
|
||||
private:
|
||||
bool dump_all_tables = false;
|
||||
bool dump_state_tables = false;
|
||||
@@ -73,6 +76,8 @@ private:
|
||||
bool dump_drop_table_syntax_only = false;
|
||||
bool dump_bot_tables = false;
|
||||
bool dump_merc_tables = false;
|
||||
bool dump_static_instance_data = false;
|
||||
|
||||
std::string dump_path;
|
||||
std::string dump_file_name;
|
||||
|
||||
@@ -93,6 +98,8 @@ private:
|
||||
std::string GetSetDumpPath();
|
||||
std::string GetQueryServTables();
|
||||
void RemoveSqlBackup();
|
||||
void BuildCredentialsFile();
|
||||
void RemoveCredentialsFile();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
#include <filesystem>
|
||||
#include "database_update.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../http/httplib.h"
|
||||
|
||||
#include "database_update_manifest.cpp"
|
||||
#include "database_update_manifest_bots.cpp"
|
||||
#include "database_dump_service.h"
|
||||
|
||||
constexpr int BREAK_LENGTH = 70;
|
||||
|
||||
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
||||
{
|
||||
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
LogError("Failed to read from [db_version] table!");
|
||||
return DatabaseVersion{};
|
||||
}
|
||||
|
||||
auto r = results.begin();
|
||||
|
||||
return DatabaseVersion{
|
||||
.server_database_version = Strings::ToInt(r[0]),
|
||||
.bots_database_version = Strings::ToInt(r[1]),
|
||||
};
|
||||
}
|
||||
|
||||
DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
|
||||
{
|
||||
return DatabaseVersion{
|
||||
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
|
||||
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
|
||||
};
|
||||
}
|
||||
|
||||
// the amount of versions we look-back to ensure we have all migrations
|
||||
// we may not want to force these, but just warn about the look-backs
|
||||
constexpr int LOOK_BACK_AMOUNT = 10;
|
||||
|
||||
// this check will take action
|
||||
void DatabaseUpdate::CheckDbUpdates()
|
||||
{
|
||||
InjectBotsVersionColumn();
|
||||
auto v = GetDatabaseVersions();
|
||||
auto b = GetBinaryDatabaseVersions();
|
||||
if (CheckVersionsUpToDate(v, b)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
|
||||
LogInfo(
|
||||
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||
b.server_database_version,
|
||||
v.server_database_version
|
||||
);
|
||||
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
|
||||
}
|
||||
|
||||
if (b.bots_database_version > 0) {
|
||||
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
|
||||
LogInfo(
|
||||
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||
b.bots_database_version,
|
||||
v.bots_database_version
|
||||
);
|
||||
m_database->QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `db_version` SET `bots_version` = {}",
|
||||
b.bots_database_version
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string DatabaseUpdate::GetQueryResult(std::string query)
|
||||
{
|
||||
auto results = m_database->QueryDatabase(query);
|
||||
|
||||
std::vector<std::string> result_lines = {};
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::vector<std::string> cols;
|
||||
|
||||
int field_count = results.ColumnCount();
|
||||
cols.reserve(field_count);
|
||||
for (int i = 0; i < field_count; ++i) {
|
||||
if (row[i] != nullptr) {
|
||||
cols.emplace_back(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
result_lines.emplace_back(Strings::Join(cols, " "));
|
||||
}
|
||||
|
||||
return Strings::Join(result_lines, "\n");
|
||||
}
|
||||
|
||||
bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_result)
|
||||
{
|
||||
std::string r = Strings::Trim(query_result);
|
||||
if (e.condition == "contains") {
|
||||
return Strings::Contains(r, e.match);
|
||||
}
|
||||
else if (e.condition == "match") {
|
||||
return r == e.match;
|
||||
}
|
||||
else if (e.condition == "missing") {
|
||||
return !Strings::Contains(r, e.match);
|
||||
}
|
||||
else if (e.condition == "empty") {
|
||||
return r.empty();
|
||||
}
|
||||
else if (e.condition == "not_empty") {
|
||||
return !r.empty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// return true if we ran updates
|
||||
bool DatabaseUpdate::UpdateManifest(
|
||||
std::vector<ManifestEntry> entries,
|
||||
int version_low,
|
||||
int version_high
|
||||
)
|
||||
{
|
||||
std::vector<int> missing_migrations = {};
|
||||
if (version_low != version_high) {
|
||||
|
||||
LogSys.DisableMySQLErrorLogs();
|
||||
for (int version = version_low + 1; version <= version_high; ++version) {
|
||||
for (auto &e: entries) {
|
||||
if (e.version == version) {
|
||||
bool has_migration = true;
|
||||
std::string r = GetQueryResult(e.check);
|
||||
if (ShouldRunMigration(e, r)) {
|
||||
has_migration = false;
|
||||
missing_migrations.emplace_back(e.version);
|
||||
}
|
||||
|
||||
std::string prefix = fmt::format(
|
||||
"[{}]",
|
||||
has_migration ? "ok" : "missing"
|
||||
);
|
||||
|
||||
LogInfo(
|
||||
"[{}] {:>10} | [{}]",
|
||||
e.version,
|
||||
prefix,
|
||||
e.description
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
LogSys.EnableMySQLErrorLogs();
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
if (!missing_migrations.empty()) {
|
||||
LogInfo("Automatically backing up database before applying updates");
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
auto s = DatabaseDumpService();
|
||||
s.SetDumpAllTables(true);
|
||||
s.SetDumpWithCompression(true);
|
||||
s.DatabaseDump();
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
}
|
||||
|
||||
if (!missing_migrations.empty()) {
|
||||
LogInfo("Running database migrations. Please wait...");
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
}
|
||||
|
||||
for (auto &m: missing_migrations) {
|
||||
for (auto &e: entries) {
|
||||
if (e.version == m) {
|
||||
bool errored_migration = false;
|
||||
|
||||
auto r = m_database->QueryDatabaseMulti(e.sql);
|
||||
|
||||
// ignore empty query result "errors"
|
||||
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
||||
LogError("(#{}) [{}]", r.ErrorNumber(), r.ErrorMessage());
|
||||
errored_migration = true;
|
||||
|
||||
LogInfo("Required database update failed. This could be a problem");
|
||||
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
||||
|
||||
// user input
|
||||
std::string input;
|
||||
bool gave_input = false;
|
||||
time_t start_time = time(nullptr);
|
||||
time_t wait_time_seconds = 60;
|
||||
|
||||
// spawn a concurrent thread that waits for input from std::cin
|
||||
std::thread t1(
|
||||
[&]() {
|
||||
std::cin >> input;
|
||||
gave_input = true;
|
||||
}
|
||||
);
|
||||
t1.detach();
|
||||
|
||||
// check the inputReceived flag once every 50ms for 10 seconds
|
||||
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
|
||||
// prompt for user skip
|
||||
if (Strings::Trim(input) == "y") {
|
||||
errored_migration = false;
|
||||
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"[{}] [{}] [{}]",
|
||||
e.version,
|
||||
e.description,
|
||||
(errored_migration ? "error" : "ok")
|
||||
);
|
||||
|
||||
if (errored_migration) {
|
||||
LogError("Fatal | Database migration [{}] failed to run", e.description);
|
||||
LogError("Fatal | Shutting down");
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
|
||||
{
|
||||
m_database = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||
{
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
LogInfo(
|
||||
"{:>8} | database [{}] binary [{}] {}",
|
||||
"Server",
|
||||
v.server_database_version,
|
||||
b.server_database_version,
|
||||
(v.server_database_version == b.server_database_version) ? "up to date" : "checking updates"
|
||||
);
|
||||
|
||||
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
|
||||
LogInfo(
|
||||
"{:>8} | database [{}] binary [{}] {}",
|
||||
"Bots",
|
||||
v.bots_database_version,
|
||||
b.bots_database_version,
|
||||
(v.bots_database_version == b.bots_database_version) ? "up to date" : "checking updates"
|
||||
);
|
||||
}
|
||||
|
||||
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
|
||||
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
// server database version is required
|
||||
bool server_up_to_date = v.server_database_version == b.server_database_version;
|
||||
// bots database version is optional, if not enabled then it is always up-to-date
|
||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
|
||||
|
||||
return server_up_to_date && bots_up_to_date;
|
||||
}
|
||||
|
||||
// checks to see if there are pending updates
|
||||
// used by zone to prevent launch or boot loop until updates are applied
|
||||
bool DatabaseUpdate::HasPendingUpdates()
|
||||
{
|
||||
auto v = GetDatabaseVersions();
|
||||
auto b = GetBinaryDatabaseVersions();
|
||||
|
||||
return !CheckVersionsUpToDate(v, b);
|
||||
}
|
||||
|
||||
void DatabaseUpdate::InjectBotsVersionColumn()
|
||||
{
|
||||
auto r = m_database->QueryDatabase("show columns from db_version where Field like '%bots_version%'");
|
||||
if (r.RowCount() == 0) {
|
||||
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef EQEMU_DATABASE_UPDATE_H
|
||||
#define EQEMU_DATABASE_UPDATE_H
|
||||
|
||||
#include "../database.h"
|
||||
|
||||
struct ManifestEntry {
|
||||
int version{}; // database version of the migration
|
||||
std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
||||
std::string check{}; // query that checks against the condition
|
||||
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||
};
|
||||
|
||||
struct DatabaseVersion {
|
||||
int server_database_version;
|
||||
int bots_database_version;
|
||||
};
|
||||
|
||||
class DatabaseUpdate {
|
||||
public:
|
||||
DatabaseVersion GetDatabaseVersions();
|
||||
DatabaseVersion GetBinaryDatabaseVersions();
|
||||
void CheckDbUpdates();
|
||||
std::string GetQueryResult(std::string query);
|
||||
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
|
||||
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
|
||||
|
||||
DatabaseUpdate *SetDatabase(Database *db);
|
||||
bool HasPendingUpdates();
|
||||
private:
|
||||
Database *m_database;
|
||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
||||
void InjectBotsVersionColumn();
|
||||
};
|
||||
|
||||
#endif //EQEMU_DATABASE_UPDATE_H
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,107 @@
|
||||
#include "database_update.h"
|
||||
|
||||
std::vector<ManifestEntry> bot_manifest_entries = {
|
||||
ManifestEntry{
|
||||
.version = 9035,
|
||||
.description = "2022_12_04_bot_archery.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `archery_setting` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `enforce_spell_settings`;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9036,
|
||||
.description = "2023_01_19_drop_bot_views.sql",
|
||||
.check = "SHOW TABLES LIKE 'vw_groups'",
|
||||
.condition = "not_empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
DROP VIEW vw_bot_groups;
|
||||
DROP VIEW vw_bot_character_mobs;
|
||||
DROP VIEW vw_groups;
|
||||
DROP VIEW vw_guild_members;
|
||||
DROP TABLE bot_guild_members;
|
||||
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9037,
|
||||
.description = "2023_01_22_add_name_index.sql",
|
||||
.check = "show index from bot_data WHERE key_name = 'name`",
|
||||
.condition = "",
|
||||
.match = "empty",
|
||||
.sql = R"(
|
||||
create index `name` on bot_data(`name`);
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9038,
|
||||
.description = "2023_02_16_add_caster_range.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'",
|
||||
.condition = "",
|
||||
.match = "empty",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9039,
|
||||
.description = "2023_03_31_remove_bot_groups.sql",
|
||||
.check = "SHOW TABLES LIKE 'bot_groups'",
|
||||
.condition = "",
|
||||
.match = "not_empty",
|
||||
.sql = R"(
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
DROP TABLE IF EXISTS `bot_groups`;
|
||||
DROP TABLE IF EXISTS `bot_group_members`;
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9040,
|
||||
.description = "2023_11_16_bot_starting_items.sql",
|
||||
.check = "SHOW TABLES LIKE 'bot_starting_items'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `bot_starting_items` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`races` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`classes` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`slot_id` mediumint(9) NOT NULL DEFAULT -1,
|
||||
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||
`content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
// .version = 9228,
|
||||
// .description = "some_new_migration.sql",
|
||||
// .check = "SHOW COLUMNS FROM `table_name` LIKE 'column_name'",
|
||||
// .condition = "empty",
|
||||
// .match = "",
|
||||
// .sql = R"(
|
||||
//
|
||||
//)"
|
||||
};
|
||||
|
||||
// see struct definitions for what each field does
|
||||
// struct ManifestEntry {
|
||||
// int version{}; // database version of the migration
|
||||
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
||||
// std::string check{}; // query that checks against the condition
|
||||
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||
// };
|
||||
+7
-1799
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/repositories/raid_members_repository.h"
|
||||
#include "../common/repositories/respawn_times_repository.h"
|
||||
#include "../common/repositories/spawn_condition_values_repository.h"
|
||||
#include "repositories/spawn2_disabled_repository.h"
|
||||
|
||||
|
||||
#include "database.h"
|
||||
@@ -49,6 +50,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
||||
{
|
||||
auto e = InstanceListPlayerRepository::NewEntity();
|
||||
@@ -131,85 +133,118 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
{
|
||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||
uint32 max = 32000;
|
||||
uint32 max_instance_id = 32000;
|
||||
|
||||
// sanity check reserved
|
||||
if (max_reserved_instance_id >= max_instance_id) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// recycle instances
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
|
||||
//query to get first unused id above reserved
|
||||
auto query = fmt::format(
|
||||
SQL(
|
||||
SELECT id
|
||||
FROM instance_list
|
||||
WHERE id = {};
|
||||
),
|
||||
max_reserved_instance_id + 1
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// first id is available
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// now look for next available above reserved
|
||||
query = fmt::format(
|
||||
SQL(
|
||||
SELECT MIN(i.id + 1) AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
||||
WHERE i.id >= {}
|
||||
AND i2.id IS NULL;
|
||||
),
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// did not retrieve any rows - bail out
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
// check that id is within limits
|
||||
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// get max unused id above reserved
|
||||
auto query = fmt::format(
|
||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||
max_reserved_instance_id,
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
query = (
|
||||
SQL(
|
||||
SELECT i.id + 1 AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
||||
WHERE i2.id IS NULL
|
||||
ORDER BY i.id
|
||||
LIMIT 0, 1;
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// did not retrieve any rows - bail out
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (Strings::ToInt(row[0]) <= max) {
|
||||
// no instances currently used
|
||||
if (!row[0]) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// check that id is within limits
|
||||
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (instance_id < max_reserved_instance_id) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
|
||||
for (auto row : results) {
|
||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (max_reserved_instance_id > max) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
}
|
||||
|
||||
instance_id = max_reserved_instance_id;
|
||||
|
||||
return true;
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
||||
@@ -520,6 +555,7 @@ void Database::PurgeExpiredInstances()
|
||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
Spawn2DisabledRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
|
||||
@@ -66,9 +66,10 @@ namespace DatabaseSchema {
|
||||
{"character_potionbelt", "id"},
|
||||
{"character_skills", "id"},
|
||||
{"character_spells", "id"},
|
||||
{"character_stats_record", "character_id"},
|
||||
{"character_task_timers", "character_id"},
|
||||
{"character_tasks", "charid"},
|
||||
{"character_tribute", "id"},
|
||||
{"character_tribute", "character_id"},
|
||||
{"completed_tasks", "charid"},
|
||||
{"data_buckets", "id"},
|
||||
{"faction_values", "char_id"},
|
||||
@@ -134,6 +135,7 @@ namespace DatabaseSchema {
|
||||
"character_potionbelt",
|
||||
"character_skills",
|
||||
"character_spells",
|
||||
"character_stats_record",
|
||||
"character_task_timers",
|
||||
"character_tasks",
|
||||
"character_tribute",
|
||||
@@ -256,7 +258,9 @@ namespace DatabaseSchema {
|
||||
{
|
||||
return {
|
||||
"chatchannels",
|
||||
"chatchannel_reserved_names",
|
||||
"command_settings",
|
||||
"command_subsettings",
|
||||
"content_flags",
|
||||
"db_str",
|
||||
"eqtime",
|
||||
@@ -341,6 +345,7 @@ namespace DatabaseSchema {
|
||||
"respawn_times",
|
||||
"saylink",
|
||||
"server_scheduled_events",
|
||||
"spawn2_disabled",
|
||||
"player_event_log_settings",
|
||||
"player_event_logs",
|
||||
"shared_task_activity_state",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <iostream>
|
||||
#include <mysqld_error.h>
|
||||
#include <string.h>
|
||||
#include "strings.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
@@ -305,3 +306,134 @@ void DBcore::SetMutex(Mutex *mutex)
|
||||
|
||||
DBcore::m_mutex = mutex;
|
||||
}
|
||||
|
||||
// executes multiple statements in one query
|
||||
// do not use this in application logic
|
||||
// this was built and maintained for database migrations only
|
||||
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
||||
{
|
||||
SetMultiStatementsOn();
|
||||
|
||||
BenchTimer timer;
|
||||
timer.reset();
|
||||
|
||||
LockMutex lock(m_mutex);
|
||||
|
||||
// Reconnect if we are not connected before hand.
|
||||
if (pStatus != Connected) {
|
||||
Open();
|
||||
}
|
||||
auto r = MySQLRequestResult{};
|
||||
|
||||
int status = mysql_real_query(mysql, query.c_str(), query.length());
|
||||
|
||||
// process single result
|
||||
if (status != 0) {
|
||||
unsigned int error_number = mysql_errno(mysql);
|
||||
|
||||
if (error_number == CR_SERVER_GONE_ERROR) {
|
||||
pStatus = Error;
|
||||
}
|
||||
|
||||
// error logging
|
||||
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
|
||||
std::string error_raw = fmt::format("{}", mysql_error(mysql));
|
||||
std::string mysql_err = Strings::Trim(error_raw);
|
||||
std::string clean_query = Strings::Replace(query, "\n", "");
|
||||
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
|
||||
|
||||
MYSQL_RES *res = mysql_store_result(mysql);
|
||||
|
||||
uint32 row_count = 0;
|
||||
if (res) {
|
||||
row_count = (uint32) mysql_num_rows(res);
|
||||
}
|
||||
|
||||
r = MySQLRequestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(mysql),
|
||||
row_count,
|
||||
(uint32) mysql_field_count(mysql),
|
||||
(uint32) mysql_insert_id(mysql)
|
||||
);
|
||||
|
||||
std::string error_message = mysql_error(mysql);
|
||||
r.SetErrorMessage(error_message);
|
||||
r.SetErrorNumber(mysql_errno(mysql));
|
||||
|
||||
if (res) {
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
SetMultiStatementsOff();
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int index = 0;
|
||||
|
||||
// there could be a query with a semicolon in the actual data, this is best effort for
|
||||
// logging / display purposes
|
||||
// rare that we see this when this is only used in DDL statements
|
||||
auto pieces = Strings::Split(query, ";");
|
||||
|
||||
// process each statement result
|
||||
do {
|
||||
uint32 row_count = 0;
|
||||
MYSQL_RES *res = mysql_store_result(mysql);
|
||||
|
||||
r = MySQLRequestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(mysql),
|
||||
row_count,
|
||||
(uint32) mysql_field_count(mysql),
|
||||
(uint32) mysql_insert_id(mysql)
|
||||
);
|
||||
|
||||
if (pieces.size() >= index) {
|
||||
auto piece = pieces[index];
|
||||
LogMySQLQuery(
|
||||
"{} -- ({} row{} affected) ({}s)",
|
||||
piece,
|
||||
r.RowsAffected(),
|
||||
r.RowsAffected() == 1 ? "" : "s",
|
||||
std::to_string(timer.elapsed())
|
||||
);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
row_count = (uint32) mysql_num_rows(res);
|
||||
}
|
||||
|
||||
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
|
||||
if ((status = mysql_next_result(mysql)) > 0) {
|
||||
if (mysql_errno(mysql) > 0) {
|
||||
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
|
||||
// error logging
|
||||
std::string error_message = mysql_error(mysql);
|
||||
r.SetErrorMessage(error_message);
|
||||
r.SetErrorNumber(mysql_errno(mysql));
|
||||
|
||||
SetMultiStatementsOff();
|
||||
|
||||
// we handle errors elsewhere
|
||||
return r;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
index++;
|
||||
} while (status == 0);
|
||||
|
||||
SetMultiStatementsOff();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
+14
-1
@@ -25,6 +25,7 @@ public:
|
||||
eStatus GetStatus() { return pStatus; }
|
||||
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
||||
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
||||
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
||||
void TransactionBegin();
|
||||
void TransactionCommit();
|
||||
void TransactionRollback();
|
||||
@@ -77,8 +78,20 @@ private:
|
||||
uint32 pPort;
|
||||
bool pSSL;
|
||||
|
||||
// allows multiple queries to be executed within the same query
|
||||
// do not use this under normal operation
|
||||
// we use this during database migrations only currently
|
||||
void SetMultiStatementsOn()
|
||||
{
|
||||
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
|
||||
}
|
||||
|
||||
// disables multiple statements to be executed in one query
|
||||
void SetMultiStatementsOff()
|
||||
{
|
||||
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+69
-119
@@ -11,7 +11,7 @@
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
@@ -19,131 +19,81 @@
|
||||
|
||||
#include "deity.h"
|
||||
|
||||
|
||||
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
return bit_DeityBertoxxulous;
|
||||
case DeityBrellSirilis:
|
||||
return bit_DeityBrellSirilis;
|
||||
case DeityCazicThule:
|
||||
return bit_DeityCazicThule;
|
||||
case DeityErollisiMarr:
|
||||
return bit_DeityErollisiMarr;
|
||||
case DeityBristlebane:
|
||||
return bit_DeityBristlebane;
|
||||
case DeityInnoruuk:
|
||||
return bit_DeityInnoruuk;
|
||||
case DeityKarana:
|
||||
return bit_DeityKarana;
|
||||
case DeityMithanielMarr:
|
||||
return bit_DeityMithanielMarr;
|
||||
case DeityPrexus:
|
||||
return bit_DeityPrexus;
|
||||
case DeityQuellious:
|
||||
return bit_DeityQuellious;
|
||||
case DeityRallosZek:
|
||||
return bit_DeityRallosZek;
|
||||
case DeityRodcetNife:
|
||||
return bit_DeityRodcetNife;
|
||||
case DeitySolusekRo:
|
||||
return bit_DeitySolusekRo;
|
||||
case DeityTheTribunal:
|
||||
return bit_DeityTheTribunal;
|
||||
case DeityTunare:
|
||||
return bit_DeityTunare;
|
||||
case DeityVeeshan:
|
||||
return bit_DeityVeeshan;
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return bit_DeityAgnostic;
|
||||
default:
|
||||
return bit_DeityAll;
|
||||
};
|
||||
case DeityBertoxxulous:
|
||||
return bit_DeityBertoxxulous;
|
||||
case DeityBrellSirilis:
|
||||
return bit_DeityBrellSirilis;
|
||||
case DeityCazicThule:
|
||||
return bit_DeityCazicThule;
|
||||
case DeityErollisiMarr:
|
||||
return bit_DeityErollisiMarr;
|
||||
case DeityBristlebane:
|
||||
return bit_DeityBristlebane;
|
||||
case DeityInnoruuk:
|
||||
return bit_DeityInnoruuk;
|
||||
case DeityKarana:
|
||||
return bit_DeityKarana;
|
||||
case DeityMithanielMarr:
|
||||
return bit_DeityMithanielMarr;
|
||||
case DeityPrexus:
|
||||
return bit_DeityPrexus;
|
||||
case DeityQuellious:
|
||||
return bit_DeityQuellious;
|
||||
case DeityRallosZek:
|
||||
return bit_DeityRallosZek;
|
||||
case DeityRodcetNife:
|
||||
return bit_DeityRodcetNife;
|
||||
case DeitySolusekRo:
|
||||
return bit_DeitySolusekRo;
|
||||
case DeityTheTribunal:
|
||||
return bit_DeityTheTribunal;
|
||||
case DeityTunare:
|
||||
return bit_DeityTunare;
|
||||
case DeityVeeshan:
|
||||
return bit_DeityVeeshan;
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return bit_DeityAgnostic;
|
||||
default:
|
||||
return bit_DeityAll;
|
||||
}
|
||||
}
|
||||
|
||||
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
||||
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
|
||||
{
|
||||
switch (deity_type_bit) {
|
||||
case bit_DeityAgnostic:
|
||||
return DeityAgnostic;
|
||||
case bit_DeityBertoxxulous:
|
||||
return DeityBertoxxulous;
|
||||
case bit_DeityBrellSirilis:
|
||||
return DeityBrellSirilis;
|
||||
case bit_DeityCazicThule:
|
||||
return DeityCazicThule;
|
||||
case bit_DeityErollisiMarr:
|
||||
return DeityErollisiMarr;
|
||||
case bit_DeityBristlebane:
|
||||
return DeityBristlebane;
|
||||
case bit_DeityInnoruuk:
|
||||
return DeityInnoruuk;
|
||||
case bit_DeityKarana:
|
||||
return DeityKarana;
|
||||
case bit_DeityMithanielMarr:
|
||||
return DeityMithanielMarr;
|
||||
case bit_DeityPrexus:
|
||||
return DeityPrexus;
|
||||
case bit_DeityQuellious:
|
||||
return DeityQuellious;
|
||||
case bit_DeityRallosZek:
|
||||
return DeityRallosZek;
|
||||
case bit_DeityRodcetNife:
|
||||
return DeityRodcetNife;
|
||||
case bit_DeitySolusekRo:
|
||||
return DeitySolusekRo;
|
||||
case bit_DeityTheTribunal:
|
||||
return DeityTheTribunal;
|
||||
case bit_DeityTunare:
|
||||
return DeityTunare;
|
||||
case bit_DeityVeeshan:
|
||||
return DeityVeeshan;
|
||||
default:
|
||||
return DeityUnknown;
|
||||
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
|
||||
{ DeityAgnostic, "Agnostic" },
|
||||
{ DeityAgnostic_LB, "Agnostic" },
|
||||
{ DeityBertoxxulous, "Bertoxxulous" },
|
||||
{ DeityBrellSirilis, "Brell Serilis" },
|
||||
{ DeityBristlebane, "Bristlebane" },
|
||||
{ DeityCazicThule, "Cazic-Thule" },
|
||||
{ DeityErollisiMarr, "Erollisi Marr" },
|
||||
{ DeityInnoruuk, "Innoruuk" },
|
||||
{ DeityKarana, "Karana" },
|
||||
{ DeityMithanielMarr, "Mithaniel Marr" },
|
||||
{ DeityPrexus, "Prexus" },
|
||||
{ DeityQuellious, "Quellious" },
|
||||
{ DeityRallosZek, "Rallos Zek" },
|
||||
{ DeityRodcetNife, "Rodcet Nife" },
|
||||
{ DeitySolusekRo, "Solusek Ro" },
|
||||
{ DeityTheTribunal, "The Tribunal" },
|
||||
{ DeityTunare, "Tunare" },
|
||||
{ DeityVeeshan, "Veeshan" }
|
||||
};
|
||||
|
||||
return deity_map;
|
||||
}
|
||||
|
||||
const char* EQ::deity::DeityName(DeityType deity_type)
|
||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
return "Bertoxxulous";
|
||||
case DeityBrellSirilis:
|
||||
return "Brell Serilis";
|
||||
case DeityCazicThule:
|
||||
return "Cazic-Thule";
|
||||
case DeityErollisiMarr:
|
||||
return "Erollisi Marr";
|
||||
case DeityBristlebane:
|
||||
return "Bristlebane";
|
||||
case DeityInnoruuk:
|
||||
return "Innoruuk";
|
||||
case DeityKarana:
|
||||
return "Karana";
|
||||
case DeityMithanielMarr:
|
||||
return "Mithaniel Marr";
|
||||
case DeityPrexus:
|
||||
return "Prexus";
|
||||
case DeityQuellious:
|
||||
return "Quellious";
|
||||
case DeityRallosZek:
|
||||
return "Rallos Zek";
|
||||
case DeityRodcetNife:
|
||||
return "Rodcet Nife";
|
||||
case DeitySolusekRo:
|
||||
return "Solusek Ro";
|
||||
case DeityTheTribunal:
|
||||
return "The Tribunal";
|
||||
case DeityTunare:
|
||||
return "Tunare";
|
||||
case DeityVeeshan:
|
||||
return "Veeshan";
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return "Agnostic";
|
||||
default:
|
||||
return "Unknown";
|
||||
};
|
||||
|
||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
+22
-21
@@ -21,6 +21,8 @@
|
||||
#define COMMON_DEITY_H
|
||||
|
||||
#include "types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace EQ
|
||||
@@ -49,30 +51,29 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum DeityTypeBit : uint32 {
|
||||
bit_DeityNone = 0x00000000,
|
||||
bit_DeityAgnostic = 0x00000001,
|
||||
bit_DeityBertoxxulous = 0x00000002,
|
||||
bit_DeityBrellSirilis = 0x00000004,
|
||||
bit_DeityCazicThule = 0x00000008,
|
||||
bit_DeityErollisiMarr = 0x00000010,
|
||||
bit_DeityBristlebane = 0x00000020,
|
||||
bit_DeityInnoruuk = 0x00000040,
|
||||
bit_DeityKarana = 0x00000080,
|
||||
bit_DeityAgnostic = 0x00000001,
|
||||
bit_DeityBertoxxulous = 0x00000002,
|
||||
bit_DeityBrellSirilis = 0x00000004,
|
||||
bit_DeityCazicThule = 0x00000008,
|
||||
bit_DeityErollisiMarr = 0x00000010,
|
||||
bit_DeityBristlebane = 0x00000020,
|
||||
bit_DeityInnoruuk = 0x00000040,
|
||||
bit_DeityKarana = 0x00000080,
|
||||
bit_DeityMithanielMarr = 0x00000100,
|
||||
bit_DeityPrexus = 0x00000200,
|
||||
bit_DeityQuellious = 0x00000400,
|
||||
bit_DeityRallosZek = 0x00000800,
|
||||
bit_DeityRodcetNife = 0x00001000,
|
||||
bit_DeitySolusekRo = 0x00002000,
|
||||
bit_DeityTheTribunal = 0x00004000,
|
||||
bit_DeityTunare = 0x00008000,
|
||||
bit_DeityVeeshan = 0x00010000,
|
||||
bit_DeityAll = 0xFFFFFFFF
|
||||
bit_DeityPrexus = 0x00000200,
|
||||
bit_DeityQuellious = 0x00000400,
|
||||
bit_DeityRallosZek = 0x00000800,
|
||||
bit_DeityRodcetNife = 0x00001000,
|
||||
bit_DeitySolusekRo = 0x00002000,
|
||||
bit_DeityTheTribunal = 0x00004000,
|
||||
bit_DeityTunare = 0x00008000,
|
||||
bit_DeityVeeshan = 0x00010000,
|
||||
bit_DeityAll = UINT32_MAX
|
||||
};
|
||||
|
||||
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
|
||||
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
|
||||
extern const char* DeityName(DeityType deity_type);
|
||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
||||
extern std::string GetDeityName(DeityType deity_type);
|
||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
||||
|
||||
} /*deity*/
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ N(OP_BeginCast),
|
||||
N(OP_Bind_Wound),
|
||||
N(OP_BlockedBuffs),
|
||||
N(OP_BoardBoat),
|
||||
N(OP_BookButton),
|
||||
N(OP_Buff),
|
||||
N(OP_BuffCreate),
|
||||
N(OP_BuffRemoveRequest),
|
||||
@@ -316,6 +317,7 @@ N(OP_LootRequest),
|
||||
N(OP_ManaChange),
|
||||
N(OP_ManaUpdate),
|
||||
N(OP_MarkNPC),
|
||||
N(OP_MarkRaidNPC),
|
||||
N(OP_Marquee),
|
||||
N(OP_MemorizeSpell),
|
||||
N(OP_Mend),
|
||||
@@ -398,6 +400,8 @@ N(OP_PVPLeaderBoardRequest),
|
||||
N(OP_PVPStats),
|
||||
N(OP_QueryResponseThing),
|
||||
N(OP_QueryUCSServerStatus),
|
||||
N(OP_RaidDelegateAbility),
|
||||
N(OP_RaidClearNPCMarks),
|
||||
N(OP_RaidInvite),
|
||||
N(OP_RaidJoin),
|
||||
N(OP_RaidUpdate),
|
||||
|
||||
@@ -1045,4 +1045,34 @@ enum ResurrectionActions
|
||||
Accept
|
||||
};
|
||||
|
||||
enum ScribeSpellActions
|
||||
{
|
||||
Scribe,
|
||||
Memorize,
|
||||
Unmemorize
|
||||
};
|
||||
|
||||
enum SpellTimeRestrictions
|
||||
{
|
||||
NoRestriction,
|
||||
Day,
|
||||
Night
|
||||
};
|
||||
|
||||
enum MoneyTypes
|
||||
{
|
||||
Copper,
|
||||
Silver,
|
||||
Gold,
|
||||
Platinum
|
||||
};
|
||||
|
||||
enum MoneySubtypes
|
||||
{
|
||||
Personal,
|
||||
Bank,
|
||||
Cursor,
|
||||
SharedBank // Platinum Only
|
||||
};
|
||||
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
@@ -1793,6 +1793,17 @@ struct GMSummon_Struct {
|
||||
/*104*/ uint32 unknown2; // E0 E0 56 00
|
||||
};
|
||||
|
||||
struct GMFind_Struct {
|
||||
char charname[64];
|
||||
char gmname[64];
|
||||
uint32 success;
|
||||
uint32 zoneID;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
uint32 unknown2;
|
||||
};
|
||||
|
||||
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
|
||||
/* 0*/ char charname[64];
|
||||
|
||||
@@ -2548,7 +2559,10 @@ struct GMEmoteZone_Struct {
|
||||
struct BookText_Struct {
|
||||
uint8 window; // where to display the text (0xFF means new window)
|
||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||
uint32 invslot; // Only used in SoF and later clients.
|
||||
int16 invslot; // Only used in SoF and later clients.
|
||||
int32 target_id;
|
||||
int8 can_cast;
|
||||
int8 can_scribe;
|
||||
char booktext[1]; // Variable Length
|
||||
};
|
||||
// This is the request to read a book.
|
||||
@@ -2557,11 +2571,18 @@ struct BookText_Struct {
|
||||
struct BookRequest_Struct {
|
||||
uint8 window; // where to display the text (0xFF means new window)
|
||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||
uint32 invslot; // Only used in Sof and later clients;
|
||||
int16 subslot; // The subslot inside of a bag if it is inside one.
|
||||
int16 invslot; // Only used in Sof and later clients;
|
||||
int32 target_id;
|
||||
char txtfile[20];
|
||||
};
|
||||
|
||||
// used by Scribe and CastSpell book buttons
|
||||
struct BookButton_Struct
|
||||
{
|
||||
int16 invslot; // server slot
|
||||
int32 target_id;
|
||||
};
|
||||
|
||||
/*
|
||||
** Object/Ground Spawn struct
|
||||
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
||||
@@ -4094,7 +4115,9 @@ struct UpdateLeadershipAA_Struct {
|
||||
|
||||
enum
|
||||
{
|
||||
GroupLeadershipAbility_MarkNPC = 0
|
||||
GroupLeadershipAbility_MarkNPC = 0,
|
||||
RaidLeadershipAbility_MarkNPC = 16,
|
||||
RaidLeadershipAbility_MainAssist = 19
|
||||
};
|
||||
|
||||
struct DoGroupLeadershipAbility_Struct
|
||||
@@ -4138,8 +4161,9 @@ struct InspectBuffs_Struct {
|
||||
struct RaidGeneral_Struct {
|
||||
/*00*/ uint32 action; //=10
|
||||
/*04*/ char player_name[64]; //should both be the player's name
|
||||
/*64*/ char leader_name[64];
|
||||
/*132*/ uint32 parameter;
|
||||
/*68*/ uint32 unknown1;
|
||||
/*72*/ char leader_name[64];
|
||||
/*136*/ uint32 parameter;
|
||||
};
|
||||
|
||||
struct RaidAddMember_Struct {
|
||||
@@ -4150,9 +4174,14 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*136*/ char motd[0]; // max size is 1024, but reply is variable
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char motd[1024];
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
|
||||
@@ -85,6 +85,12 @@ void EQEmuConfig::parse_config()
|
||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||
Locked = false;
|
||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||
|
||||
auto_database_updates = false;
|
||||
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
|
||||
auto_database_updates = true;
|
||||
}
|
||||
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ class EQEmuConfig
|
||||
uint16 ZonePortHigh;
|
||||
uint8 DefaultStatus;
|
||||
|
||||
bool auto_database_updates;
|
||||
|
||||
// uint16 DynamicCount;
|
||||
|
||||
// map<string,uint16> StaticZones;
|
||||
|
||||
+94
-21
@@ -100,13 +100,15 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::EqTime].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* RFC 5424
|
||||
*/
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* Set Category enabled status on defaults
|
||||
@@ -219,7 +221,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
||||
int line
|
||||
)
|
||||
{
|
||||
bool is_error = (
|
||||
bool is_error = (
|
||||
log_category == Logs::LogCategory::Error ||
|
||||
log_category == Logs::LogCategory::MySQLError ||
|
||||
log_category == Logs::LogCategory::Crash ||
|
||||
@@ -261,7 +263,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
||||
}
|
||||
|
||||
if (log_category == Logs::LogCategory::MySQLQuery) {
|
||||
auto s = Strings::Split(message, "--");
|
||||
auto s = Strings::Split(message, "--");
|
||||
if (s.size() > 1) {
|
||||
std::string query = Strings::Trim(s[0]);
|
||||
std::string meta = Strings::Trim(s[1]);
|
||||
@@ -297,19 +299,76 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_upper) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< rang::fgB::yellow
|
||||
<< e
|
||||
<< rang::fgB::gray
|
||||
<< "] "
|
||||
;
|
||||
// color matching in []
|
||||
// ex: [<red>variable] would produce [variable] with red inside brackets
|
||||
std::map<std::string, rang::fgB> colors = {
|
||||
{"<black>", rang::fgB::black},
|
||||
{"<green>", rang::fgB::green},
|
||||
{"<yellow>", rang::fgB::yellow},
|
||||
{"<blue>", rang::fgB::blue},
|
||||
{"<magenta>", rang::fgB::magenta},
|
||||
{"<cyan>", rang::fgB::cyan},
|
||||
{"<gray>", rang::fgB::gray},
|
||||
{"<red>", rang::fgB::red},
|
||||
};
|
||||
|
||||
bool match_color = false;
|
||||
for (auto &c: colors) {
|
||||
if (Strings::Contains(e, c.first)) {
|
||||
e = Strings::Replace(e, c.first, "");
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< c.second
|
||||
<< e
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< "] ";
|
||||
match_color = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||
|
||||
// string match to colors
|
||||
std::map<std::string, rang::fgB> matches = {
|
||||
{"missing", rang::fgB::red},
|
||||
{"error", rang::fgB::red},
|
||||
{"ok", rang::fgB::green},
|
||||
};
|
||||
|
||||
for (auto &c: matches) {
|
||||
if (Strings::Contains(e, c.first)) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< c.second
|
||||
<< e
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< "] ";
|
||||
match_color = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't match a color in either the string matching or
|
||||
// the color tag matching, we default to yellow inside brackets
|
||||
// if uppercase, does not get colored
|
||||
if (!match_color) {
|
||||
if (!is_upper) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< rang::fgB::yellow
|
||||
<< e
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< "] ";
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -389,6 +448,8 @@ void EQEmuLogSys::Out(
|
||||
// remove this when we remove all legacy logs
|
||||
bool ignore_log_legacy_format = (
|
||||
log_category == Logs::Netcode ||
|
||||
log_category == Logs::MySQLQuery ||
|
||||
log_category == Logs::MySQLError ||
|
||||
log_category == Logs::PacketServerClient ||
|
||||
log_category == Logs::PacketClientServer ||
|
||||
log_category == Logs::PacketServerToServer
|
||||
@@ -523,6 +584,8 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
*/
|
||||
void EQEmuLogSys::SilenceConsoleLogging()
|
||||
{
|
||||
std::copy(std::begin(log_settings), std::end(log_settings), std::begin(pre_silence_settings));
|
||||
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = 0;
|
||||
log_settings[log_index].is_category_enabled = 0;
|
||||
@@ -536,10 +599,7 @@ void EQEmuLogSys::SilenceConsoleLogging()
|
||||
*/
|
||||
void EQEmuLogSys::EnableConsoleLogging()
|
||||
{
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = Logs::General;
|
||||
log_settings[log_index].is_category_enabled = 1;
|
||||
}
|
||||
std::copy(std::begin(pre_silence_settings), std::end(pre_silence_settings), std::begin(log_settings));
|
||||
}
|
||||
|
||||
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
@@ -741,3 +801,16 @@ EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
|
||||
return this;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::DisableMySQLErrorLogs()
|
||||
{
|
||||
log_settings[Logs::MySQLError].log_to_file = 0;
|
||||
log_settings[Logs::MySQLError].log_to_console = 0;
|
||||
log_settings[Logs::MySQLError].log_to_gmsay = 0;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::EnableMySQLErrorLogs()
|
||||
{
|
||||
log_settings[Logs::MySQLError].log_to_file = 1;
|
||||
log_settings[Logs::MySQLError].log_to_console = 1;
|
||||
log_settings[Logs::MySQLError].log_to_gmsay = 1;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,9 @@ namespace Logs {
|
||||
Bugs,
|
||||
QuestErrors,
|
||||
PlayerEvents,
|
||||
DataBuckets,
|
||||
Zoning,
|
||||
EqTime,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -233,6 +236,9 @@ namespace Logs {
|
||||
"Bugs",
|
||||
"QuestErrors",
|
||||
"PlayerEvents",
|
||||
"DataBuckets",
|
||||
"Zoning",
|
||||
"EqTime",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -324,6 +330,9 @@ public:
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
// temporary bucket to re-load after silencing
|
||||
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
struct LogEnabled {
|
||||
bool log_to_file_enabled;
|
||||
bool log_to_console_enabled;
|
||||
@@ -374,6 +383,9 @@ public:
|
||||
[[nodiscard]] const std::string &GetLogPath() const;
|
||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
||||
|
||||
void DisableMySQLErrorLogs();
|
||||
void EnableMySQLErrorLogs();
|
||||
|
||||
private:
|
||||
|
||||
// reference to database
|
||||
|
||||
@@ -794,6 +794,36 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDataBuckets(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::DataBuckets))\
|
||||
OutF(LogSys, Logs::General, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDataBucketsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DataBuckets))\
|
||||
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoning(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::General, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoningDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEqTime(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::EqTime))\
|
||||
OutF(LogSys, Logs::General, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEqTimeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EqTime))\
|
||||
OutF(LogSys, Logs::Detail, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
+51
-7
@@ -46,16 +46,16 @@ EQTime::EQTime()
|
||||
timezone = 0;
|
||||
memset(&eqTime, 0, sizeof(eqTime));
|
||||
//Defaults for time
|
||||
TimeOfDay_Struct start;
|
||||
start.day = 1;
|
||||
start.hour = 9;
|
||||
start.minute = 0;
|
||||
start.month = 1;
|
||||
start.year = 3100;
|
||||
TimeOfDay_Struct t{};
|
||||
t.day = 1;
|
||||
t.hour = 9;
|
||||
t.minute = 0;
|
||||
t.month = 1;
|
||||
t.year = 3100;
|
||||
//Set default time zone
|
||||
timezone = 0;
|
||||
//Start EQTimer
|
||||
SetCurrentEQTimeOfDay(start, time(0));
|
||||
SetCurrentEQTimeOfDay(t, time(nullptr));
|
||||
}
|
||||
|
||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
||||
@@ -200,3 +200,47 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
||||
buf[127] = '\0';
|
||||
str = buf;
|
||||
}
|
||||
|
||||
bool EQTime::IsDayTime() {
|
||||
TimeOfDay_Struct tod{}; //Day time is 5am to 6:59pm (14 hours in-game)
|
||||
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||
|
||||
if (tod.hour >= 5 || tod.hour < 19) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQTime::IsNightTime() {
|
||||
TimeOfDay_Struct tod{}; //Night time is 7pm to 4:59am (10 hours in-game)
|
||||
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||
|
||||
if (tod.hour >= 19 || tod.hour < 5) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQTime::IsInbetweenTime(uint8 min_time, uint8 max_time) {
|
||||
TimeOfDay_Struct tod{};
|
||||
GetCurrentEQTimeOfDay(&tod);
|
||||
|
||||
if (min_time == 0 || max_time == 0 || min_time > 24 || max_time > 24) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (max_time < min_time) {
|
||||
if ((tod.hour >= min_time && tod.hour > max_time) || (tod.hour < min_time && tod.hour <= max_time)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tod.hour >= min_time && tod.hour <= max_time) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ public:
|
||||
uint32 getEQTimeZone() { return timezone; }
|
||||
uint32 getEQTimeZoneHr() { return timezone/60; }
|
||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||
bool IsDayTime();
|
||||
bool IsNightTime();
|
||||
bool IsInbetweenTime(uint8 min_time, uint8 max_time);
|
||||
|
||||
//Set functions
|
||||
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
||||
|
||||
+13
-29
@@ -240,36 +240,20 @@ enum { //some random constants
|
||||
|
||||
//Some hard coded statuses from commands and other places:
|
||||
enum {
|
||||
minStatusToBeGM = 40,
|
||||
minStatusToUseGMCommands = 80,
|
||||
minStatusToKick = 150,
|
||||
minStatusToAvoidFalling = 100,
|
||||
minStatusToHaveInvalidSpells = 80,
|
||||
minStatusToHaveInvalidSkills = 80,
|
||||
minStatusToIgnoreZoneFlags = 80,
|
||||
minStatusToBeGM = 40,
|
||||
minStatusToUseGMCommands = 80,
|
||||
minStatusToKick = 150,
|
||||
minStatusToAvoidFalling = 100,
|
||||
minStatusToIgnoreZoneFlags = 80,
|
||||
minStatusToSeeOthersZoneFlags = 80,
|
||||
minStatusToEditOtherGuilds = 80,
|
||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
||||
commandZoneToSpecials = 80, //zone to cshome, out of load zones
|
||||
commandToggleAI = 250, //can turn NPC AI on and off
|
||||
commandCastSpecials = 100, //can cast special spells
|
||||
commandInstacast = 100, //insta-cast all #casted spells
|
||||
commandLevelAboveCap = 100, //can #level players above level cap
|
||||
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
|
||||
commandSetSkillsOther = 100, //ability to setskills on others
|
||||
commandRaceOthers = 100, //ability to #race on others
|
||||
commandGenderOthers = 100, //ability to #gender on others
|
||||
commandTextureOthers = 100, //ability to #texture on others
|
||||
commandDoAnimOthers = 100, //can #doanim on others
|
||||
commandLockZones = 101, //can lock or unlock zones
|
||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
||||
commandChangeFlags = 200, //ability to set/refresh flags
|
||||
commandBanPlayers = 100, //can set bans on players
|
||||
commandChangeDatarate = 201, //edit client's data rate
|
||||
commandZoneToCoords = 0, //can #zone with coords
|
||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
||||
minStatusToEditOtherGuilds = 80,
|
||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
||||
commandCastSpecials = 100, //can cast special spells
|
||||
commandDoAnimOthers = 100, //can #doanim on others
|
||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
||||
};
|
||||
|
||||
|
||||
|
||||
+8
-2
@@ -55,8 +55,14 @@ bool File::Exists(const std::string &name)
|
||||
*/
|
||||
void File::Makedir(const std::string &directory_name)
|
||||
{
|
||||
fs::create_directory(directory_name);
|
||||
fs::permissions(directory_name, fs::perms::owner_all);
|
||||
try {
|
||||
fs::create_directory(directory_name);
|
||||
fs::permissions(directory_name, fs::perms::owner_all);
|
||||
}
|
||||
catch (const fs::filesystem_error &ex) {
|
||||
std::cout << "Failed to create directory: " << directory_name << std::endl;
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string File::FindEqemuConfigPath()
|
||||
|
||||
@@ -353,7 +353,7 @@ bool EQ::InventoryProfile::SwapItem(
|
||||
fail_state = swapRaceClass;
|
||||
return false;
|
||||
}
|
||||
if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) {
|
||||
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
|
||||
fail_state = swapDeity;
|
||||
return false;
|
||||
}
|
||||
@@ -379,7 +379,7 @@ bool EQ::InventoryProfile::SwapItem(
|
||||
fail_state = swapRaceClass;
|
||||
return false;
|
||||
}
|
||||
if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) {
|
||||
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
|
||||
fail_state = swapDeity;
|
||||
return false;
|
||||
}
|
||||
@@ -1444,7 +1444,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
||||
}
|
||||
|
||||
if (result == INVALID_INDEX) {
|
||||
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
||||
LogError("Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
||||
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
||||
}
|
||||
|
||||
|
||||
@@ -230,6 +230,10 @@ bool EQ::ItemData::IsTypeShield() const
|
||||
return (ItemType == item::ItemTypeShield);
|
||||
}
|
||||
|
||||
bool EQ::ItemData::IsQuestItem() const {
|
||||
return QuestItemFlag;
|
||||
}
|
||||
|
||||
bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
|
||||
{
|
||||
if (!l_item || !r_item)
|
||||
|
||||
@@ -356,6 +356,7 @@ namespace EQ
|
||||
struct ItemData {
|
||||
// Non packet based fields
|
||||
uint8 MinStatus {};
|
||||
char Comment[255] {};
|
||||
|
||||
// Packet based fields
|
||||
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
||||
@@ -546,6 +547,7 @@ namespace EQ
|
||||
bool IsType1HWeapon() const;
|
||||
bool IsType2HWeapon() const;
|
||||
bool IsTypeShield() const;
|
||||
bool IsQuestItem() const;
|
||||
|
||||
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
||||
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
|
||||
|
||||
@@ -720,12 +720,14 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
|
||||
|
||||
bool EQ::ItemInstance::IsAugmented()
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon())
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
||||
if (GetAugmentItemID(index))
|
||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||
if (GetAugmentItemID(slot_id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -108,7 +108,8 @@ namespace EQ
|
||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||
int8 AvailableAugmentSlot(int32 augment_type) const;
|
||||
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||
inline int GetAugmentType() const { return m_item ? m_item->AugType : 0; }
|
||||
inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; }
|
||||
|
||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||
|
||||
|
||||
+24640
File diff suppressed because it is too large
Load Diff
@@ -48,5 +48,7 @@
|
||||
#define LANG_HADAL 26
|
||||
#define LANG_UNKNOWN 27
|
||||
|
||||
#define MAX_LANGUAGE_SKILL 100
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
-117
@@ -214,123 +214,6 @@ std::string x;
|
||||
return i;
|
||||
}
|
||||
|
||||
void LoadItemDBFieldNames() {
|
||||
DBFieldNames[0]="N/A"; // Charges
|
||||
DBFieldNames[1]="unknown002"; // ?
|
||||
DBFieldNames[2]="N/A"; // Current Equip Slot
|
||||
DBFieldNames[3]="unknown004";
|
||||
DBFieldNames[4]="unknown005"; // ?
|
||||
DBFieldNames[5]="itemclass"; // "Item Type (0=common, 1=container, 2=book)"
|
||||
DBFieldNames[6]="name"; // Name
|
||||
DBFieldNames[7]="lore"; // "Lore Name (*=lore, &=summoned, #=artifact)"
|
||||
DBFieldNames[8]="idfile"; // IDFile
|
||||
DBFieldNames[9]="id"; // ItemNumber
|
||||
DBFieldNames[10]="weight"; // Weight
|
||||
DBFieldNames[11]="norent"; // "NoRent (0=norent, 255=not norent)"
|
||||
DBFieldNames[12]="nodrop"; // "NoDrop (0=nodrop, 255=not nodrop)"
|
||||
DBFieldNames[13]="size"; // "Size (0=tiny, 1=small, 2=medium, 3=large, 4=giant)"
|
||||
DBFieldNames[14]="slots"; // EquipSlots
|
||||
DBFieldNames[15]="cost"; // Cost
|
||||
DBFieldNames[16]="icon"; // IconNumber
|
||||
DBFieldNames[17]="unknown018";
|
||||
DBFieldNames[18]="unknown019";
|
||||
DBFieldNames[19]="unknown020"; // ?
|
||||
DBFieldNames[20]="tradeskills"; // "Tradeskill Item (1=is a tradeskill item, 0=not)"
|
||||
DBFieldNames[21]="cr"; // SvCold
|
||||
DBFieldNames[22]="dr"; // SvDisease
|
||||
DBFieldNames[23]="pr"; // SvPoison
|
||||
DBFieldNames[24]="mr"; // SvMagic
|
||||
DBFieldNames[25]="fr"; // SvFire
|
||||
DBFieldNames[26]="astr"; // STR
|
||||
DBFieldNames[27]="asta"; // STA
|
||||
DBFieldNames[28]="aagi"; // AGI
|
||||
DBFieldNames[29]="adex"; // DEX
|
||||
DBFieldNames[30]="acha"; // CHA
|
||||
DBFieldNames[31]="aint"; // INT
|
||||
DBFieldNames[32]="awis"; // WIS
|
||||
DBFieldNames[33]="hp"; // HP
|
||||
DBFieldNames[34]="mana"; // Mana
|
||||
DBFieldNames[35]="ac"; // AC
|
||||
DBFieldNames[36]="deity"; // Deity
|
||||
DBFieldNames[37]="skillmodvalue"; // Skill Mod Value
|
||||
DBFieldNames[38]="skillmodtype"; // Skill Mod Type
|
||||
DBFieldNames[39]="banedmgrace"; // Bane Dmg Race
|
||||
DBFieldNames[40]="banedmgamt"; // Band Dmg
|
||||
DBFieldNames[41]="banedmgbody"; // Band Dmg Body
|
||||
DBFieldNames[42]="magic"; // "Magic (0=not magic, 1=magic)"
|
||||
DBFieldNames[43]="casttime2"; // Casttime appears twice
|
||||
DBFieldNames[44]="hasteproclvl"; // "Level (Haste value, rather)"
|
||||
DBFieldNames[45]="reqlevel"; // Required Level
|
||||
DBFieldNames[46]="bardtype"; // Bard Type
|
||||
DBFieldNames[47]="bardvalue"; // Bard Type Amount
|
||||
DBFieldNames[48]="light"; // Light
|
||||
DBFieldNames[49]="delay"; // Attack Delay
|
||||
DBFieldNames[50]="reclevel"; // Recommended Level
|
||||
DBFieldNames[51]="recskill"; // Recommended Skill
|
||||
DBFieldNames[52]="elemdmgamt"; // "Elemental Dmg Type (1=magic, 2=fire, 3=cold, 4=poison, 5=disease)"
|
||||
DBFieldNames[53]="elemdmgtype"; // Elemental Dmg
|
||||
DBFieldNames[54]="effecttype"; // "Effect Type (0=combat, 1=clicky, 2=Worn, 3=Expendable charges, 4=Must Equip Clicky, 5=clicky)"
|
||||
DBFieldNames[55]="range"; // Range
|
||||
DBFieldNames[56]="damage"; // Damage
|
||||
DBFieldNames[57]="color"; // Color
|
||||
DBFieldNames[58]="classes"; // Classes
|
||||
DBFieldNames[59]="races"; // Races
|
||||
DBFieldNames[60]="unknown061";
|
||||
DBFieldNames[61]="spellid"; // SpellId
|
||||
DBFieldNames[62]="maxcharges"; // MaxCharges
|
||||
DBFieldNames[63]="itemtype"; // "Skill (ItemType: 1hs, etc)"
|
||||
DBFieldNames[64]="material"; // Material
|
||||
DBFieldNames[65]="sellrate"; // ** Sell Rate
|
||||
DBFieldNames[66]="unknown067";
|
||||
DBFieldNames[67]="casttime"; // CastTime (milliseconds)
|
||||
DBFieldNames[68]="unknown069";
|
||||
DBFieldNames[69]="unknown070"; // ?
|
||||
DBFieldNames[70]="focusid"; // Focus Effect Spell Id
|
||||
DBFieldNames[71]="combateffects"; // CombatEffects
|
||||
DBFieldNames[72]="shielding"; // Shielding
|
||||
DBFieldNames[73]="stunresist"; // StunResist
|
||||
DBFieldNames[74]="strikethrough"; // StrikeThrough
|
||||
DBFieldNames[75]="unknown076";
|
||||
DBFieldNames[76]="unknown077"; // ?
|
||||
DBFieldNames[77]="spellshield"; // Spell Shield
|
||||
DBFieldNames[78]="avoidance"; // Avoidance
|
||||
DBFieldNames[79]="accuracy"; // Accuracy
|
||||
DBFieldNames[80]="factionmod1"; // Faction Mod Index 1
|
||||
DBFieldNames[81]="factionmod2"; // Faction Mod Index 2
|
||||
DBFieldNames[82]="factionmod3"; // Faction Mod Index 3
|
||||
DBFieldNames[83]="factionmod4"; // Faction Mod Index 4
|
||||
DBFieldNames[84]="factionamt1"; // Faction Mod Value 1
|
||||
DBFieldNames[85]="factionamt2"; // Faction Mod Value 2
|
||||
DBFieldNames[86]="factionamt3"; // Faction Mod Value 3
|
||||
DBFieldNames[87]="factionamt4"; // Faction Mod Value 4
|
||||
DBFieldNames[88]="unknown089";
|
||||
DBFieldNames[89]="charmfile"; // ** Charm File
|
||||
DBFieldNames[90]="unknown091";
|
||||
DBFieldNames[91]="augslot1type"; // Slot1Type
|
||||
DBFieldNames[92]="augslot2type"; // Slot2Type
|
||||
DBFieldNames[93]="augslot3type"; // Slot3Type
|
||||
DBFieldNames[94]="augslot4type"; // Slot4Type
|
||||
DBFieldNames[95]="augslot5type"; // Slot5Type
|
||||
DBFieldNames[96]="ldonpointtheme";
|
||||
DBFieldNames[97]="ldonpointcost"; // ?
|
||||
DBFieldNames[98]="unknown099";
|
||||
DBFieldNames[99]="bagtype"; // bag type
|
||||
DBFieldNames[100]="bagslots"; // bag slots
|
||||
DBFieldNames[101]="bagsize"; // bag size capacity
|
||||
DBFieldNames[102]="bagwr"; // bag weight reduction
|
||||
DBFieldNames[103]="booktype"; // "book type (0=rolled up note, 1=book)"
|
||||
DBFieldNames[104]="unknown105";
|
||||
DBFieldNames[105]="filename"; // Book Filename
|
||||
DBFieldNames[106]="unknown107";
|
||||
DBFieldNames[107]="unknown108";
|
||||
DBFieldNames[108]="loreflag";
|
||||
DBFieldNames[109]="unknown111";
|
||||
DBFieldNames[110]="unknown112";
|
||||
DBFieldNames[111]="unknown113";
|
||||
DBFieldNames[112]="unknown114";
|
||||
DBFieldNames[113]="unknown115"; // ? (end quote)
|
||||
}
|
||||
|
||||
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
||||
{
|
||||
unsigned long i,j;
|
||||
|
||||
@@ -15,8 +15,6 @@ bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::stri
|
||||
|
||||
int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
||||
|
||||
void LoadItemDBFieldNames();
|
||||
|
||||
#ifndef WIN32
|
||||
int print_stacktrace();
|
||||
#endif
|
||||
|
||||
@@ -51,6 +51,7 @@ void MySQLRequestResult::ZeroOut()
|
||||
m_RowCount = 0;
|
||||
m_RowsAffected = 0;
|
||||
m_LastInsertedID = 0;
|
||||
m_error_message = "";
|
||||
}
|
||||
|
||||
MySQLRequestResult::~MySQLRequestResult()
|
||||
@@ -137,3 +138,23 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
|
||||
other.ZeroOut();
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32 MySQLRequestResult::GetErrorNumber() const
|
||||
{
|
||||
return m_ErrorNumber;
|
||||
}
|
||||
|
||||
void MySQLRequestResult::SetErrorNumber(uint32 m_error_number)
|
||||
{
|
||||
m_ErrorNumber = m_error_number;
|
||||
}
|
||||
|
||||
const std::string &MySQLRequestResult::GetErrorMessage() const
|
||||
{
|
||||
return m_error_message;
|
||||
}
|
||||
|
||||
void MySQLRequestResult::SetErrorMessage(const std::string &m_error_message)
|
||||
{
|
||||
MySQLRequestResult::m_error_message = m_error_message;
|
||||
}
|
||||
|
||||
@@ -33,30 +33,42 @@ private:
|
||||
uint32 m_LastInsertedID;
|
||||
uint32 m_ErrorNumber;
|
||||
|
||||
std::string m_error_message;
|
||||
|
||||
public:
|
||||
|
||||
MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected = 0, uint32 rowCount = 0, uint32 columnCount = 0, uint32 lastInsertedID = 0, uint32 errorNumber = 0, char *errorBuffer = nullptr);
|
||||
MySQLRequestResult();
|
||||
MySQLRequestResult();
|
||||
MySQLRequestResult(MySQLRequestResult&& moveItem);
|
||||
~MySQLRequestResult();
|
||||
|
||||
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
||||
|
||||
bool Success() const { return m_Success;}
|
||||
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
|
||||
std::string ErrorMessage() const {
|
||||
if (!m_error_message.empty()) {
|
||||
return m_error_message;
|
||||
}
|
||||
|
||||
return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");
|
||||
}
|
||||
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
||||
uint32 RowsAffected() const {return m_RowsAffected;}
|
||||
uint32 RowCount() const {return m_RowCount;}
|
||||
uint32 ColumnCount() const {return m_ColumnCount;}
|
||||
uint32 LastInsertedID() const {return m_LastInsertedID;}
|
||||
// default to 0 index since we mostly use it that way anyways.
|
||||
uint32 LengthOfColumn(int columnIndex = 0);
|
||||
uint32 LengthOfColumn(int columnIndex = 0);
|
||||
const std::string FieldName(int columnIndex);
|
||||
|
||||
MySQLRequestRow& begin() { return m_CurrentRow; }
|
||||
MySQLRequestRow& end() { return m_OneBeyondRow; }
|
||||
|
||||
uint32 GetErrorNumber() const;
|
||||
void SetErrorNumber(uint32 m_error_number);
|
||||
const std::string &GetErrorMessage() const;
|
||||
void SetErrorMessage(const std::string &m_error_message);
|
||||
|
||||
private:
|
||||
void FreeInternals();
|
||||
void ZeroOut();
|
||||
|
||||
+135
-88
@@ -34,6 +34,7 @@
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
#include "../races.h"
|
||||
#include "../raid.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -2608,88 +2609,124 @@ namespace RoF
|
||||
|
||||
ENCODE(OP_RaidJoin)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
general->action = 8;
|
||||
general->parameter = 1;
|
||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
general->action = raidCreate;
|
||||
general->parameter = RaidCommandAcceptInvite;
|
||||
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
safe_delete(inapp);
|
||||
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
||||
switch (raid_gen->action)
|
||||
{
|
||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
||||
case raidAdd:
|
||||
{
|
||||
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
|
||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
||||
add_member->_class = in_add_member->_class;
|
||||
add_member->level = in_add_member->level;
|
||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
||||
add_member->flags[0] = in_add_member->flags[0];
|
||||
add_member->flags[1] = in_add_member->flags[1];
|
||||
add_member->flags[2] = in_add_member->flags[2];
|
||||
add_member->flags[3] = in_add_member->flags[3];
|
||||
add_member->flags[4] = in_add_member->flags[4];
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
else if (raid_gen->action == 35)
|
||||
{
|
||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
||||
strlen(inmotd->motd) + 1);
|
||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
||||
OUT(raidGen.action);
|
||||
OUT(raidGen.parameter);
|
||||
OUT_str(raidGen.leader_name);
|
||||
OUT_str(raidGen.player_name);
|
||||
OUT(_class);
|
||||
OUT(level);
|
||||
OUT(isGroupLeader);
|
||||
OUT(flags[0]);
|
||||
OUT(flags[1]);
|
||||
OUT(flags[2]);
|
||||
OUT(flags[3]);
|
||||
OUT(flags[4]);
|
||||
|
||||
outmotd->general.action = inmotd->general.action;
|
||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
||||
case raidSetMotd:
|
||||
{
|
||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
||||
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(motd);
|
||||
|
||||
outlaa->action = inlaa->action;
|
||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case raidSetLeaderAbilities:
|
||||
case raidMakeLeader:
|
||||
{
|
||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
||||
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT_str(player_name);
|
||||
OUT_str(leader_name);
|
||||
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(note);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidNoRaid:
|
||||
{
|
||||
dest->QueuePacket(inapp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
||||
raid_general->action = in_raid_general->action;
|
||||
raid_general->parameter = in_raid_general->parameter;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT(parameter);
|
||||
OUT_str(leader_name);
|
||||
OUT_str(player_name);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
@@ -4861,37 +4898,47 @@ namespace RoF
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
|
||||
// This is a switch on the RaidGeneral action
|
||||
switch (*(uint32 *)__packet->pBuffer) {
|
||||
case 35: { // raidMOTD
|
||||
// we don't have a nice macro for this
|
||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
||||
__eq_buffer->motd[1023] = '\0';
|
||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case 36: { // raidPlayerNote unhandled
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||
|
||||
switch (rgs->action)
|
||||
{
|
||||
case raidSetMotd:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(motd);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(note);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
IN_str(leader_name);
|
||||
IN_str(player_name);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+152
-91
@@ -35,6 +35,7 @@
|
||||
#include "../path_manager.h"
|
||||
#include "../classes.h"
|
||||
#include "../races.h"
|
||||
#include "../raid.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -2677,88 +2678,124 @@ namespace RoF2
|
||||
|
||||
ENCODE(OP_RaidJoin)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
general->action = 8;
|
||||
general->parameter = 1;
|
||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
general->action = raidCreate;
|
||||
general->parameter = RaidCommandAcceptInvite;
|
||||
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
safe_delete(inapp);
|
||||
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
||||
switch (raid_gen->action)
|
||||
{
|
||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
||||
case raidAdd:
|
||||
{
|
||||
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
|
||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
||||
add_member->_class = in_add_member->_class;
|
||||
add_member->level = in_add_member->level;
|
||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
||||
add_member->flags[0] = in_add_member->flags[0];
|
||||
add_member->flags[1] = in_add_member->flags[1];
|
||||
add_member->flags[2] = in_add_member->flags[2];
|
||||
add_member->flags[3] = in_add_member->flags[3];
|
||||
add_member->flags[4] = in_add_member->flags[4];
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
else if (raid_gen->action == 35)
|
||||
{
|
||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
||||
strlen(inmotd->motd) + 1);
|
||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
||||
OUT(raidGen.action);
|
||||
OUT(raidGen.parameter);
|
||||
OUT_str(raidGen.leader_name);
|
||||
OUT_str(raidGen.player_name);
|
||||
OUT(_class);
|
||||
OUT(level);
|
||||
OUT(isGroupLeader);
|
||||
OUT(flags[0]);
|
||||
OUT(flags[1]);
|
||||
OUT(flags[2]);
|
||||
OUT(flags[3]);
|
||||
OUT(flags[4]);
|
||||
|
||||
outmotd->general.action = inmotd->general.action;
|
||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
||||
case raidSetMotd:
|
||||
{
|
||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
||||
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(motd);
|
||||
|
||||
outlaa->action = inlaa->action;
|
||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case raidSetLeaderAbilities:
|
||||
case raidMakeLeader:
|
||||
{
|
||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
||||
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT_str(player_name);
|
||||
OUT_str(leader_name);
|
||||
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(note);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidNoRaid:
|
||||
{
|
||||
dest->QueuePacket(inapp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
||||
raid_general->action = in_raid_general->action;
|
||||
raid_general->parameter = in_raid_general->parameter;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT(parameter);
|
||||
OUT_str(leader_name);
|
||||
OUT_str(player_name);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
@@ -2772,7 +2809,10 @@ namespace RoF2
|
||||
else
|
||||
eq->window = emu->window;
|
||||
OUT(type);
|
||||
OUT(invslot);
|
||||
eq->invslot = ServerToRoF2TypelessSlot(emu->invslot, invtype::typePossessions);
|
||||
OUT(target_id);
|
||||
OUT(can_cast);
|
||||
OUT(can_scribe);
|
||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -4398,6 +4438,17 @@ namespace RoF2
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_BookButton)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||
|
||||
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->slot, invtype::typePossessions));
|
||||
IN(target_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Buff)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||
@@ -5064,37 +5115,47 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
|
||||
// This is a switch on the RaidGeneral action
|
||||
switch (*(uint32 *)__packet->pBuffer) {
|
||||
case 35: { // raidMOTD
|
||||
// we don't have a nice macro for this
|
||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
||||
__eq_buffer->motd[1023] = '\0';
|
||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case 36: { // raidPlayerNote unhandled
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||
|
||||
switch (rgs->action)
|
||||
{
|
||||
case raidSetMotd:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(motd);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(note);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
IN_str(leader_name);
|
||||
IN_str(player_name);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5104,8 +5165,8 @@ namespace RoF2
|
||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||
|
||||
IN(type);
|
||||
IN(invslot);
|
||||
IN(subslot);
|
||||
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->invslot, invtype::typePossessions));
|
||||
IN(target_id);
|
||||
emu->window = (uint8)eq->window;
|
||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_BlockedBuffs)
|
||||
D(OP_BookButton)
|
||||
D(OP_Buff)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_CastSpell)
|
||||
|
||||
@@ -2868,15 +2868,23 @@ struct BookText_Struct {
|
||||
// This is just a "text file" on the server
|
||||
// or in our case, the 'name' column in our books table.
|
||||
struct BookRequest_Struct {
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint16 invslot; // Is the slot, but the RoF2 conversion causes it to fail. Turned to 0 since it isnt required anyway.
|
||||
/*0006*/ int16 subslot; // Inventory sub-slot (0-x)
|
||||
/*0008*/ uint16 unknown006; // Seen FFFF
|
||||
/*0010*/ uint16 unknown008; // seen 0000
|
||||
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0016*/ uint32 unknown0012;
|
||||
/*0020*/ uint16 unknown0016;
|
||||
/*0022*/ char txtfile[8194];
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ TypelessInventorySlot_Struct invslot; // book ItemIndex (with int16_t alignment padding)
|
||||
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0016*/ uint32 target_id; // client's target when using the book
|
||||
/*0020*/ uint8 can_cast; // show Cast Spell button in book window
|
||||
/*0021*/ uint8 can_scribe; // show Scribe button in book window
|
||||
/*0022*/ char txtfile[8194];
|
||||
/*8216*/
|
||||
};
|
||||
|
||||
// used by Scribe and CastSpell book buttons
|
||||
struct BookButton_Struct
|
||||
{
|
||||
/*0000*/ TypelessInventorySlot_Struct slot; // book ItemIndex (with int16_t alignment padding)
|
||||
/*0008*/ int32 target_id; // client's target when using the book button
|
||||
/*0012*/ int32 unused; // always 0 from button packets
|
||||
/*0016*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -4190,9 +4198,14 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char motd[1024];
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
|
||||
@@ -4136,9 +4136,14 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
|
||||
+151
-89
@@ -34,6 +34,7 @@
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
#include "../races.h"
|
||||
#include "../raid.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -1686,88 +1687,124 @@ namespace SoD
|
||||
|
||||
ENCODE(OP_RaidJoin)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
general->action = 8;
|
||||
general->parameter = 1;
|
||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
general->action = raidCreate;
|
||||
general->parameter = RaidCommandAcceptInvite;
|
||||
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
safe_delete(inapp);
|
||||
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
||||
switch (raid_gen->action)
|
||||
{
|
||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
||||
case raidAdd:
|
||||
{
|
||||
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
|
||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
||||
add_member->_class = in_add_member->_class;
|
||||
add_member->level = in_add_member->level;
|
||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
||||
add_member->flags[0] = in_add_member->flags[0];
|
||||
add_member->flags[1] = in_add_member->flags[1];
|
||||
add_member->flags[2] = in_add_member->flags[2];
|
||||
add_member->flags[3] = in_add_member->flags[3];
|
||||
add_member->flags[4] = in_add_member->flags[4];
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
else if (raid_gen->action == 35)
|
||||
{
|
||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
||||
strlen(inmotd->motd) + 1);
|
||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
||||
OUT(raidGen.action);
|
||||
OUT(raidGen.parameter);
|
||||
OUT_str(raidGen.leader_name);
|
||||
OUT_str(raidGen.player_name);
|
||||
OUT(_class);
|
||||
OUT(level);
|
||||
OUT(isGroupLeader);
|
||||
OUT(flags[0]);
|
||||
OUT(flags[1]);
|
||||
OUT(flags[2]);
|
||||
OUT(flags[3]);
|
||||
OUT(flags[4]);
|
||||
|
||||
outmotd->general.action = inmotd->general.action;
|
||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
||||
case raidSetMotd:
|
||||
{
|
||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
||||
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(motd);
|
||||
|
||||
outlaa->action = inlaa->action;
|
||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case raidSetLeaderAbilities:
|
||||
case raidMakeLeader:
|
||||
{
|
||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
||||
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT_str(player_name);
|
||||
OUT_str(leader_name);
|
||||
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(note);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidNoRaid:
|
||||
{
|
||||
dest->QueuePacket(inapp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
||||
raid_general->action = in_raid_general->action;
|
||||
raid_general->parameter = in_raid_general->parameter;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT(parameter);
|
||||
OUT_str(leader_name);
|
||||
OUT_str(player_name);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
@@ -1782,6 +1819,9 @@ namespace SoD
|
||||
eq->window = emu->window;
|
||||
OUT(type);
|
||||
eq->invslot = ServerToSoDSlot(emu->invslot);
|
||||
OUT(target_id);
|
||||
OUT(can_cast);
|
||||
OUT(can_scribe);
|
||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -2817,6 +2857,17 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_BookButton)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||
|
||||
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
|
||||
IN(target_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Buff)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||
@@ -3324,37 +3375,47 @@ namespace SoD
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
|
||||
// This is a switch on the RaidGeneral action
|
||||
switch (*(uint32 *)__packet->pBuffer) {
|
||||
case 35: { // raidMOTD
|
||||
// we don't have a nice macro for this
|
||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
||||
__eq_buffer->motd[1023] = '\0';
|
||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case 36: { // raidPlayerNote unhandled
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||
|
||||
switch (rgs->action)
|
||||
{
|
||||
case raidSetMotd:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(motd);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(note);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
IN_str(leader_name);
|
||||
IN_str(player_name);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3364,7 +3425,8 @@ namespace SoD
|
||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||
|
||||
IN(type);
|
||||
emu->invslot = SoDToServerSlot(eq->invslot);
|
||||
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
|
||||
IN(target_id);
|
||||
emu->window = (uint8)eq->window;
|
||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_BookButton)
|
||||
D(OP_Buff)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
|
||||
@@ -2351,12 +2351,21 @@ struct BookText_Struct {
|
||||
// This is just a "text file" on the server
|
||||
// or in our case, the 'name' column in our books table.
|
||||
struct BookRequest_Struct {
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0012*/ uint32 unknown0012;
|
||||
/*0016*/ uint16 unknown0016;
|
||||
/*0018*/ char txtfile[8194];
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0012*/ uint32 target_id;
|
||||
/*0016*/ uint8 can_cast;
|
||||
/*0017*/ uint8 can_scribe;
|
||||
/*0018*/ char txtfile[8194];
|
||||
};
|
||||
|
||||
// used by Scribe and CastSpell book buttons
|
||||
struct BookButton_Struct
|
||||
{
|
||||
/*0000*/ int32 invslot;
|
||||
/*0004*/ int32 target_id; // client's target when using the book
|
||||
/*0008*/ int32 unused; // always 0 from button packets
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3583,9 +3592,14 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
|
||||
+151
-89
@@ -33,6 +33,7 @@
|
||||
#include "sof_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
#include "../raid.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -1356,88 +1357,124 @@ namespace SoF
|
||||
|
||||
ENCODE(OP_RaidJoin)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
general->action = 8;
|
||||
general->parameter = 1;
|
||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
general->action = raidCreate;
|
||||
general->parameter = RaidCommandAcceptInvite;
|
||||
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
safe_delete(inapp);
|
||||
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
||||
switch (raid_gen->action)
|
||||
{
|
||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
||||
case raidAdd:
|
||||
{
|
||||
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
|
||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
||||
add_member->_class = in_add_member->_class;
|
||||
add_member->level = in_add_member->level;
|
||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
||||
add_member->flags[0] = in_add_member->flags[0];
|
||||
add_member->flags[1] = in_add_member->flags[1];
|
||||
add_member->flags[2] = in_add_member->flags[2];
|
||||
add_member->flags[3] = in_add_member->flags[3];
|
||||
add_member->flags[4] = in_add_member->flags[4];
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
else if (raid_gen->action == 35)
|
||||
{
|
||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
||||
strlen(inmotd->motd) + 1);
|
||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
||||
OUT(raidGen.action);
|
||||
OUT(raidGen.parameter);
|
||||
OUT_str(raidGen.leader_name);
|
||||
OUT_str(raidGen.player_name);
|
||||
OUT(_class);
|
||||
OUT(level);
|
||||
OUT(isGroupLeader);
|
||||
OUT(flags[0]);
|
||||
OUT(flags[1]);
|
||||
OUT(flags[2]);
|
||||
OUT(flags[3]);
|
||||
OUT(flags[4]);
|
||||
|
||||
outmotd->general.action = inmotd->general.action;
|
||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
||||
case raidSetMotd:
|
||||
{
|
||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
||||
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(motd);
|
||||
|
||||
outlaa->action = inlaa->action;
|
||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case raidSetLeaderAbilities:
|
||||
case raidMakeLeader:
|
||||
{
|
||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
||||
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT_str(player_name);
|
||||
OUT_str(leader_name);
|
||||
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(note);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidNoRaid:
|
||||
{
|
||||
dest->QueuePacket(inapp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
||||
raid_general->action = in_raid_general->action;
|
||||
raid_general->parameter = in_raid_general->parameter;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT(parameter);
|
||||
OUT_str(leader_name);
|
||||
OUT_str(player_name);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
@@ -1452,6 +1489,9 @@ namespace SoF
|
||||
eq->window = emu->window;
|
||||
OUT(type);
|
||||
eq->invslot = ServerToSoFSlot(emu->invslot);
|
||||
OUT(target_id);
|
||||
OUT(can_cast);
|
||||
OUT(can_scribe);
|
||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -2261,6 +2301,17 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_BookButton)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||
|
||||
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
|
||||
IN(target_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Buff)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||
@@ -2729,37 +2780,47 @@ namespace SoF
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
|
||||
// This is a switch on the RaidGeneral action
|
||||
switch (*(uint32 *)__packet->pBuffer) {
|
||||
case 35: { // raidMOTD
|
||||
// we don't have a nice macro for this
|
||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
||||
__eq_buffer->motd[1023] = '\0';
|
||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case 36: { // raidPlayerNote unhandled
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||
|
||||
switch (rgs->action)
|
||||
{
|
||||
case raidSetMotd:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(motd);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(note);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
IN_str(leader_name);
|
||||
IN_str(player_name);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2769,7 +2830,8 @@ namespace SoF
|
||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||
|
||||
IN(type);
|
||||
emu->invslot = SoFToServerSlot(eq->invslot);
|
||||
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
|
||||
IN(target_id);
|
||||
emu->window = (uint8)eq->window;
|
||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ D(OP_AltCurrencySellSelection)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BookButton)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
|
||||
@@ -2321,12 +2321,21 @@ struct BookText_Struct {
|
||||
// This is just a "text file" on the server
|
||||
// or in our case, the 'name' column in our books table.
|
||||
struct BookRequest_Struct {
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0012*/ uint32 unknown0012;
|
||||
/*0016*/ uint16 unknown0016;
|
||||
/*0018*/ char txtfile[8194];
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0012*/ uint32 target_id;
|
||||
/*0016*/ uint8 can_cast;
|
||||
/*0017*/ uint8 can_scribe;
|
||||
/*0018*/ char txtfile[8194];
|
||||
};
|
||||
|
||||
// used by Scribe and CastSpell book buttons
|
||||
struct BookButton_Struct
|
||||
{
|
||||
/*0000*/ int32 invslot;
|
||||
/*0004*/ int32 target_id; // client's target when using the book
|
||||
/*0008*/ int32 unused; // always 0 from button packets
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3508,9 +3517,14 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
|
||||
@@ -128,6 +128,15 @@
|
||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||
|
||||
#define SETUP_VAR_DECODE(emu_struct, eq_struct, var_field) \
|
||||
unsigned char *__eq_buffer = __packet->pBuffer; \
|
||||
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
||||
auto size = strlen(in->var_field); \
|
||||
__packet->size = sizeof(emu_struct) + size + 1; \
|
||||
__packet->pBuffer = new unsigned char[__packet->size]; \
|
||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||
|
||||
#define MEMSET_IN(emu_struct) \
|
||||
memset(__packet->pBuffer, 0, sizeof(emu_struct));
|
||||
|
||||
@@ -146,6 +155,9 @@
|
||||
delete[] __eq_buffer; \
|
||||
p->SetOpcode(OP_Unknown);
|
||||
|
||||
#define FINISH_VAR_DECODE() \
|
||||
delete[] __eq_buffer;
|
||||
|
||||
//call to finish an encoder using SETUP_DIRECT_DECODE
|
||||
#define FINISH_DIRECT_DECODE() \
|
||||
delete[] __eq_buffer;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "../item_instance.h"
|
||||
#include "titanium_structs.h"
|
||||
#include "../path_manager.h"
|
||||
#include "../raid.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@@ -1245,6 +1246,119 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_MarkRaidNPC)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MarkNPC_Struct);
|
||||
SETUP_DIRECT_ENCODE(MarkNPC_Struct, MarkNPC_Struct);
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
|
||||
mnpcs->TargetID = emu->TargetID;
|
||||
mnpcs->Number = emu->Number;
|
||||
dest->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
{
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
switch (raid_gen->action)
|
||||
{
|
||||
case raidAdd:
|
||||
{
|
||||
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(raidGen.action);
|
||||
OUT(raidGen.parameter);
|
||||
OUT_str(raidGen.leader_name);
|
||||
OUT_str(raidGen.player_name);
|
||||
OUT(_class);
|
||||
OUT(level);
|
||||
OUT(isGroupLeader);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
|
||||
}
|
||||
case raidSetMotd:
|
||||
{
|
||||
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(motd);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetLeaderAbilities:
|
||||
case raidMakeLeader:
|
||||
{
|
||||
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT_str(player_name);
|
||||
OUT_str(leader_name);
|
||||
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(note);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidNoRaid:
|
||||
{
|
||||
dest->QueuePacket(inapp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT(parameter);
|
||||
OUT_str(leader_name);
|
||||
OUT_str(player_name);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
{
|
||||
// no apparent slot translation needed
|
||||
@@ -2272,6 +2386,63 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_RaidInvite)
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||
|
||||
switch (rgs->action)
|
||||
{
|
||||
case raidSetMotd:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
|
||||
auto len = 0;
|
||||
if (__packet->size < sizeof(structs::RaidMOTD_Struct)) {
|
||||
len = __packet->size - sizeof(structs::RaidGeneral_Struct);
|
||||
}
|
||||
else {
|
||||
len = sizeof(eq->motd);
|
||||
}
|
||||
|
||||
strn0cpy(emu->motd, eq->motd, len > 1024 ? 1024 : len);
|
||||
emu->motd[len - 1] = '\0';
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(note);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
IN_str(leader_name);
|
||||
IN_str(player_name);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_ReadBook)
|
||||
{
|
||||
// no apparent slot translation needed
|
||||
|
||||
@@ -61,6 +61,8 @@ E(OP_OnLevelMessage)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_MarkRaidNPC)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_ReadBook)
|
||||
E(OP_RespondAA)
|
||||
E(OP_SendCharInfo)
|
||||
@@ -106,6 +108,7 @@ D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
|
||||
@@ -3017,23 +3017,39 @@ struct leadExpUpdateStruct {
|
||||
/*0028*/ uint32 unknown0028;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct RaidGeneral_Struct {
|
||||
/*00*/ uint32 action; //=10
|
||||
/*04*/ char player_name[64]; //should both be the player's name
|
||||
/*04*/ char leader_name[64];
|
||||
/*000*/ uint32 action; //=10
|
||||
/*004*/ char player_name[64]; //should both be the player's name
|
||||
/*068*/ char leader_name[64];
|
||||
/*132*/ uint32 parameter;
|
||||
};
|
||||
|
||||
struct RaidAdd_Struct {
|
||||
/*000*/ uint32 action; //=0
|
||||
/*004*/ char player_name[64]; //should both be the player's name
|
||||
/*068*/ char leader_name[64];
|
||||
/*132*/ uint8 _class;
|
||||
/*133*/ uint8 level;
|
||||
/*134*/ uint8 has_group;
|
||||
/*135*/ uint8 unknown135; //seems to be 0x42 or 0
|
||||
struct RaidAddMember_Struct {
|
||||
/*000*/ RaidGeneral_Struct raidGen;
|
||||
/*136*/ uint8 _class;
|
||||
/*137*/ uint8 level;
|
||||
/*138*/ uint8 isGroupLeader;
|
||||
/*139*/ uint8 unknown139; //seems to be 0x42 or 0
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*136*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*136*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ char player_name[64];
|
||||
// /*068*/ uint32 Unknown068;
|
||||
/*072*/ char leader_name[64];
|
||||
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||
/*200*/ RaidLeadershipAA_Struct raid;
|
||||
/*264*/ char Unknown264[128];
|
||||
};
|
||||
|
||||
struct RaidCreate_Struct {
|
||||
|
||||
+151
-90
@@ -35,6 +35,7 @@
|
||||
#include "../path_manager.h"
|
||||
#include "../classes.h"
|
||||
#include "../races.h"
|
||||
#include "../raid.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -1931,88 +1932,124 @@ namespace UF
|
||||
|
||||
ENCODE(OP_RaidJoin)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
general->action = 8;
|
||||
general->parameter = 1;
|
||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
||||
general->action = raidCreate;
|
||||
general->parameter = RaidCommandAcceptInvite;
|
||||
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
safe_delete(inapp);
|
||||
|
||||
}
|
||||
|
||||
ENCODE(OP_RaidUpdate)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
EQApplicationPacket* inapp = *p;
|
||||
*p = nullptr;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
||||
switch (raid_gen->action)
|
||||
{
|
||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
||||
case raidAdd:
|
||||
{
|
||||
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||
|
||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
||||
add_member->_class = in_add_member->_class;
|
||||
add_member->level = in_add_member->level;
|
||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
||||
add_member->flags[0] = in_add_member->flags[0];
|
||||
add_member->flags[1] = in_add_member->flags[1];
|
||||
add_member->flags[2] = in_add_member->flags[2];
|
||||
add_member->flags[3] = in_add_member->flags[3];
|
||||
add_member->flags[4] = in_add_member->flags[4];
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
else if (raid_gen->action == 35)
|
||||
{
|
||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
||||
strlen(inmotd->motd) + 1);
|
||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
||||
OUT(raidGen.action);
|
||||
OUT(raidGen.parameter);
|
||||
OUT_str(raidGen.leader_name);
|
||||
OUT_str(raidGen.player_name);
|
||||
OUT(_class);
|
||||
OUT(level);
|
||||
OUT(isGroupLeader);
|
||||
OUT(flags[0]);
|
||||
OUT(flags[1]);
|
||||
OUT(flags[2]);
|
||||
OUT(flags[3]);
|
||||
OUT(flags[4]);
|
||||
|
||||
outmotd->general.action = inmotd->general.action;
|
||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
||||
case raidSetMotd:
|
||||
{
|
||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
||||
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(motd);
|
||||
|
||||
outlaa->action = inlaa->action;
|
||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case raidSetLeaderAbilities:
|
||||
case raidMakeLeader:
|
||||
{
|
||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
||||
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT_str(player_name);
|
||||
OUT_str(leader_name);
|
||||
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(general.action);
|
||||
OUT_str(general.leader_name);
|
||||
OUT_str(general.player_name);
|
||||
OUT_str(note);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
case raidNoRaid:
|
||||
{
|
||||
dest->QueuePacket(inapp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
||||
raid_general->action = in_raid_general->action;
|
||||
raid_general->parameter = in_raid_general->parameter;
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||
|
||||
OUT(action);
|
||||
OUT(parameter);
|
||||
OUT_str(leader_name);
|
||||
OUT_str(player_name);
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
safe_delete(inapp);
|
||||
}
|
||||
|
||||
@@ -2027,6 +2064,9 @@ namespace UF
|
||||
eq->window = emu->window;
|
||||
OUT(type);
|
||||
eq->invslot = ServerToUFSlot(emu->invslot);
|
||||
OUT(target_id);
|
||||
OUT(can_cast);
|
||||
OUT(can_scribe);
|
||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -3105,6 +3145,17 @@ namespace UF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_BookButton)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||
|
||||
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
|
||||
IN(target_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Buff)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||
@@ -3623,39 +3674,48 @@ namespace UF
|
||||
{
|
||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||
|
||||
// This is a switch on the RaidGeneral action
|
||||
switch (*(uint32 *)__packet->pBuffer) {
|
||||
case 35: { // raidMOTD
|
||||
// we don't have a nice macro for this
|
||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
||||
__eq_buffer->motd[1023] = '\0';
|
||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
||||
__packet->pBuffer = new unsigned char[__packet->size];
|
||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case 36: { // raidPlayerNote unhandled
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||
|
||||
switch (rgs->action)
|
||||
{
|
||||
case raidSetMotd:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(motd);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
case raidSetNote:
|
||||
{
|
||||
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||
|
||||
IN(general.action);
|
||||
IN(general.parameter);
|
||||
IN_str(general.leader_name);
|
||||
IN_str(general.player_name);
|
||||
IN_str(note);
|
||||
|
||||
FINISH_VAR_DECODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||
IN(action);
|
||||
IN(parameter);
|
||||
IN_str(leader_name);
|
||||
IN_str(player_name);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_ReadBook)
|
||||
@@ -3664,7 +3724,8 @@ namespace UF
|
||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||
|
||||
IN(type);
|
||||
emu->invslot = UFToServerSlot(eq->invslot);
|
||||
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
|
||||
IN(target_id);
|
||||
emu->window = (uint8)eq->window;
|
||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_BookButton)
|
||||
D(OP_Buff)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_CastSpell)
|
||||
|
||||
@@ -2400,12 +2400,21 @@ struct BookText_Struct {
|
||||
// This is just a "text file" on the server
|
||||
// or in our case, the 'name' column in our books table.
|
||||
struct BookRequest_Struct {
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0012*/ uint32 unknown0012;
|
||||
/*0016*/ uint16 unknown0016;
|
||||
/*0018*/ char txtfile[8194];
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0012*/ uint32 target_id;
|
||||
/*0016*/ uint8 can_cast;
|
||||
/*0017*/ uint8 can_scribe;
|
||||
/*0018*/ char txtfile[8194];
|
||||
};
|
||||
|
||||
// used by Scribe and CastSpell book buttons
|
||||
struct BookButton_Struct
|
||||
{
|
||||
/*0000*/ int32 invslot;
|
||||
/*0004*/ int32 target_id; // client's target when using the book
|
||||
/*0008*/ int32 unused; // always 0 from button packets
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3638,9 +3647,14 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char motd[1024];
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
|
||||
@@ -72,6 +72,8 @@ std::string GetPlatformName()
|
||||
return "HC";
|
||||
case EQEmuExePlatform::ExePlatformTests:
|
||||
return "Tests";
|
||||
case EQEmuExePlatform::ExePlatformZoneSidecar:
|
||||
return "ZoneSidecar";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
+2
-1
@@ -37,7 +37,8 @@ enum EQEmuExePlatform
|
||||
ExePlatformClientImport,
|
||||
ExePlatformClientExport,
|
||||
ExePlatformHC,
|
||||
ExePlatformTests
|
||||
ExePlatformTests,
|
||||
ExePlatformZoneSidecar
|
||||
};
|
||||
|
||||
void RegisterExecutablePlatform(EQEmuExePlatform p);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include "process.h"
|
||||
|
||||
inline std::string random_string(size_t length)
|
||||
{
|
||||
auto randchar = []() -> char {
|
||||
const char charset[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
|
||||
const size_t max_index = (sizeof(charset) - 1);
|
||||
return charset[static_cast<size_t>(std::rand()) % max_index];
|
||||
};
|
||||
std::string str(length, 0);
|
||||
std::generate_n(str.begin(), length, randchar);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string Process::execute(const std::string &cmd, bool return_result)
|
||||
{
|
||||
std::string random = "/tmp/" + random_string(25);
|
||||
const char *file_name = random.c_str();
|
||||
|
||||
if (return_result) {
|
||||
#ifdef _WINDOWS
|
||||
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||
#else
|
||||
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
std::system((cmd).c_str());
|
||||
}
|
||||
|
||||
std::string result;
|
||||
|
||||
if (return_result) {
|
||||
std::ifstream file(file_name);
|
||||
result = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
|
||||
std::remove(file_name);
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef EQEMU_PROCESS_H
|
||||
#define EQEMU_PROCESS_H
|
||||
|
||||
class Process {
|
||||
public:
|
||||
static std::string execute(const std::string &cmd, bool return_result = true);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_PROCESS_H
|
||||
+64
-7
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "../common/races.h"
|
||||
#include "data_verification.h"
|
||||
|
||||
const char* GetRaceIDName(uint16 race_id)
|
||||
{
|
||||
@@ -67,7 +68,7 @@ const char* GetRaceIDName(uint16 race_id)
|
||||
// return "Froglok";
|
||||
//case DRAKKIN:
|
||||
// return "Drakkin";
|
||||
|
||||
|
||||
// RoF2 Race Labels
|
||||
case RT_ABHORRENT:
|
||||
return "Abhorrent";
|
||||
@@ -1593,11 +1594,13 @@ float GetRaceGenderDefaultHeight(int race, int gender)
|
||||
|
||||
const auto size = sizeof(male_height) / sizeof(male_height[0]);
|
||||
|
||||
if (race >= size)
|
||||
if (race >= size) {
|
||||
return 6.0f;
|
||||
}
|
||||
|
||||
if (gender == 1)
|
||||
if (gender == FEMALE) {
|
||||
return female_height[race];
|
||||
}
|
||||
|
||||
return male_height[race];
|
||||
}
|
||||
@@ -1696,7 +1699,7 @@ bool PlayerAppearance::IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8
|
||||
{
|
||||
if (beard_color_value == 0xFF)
|
||||
return true;
|
||||
|
||||
|
||||
switch (BINDRG(race_id, gender_id)) {
|
||||
case GNOME_MALE:
|
||||
if (beard_color_value <= 24)
|
||||
@@ -1783,7 +1786,7 @@ bool PlayerAppearance::IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 ey
|
||||
case VAHSHIR_FEMALE:
|
||||
if (eye_color_value <= 9)
|
||||
return true;
|
||||
break;
|
||||
break;
|
||||
case TROLL_MALE:
|
||||
case TROLL_FEMALE:
|
||||
if (eye_color_value <= 10)
|
||||
@@ -2109,7 +2112,7 @@ bool PlayerAppearance::IsValidTexture(uint16 race_id, uint8 gender_id, uint8 tex
|
||||
{
|
||||
if (texture_value == 0xFF)
|
||||
return true;
|
||||
|
||||
|
||||
if (use_luclin) {
|
||||
switch (BINDRG(race_id, gender_id)) {
|
||||
case HUMAN_MALE:
|
||||
@@ -2243,4 +2246,58 @@ const char* GetGenderName(uint32 gender_id) {
|
||||
gender_name = "Neuter";
|
||||
}
|
||||
return gender_name;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string GetPlayerRaceAbbreviation(uint16 race_id)
|
||||
{
|
||||
if (!IsPlayerRace(race_id)) {
|
||||
return std::string("UNK");
|
||||
}
|
||||
|
||||
switch (race_id) {
|
||||
case RACE_HUMAN_1:
|
||||
return "HUM";
|
||||
case RACE_BARBARIAN_2:
|
||||
return "BAR";
|
||||
case RACE_ERUDITE_3:
|
||||
return "ERU";
|
||||
case RACE_WOOD_ELF_4:
|
||||
return "ELF";
|
||||
case RACE_HIGH_ELF_5:
|
||||
return "HIE";
|
||||
case RACE_DARK_ELF_6:
|
||||
return "DEF";
|
||||
case RACE_HALF_ELF_7:
|
||||
return "HEF";
|
||||
case RACE_DWARF_8:
|
||||
return "DWF";
|
||||
case RACE_TROLL_9:
|
||||
return "TRL";
|
||||
case RACE_OGRE_10:
|
||||
return "OGR";
|
||||
case RACE_HALFLING_11:
|
||||
return "HFL";
|
||||
case RACE_GNOME_12:
|
||||
return "GNM";
|
||||
case RACE_IKSAR_128:
|
||||
return "IKS";
|
||||
case RACE_VAH_SHIR_130:
|
||||
return "VAH";
|
||||
case RACE_FROGLOK_330:
|
||||
return "FRG";
|
||||
case RACE_DRAKKIN_522:
|
||||
return "DRK";
|
||||
}
|
||||
|
||||
return std::string("UNK");
|
||||
}
|
||||
|
||||
bool IsPlayerRace(uint16 race_id) {
|
||||
return (
|
||||
EQ::ValueWithin(race_id, RACE_HUMAN_1, RACE_GNOME_12) ||
|
||||
race_id == RACE_IKSAR_128 ||
|
||||
race_id == RACE_VAH_SHIR_130 ||
|
||||
race_id == RACE_FROGLOK_330 ||
|
||||
race_id == RACE_DRAKKIN_522
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef RACES_H
|
||||
#define RACES_H
|
||||
#include "../common/types.h"
|
||||
#include <string>
|
||||
|
||||
#define MALE 0
|
||||
#define FEMALE 1
|
||||
@@ -853,6 +854,9 @@ const char* GetRaceIDName(uint16 race_id);
|
||||
const char* GetPlayerRaceName(uint32 player_race_value);
|
||||
const char* GetGenderName(uint32 gender_id);
|
||||
|
||||
bool IsPlayerRace(uint16 race_id);
|
||||
const std::string GetPlayerRaceAbbreviation(uint16 race_id);
|
||||
|
||||
uint32 GetPlayerRaceValue(uint16 race_id);
|
||||
uint32 GetPlayerRaceBit(uint16 race_id);
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef RAID_H
|
||||
#define RAID_H
|
||||
|
||||
enum { //raid packet types:
|
||||
raidAdd = 0,
|
||||
raidRemove2 = 1, //parameter=0
|
||||
raidMemberNameChange = 2,
|
||||
raidRemove1 = 3, //parameter=0xFFFFFFFF
|
||||
raidNoLongerLeader = 4,
|
||||
raidDisband = 5,
|
||||
raidMembers = 6, //len 395+, details + members list
|
||||
raidNoAssignLeadership = 7,
|
||||
raidCreate = 8, //len 72
|
||||
raidUnknown = 9, // unused?
|
||||
raidNoRaid = 10, //parameter=0
|
||||
raidChangeLootType = 11,
|
||||
raidStringID = 12,
|
||||
raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id?
|
||||
raidSetLeaderAbilities = 14, //472
|
||||
raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general
|
||||
raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2)
|
||||
raidLock = 17, //len 136 leader?, leader, 0
|
||||
raidUnlock = 18, //len 136 leader?, leader, 0
|
||||
raidRedStringID = 19,
|
||||
raidSetLeader = 20, //len 388, contains 'details' struct without members; also used for "invite to raid"
|
||||
raidMakeLeader = 30,
|
||||
raidSetMotd = 35,
|
||||
raidSetNote = 36,
|
||||
};
|
||||
|
||||
|
||||
enum { //raid command types
|
||||
RaidCommandInviteIntoExisting = 0, //in use
|
||||
RaidCommandAcceptInvite = 1, //in use
|
||||
RaidCommandInvite = 3, //in use
|
||||
RaidCommandDisband = 5, //in use
|
||||
RaidCommandMoveGroup = 6, //in use
|
||||
RaidCommandRemoveGroupLeader = 7,
|
||||
RaidCommandRaidLock = 8, //in use
|
||||
RaidCommandRaidUnlock = 9, //in use
|
||||
RaidCommandLootType = 20, //in use
|
||||
RaidCommandAddLooter = 21, //in use
|
||||
RaidCommandRemoveLooter = 22, //in use
|
||||
RaidCommandMakeLeader = 30,
|
||||
RaidCommandInviteFail = 31, //already in raid, waiting on invite from other raid, etc
|
||||
RaidCommandLootType2 = 32, //in use
|
||||
RaidCommandAddLooter2 = 33, //in use
|
||||
RaidCommandRemoveLooter2 = 34, //in use
|
||||
RaidCommandSetMotd = 35,
|
||||
RaidCommandSetNote = 36,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -44,7 +44,35 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static void ClearFlag(
|
||||
Database& db,
|
||||
AccountFlagsRepository::AccountFlags e
|
||||
) {
|
||||
AccountFlagsRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"p_accid = {} AND p_flag = '{}'",
|
||||
e.p_accid,
|
||||
Strings::Escape(e.p_flag)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static void ReplaceFlag(
|
||||
Database& db,
|
||||
AccountFlagsRepository::AccountFlags e
|
||||
) {
|
||||
db.QueryDatabase(
|
||||
fmt::format(
|
||||
"REPLACE INTO {} ({}) VALUES ({}, '{}', '{}')",
|
||||
TableName(),
|
||||
ColumnsRaw(),
|
||||
e.p_accid,
|
||||
Strings::Escape(e.p_flag),
|
||||
Strings::Escape(e.p_value)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_ACCOUNT_FLAGS_REPOSITORY_H
|
||||
|
||||
@@ -0,0 +1,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_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||
#define EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseBotStartingItemsRepository {
|
||||
public:
|
||||
struct BotStartingItems {
|
||||
uint32_t id;
|
||||
uint32_t races;
|
||||
uint32_t classes;
|
||||
uint32_t item_id;
|
||||
uint8_t item_charges;
|
||||
int32_t slot_id;
|
||||
int8_t min_expansion;
|
||||
int8_t max_expansion;
|
||||
std::string content_flags;
|
||||
std::string content_flags_disabled;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"races",
|
||||
"classes",
|
||||
"item_id",
|
||||
"item_charges",
|
||||
"slot_id",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
"content_flags",
|
||||
"content_flags_disabled",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"races",
|
||||
"classes",
|
||||
"item_id",
|
||||
"item_charges",
|
||||
"slot_id",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
"content_flags",
|
||||
"content_flags_disabled",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string SelectColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("bot_starting_items");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
SelectColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static BotStartingItems NewEntity()
|
||||
{
|
||||
BotStartingItems e{};
|
||||
|
||||
e.id = 0;
|
||||
e.races = 0;
|
||||
e.classes = 0;
|
||||
e.item_id = 0;
|
||||
e.item_charges = 1;
|
||||
e.slot_id = -1;
|
||||
e.min_expansion = -1;
|
||||
e.max_expansion = -1;
|
||||
e.content_flags = "";
|
||||
e.content_flags_disabled = "";
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static BotStartingItems GetBotStartingItems(
|
||||
const std::vector<BotStartingItems> &bot_starting_itemss,
|
||||
int bot_starting_items_id
|
||||
)
|
||||
{
|
||||
for (auto &bot_starting_items : bot_starting_itemss) {
|
||||
if (bot_starting_items.id == bot_starting_items_id) {
|
||||
return bot_starting_items;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static BotStartingItems FindOne(
|
||||
Database& db,
|
||||
int bot_starting_items_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
bot_starting_items_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
BotStartingItems e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||
e.slot_id = static_cast<int32_t>(atoi(row[5]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||
e.content_flags = row[8] ? row[8] : "";
|
||||
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int bot_starting_items_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
bot_starting_items_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const BotStartingItems &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.races));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.classes));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.item_charges));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.slot_id));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[9] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static BotStartingItems InsertOne(
|
||||
Database& db,
|
||||
BotStartingItems e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.races));
|
||||
v.push_back(std::to_string(e.classes));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
v.push_back(std::to_string(e.item_charges));
|
||||
v.push_back(std::to_string(e.slot_id));
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
|
||||
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<BotStartingItems> &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.races));
|
||||
v.push_back(std::to_string(e.classes));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
v.push_back(std::to_string(e.item_charges));
|
||||
v.push_back(std::to_string(e.slot_id));
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
|
||||
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<BotStartingItems> All(Database& db)
|
||||
{
|
||||
std::vector<BotStartingItems> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
BotStartingItems e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||
e.slot_id = static_cast<int32_t>(atoi(row[5]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||
e.content_flags = row[8] ? row[8] : "";
|
||||
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<BotStartingItems> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<BotStartingItems> 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) {
|
||||
BotStartingItems e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||
e.slot_id = static_cast<int32_t>(atoi(row[5]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||
e.content_flags = row[8] ? row[8] : "";
|
||||
e.content_flags_disabled = row[9] ? 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_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,354 @@
|
||||
/**
|
||||
* DO NOT MODIFY THIS FILE
|
||||
*
|
||||
* This repository was automatically generated and is NOT to be modified directly.
|
||||
* Any repository modifications are meant to be made to the repository extending the base.
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
|
||||
#define EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseCharacterTributeRepository {
|
||||
public:
|
||||
struct CharacterTribute {
|
||||
int32_t id;
|
||||
uint32_t character_id;
|
||||
uint8_t tier;
|
||||
uint32_t tribute;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"character_id",
|
||||
"tier",
|
||||
"tribute",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"character_id",
|
||||
"tier",
|
||||
"tribute",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string SelectColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("character_tribute");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
SelectColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static CharacterTribute NewEntity()
|
||||
{
|
||||
CharacterTribute e{};
|
||||
|
||||
e.id = 0;
|
||||
e.character_id = 0;
|
||||
e.tier = 0;
|
||||
e.tribute = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static CharacterTribute GetCharacterTribute(
|
||||
const std::vector<CharacterTribute> &character_tributes,
|
||||
int character_tribute_id
|
||||
)
|
||||
{
|
||||
for (auto &character_tribute : character_tributes) {
|
||||
if (character_tribute.id == character_tribute_id) {
|
||||
return character_tribute;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static CharacterTribute FindOne(
|
||||
Database& db,
|
||||
int character_tribute_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
character_tribute_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
CharacterTribute e{};
|
||||
|
||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
||||
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
|
||||
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int character_tribute_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
character_tribute_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const CharacterTribute &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.character_id));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.tier));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.tribute));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static CharacterTribute InsertOne(
|
||||
Database& db,
|
||||
CharacterTribute e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.tier));
|
||||
v.push_back(std::to_string(e.tribute));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
e = NewEntity();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static int InsertMany(
|
||||
Database& db,
|
||||
const std::vector<CharacterTribute> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.tier));
|
||||
v.push_back(std::to_string(e.tribute));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static std::vector<CharacterTribute> All(Database& db)
|
||||
{
|
||||
std::vector<CharacterTribute> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterTribute e{};
|
||||
|
||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
||||
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
|
||||
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<CharacterTribute> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<CharacterTribute> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {}",
|
||||
BaseSelect(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterTribute e{};
|
||||
|
||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
||||
e.character_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||
e.tier = static_cast<uint8_t>(strtoul(row[2], nullptr, 10));
|
||||
e.tribute = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {}",
|
||||
TableName(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int Truncate(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"TRUNCATE TABLE {}",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int64 GetMaxId(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||
PrimaryKey(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COUNT(*) FROM {} {}",
|
||||
TableName(),
|
||||
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_CHARACTER_TRIBUTE_REPOSITORY_H
|
||||
@@ -0,0 +1,364 @@
|
||||
/**
|
||||
* DO NOT MODIFY THIS FILE
|
||||
*
|
||||
* This repository was automatically generated and is NOT to be modified directly.
|
||||
* Any repository modifications are meant to be made to the repository extending the base.
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H
|
||||
#define EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseCommandSubsettingsRepository {
|
||||
public:
|
||||
struct CommandSubsettings {
|
||||
uint32_t id;
|
||||
std::string parent_command;
|
||||
std::string sub_command;
|
||||
uint32_t access_level;
|
||||
std::string top_level_aliases;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"parent_command",
|
||||
"sub_command",
|
||||
"access_level",
|
||||
"top_level_aliases",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"parent_command",
|
||||
"sub_command",
|
||||
"access_level",
|
||||
"top_level_aliases",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string SelectColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("command_subsettings");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
SelectColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static CommandSubsettings NewEntity()
|
||||
{
|
||||
CommandSubsettings e{};
|
||||
|
||||
e.id = 0;
|
||||
e.parent_command = "";
|
||||
e.sub_command = "";
|
||||
e.access_level = 0;
|
||||
e.top_level_aliases = "";
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static CommandSubsettings GetCommandSubsettings(
|
||||
const std::vector<CommandSubsettings> &command_subsettingss,
|
||||
int command_subsettings_id
|
||||
)
|
||||
{
|
||||
for (auto &command_subsettings : command_subsettingss) {
|
||||
if (command_subsettings.id == command_subsettings_id) {
|
||||
return command_subsettings;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static CommandSubsettings FindOne(
|
||||
Database& db,
|
||||
int command_subsettings_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
command_subsettings_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
CommandSubsettings e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.parent_command = row[1] ? row[1] : "";
|
||||
e.sub_command = row[2] ? row[2] : "";
|
||||
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.top_level_aliases = row[4] ? row[4] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int command_subsettings_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
command_subsettings_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const CommandSubsettings &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.parent_command) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.sub_command) + "'");
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.access_level));
|
||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.top_level_aliases) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static CommandSubsettings InsertOne(
|
||||
Database& db,
|
||||
CommandSubsettings e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.parent_command) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.sub_command) + "'");
|
||||
v.push_back(std::to_string(e.access_level));
|
||||
v.push_back("'" + Strings::Escape(e.top_level_aliases) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
e = NewEntity();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static int InsertMany(
|
||||
Database& db,
|
||||
const std::vector<CommandSubsettings> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.parent_command) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.sub_command) + "'");
|
||||
v.push_back(std::to_string(e.access_level));
|
||||
v.push_back("'" + Strings::Escape(e.top_level_aliases) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static std::vector<CommandSubsettings> All(Database& db)
|
||||
{
|
||||
std::vector<CommandSubsettings> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CommandSubsettings e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.parent_command = row[1] ? row[1] : "";
|
||||
e.sub_command = row[2] ? row[2] : "";
|
||||
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.top_level_aliases = row[4] ? row[4] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<CommandSubsettings> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<CommandSubsettings> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {}",
|
||||
BaseSelect(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CommandSubsettings e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.parent_command = row[1] ? row[1] : "";
|
||||
e.sub_command = row[2] ? row[2] : "";
|
||||
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.top_level_aliases = row[4] ? row[4] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {}",
|
||||
TableName(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int Truncate(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"TRUNCATE TABLE {}",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int64 GetMaxId(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||
PrimaryKey(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COUNT(*) FROM {} {}",
|
||||
TableName(),
|
||||
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
#include <cereal/cereal.hpp>
|
||||
|
||||
class BaseDataBucketsRepository {
|
||||
public:
|
||||
@@ -24,6 +24,24 @@ public:
|
||||
std::string key_;
|
||||
std::string value;
|
||||
uint32_t expires;
|
||||
int64_t character_id;
|
||||
int64_t npc_id;
|
||||
int64_t bot_id;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(id),
|
||||
CEREAL_NVP(key_),
|
||||
CEREAL_NVP(value),
|
||||
CEREAL_NVP(expires),
|
||||
CEREAL_NVP(character_id),
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(bot_id)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -38,6 +56,9 @@ public:
|
||||
"`key`",
|
||||
"value",
|
||||
"expires",
|
||||
"character_id",
|
||||
"npc_id",
|
||||
"bot_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,6 +69,9 @@ public:
|
||||
"`key`",
|
||||
"value",
|
||||
"expires",
|
||||
"character_id",
|
||||
"npc_id",
|
||||
"bot_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -88,10 +112,13 @@ public:
|
||||
{
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = 0;
|
||||
e.key_ = "";
|
||||
e.value = "";
|
||||
e.expires = 0;
|
||||
e.id = 0;
|
||||
e.key_ = "";
|
||||
e.value = "";
|
||||
e.expires = 0;
|
||||
e.character_id = 0;
|
||||
e.npc_id = 0;
|
||||
e.bot_id = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -128,10 +155,13 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.character_id = strtoll(row[4], nullptr, 10);
|
||||
e.npc_id = strtoll(row[5], nullptr, 10);
|
||||
e.bot_id = strtoll(row[6], nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -168,6 +198,9 @@ public:
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.expires));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.character_id));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.npc_id));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.bot_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -193,6 +226,9 @@ public:
|
||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(std::to_string(e.expires));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.npc_id));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -226,6 +262,9 @@ public:
|
||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(std::to_string(e.expires));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.npc_id));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -259,10 +298,13 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.character_id = strtoll(row[4], nullptr, 10);
|
||||
e.npc_id = strtoll(row[5], nullptr, 10);
|
||||
e.bot_id = strtoll(row[6], nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -287,10 +329,13 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
e.character_id = strtoll(row[4], nullptr, 10);
|
||||
e.npc_id = strtoll(row[5], nullptr, 10);
|
||||
e.bot_id = strtoll(row[6], nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseItemsRepository {
|
||||
public:
|
||||
struct Items {
|
||||
@@ -122,7 +123,7 @@ public:
|
||||
int32_t pr;
|
||||
int32_t procrate;
|
||||
int32_t races;
|
||||
int32_t range;
|
||||
int32_t range_;
|
||||
int32_t reclevel;
|
||||
int32_t recskill;
|
||||
int32_t reqlevel;
|
||||
@@ -417,7 +418,7 @@ public:
|
||||
"pr",
|
||||
"procrate",
|
||||
"races",
|
||||
"range",
|
||||
"`range`",
|
||||
"reclevel",
|
||||
"recskill",
|
||||
"reqlevel",
|
||||
@@ -708,7 +709,7 @@ public:
|
||||
"pr",
|
||||
"procrate",
|
||||
"races",
|
||||
"range",
|
||||
"`range`",
|
||||
"reclevel",
|
||||
"recskill",
|
||||
"reqlevel",
|
||||
@@ -1033,7 +1034,7 @@ public:
|
||||
e.pr = 0;
|
||||
e.procrate = 0;
|
||||
e.races = 0;
|
||||
e.range = 0;
|
||||
e.range_ = 0;
|
||||
e.reclevel = 0;
|
||||
e.recskill = 0;
|
||||
e.reqlevel = 0;
|
||||
@@ -1240,8 +1241,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
items_id
|
||||
)
|
||||
);
|
||||
@@ -1353,7 +1355,7 @@ public:
|
||||
e.pr = static_cast<int32_t>(atoi(row[100]));
|
||||
e.procrate = static_cast<int32_t>(atoi(row[101]));
|
||||
e.races = static_cast<int32_t>(atoi(row[102]));
|
||||
e.range = static_cast<int32_t>(atoi(row[103]));
|
||||
e.range_ = static_cast<int32_t>(atoi(row[103]));
|
||||
e.reclevel = static_cast<int32_t>(atoi(row[104]));
|
||||
e.recskill = static_cast<int32_t>(atoi(row[105]));
|
||||
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
|
||||
@@ -1671,7 +1673,7 @@ public:
|
||||
v.push_back(columns[100] + " = " + std::to_string(e.pr));
|
||||
v.push_back(columns[101] + " = " + std::to_string(e.procrate));
|
||||
v.push_back(columns[102] + " = " + std::to_string(e.races));
|
||||
v.push_back(columns[103] + " = " + std::to_string(e.range));
|
||||
v.push_back(columns[103] + " = " + std::to_string(e.range_));
|
||||
v.push_back(columns[104] + " = " + std::to_string(e.reclevel));
|
||||
v.push_back(columns[105] + " = " + std::to_string(e.recskill));
|
||||
v.push_back(columns[106] + " = " + std::to_string(e.reqlevel));
|
||||
@@ -1977,7 +1979,7 @@ public:
|
||||
v.push_back(std::to_string(e.pr));
|
||||
v.push_back(std::to_string(e.procrate));
|
||||
v.push_back(std::to_string(e.races));
|
||||
v.push_back(std::to_string(e.range));
|
||||
v.push_back(std::to_string(e.range_));
|
||||
v.push_back(std::to_string(e.reclevel));
|
||||
v.push_back(std::to_string(e.recskill));
|
||||
v.push_back(std::to_string(e.reqlevel));
|
||||
@@ -2291,7 +2293,7 @@ public:
|
||||
v.push_back(std::to_string(e.pr));
|
||||
v.push_back(std::to_string(e.procrate));
|
||||
v.push_back(std::to_string(e.races));
|
||||
v.push_back(std::to_string(e.range));
|
||||
v.push_back(std::to_string(e.range_));
|
||||
v.push_back(std::to_string(e.reclevel));
|
||||
v.push_back(std::to_string(e.recskill));
|
||||
v.push_back(std::to_string(e.reqlevel));
|
||||
@@ -2609,7 +2611,7 @@ public:
|
||||
e.pr = static_cast<int32_t>(atoi(row[100]));
|
||||
e.procrate = static_cast<int32_t>(atoi(row[101]));
|
||||
e.races = static_cast<int32_t>(atoi(row[102]));
|
||||
e.range = static_cast<int32_t>(atoi(row[103]));
|
||||
e.range_ = static_cast<int32_t>(atoi(row[103]));
|
||||
e.reclevel = static_cast<int32_t>(atoi(row[104]));
|
||||
e.recskill = static_cast<int32_t>(atoi(row[105]));
|
||||
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
|
||||
@@ -2918,7 +2920,7 @@ public:
|
||||
e.pr = static_cast<int32_t>(atoi(row[100]));
|
||||
e.procrate = static_cast<int32_t>(atoi(row[101]));
|
||||
e.races = static_cast<int32_t>(atoi(row[102]));
|
||||
e.range = static_cast<int32_t>(atoi(row[103]));
|
||||
e.range_ = static_cast<int32_t>(atoi(row[103]));
|
||||
e.reclevel = static_cast<int32_t>(atoi(row[104]));
|
||||
e.recskill = static_cast<int32_t>(atoi(row[105]));
|
||||
e.reqlevel = static_cast<int32_t>(atoi(row[106]));
|
||||
|
||||
@@ -66,8 +66,8 @@ public:
|
||||
uint8_t armortint_red;
|
||||
uint8_t armortint_green;
|
||||
uint8_t armortint_blue;
|
||||
int32_t d_melee_texture1;
|
||||
int32_t d_melee_texture2;
|
||||
uint32_t d_melee_texture1;
|
||||
uint32_t d_melee_texture2;
|
||||
std::string ammo_idfile;
|
||||
uint8_t prim_melee_type;
|
||||
uint8_t sec_melee_type;
|
||||
@@ -583,7 +583,7 @@ public:
|
||||
e.exp_mod = 100;
|
||||
e.heroic_strikethrough = 0;
|
||||
e.faction_amount = 0;
|
||||
e.keeps_sold_items = 0;
|
||||
e.keeps_sold_items = 1;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -666,8 +666,8 @@ public:
|
||||
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
|
||||
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
|
||||
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
|
||||
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
|
||||
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
|
||||
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
|
||||
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
|
||||
e.ammo_idfile = row[48] ? row[48] : "";
|
||||
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
|
||||
@@ -1289,8 +1289,8 @@ public:
|
||||
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
|
||||
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
|
||||
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
|
||||
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
|
||||
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
|
||||
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
|
||||
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
|
||||
e.ammo_idfile = row[48] ? row[48] : "";
|
||||
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
|
||||
@@ -1440,8 +1440,8 @@ public:
|
||||
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
|
||||
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
|
||||
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
|
||||
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
|
||||
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
|
||||
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
|
||||
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
|
||||
e.ammo_idfile = row[48] ? row[48] : "";
|
||||
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseRaidDetailsRepository {
|
||||
public:
|
||||
struct RaidDetails {
|
||||
@@ -23,6 +24,15 @@ public:
|
||||
int32_t loottype;
|
||||
int8_t locked;
|
||||
std::string motd;
|
||||
uint32_t marked_npc_1_entity_id;
|
||||
uint32_t marked_npc_1_zone_id;
|
||||
uint32_t marked_npc_1_instance_id;
|
||||
uint32_t marked_npc_2_entity_id;
|
||||
uint32_t marked_npc_2_zone_id;
|
||||
uint32_t marked_npc_2_instance_id;
|
||||
uint32_t marked_npc_3_entity_id;
|
||||
uint32_t marked_npc_3_zone_id;
|
||||
uint32_t marked_npc_3_instance_id;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -37,6 +47,15 @@ public:
|
||||
"loottype",
|
||||
"locked",
|
||||
"motd",
|
||||
"marked_npc_1_entity_id",
|
||||
"marked_npc_1_zone_id",
|
||||
"marked_npc_1_instance_id",
|
||||
"marked_npc_2_entity_id",
|
||||
"marked_npc_2_zone_id",
|
||||
"marked_npc_2_instance_id",
|
||||
"marked_npc_3_entity_id",
|
||||
"marked_npc_3_zone_id",
|
||||
"marked_npc_3_instance_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,6 +66,15 @@ public:
|
||||
"loottype",
|
||||
"locked",
|
||||
"motd",
|
||||
"marked_npc_1_entity_id",
|
||||
"marked_npc_1_zone_id",
|
||||
"marked_npc_1_instance_id",
|
||||
"marked_npc_2_entity_id",
|
||||
"marked_npc_2_zone_id",
|
||||
"marked_npc_2_instance_id",
|
||||
"marked_npc_3_entity_id",
|
||||
"marked_npc_3_zone_id",
|
||||
"marked_npc_3_instance_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,10 +115,19 @@ public:
|
||||
{
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = 0;
|
||||
e.loottype = 0;
|
||||
e.locked = 0;
|
||||
e.motd = "";
|
||||
e.raidid = 0;
|
||||
e.loottype = 0;
|
||||
e.locked = 0;
|
||||
e.motd = "";
|
||||
e.marked_npc_1_entity_id = 0;
|
||||
e.marked_npc_1_zone_id = 0;
|
||||
e.marked_npc_1_instance_id = 0;
|
||||
e.marked_npc_2_entity_id = 0;
|
||||
e.marked_npc_2_zone_id = 0;
|
||||
e.marked_npc_2_instance_id = 0;
|
||||
e.marked_npc_3_entity_id = 0;
|
||||
e.marked_npc_3_zone_id = 0;
|
||||
e.marked_npc_3_instance_id = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -116,8 +153,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
raid_details_id
|
||||
)
|
||||
);
|
||||
@@ -126,10 +164,19 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1_entity_id = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_1_zone_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_1_instance_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
e.marked_npc_2_entity_id = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
|
||||
e.marked_npc_2_zone_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||
e.marked_npc_2_instance_id = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
|
||||
e.marked_npc_3_entity_id = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
|
||||
e.marked_npc_3_zone_id = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
|
||||
e.marked_npc_3_instance_id = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -167,6 +214,15 @@ public:
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.loottype));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.locked));
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.motd) + "'");
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1_entity_id));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_1_zone_id));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_1_instance_id));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.marked_npc_2_entity_id));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.marked_npc_2_zone_id));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.marked_npc_2_instance_id));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.marked_npc_3_entity_id));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.marked_npc_3_zone_id));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.marked_npc_3_instance_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -192,6 +248,15 @@ public:
|
||||
v.push_back(std::to_string(e.loottype));
|
||||
v.push_back(std::to_string(e.locked));
|
||||
v.push_back("'" + Strings::Escape(e.motd) + "'");
|
||||
v.push_back(std::to_string(e.marked_npc_1_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_instance_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -225,6 +290,15 @@ public:
|
||||
v.push_back(std::to_string(e.loottype));
|
||||
v.push_back(std::to_string(e.locked));
|
||||
v.push_back("'" + Strings::Escape(e.motd) + "'");
|
||||
v.push_back(std::to_string(e.marked_npc_1_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_instance_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -258,10 +332,19 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1_entity_id = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_1_zone_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_1_instance_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
e.marked_npc_2_entity_id = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
|
||||
e.marked_npc_2_zone_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||
e.marked_npc_2_instance_id = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
|
||||
e.marked_npc_3_entity_id = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
|
||||
e.marked_npc_3_zone_id = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
|
||||
e.marked_npc_3_instance_id = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -286,10 +369,19 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1_entity_id = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_1_zone_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_1_instance_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
e.marked_npc_2_entity_id = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
|
||||
e.marked_npc_2_zone_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||
e.marked_npc_2_instance_id = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
|
||||
e.marked_npc_3_entity_id = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
|
||||
e.marked_npc_3_zone_id = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
|
||||
e.marked_npc_3_instance_id = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ public:
|
||||
int8_t isgroupleader;
|
||||
int8_t israidleader;
|
||||
int8_t islooter;
|
||||
uint8_t is_marker;
|
||||
uint8_t is_assister;
|
||||
std::string note;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -52,6 +55,9 @@ public:
|
||||
"isgroupleader",
|
||||
"israidleader",
|
||||
"islooter",
|
||||
"is_marker",
|
||||
"is_assister",
|
||||
"note",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -69,6 +75,9 @@ public:
|
||||
"isgroupleader",
|
||||
"israidleader",
|
||||
"islooter",
|
||||
"is_marker",
|
||||
"is_assister",
|
||||
"note",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -120,6 +129,9 @@ public:
|
||||
e.isgroupleader = 0;
|
||||
e.israidleader = 0;
|
||||
e.islooter = 0;
|
||||
e.is_marker = 0;
|
||||
e.is_assister = 0;
|
||||
e.note = "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -167,6 +179,9 @@ public:
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[9]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[10]));
|
||||
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
|
||||
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||
e.note = row[13] ? row[13] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -210,6 +225,9 @@ public:
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.isgroupleader));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.israidleader));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.islooter));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.is_marker));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.is_assister));
|
||||
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -242,6 +260,9 @@ public:
|
||||
v.push_back(std::to_string(e.isgroupleader));
|
||||
v.push_back(std::to_string(e.israidleader));
|
||||
v.push_back(std::to_string(e.islooter));
|
||||
v.push_back(std::to_string(e.is_marker));
|
||||
v.push_back(std::to_string(e.is_assister));
|
||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -282,6 +303,9 @@ public:
|
||||
v.push_back(std::to_string(e.isgroupleader));
|
||||
v.push_back(std::to_string(e.israidleader));
|
||||
v.push_back(std::to_string(e.islooter));
|
||||
v.push_back(std::to_string(e.is_marker));
|
||||
v.push_back(std::to_string(e.is_assister));
|
||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -326,6 +350,9 @@ public:
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[9]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[10]));
|
||||
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
|
||||
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||
e.note = row[13] ? row[13] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -361,6 +388,9 @@ public:
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[9]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[10]));
|
||||
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
|
||||
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||
e.note = row[13] ? row[13] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,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_SPAWN2_DISABLED_REPOSITORY_H
|
||||
#define EQEMU_BASE_SPAWN2_DISABLED_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseSpawn2DisabledRepository {
|
||||
public:
|
||||
struct Spawn2Disabled {
|
||||
int64_t id;
|
||||
int32_t spawn2_id;
|
||||
int32_t instance_id;
|
||||
int16_t disabled;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"spawn2_id",
|
||||
"instance_id",
|
||||
"disabled",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"spawn2_id",
|
||||
"instance_id",
|
||||
"disabled",
|
||||
};
|
||||
}
|
||||
|
||||
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("spawn2_disabled");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
SelectColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static Spawn2Disabled NewEntity()
|
||||
{
|
||||
Spawn2Disabled e{};
|
||||
|
||||
e.id = 0;
|
||||
e.spawn2_id = 0;
|
||||
e.instance_id = 0;
|
||||
e.disabled = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static Spawn2Disabled GetSpawn2Disabled(
|
||||
const std::vector<Spawn2Disabled> &spawn2_disableds,
|
||||
int spawn2_disabled_id
|
||||
)
|
||||
{
|
||||
for (auto &spawn2_disabled : spawn2_disableds) {
|
||||
if (spawn2_disabled.id == spawn2_disabled_id) {
|
||||
return spawn2_disabled;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static Spawn2Disabled FindOne(
|
||||
Database& db,
|
||||
int spawn2_disabled_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
spawn2_disabled_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
Spawn2Disabled e{};
|
||||
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.spawn2_id = static_cast<int32_t>(atoi(row[1]));
|
||||
e.instance_id = static_cast<int32_t>(atoi(row[2]));
|
||||
e.disabled = static_cast<int16_t>(atoi(row[3]));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int spawn2_disabled_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
spawn2_disabled_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const Spawn2Disabled &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.spawn2_id));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.instance_id));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.disabled));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static Spawn2Disabled InsertOne(
|
||||
Database& db,
|
||||
Spawn2Disabled e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.spawn2_id));
|
||||
v.push_back(std::to_string(e.instance_id));
|
||||
v.push_back(std::to_string(e.disabled));
|
||||
|
||||
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<Spawn2Disabled> &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.spawn2_id));
|
||||
v.push_back(std::to_string(e.instance_id));
|
||||
v.push_back(std::to_string(e.disabled));
|
||||
|
||||
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<Spawn2Disabled> All(Database& db)
|
||||
{
|
||||
std::vector<Spawn2Disabled> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Spawn2Disabled e{};
|
||||
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.spawn2_id = static_cast<int32_t>(atoi(row[1]));
|
||||
e.instance_id = static_cast<int32_t>(atoi(row[2]));
|
||||
e.disabled = static_cast<int16_t>(atoi(row[3]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<Spawn2Disabled> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<Spawn2Disabled> 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) {
|
||||
Spawn2Disabled e{};
|
||||
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.spawn2_id = static_cast<int32_t>(atoi(row[1]));
|
||||
e.instance_id = static_cast<int32_t>(atoi(row[2]));
|
||||
e.disabled = static_cast<int16_t>(atoi(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_SPAWN2_DISABLED_REPOSITORY_H
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseSpawn2Repository {
|
||||
public:
|
||||
struct Spawn2 {
|
||||
@@ -33,7 +34,6 @@ public:
|
||||
int8_t path_when_zone_idle;
|
||||
uint32_t _condition;
|
||||
int32_t cond_value;
|
||||
uint8_t enabled;
|
||||
uint8_t animation;
|
||||
int8_t min_expansion;
|
||||
int8_t max_expansion;
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
"path_when_zone_idle",
|
||||
"_condition",
|
||||
"cond_value",
|
||||
"enabled",
|
||||
"animation",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
@@ -89,7 +88,6 @@ public:
|
||||
"path_when_zone_idle",
|
||||
"_condition",
|
||||
"cond_value",
|
||||
"enabled",
|
||||
"animation",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
@@ -149,7 +147,6 @@ public:
|
||||
e.path_when_zone_idle = 0;
|
||||
e._condition = 0;
|
||||
e.cond_value = 1;
|
||||
e.enabled = 1;
|
||||
e.animation = 0;
|
||||
e.min_expansion = -1;
|
||||
e.max_expansion = -1;
|
||||
@@ -180,8 +177,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
spawn2_id
|
||||
)
|
||||
);
|
||||
@@ -204,12 +202,11 @@ public:
|
||||
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
||||
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
||||
e.enabled = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||
e.animation = static_cast<uint8_t>(strtoul(row[15], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[17]));
|
||||
e.content_flags = row[18] ? row[18] : "";
|
||||
e.content_flags_disabled = row[19] ? row[19] : "";
|
||||
e.animation = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[15]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||
e.content_flags = row[17] ? row[17] : "";
|
||||
e.content_flags_disabled = row[18] ? row[18] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -256,12 +253,11 @@ public:
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.path_when_zone_idle));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e._condition));
|
||||
v.push_back(columns[13] + " = " + std::to_string(e.cond_value));
|
||||
v.push_back(columns[14] + " = " + std::to_string(e.enabled));
|
||||
v.push_back(columns[15] + " = " + std::to_string(e.animation));
|
||||
v.push_back(columns[16] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[17] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[18] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[19] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(columns[14] + " = " + std::to_string(e.animation));
|
||||
v.push_back(columns[15] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[16] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[17] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[18] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -297,7 +293,6 @@ public:
|
||||
v.push_back(std::to_string(e.path_when_zone_idle));
|
||||
v.push_back(std::to_string(e._condition));
|
||||
v.push_back(std::to_string(e.cond_value));
|
||||
v.push_back(std::to_string(e.enabled));
|
||||
v.push_back(std::to_string(e.animation));
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
@@ -346,7 +341,6 @@ public:
|
||||
v.push_back(std::to_string(e.path_when_zone_idle));
|
||||
v.push_back(std::to_string(e._condition));
|
||||
v.push_back(std::to_string(e.cond_value));
|
||||
v.push_back(std::to_string(e.enabled));
|
||||
v.push_back(std::to_string(e.animation));
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
@@ -399,12 +393,11 @@ public:
|
||||
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
||||
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
||||
e.enabled = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||
e.animation = static_cast<uint8_t>(strtoul(row[15], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[17]));
|
||||
e.content_flags = row[18] ? row[18] : "";
|
||||
e.content_flags_disabled = row[19] ? row[19] : "";
|
||||
e.animation = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[15]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||
e.content_flags = row[17] ? row[17] : "";
|
||||
e.content_flags_disabled = row[18] ? row[18] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -443,12 +436,11 @@ public:
|
||||
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
||||
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
||||
e.enabled = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||
e.animation = static_cast<uint8_t>(strtoul(row[15], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[17]));
|
||||
e.content_flags = row[18] ? row[18] : "";
|
||||
e.content_flags_disabled = row[19] ? row[19] : "";
|
||||
e.animation = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[15]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||
e.content_flags = row[17] ? row[17] : "";
|
||||
e.content_flags_disabled = row[18] ? row[18] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseSpawnentryRepository {
|
||||
public:
|
||||
struct Spawnentry {
|
||||
@@ -23,6 +24,8 @@ public:
|
||||
int32_t npcID;
|
||||
int16_t chance;
|
||||
int32_t condition_value_filter;
|
||||
int16_t min_time;
|
||||
int16_t max_time;
|
||||
int8_t min_expansion;
|
||||
int8_t max_expansion;
|
||||
std::string content_flags;
|
||||
@@ -41,6 +44,8 @@ public:
|
||||
"npcID",
|
||||
"chance",
|
||||
"condition_value_filter",
|
||||
"min_time",
|
||||
"max_time",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
"content_flags",
|
||||
@@ -55,6 +60,8 @@ public:
|
||||
"npcID",
|
||||
"chance",
|
||||
"condition_value_filter",
|
||||
"min_time",
|
||||
"max_time",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
"content_flags",
|
||||
@@ -103,6 +110,8 @@ public:
|
||||
e.npcID = 0;
|
||||
e.chance = 0;
|
||||
e.condition_value_filter = 1;
|
||||
e.min_time = 0;
|
||||
e.max_time = 0;
|
||||
e.min_expansion = -1;
|
||||
e.max_expansion = -1;
|
||||
e.content_flags = "";
|
||||
@@ -132,8 +141,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
spawnentry_id
|
||||
)
|
||||
);
|
||||
@@ -146,10 +156,12 @@ public:
|
||||
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
||||
e.chance = static_cast<int16_t>(atoi(row[2]));
|
||||
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[4]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[5]));
|
||||
e.content_flags = row[6] ? row[6] : "";
|
||||
e.content_flags_disabled = row[7] ? row[7] : "";
|
||||
e.min_time = static_cast<int16_t>(atoi(row[4]));
|
||||
e.max_time = static_cast<int16_t>(atoi(row[5]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||
e.content_flags = row[8] ? row[8] : "";
|
||||
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -187,10 +199,12 @@ public:
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.npcID));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.chance));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.condition_value_filter));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[6] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[7] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.min_time));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.max_time));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[9] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -216,6 +230,8 @@ public:
|
||||
v.push_back(std::to_string(e.npcID));
|
||||
v.push_back(std::to_string(e.chance));
|
||||
v.push_back(std::to_string(e.condition_value_filter));
|
||||
v.push_back(std::to_string(e.min_time));
|
||||
v.push_back(std::to_string(e.max_time));
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
@@ -253,6 +269,8 @@ public:
|
||||
v.push_back(std::to_string(e.npcID));
|
||||
v.push_back(std::to_string(e.chance));
|
||||
v.push_back(std::to_string(e.condition_value_filter));
|
||||
v.push_back(std::to_string(e.min_time));
|
||||
v.push_back(std::to_string(e.max_time));
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
@@ -294,10 +312,12 @@ public:
|
||||
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
||||
e.chance = static_cast<int16_t>(atoi(row[2]));
|
||||
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[4]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[5]));
|
||||
e.content_flags = row[6] ? row[6] : "";
|
||||
e.content_flags_disabled = row[7] ? row[7] : "";
|
||||
e.min_time = static_cast<int16_t>(atoi(row[4]));
|
||||
e.max_time = static_cast<int16_t>(atoi(row[5]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||
e.content_flags = row[8] ? row[8] : "";
|
||||
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -326,10 +346,12 @@ public:
|
||||
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
||||
e.chance = static_cast<int16_t>(atoi(row[2]));
|
||||
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[4]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[5]));
|
||||
e.content_flags = row[6] ? row[6] : "";
|
||||
e.content_flags_disabled = row[7] ? row[7] : "";
|
||||
e.min_time = static_cast<int16_t>(atoi(row[4]));
|
||||
e.max_time = static_cast<int16_t>(atoi(row[5]));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||
e.content_flags = row[8] ? row[8] : "";
|
||||
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||
#define EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_bot_starting_items_repository.h"
|
||||
|
||||
class BotStartingItemsRepository: public BaseBotStartingItemsRepository {
|
||||
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
|
||||
*
|
||||
* BotStartingItemsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* BotStartingItemsRepository::GetWhereNeverExpires()
|
||||
* BotStartingItemsRepository::GetWhereXAndY()
|
||||
* BotStartingItemsRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||
* method and encapsulate filters there
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef EQEMU_CHARACTER_STATS_RECORD_REPOSITORY_H
|
||||
#define EQEMU_CHARACTER_STATS_RECORD_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_character_stats_record_repository.h"
|
||||
|
||||
class CharacterStatsRecordRepository: public BaseCharacterStatsRecordRepository {
|
||||
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
|
||||
*
|
||||
* CharacterStatsRecordRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* CharacterStatsRecordRepository::GetWhereNeverExpires()
|
||||
* CharacterStatsRecordRepository::GetWhereXAndY()
|
||||
* CharacterStatsRecordRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||
* method and encapsulate filters there
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_CHARACTER_STATS_RECORD_REPOSITORY_H
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
|
||||
#define EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_character_tribute_repository.h"
|
||||
|
||||
class CharacterTributeRepository: public BaseCharacterTributeRepository {
|
||||
public:
|
||||
|
||||
/**
|
||||
* This file was auto generated and can be modified and extended upon
|
||||
*
|
||||
* Base repository methods are automatically
|
||||
* generated in the "base" version of this repository. The base repository
|
||||
* is immutable and to be left untouched, while methods in this class
|
||||
* are used as extension methods for more specific persistence-layer
|
||||
* accessors or mutators.
|
||||
*
|
||||
* Base Methods (Subject to be expanded upon in time)
|
||||
*
|
||||
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
||||
*
|
||||
* InsertOne
|
||||
* UpdateOne
|
||||
* DeleteOne
|
||||
* FindOne
|
||||
* GetWhere(std::string where_filter)
|
||||
* DeleteWhere(std::string where_filter)
|
||||
* InsertMany
|
||||
* All
|
||||
*
|
||||
* Example custom methods in a repository
|
||||
*
|
||||
* CharacterTributeRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* CharacterTributeRepository::GetWhereNeverExpires()
|
||||
* CharacterTributeRepository::GetWhereXAndY()
|
||||
* CharacterTributeRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||
* method and encapsulate filters there
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_CHARACTER_TRIBUTE_REPOSITORY_H
|
||||
@@ -0,0 +1,222 @@
|
||||
#ifndef EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H
|
||||
#define EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_command_subsettings_repository.h"
|
||||
|
||||
class CommandSubsettingsRepository: public BaseCommandSubsettingsRepository {
|
||||
public:
|
||||
|
||||
/**
|
||||
* This file was auto generated and can be modified and extended upon
|
||||
*
|
||||
* Base repository methods are automatically
|
||||
* generated in the "base" version of this repository. The base repository
|
||||
* is immutable and to be left untouched, while methods in this class
|
||||
* are used as extension methods for more specific persistence-layer
|
||||
* accessors or mutators.
|
||||
*
|
||||
* Base Methods (Subject to be expanded upon in time)
|
||||
*
|
||||
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
||||
*
|
||||
* InsertOne
|
||||
* UpdateOne
|
||||
* DeleteOne
|
||||
* FindOne
|
||||
* GetWhere(std::string where_filter)
|
||||
* DeleteWhere(std::string where_filter)
|
||||
* InsertMany
|
||||
* All
|
||||
*
|
||||
* Example custom methods in a repository
|
||||
*
|
||||
* CommandSubsettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* CommandSubsettingsRepository::GetWhereNeverExpires()
|
||||
* CommandSubsettingsRepository::GetWhereXAndY()
|
||||
* CommandSubsettingsRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||
* method and encapsulate filters there
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static std::vector<CommandSubsettingsRepository::CommandSubsettings> GetAll(Database& db)
|
||||
{
|
||||
// these are the base definitions for command_subsettings and can be over-ridden by the database
|
||||
std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = {
|
||||
{.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"},
|
||||
{.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"},
|
||||
{.parent_command = "find", .sub_command = "class", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findclass"},
|
||||
{.parent_command = "find", .sub_command = "currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcurrency"},
|
||||
{.parent_command = "find", .sub_command = "deity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "finddeity"},
|
||||
{.parent_command = "find", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findemote"},
|
||||
{.parent_command = "find", .sub_command = "faction", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findfaction"},
|
||||
{.parent_command = "find", .sub_command = "item", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fi|finditem|itemsearch"},
|
||||
{.parent_command = "find", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findlanguage"},
|
||||
{.parent_command = "find", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fn|findnpc|findnpctype"},
|
||||
{.parent_command = "find", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrace"},
|
||||
{.parent_command = "find", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrecipe"},
|
||||
{.parent_command = "find", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findskill"},
|
||||
{.parent_command = "find", .sub_command = "spell", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fs|findspell"},
|
||||
{.parent_command = "find", .sub_command = "task", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findtask"},
|
||||
{.parent_command = "find", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fz|findzone"},
|
||||
{.parent_command = "set", .sub_command = "aa_exp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaaxp|setaaexp"},
|
||||
{.parent_command = "set", .sub_command = "aa_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaapts|setaapoints"},
|
||||
{.parent_command = "set", .sub_command = "adventure_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setadventurepoints"},
|
||||
{.parent_command = "set", .sub_command = "alternate_currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaltcurrency"},
|
||||
{.parent_command = "set", .sub_command = "animation", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setanim"},
|
||||
{.parent_command = "set", .sub_command = "anon", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setanon"},
|
||||
{.parent_command = "set", .sub_command = "bind", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "bind"},
|
||||
{.parent_command = "set", .sub_command = "checksum", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "updatechecksum"},
|
||||
{.parent_command = "set", .sub_command = "class_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permaclass"},
|
||||
{.parent_command = "set", .sub_command = "crystals", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setcrystals"},
|
||||
{.parent_command = "set", .sub_command = "date", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "date"},
|
||||
{.parent_command = "set", .sub_command = "endurance", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setendurance"},
|
||||
{.parent_command = "set", .sub_command = "endurance_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "endurance"},
|
||||
{.parent_command = "set", .sub_command = "exp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setxp|setexp"},
|
||||
{.parent_command = "set", .sub_command = "faction", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setfaction"},
|
||||
{.parent_command = "set", .sub_command = "flymode", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flymode"},
|
||||
{.parent_command = "set", .sub_command = "freeze", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "freeze|unfreeze"},
|
||||
{.parent_command = "set", .sub_command = "gender", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gender"},
|
||||
{.parent_command = "set", .sub_command = "gender_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permagender"},
|
||||
{.parent_command = "set", .sub_command = "gm", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gm"},
|
||||
{.parent_command = "set", .sub_command = "gm_speed", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gmspeed"},
|
||||
{.parent_command = "set", .sub_command = "gm_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flag"},
|
||||
{.parent_command = "set", .sub_command = "god_mode", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "godmode"},
|
||||
{.parent_command = "set", .sub_command = "haste", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "haste"},
|
||||
{.parent_command = "set", .sub_command = "hero_model", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "heromodel"},
|
||||
{.parent_command = "set", .sub_command = "hide_me", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hideme"},
|
||||
{.parent_command = "set", .sub_command = "hp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "sethp"},
|
||||
{.parent_command = "set", .sub_command = "hp_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "heal"},
|
||||
{.parent_command = "set", .sub_command = "invulnerable", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "invul|invulnerable"},
|
||||
{.parent_command = "set", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setlanguage"},
|
||||
{.parent_command = "set", .sub_command = "last_name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "lastname"},
|
||||
{.parent_command = "set", .sub_command = "level", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "level"},
|
||||
{.parent_command = "set", .sub_command = "loginserver_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setlsinfo"},
|
||||
{.parent_command = "set", .sub_command = "mana", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setmana"},
|
||||
{.parent_command = "set", .sub_command = "mana_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "mana"},
|
||||
{.parent_command = "set", .sub_command = "motd", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "motd"},
|
||||
{.parent_command = "set", .sub_command = "name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "name"},
|
||||
{.parent_command = "set", .sub_command = "ooc_mute", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "oocmute"},
|
||||
{.parent_command = "set", .sub_command = "password", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setpass"},
|
||||
{.parent_command = "set", .sub_command = "pvp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "pvp"},
|
||||
{.parent_command = "set", .sub_command = "pvp_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setpvppoints"},
|
||||
{.parent_command = "set", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "race"},
|
||||
{.parent_command = "set", .sub_command = "race_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permarace"},
|
||||
{.parent_command = "set", .sub_command = "server_locked", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "lock|serverlock|serverunlock|unlock"},
|
||||
{.parent_command = "set", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setskill"},
|
||||
{.parent_command = "set", .sub_command = "skill_all", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setallskill|setallskills|setskillall"},
|
||||
{.parent_command = "set", .sub_command = "skill_all_max", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "maxskills"},
|
||||
{.parent_command = "set", .sub_command = "start_zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setstartzone"},
|
||||
{.parent_command = "set", .sub_command = "temporary_name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "tempname"},
|
||||
{.parent_command = "set", .sub_command = "texture", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "texture"},
|
||||
{.parent_command = "set", .sub_command = "time", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "time"},
|
||||
{.parent_command = "set", .sub_command = "time_zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "timezone"},
|
||||
{.parent_command = "set", .sub_command = "title", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "title"},
|
||||
{.parent_command = "set", .sub_command = "title_suffix", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "titlesuffix"},
|
||||
{.parent_command = "set", .sub_command = "weather", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "weather"},
|
||||
{.parent_command = "set", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zclip|zcolor|zheader|zonelock|zsafecoords|zsky|zunderworld"},
|
||||
{.parent_command = "show", .sub_command = "aa_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showaapoints|showaapts"},
|
||||
{.parent_command = "show", .sub_command = "aggro", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "aggro"},
|
||||
{.parent_command = "show", .sub_command = "buffs", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showbuffs"},
|
||||
{.parent_command = "show", .sub_command = "buried_corpse_count", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getplayerburiedcorpsecount"},
|
||||
{.parent_command = "show", .sub_command = "client_version_summary", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "cvs"},
|
||||
{.parent_command = "show", .sub_command = "currencies", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewcurrencies"},
|
||||
{.parent_command = "show", .sub_command = "distance", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "distance"},
|
||||
{.parent_command = "show", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "emoteview"},
|
||||
{.parent_command = "show", .sub_command = "field_of_view", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fov"},
|
||||
{.parent_command = "show", .sub_command = "flags", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flags"},
|
||||
{.parent_command = "show", .sub_command = "group_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "ginfo"},
|
||||
{.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"},
|
||||
{.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"},
|
||||
{.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"},
|
||||
{.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"},
|
||||
{.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"},
|
||||
{.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"},
|
||||
{.parent_command = "show", .sub_command = "npc_global_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "shownpcgloballoot"},
|
||||
{.parent_command = "show", .sub_command = "npc_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "npcstats"},
|
||||
{.parent_command = "show", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewnpctype"},
|
||||
{.parent_command = "show", .sub_command = "peqzone_flags", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peqzone_flags"},
|
||||
{.parent_command = "show", .sub_command = "petition", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "listpetition|viewpetition"},
|
||||
{.parent_command = "show", .sub_command = "petition_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "petitioninfo"},
|
||||
{.parent_command = "show", .sub_command = "proximity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "proximity"},
|
||||
{.parent_command = "show", .sub_command = "quest_errors", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "questerrors"},
|
||||
{.parent_command = "show", .sub_command = "quest_globals", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "globalview"},
|
||||
{.parent_command = "show", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewrecipe"},
|
||||
{.parent_command = "show", .sub_command = "server_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "serverinfo"},
|
||||
{.parent_command = "show", .sub_command = "skills", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showskills"},
|
||||
{.parent_command = "show", .sub_command = "spawn_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "spawnstatus"},
|
||||
{.parent_command = "show", .sub_command = "spells", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showspells"},
|
||||
{.parent_command = "show", .sub_command = "spells_list", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showspellslist"},
|
||||
{.parent_command = "show", .sub_command = "stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showstats"},
|
||||
{.parent_command = "show", .sub_command = "timers", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "timers"},
|
||||
{.parent_command = "show", .sub_command = "traps", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "trapinfo"},
|
||||
{.parent_command = "show", .sub_command = "uptime", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "uptime"},
|
||||
{.parent_command = "show", .sub_command = "variable", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getvariable"},
|
||||
{.parent_command = "show", .sub_command = "version", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "version"},
|
||||
{.parent_command = "show", .sub_command = "waypoints", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "wpinfo"},
|
||||
{.parent_command = "show", .sub_command = "who", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "who"},
|
||||
{.parent_command = "show", .sub_command = "xtargets", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "xtargets"},
|
||||
{.parent_command = "show", .sub_command = "zone_global_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showzonegloballoot"},
|
||||
{.parent_command = "show", .sub_command = "zone_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewzoneloot"},
|
||||
{.parent_command = "show", .sub_command = "zone_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showzonepoints"},
|
||||
{.parent_command = "show", .sub_command = "zone_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zstats"},
|
||||
{.parent_command = "show", .sub_command = "zone_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zonestatus"},
|
||||
};
|
||||
|
||||
auto db_sub_settings = All(db);
|
||||
|
||||
// inject commands in the database that are not already there
|
||||
std::vector<CommandSubsettingsRepository::CommandSubsettings> new_records = {};
|
||||
for (const auto &r: static_records) {
|
||||
bool found = false;
|
||||
for (const auto &db_r: db_sub_settings) {
|
||||
if (r.parent_command == db_r.parent_command && r.sub_command == db_r.sub_command) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
LogInfo("New command [{}] sub-command [{}] added to database table [{}] !", r.parent_command, r.sub_command, TableName());
|
||||
new_records.emplace_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_records.empty()) {
|
||||
InsertMany(db, new_records);
|
||||
// if any were added, we need to reload the list
|
||||
db_sub_settings = All(db);
|
||||
}
|
||||
|
||||
// remove commands from the database that are not in the static list
|
||||
bool any_deleted = false;
|
||||
for (const auto &db_r: db_sub_settings) {
|
||||
bool found = false;
|
||||
for (const auto &r: static_records) {
|
||||
if (r.parent_command == db_r.parent_command && r.sub_command == db_r.sub_command) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
LogInfo("Command [{}] sub-command [{}] removed from database table [{}] !", db_r.parent_command, db_r.sub_command, TableName());
|
||||
DeleteWhere(db, fmt::format("parent_command = '{}' AND sub_command = '{}'", db_r.parent_command, db_r.sub_command));
|
||||
any_deleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if any were deleted, re-read the database
|
||||
if (any_deleted) {
|
||||
db_sub_settings = All(db);
|
||||
}
|
||||
|
||||
// return the final list of what's in the database
|
||||
return db_sub_settings;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H
|
||||
@@ -44,7 +44,35 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static std::vector<int32> GetItemIDsBySearchCriteria(
|
||||
Database& db,
|
||||
std::string search_string,
|
||||
int query_limit = 0
|
||||
)
|
||||
{
|
||||
auto query = fmt::format(
|
||||
"SELECT `id` FROM {} WHERE LOWER(`name`) LIKE '%%{}%%' ORDER BY id ASC",
|
||||
TableName(),
|
||||
Strings::Escape(search_string)
|
||||
);
|
||||
|
||||
if (query_limit >= 1) {
|
||||
query += fmt::format(" LIMIT {}", query_limit);
|
||||
}
|
||||
|
||||
std::vector<int32> item_id_list;
|
||||
|
||||
auto results = db.QueryDatabase(query);
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return item_id_list;
|
||||
}
|
||||
|
||||
for (auto row : results) {
|
||||
item_id_list.emplace_back(Strings::ToInt(row[0]));
|
||||
}
|
||||
|
||||
return item_id_list;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_ITEMS_REPOSITORY_H
|
||||
|
||||
@@ -44,7 +44,28 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static int UpdateRaidMarkedNPC(
|
||||
Database& db,
|
||||
int32_t raid_id,
|
||||
uint32_t marked_npc_entity_id,
|
||||
uint32_t marked_npc_zone_id,
|
||||
uint32_t marked_npc_instance_id,
|
||||
uint32_t slot_number
|
||||
) {
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `{0}` SET `marked_npc_{4}_entity_id` = '{1}',`marked_npc_{4}_zone_id` = '{2}',`marked_npc_{4}_instance_id` = '{3}' WHERE raidid = '{5}';",
|
||||
TableName(),
|
||||
marked_npc_entity_id,
|
||||
marked_npc_zone_id,
|
||||
marked_npc_instance_id,
|
||||
slot_number,
|
||||
raid_id
|
||||
)
|
||||
);
|
||||
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_RAID_DETAILS_REPOSITORY_H
|
||||
|
||||
@@ -44,7 +44,59 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static int UpdateRaidNote(
|
||||
Database& db,
|
||||
int32_t raid_id,
|
||||
const std::string& note,
|
||||
const std::string& character_name
|
||||
) {
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format("UPDATE `{}` SET `note` = '{}' WHERE raidid = '{}' AND name = '{}';",
|
||||
TableName(),
|
||||
Strings::Escape(note),
|
||||
raid_id,
|
||||
Strings::Escape(character_name)
|
||||
)
|
||||
);
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
|
||||
static int UpdateRaidAssister(
|
||||
Database& db,
|
||||
int32_t raid_id,
|
||||
const std::string& character_name,
|
||||
uint8_t value
|
||||
) {
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `{}` SET `is_assister` = '{}' WHERE raidid = '{}' AND `name` = '{}';",
|
||||
TableName(),
|
||||
value,
|
||||
raid_id,
|
||||
Strings::Escape(character_name)
|
||||
)
|
||||
);
|
||||
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
|
||||
static int UpdateRaidMarker(
|
||||
Database& db,
|
||||
int32_t raid_id,
|
||||
const std::string& character_name,
|
||||
uint8_t value
|
||||
) {
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `{}` SET `is_marker` = '{}' WHERE raidid = '{}' AND `name` = '{}';",
|
||||
TableName(),
|
||||
value,
|
||||
raid_id,
|
||||
Strings::Escape(character_name)
|
||||
)
|
||||
);
|
||||
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_RAID_MEMBERS_REPOSITORY_H
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef EQEMU_SPAWN2_DISABLED_REPOSITORY_H
|
||||
#define EQEMU_SPAWN2_DISABLED_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_spawn2_disabled_repository.h"
|
||||
|
||||
class Spawn2DisabledRepository: public BaseSpawn2DisabledRepository {
|
||||
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
|
||||
*
|
||||
* Spawn2DisabledRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* Spawn2DisabledRepository::GetWhereNeverExpires()
|
||||
* Spawn2DisabledRepository::GetWhereXAndY()
|
||||
* Spawn2DisabledRepository::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_SPAWN2_DISABLED_REPOSITORY_H
|
||||
+22
-4
@@ -58,6 +58,7 @@ RULE_REAL(Character, ExpMultiplier, 0.5, "If greater than 0, the experience gain
|
||||
RULE_REAL(Character, AAExpMultiplier, 0.5, "If greater than 0, the AA experience gained is multiplied by this value. ")
|
||||
RULE_REAL(Character, GroupExpMultiplier, 0.5, "The experience in a group is multiplied by this value in addition to the group multiplier. The group multiplier is: 2 members=x 1.2, 3=x1.4, 4=x1.6, 5=x1.8, 6=x2.16")
|
||||
RULE_REAL(Character, RaidExpMultiplier, 0.2, "The experience gained in raids is multiplied by (1-RaidExpMultiplier) ")
|
||||
RULE_REAL(Character, FinalRaidExpMultiplier, 1.0, "Multiplies all raid experience by this value. Default: 1.0")
|
||||
RULE_BOOL(Character, UseXPConScaling, true, "When activated, the experience is modified depending on the difference between player level and NPC level. The values from the rules GreenModifier to RedModifier are used")
|
||||
RULE_INT(Character, ShowExpValues, 0, "Show experience values. 0=normal, 1=show raw experience values, 2=show raw experience values and percent")
|
||||
RULE_INT(Character, GreenModifier, 20, "The experience obtained for green con mobs is multiplied by value/100")
|
||||
@@ -241,6 +242,7 @@ RULE_CATEGORY_END()
|
||||
RULE_CATEGORY(Skills)
|
||||
RULE_INT(Skills, MaxTrainTradeskills, 21, "Highest level for trading skills that can be learnt by the trainer")
|
||||
RULE_BOOL(Skills, UseLimitTradeskillSearchSkillDiff, true, "Enables the limit for the maximum difference between trivial and skill for recipe searches and favorites")
|
||||
RULE_BOOL(Skills, TrivialTradeskillCombinesNoFail, false, "Enable to make all trivial tradeskill combines unable to fail")
|
||||
RULE_INT(Skills, MaxTradeskillSearchSkillDiff, 50, "The maximum difference in skill between the trivial of an item and the skill of the player if the trivial is higher than the skill. Recipes that have not been learnt or made at least once via the Experiment mode will be removed from searches based on this criteria.")
|
||||
RULE_INT(Skills, MaxTrainSpecializations, 50, "Maximum level a GM trainer will train casting specializations")
|
||||
RULE_INT(Skills, SwimmingStartValue, 100, "Start value of swimming skill")
|
||||
@@ -255,7 +257,9 @@ RULE_REAL(Pets, AttackCommandRange, 150, "Range at which a pet will respond to a
|
||||
RULE_BOOL(Pets, UnTargetableSwarmPet, false, "Setting whether swarm pets should be targetable")
|
||||
RULE_REAL(Pets, PetPowerLevelCap, 10, "Maximum number of levels a player pet can go up with pet power")
|
||||
RULE_BOOL(Pets, CanTakeNoDrop, false, "Setting whether anyone can give no-drop items to pets")
|
||||
RULE_BOOL(Pets, CanTakeQuestItems, true, "Setting whether anyone can give quest items to pets")
|
||||
RULE_BOOL(Pets, LivelikeBreakCharmOnInvis, true, "Default: true will break charm on any type of invis (hide/ivu/iva/etc) false will only break if the pet can not see you (ex. you have an undead pet and cast IVU")
|
||||
RULE_BOOL(Pets, ClientPetsUseOwnerNameInLastName, true, "Disable this to keep client pet's last names from being owner_name's pet")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(GM)
|
||||
@@ -285,7 +289,8 @@ RULE_BOOL(World, GMAccountIPList, false, "Check IP list against GM accounts. Thi
|
||||
RULE_INT(World, MinGMAntiHackStatus, 1, "Minimum status to check against AntiHack list")
|
||||
RULE_INT(World, SoFStartZoneID, -1, "Sets the Starting Zone for SoF Clients separate from Titanium Clients (-1 is disabled)")
|
||||
RULE_INT(World, TitaniumStartZoneID, -1, "Sets the Starting Zone for Titanium Clients (-1 is disabled). Replaces the old method")
|
||||
RULE_INT(World, ExpansionSettings, 16383, "Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS, value is bitmask")
|
||||
RULE_INT(World, ExpansionSettings, 16383, "Sets the expansion settings bitmask for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS, value is bitmask")
|
||||
RULE_INT(World, CharacterSelectExpansionSettings, -1, "Sets the expansion settings bitmask for character select if you wish to override. -1 is off")
|
||||
RULE_BOOL(World, UseClientBasedExpansionSettings, true, "If true it will overrule World, ExpansionSettings and set someone's expansion based on the client they're using")
|
||||
RULE_INT(World, PVPSettings, 0, "Sets the PVP settings for the server. 1=Rallos Zek RuleSet, 2=Tallon/Vallon Zek Ruleset, 4=Sullon Zek Ruleset, 6=Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. NOTE: edit IsAttackAllowed in Zone-table to accomodate for these rules")
|
||||
RULE_INT(World, PVPMinLevel, 0, "Minimum level to pvp")
|
||||
@@ -297,6 +302,8 @@ RULE_BOOL(World, StartZoneSameAsBindOnCreation, true, "Should the start zone alw
|
||||
RULE_BOOL(World, EnforceCharacterLimitAtLogin, false, "Enforce the limit for characters that are online at login")
|
||||
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
|
||||
RULE_BOOL(World, EnableChecksumVerification, false, "Enable or Disable the Checksum Verification for eqgame.exe and spells_us.txt")
|
||||
RULE_INT(World, MaximumQuestErrors, 30, "Changes the maximum number of quest errors that can be displayed in #questerrors, default is 30")
|
||||
RULE_INT(World, BootHour, 0, "Sets the in-game hour world will set when it first boots. 0-24 are valid options, where 0 disables this rule")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Zone)
|
||||
@@ -444,11 +451,16 @@ RULE_BOOL(Spells, IllusionsAlwaysPersist, false, "Allows Illusions to persist be
|
||||
RULE_BOOL(Spells, UseItemCastMessage, false, "Enable to use the \"item begins to glow\" messages when casting from an item.")
|
||||
RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove combat range requirement from Target's Target Spell Target Type")
|
||||
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
|
||||
RULE_BOOL(Spells, ResurrectionEffectsBlock, true, "If enabled, resurrection effects cannot be overwritten.")
|
||||
RULE_INT(Spells, ResurrectionEffectBlock, 2, "0 = allow overwrites/rule disabled. If set to 1 = Block all buffs that would overwrite Resurrection Effects. If set to 2 = Will not overwrite Resurrection Effects, instead moves new buff to an empty slot if available. Default is 2.")
|
||||
RULE_BOOL(Spells, WaterMatchRequiredForLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for spells LoS to pass.")
|
||||
RULE_INT(Spells, WizardCritMinimumRandomRatio, 20, "The minimum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 20 for vanilla values.")
|
||||
RULE_INT(Spells, WizardCritMaximumRandomRatio, 70, "The maximum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 70 for vanilla values.")
|
||||
RULE_INT(Spells, DefensiveProcPenaltyLevelGap, 6, "Defensive Proc Penalty Level Gap where procs start losing their proc rate at RuleR(Spells, DefensiveProcPenaltyModifier)% per level difference")
|
||||
RULE_REAL(Spells, DefensiveProcPenaltyLevelGapModifier, 10.0f, "Defensive Proc Penalty Level Gap Modifier where procs start losing their proc rate at defined % after RuleI(Spells, DefensiveProcLevelGap) level difference")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
RULE_REAL(Combat, AERampageSafeZone, 0.018, "max hit ae ramp reduction range")
|
||||
RULE_REAL(Combat, AERampageMaxDistance, 70, "Max AERampage range (% of max combat distance)")
|
||||
RULE_INT(Combat, PetBaseCritChance, 0, "Pet base crit chance")
|
||||
RULE_INT(Combat, NPCBashKickLevel, 6, "The level that NPCcan KICK/BASH")
|
||||
RULE_INT(Combat, MeleeCritDifficulty, 8900, "Value against which is rolled to check if a melee crit is triggered. Lower is easier")
|
||||
@@ -518,6 +530,9 @@ RULE_BOOL(Combat, EnableWarriorShielding, true, "Enable or disable Warrior Shiel
|
||||
RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental weapon damage affecting backstab damage, false by default.")
|
||||
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
|
||||
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
|
||||
RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.")
|
||||
RULE_INT(Combat, ExtraAllowedKickClassesBitmask, 0, "Bitmask for allowing extra classes beyond Warrior, Ranger, Beastlord, and Berserker to kick, No Extra Classes (0) by default")
|
||||
RULE_INT(Combat, MaxProcs, 4, "Adjustable maximum number of procs per round, the hard cap is MAX_PROCS (11). Requires mob repop or client zone when changed")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(NPC)
|
||||
@@ -535,6 +550,7 @@ RULE_INT(NPC, LastFightingDelayMovingMin, 10000, "Minimum time before mob goes h
|
||||
RULE_INT(NPC, LastFightingDelayMovingMax, 20000, "Maximum time before mob goes home after all aggro loss (milliseconds)")
|
||||
RULE_BOOL(NPC, SmartLastFightingDelayMoving, true, "When true, mobs that started going home previously will do so again immediately if still on FD hate list")
|
||||
RULE_BOOL(NPC, ReturnNonQuestNoDropItems, false, "Returns NO DROP items on NPC that don't have an EVENT_TRADE sub in their script")
|
||||
RULE_BOOL(NPC, ReturnQuestItemsFromNonQuestNPCs, false, "Returns Quest items traded to NPCs that are not flagged as a Quest NPC")
|
||||
RULE_INT(NPC, StartEnrageValue, 9, " Percentage HP that an NPC will begin to enrage")
|
||||
RULE_BOOL(NPC, LiveLikeEnrage, false, "If set to true then only player controlled pets will enrage")
|
||||
RULE_BOOL(NPC, EnableMeritBasedFaction, false, "If set to true, faction will be given in the same way as experience (solo/group/raid)")
|
||||
@@ -614,7 +630,7 @@ RULE_BOOL(Bots, FinishBuffing, false, "Allow for buffs to complete even if the b
|
||||
RULE_BOOL(Bots, GroupBuffing, false, "Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB")
|
||||
RULE_INT(Bots, HealRotationMaxMembers, 24, "Maximum number of heal rotation members")
|
||||
RULE_INT(Bots, HealRotationMaxTargets, 12, "Maximum number of heal rotation targets")
|
||||
RULE_REAL(Bots, ManaRegen, 2.0, "Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players")
|
||||
RULE_REAL(Bots, ManaRegen, 2.0, "Adjust mana regen. Acts as a final multiplier, stacks with Rule Character:ManaRegenMultiplier.")
|
||||
RULE_BOOL(Bots, PreferNoManaCommandSpells, true, "Give sorting priority to newer no-mana spells (i.e., 'Bind Affinity')")
|
||||
RULE_BOOL(Bots, QuestableSpawnLimit, false, "Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl")
|
||||
RULE_INT(Bots, SpawnLimit, 71, "Number of bots a character can have spawned at one time, You + 71 bots is a 12 group pseudo-raid")
|
||||
@@ -632,6 +648,7 @@ RULE_BOOL(Bots, OldRaceRezEffects, false, "Older clients had ID 757 for races wi
|
||||
RULE_BOOL(Bots, ResurrectionSickness, true, "Use Resurrection Sickness based on Resurrection spell cast, set to false to disable Resurrection Sickness.")
|
||||
RULE_INT(Bots, OldResurrectionSicknessSpell, 757, "757 is Default Old Resurrection Sickness Spell")
|
||||
RULE_INT(Bots, ResurrectionSicknessSpell, 756, "756 is Default Resurrection Sickness Spell")
|
||||
RULE_BOOL(Bots, AllowPickpocketCommand, true, "Allows the use of the bot command 'pickpocket'")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Chat)
|
||||
@@ -808,6 +825,7 @@ RULE_CATEGORY_END()
|
||||
RULE_CATEGORY(Expansion)
|
||||
RULE_INT(Expansion, CurrentExpansion, -1, "The current expansion enabled for the server [-1 = ALL, 0 = Classic, 1 = Kunark etc.]")
|
||||
RULE_BOOL(Expansion, UseCurrentExpansionAAOnly, false, "When true will only load AA ranks that match CurrentExpansion rule")
|
||||
RULE_INT(Expansion, AutoGrantAAExpansion, -1, "Expansion to auto grant AAs up to, [-1 = Disabled, 0 = Classic, 1 = Kunark etc.]")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Instances)
|
||||
|
||||
+2
-1
@@ -376,7 +376,7 @@ std::string EQ::SayLinkEngine::InjectSaylinksIfNotExist(const char *message)
|
||||
|
||||
void EQ::SayLinkEngine::LoadCachedSaylinks()
|
||||
{
|
||||
auto saylinks = SaylinkRepository::GetWhere(database, "phrase not like '%#%'");
|
||||
auto saylinks = SaylinkRepository::GetWhere(database, "phrase not REGEXP BINARY '[A-Z]' and phrase not REGEXP '[0-9]'");
|
||||
LogSaylink("Loaded [{}] saylinks into cache", saylinks.size());
|
||||
g_cached_saylinks = saylinks;
|
||||
}
|
||||
@@ -399,6 +399,7 @@ SaylinkRepository::Saylink EQ::SayLinkEngine::GetOrSaveSaylink(std::string sayli
|
||||
|
||||
// return if found from the database
|
||||
if (!saylinks.empty()) {
|
||||
g_cached_saylinks.emplace_back(saylinks[0]);
|
||||
return saylinks[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct eq_cpu_info_s {
|
||||
std::string model;
|
||||
|
||||
+105
-83
@@ -10,6 +10,7 @@
|
||||
#include <cereal/types/chrono.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#define SERVER_TIMEOUT 45000 // how often keepalive gets sent
|
||||
#define INTERSERVER_TIMER 10000
|
||||
@@ -113,6 +114,7 @@
|
||||
#define ServerOP_GroupFollowAck 0x0111
|
||||
#define ServerOP_GroupCancelInvite 0x0112
|
||||
#define ServerOP_RaidMOTD 0x0113
|
||||
#define ServerOP_RaidNote 0x0114
|
||||
|
||||
#define ServerOP_InstanceUpdateTime 0x014F
|
||||
#define ServerOP_AdventureRequest 0x0150
|
||||
@@ -235,18 +237,20 @@
|
||||
#define ServerOP_ReloadMerchants 0x4109
|
||||
#define ServerOP_ReloadNPCEmotes 0x4110
|
||||
#define ServerOP_ReloadObjects 0x4111
|
||||
#define ServerOP_ReloadPerlExportSettings 0x4112
|
||||
#define ServerOP_ReloadRules 0x4113
|
||||
#define ServerOP_ReloadStaticZoneData 0x4114
|
||||
#define ServerOP_ReloadTasks 0x4115
|
||||
#define ServerOP_ReloadTitles 0x4116
|
||||
#define ServerOP_ReloadTraps 0x4117
|
||||
#define ServerOP_ReloadVariables 0x4118
|
||||
#define ServerOP_ReloadVeteranRewards 0x4119
|
||||
#define ServerOP_ReloadWorld 0x4120
|
||||
#define ServerOP_ReloadZonePoints 0x4121
|
||||
#define ServerOP_ReloadDzTemplates 0x4122
|
||||
#define ServerOP_ReloadZoneData 0x4123
|
||||
#define ServerOP_ReloadOpcodes 0x4112
|
||||
#define ServerOP_ReloadPerlExportSettings 0x4113
|
||||
#define ServerOP_ReloadRules 0x4114
|
||||
#define ServerOP_ReloadStaticZoneData 0x4115
|
||||
#define ServerOP_ReloadTasks 0x4116
|
||||
#define ServerOP_ReloadTitles 0x4117
|
||||
#define ServerOP_ReloadTraps 0x4118
|
||||
#define ServerOP_ReloadVariables 0x4119
|
||||
#define ServerOP_ReloadVeteranRewards 0x4120
|
||||
#define ServerOP_ReloadWorld 0x4121
|
||||
#define ServerOP_ReloadZonePoints 0x4122
|
||||
#define ServerOP_ReloadDzTemplates 0x4123
|
||||
#define ServerOP_ReloadZoneData 0x4124
|
||||
#define ServerOP_ReloadDataBucketsCache 0x4125
|
||||
|
||||
#define ServerOP_CZDialogueWindow 0x4500
|
||||
#define ServerOP_CZLDoNUpdate 0x4501
|
||||
@@ -284,6 +288,8 @@
|
||||
// player events
|
||||
#define ServerOP_PlayerEvent 0x5100
|
||||
|
||||
#define ServerOP_DataBucketCacheUpdate 0x5200
|
||||
|
||||
enum {
|
||||
CZUpdateType_Character,
|
||||
CZUpdateType_Group,
|
||||
@@ -1071,7 +1077,11 @@ struct ServerRaidMessage_Struct {
|
||||
|
||||
struct ServerRaidMOTD_Struct {
|
||||
uint32 rid;
|
||||
char motd[0];
|
||||
char motd[1024];
|
||||
};
|
||||
|
||||
struct ServerRaidNote_Struct {
|
||||
uint32 rid;
|
||||
};
|
||||
|
||||
struct ServerLFGMatchesRequest_Struct {
|
||||
@@ -1132,10 +1142,10 @@ struct ServerInstanceUpdateTime_Struct
|
||||
uint32 new_duration;
|
||||
};
|
||||
|
||||
struct ServerSpawnStatusChange_Struct
|
||||
{
|
||||
struct ServerSpawnStatusChange_Struct {
|
||||
uint32 id;
|
||||
bool new_status;
|
||||
bool new_status;
|
||||
uint32 instance_id;
|
||||
};
|
||||
|
||||
struct ServerQGlobalUpdate_Struct
|
||||
@@ -1477,95 +1487,96 @@ struct CZClientMessageString_Struct {
|
||||
|
||||
struct CZDialogueWindow_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
char message[4096];
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
char message[4096];
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct CZLDoNUpdate_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Loss, 1 - Points, 2 - Win
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Loss, 1 - Points, 2 - Win
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint32 theme_id;
|
||||
int points; // Only used in Points Subtype, else 1
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
int points; // Only used in Points Subtype, else 1
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct CZMarquee_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint32 type;
|
||||
uint32 priority;
|
||||
uint32 fade_in;
|
||||
uint32 fade_out;
|
||||
uint32 duration;
|
||||
char message[512];
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
char message[512];
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct CZMessage_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
int update_identifier; // Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
int update_identifier; // Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint32 type;
|
||||
char message[512];
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
char message[512];
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct CZMove_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Move Zone, 1 - Move Zone Instance
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint16 instance_id; // Only used by Move Zone Instance, else 0
|
||||
char zone_short_name[32]; // Only by with Move Zone, else empty
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
std::string client_name = std::string(); // Only used by Character Name Type, else empty
|
||||
glm::vec4 coordinates = glm::vec4(0.f); // XYZ or XYZH, heading is optional, defaults to 0.
|
||||
uint16 instance_id = 0; // Only used by Move Zone Instance, else 0
|
||||
uint32 update_identifier = 0; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Move Zone, 1 - Move Zone Instance
|
||||
std::string zone_short_name = std::string(); // Only used by Move Zone, else empty
|
||||
};
|
||||
|
||||
struct CZSetEntityVariable_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
|
||||
int update_identifier; // Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
|
||||
char variable_name[256];
|
||||
char variable_value[256];
|
||||
char client_name[64]; // Only used by Character Type, else empty
|
||||
int update_identifier; // Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
|
||||
char variable_name[256];
|
||||
char variable_value[256];
|
||||
char client_name[64]; // Only used by Character Type, else empty
|
||||
};
|
||||
|
||||
struct CZSignal_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
|
||||
int signal_id;
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
|
||||
int signal_id;
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct CZSpell_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Cast Spell, 1 - Remove Spell
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Cast Spell, 1 - Remove Spell
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint32 spell_id;
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct CZTaskUpdate_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
|
||||
uint8 update_subtype; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
|
||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
|
||||
uint32 task_identifier;
|
||||
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
|
||||
int update_count; // Only used by Activity Update, else 1
|
||||
bool enforce_level_requirement; // Only used by Assign Task
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
|
||||
int update_count; // Only used by Activity Update, else 1
|
||||
bool enforce_level_requirement; // Only used by Assign Task
|
||||
char client_name[64]; // Only used by Character Name Type, else empty
|
||||
};
|
||||
|
||||
struct WWDialogueWindow_Struct {
|
||||
char message[4096];
|
||||
char message[4096];
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWLDoNUpdate_Struct {
|
||||
uint8 update_type; // 0 - Loss, 1 - Points, 2 - Win
|
||||
uint8 update_type; // 0 - Loss, 1 - Points, 2 - Win
|
||||
uint32 theme_id;
|
||||
int points; // Only used in Points Subtype, else 1
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
int points; // Only used in Points Subtype, else 1
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWMarquee_Struct {
|
||||
@@ -1574,56 +1585,57 @@ struct WWMarquee_Struct {
|
||||
uint32 fade_in;
|
||||
uint32 fade_out;
|
||||
uint32 duration;
|
||||
char message[512];
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
char message[512];
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWMessage_Struct {
|
||||
uint32 type;
|
||||
char message[512];
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
char message[512];
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWMove_Struct {
|
||||
uint8 update_type; // 0 - Move Zone, 1 - Move Zone Instance
|
||||
char zone_short_name[32]; // Used with Move Zone
|
||||
uint8 update_type; // 0 - Move Zone, 1 - Move Zone Instance
|
||||
char zone_short_name[32]; // Used with Move Zone
|
||||
uint16 instance_id; // Used with Move Zone Instance
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
|
||||
struct WWSetEntityVariable_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - NPC
|
||||
char variable_name[256];
|
||||
char variable_value[256];
|
||||
char variable_name[256];
|
||||
char variable_value[256];
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWSignal_Struct {
|
||||
uint8 update_type; // 0 - Character, 1 - NPC
|
||||
int signal_id;
|
||||
int signal_id;
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWSpell_Struct {
|
||||
uint8 update_type; // 0 - Cast Spell, 1 - Remove Spell
|
||||
uint8 update_type; // 0 - Cast Spell, 1 - Remove Spell
|
||||
uint32 spell_id;
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct WWTaskUpdate_Struct {
|
||||
uint8 update_type; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
|
||||
uint8 update_type; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
|
||||
uint32 task_identifier;
|
||||
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
|
||||
int update_count; // Update Count for Activity Update, else 1
|
||||
bool enforce_level_requirement; // Only used by Assign Task, else false
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
|
||||
int update_count; // Update Count for Activity Update, else 1
|
||||
bool enforce_level_requirement; // Only used by Assign Task, else false
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
};
|
||||
|
||||
struct ReloadWorld_Struct {
|
||||
@@ -1814,6 +1826,11 @@ struct ServerSendPlayerEvent_Struct {
|
||||
char cereal_data[0];
|
||||
};
|
||||
|
||||
struct ServerDataBucketCacheUpdate_Struct {
|
||||
uint32_t cereal_size;
|
||||
char cereal_data[0];
|
||||
};
|
||||
|
||||
struct ServerFlagUpdate_Struct {
|
||||
uint32 account_id;
|
||||
int16 admin;
|
||||
@@ -1823,6 +1840,11 @@ struct ServerOOCMute_Struct {
|
||||
bool is_muted;
|
||||
};
|
||||
|
||||
struct ServerZoneStatus_Struct {
|
||||
char name[64];
|
||||
int16 admin;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
+94
-50
@@ -51,7 +51,9 @@ namespace ItemField
|
||||
#define F(x) x,
|
||||
#include "item_fieldlist.h"
|
||||
#undef F
|
||||
updated
|
||||
updated,
|
||||
minstatus,
|
||||
comment,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,55 +135,54 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
||||
|
||||
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
||||
{
|
||||
char MailKeyString[17];
|
||||
char mail_key[17];
|
||||
|
||||
if (RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
|
||||
else
|
||||
sprintf(MailKeyString, "%08X", MailKey);
|
||||
if (RuleB(Chat, EnableMailKeyIPVerification) == true) {
|
||||
sprintf(mail_key, "%08X%08X", IPAddress, MailKey);
|
||||
}
|
||||
else {
|
||||
sprintf(mail_key, "%08X", MailKey);
|
||||
}
|
||||
|
||||
const std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||
MailKeyString, CharID);
|
||||
const auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||
const std::string query = StringFormat(
|
||||
"UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||
mail_key, CharID
|
||||
);
|
||||
|
||||
const auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, mail_key, results.ErrorMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string SharedDatabase::GetMailKey(int CharID, bool key_only)
|
||||
SharedDatabase::MailKeys SharedDatabase::GetMailKey(int character_id)
|
||||
{
|
||||
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", character_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
|
||||
Log(Logs::Detail, Logs::MySQLError, "Error retrieving mailkey from database: %s", results.ErrorMessage().c_str());
|
||||
return std::string();
|
||||
return MailKeys{};
|
||||
}
|
||||
|
||||
if (!results.RowCount()) {
|
||||
|
||||
Log(Logs::General, Logs::ClientLogin, "Error: Mailkey for character id [%i] does not exist or could not be found", CharID);
|
||||
return std::string();
|
||||
Log(Logs::General,
|
||||
Logs::ClientLogin,
|
||||
"Error: Mailkey for character id [%i] does not exist or could not be found",
|
||||
character_id
|
||||
);
|
||||
return MailKeys{};
|
||||
}
|
||||
|
||||
auto& row = results.begin();
|
||||
auto &row = results.begin();
|
||||
if (row != results.end()) {
|
||||
|
||||
std::string mail_key = row[0];
|
||||
|
||||
if (mail_key.length() > 8 && key_only) {
|
||||
return mail_key.substr(8);
|
||||
}
|
||||
else {
|
||||
return mail_key;
|
||||
}
|
||||
return MailKeys{
|
||||
.mail_key = mail_key.substr(8),
|
||||
.mail_key_full = mail_key
|
||||
};
|
||||
}
|
||||
else {
|
||||
|
||||
Log(Logs::General, Logs::MySQLError, "Internal MySQL error in SharedDatabase::GetMailKey(int, bool)");
|
||||
return std::string();
|
||||
}
|
||||
return MailKeys{};
|
||||
}
|
||||
|
||||
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQ::ItemInstance*>::const_iterator &start, std::list<EQ::ItemInstance*>::const_iterator &end)
|
||||
@@ -966,7 +967,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
#define F(x) "`"#x"`,"
|
||||
#include "item_fieldlist.h"
|
||||
#undef F
|
||||
"updated FROM items ORDER BY id";
|
||||
"updated, minstatus, comment FROM items ORDER BY id";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
@@ -978,9 +979,13 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
// Unique Identifier
|
||||
item.ID = Strings::ToUnsignedInt(row[ItemField::id]);
|
||||
|
||||
// Name and Lore
|
||||
// Minimum Status
|
||||
item.MinStatus = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::minstatus]));
|
||||
|
||||
// Name, Lore, and Comment
|
||||
strn0cpy(item.Name, row[ItemField::name], sizeof(item.Name));
|
||||
strn0cpy(item.Lore, row[ItemField::lore], sizeof(item.Lore));
|
||||
strn0cpy(item.Comment, row[ItemField::comment], sizeof(item.Comment));
|
||||
|
||||
// Flags
|
||||
item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]);
|
||||
@@ -1636,25 +1641,29 @@ bool SharedDatabase::GetCommandSettings(std::map<std::string, std::pair<uint8, s
|
||||
{
|
||||
command_settings.clear();
|
||||
|
||||
const std::string query = "SELECT `command`, `access`, `aliases` FROM `command_settings`";
|
||||
const std::string& query = "SELECT `command`, `access`, `aliases` FROM `command_settings`";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
for (auto row : results) {
|
||||
command_settings[row[0]].first = Strings::ToUnsignedInt(row[1]);
|
||||
if (row[2][0] == 0)
|
||||
if (row[2][0] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> aliases = Strings::Split(row[2], '|');
|
||||
for (auto iter = aliases.begin(); iter != aliases.end(); ++iter) {
|
||||
if (iter->empty())
|
||||
for (const auto& e : aliases) {
|
||||
if (e.empty()) {
|
||||
continue;
|
||||
command_settings[row[0]].second.push_back(*iter);
|
||||
}
|
||||
|
||||
command_settings[row[0]].second.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected)
|
||||
@@ -1669,13 +1678,15 @@ bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<s
|
||||
)
|
||||
);
|
||||
|
||||
if (!QueryDatabase(query).Success()) {
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"[{0}] New Command(s) Added",
|
||||
injected.size()
|
||||
"[{}] New Command{} Added",
|
||||
injected.size(),
|
||||
injected.size() != 1 ? "s" : ""
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1685,25 +1696,58 @@ bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<s
|
||||
bool SharedDatabase::UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned)
|
||||
{
|
||||
if (orphaned.size()) {
|
||||
const std::string query = fmt::format(
|
||||
std::string query = fmt::format(
|
||||
"DELETE FROM `command_settings` WHERE `command` IN ({})",
|
||||
Strings::ImplodePair(",", std::pair<char, char>('\'', '\''), orphaned)
|
||||
);
|
||||
|
||||
if (!QueryDatabase(query).Success()) {
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
query = fmt::format(
|
||||
"DELETE FROM `command_subsettings` WHERE `parent_command` IN ({})",
|
||||
Strings::ImplodePair(",", std::pair<char, char>('\'', '\''), orphaned)
|
||||
);
|
||||
|
||||
auto results_two = QueryDatabase(query);
|
||||
if (!results_two.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"{} Orphaned Command{} Deleted",
|
||||
"{} Orphaned Command{} Deleted | {} Orphaned Subcommand{} Deleted",
|
||||
orphaned.size(),
|
||||
(orphaned.size() == 1 ? "" : "s")
|
||||
orphaned.size() != 1 ? "s" : "",
|
||||
results_two.RowsAffected(),
|
||||
results_two.RowsAffected() != 1 ? "s" : ""
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings)
|
||||
{
|
||||
command_subsettings.clear();
|
||||
|
||||
const auto& l = CommandSubsettingsRepository::GetAll(*this);
|
||||
|
||||
if (l.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
command_subsettings.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
command_subsettings.emplace_back(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SharedDatabase::LoadSkillCaps(const std::string &prefix) {
|
||||
skill_caps_mmf.reset(nullptr);
|
||||
|
||||
|
||||
+7
-1
@@ -28,6 +28,7 @@
|
||||
#include "fixed_memory_hash_set.h"
|
||||
#include "fixed_memory_variable_hash_set.h"
|
||||
#include "say_link.h"
|
||||
#include "repositories/command_subsettings_repository.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -77,11 +78,16 @@ public:
|
||||
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
|
||||
bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
|
||||
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
|
||||
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
|
||||
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
||||
bool SetGMInvul(uint32 account_id, bool gminvul);
|
||||
bool SetGMFlymode(uint32 account_id, uint8 flymode);
|
||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
||||
std::string GetMailKey(int CharID, bool key_only = false);
|
||||
struct MailKeys {
|
||||
std::string mail_key;
|
||||
std::string mail_key_full;
|
||||
};
|
||||
MailKeys GetMailKey(int character_id);
|
||||
bool SaveCursor(
|
||||
uint32 char_id,
|
||||
std::list<EQ::ItemInstance *>::const_iterator &start,
|
||||
|
||||
+1177
-700
File diff suppressed because it is too large
Load Diff
+101
-60
@@ -171,6 +171,37 @@
|
||||
#define SPELL_ILLUSION_MALE 1732
|
||||
#define SPELL_UNSUMMON_SELF 892
|
||||
#define SPELL_ANCIENT_LIFEBANE 2115
|
||||
#define SPELL_GMHP25K 6817
|
||||
#define SPELL_GMHP50K 6818
|
||||
#define SPELL_GMHP100K 6819
|
||||
#define SPELL_GMHP225K 6820
|
||||
#define SPELL_GMHP475K 6821
|
||||
#define SPELL_GMHP925K 6822
|
||||
#define SPELL_GMHP2M 6823
|
||||
#define SPELL_GMHP3M 6824
|
||||
#define SPELL_GMHP5M 39851
|
||||
#define SPELL_GUIDE_ACTING_ONE 778
|
||||
#define SPELL_GUIDE_ALLIANCE_ONE 810
|
||||
#define SPELL_GUIDE_CANCEL_MAGIC_ONE 811
|
||||
#define SPELL_GUIDE_JOURNEY_ONE 813
|
||||
#define SPELL_GUIDE_VISION_ONE 814
|
||||
#define SPELL_GUIDE_HEALTH_ONE 815
|
||||
#define SPELL_GUIDE_INVULNERABILITY_ONE 816
|
||||
#define SPELL_GUIDE_BOLT_ONE 817
|
||||
#define SPELL_GUIDE_MEMORY_BLUR_ONE 818
|
||||
#define SPELL_GUIDE_ACTING_TWO 1209
|
||||
#define SPELL_GUIDE_CANCEL_MAGIC_TWO 1211
|
||||
#define SPELL_GUIDE_JOURNEY_TWO 1212
|
||||
#define SPELL_GUIDE_VISION_TWO 1213
|
||||
#define SPELL_GUIDE_HEALTH_TWO 1214
|
||||
#define SPELL_GUIDE_INVULNERABILITY_TWO 1215
|
||||
#define SPELL_GUIDE_BOLT_TWO 1216
|
||||
#define SPELL_GUIDE_MEMORY_BLUR_TWO 1217
|
||||
#define SPELL_GUIDE_ALLIANCE_TWO 1219
|
||||
#define SPELL_GUIDE_EVACUATION 3921
|
||||
#define SPELL_GUIDE_LEVITATION 39852
|
||||
#define SPELL_GUIDE_SPELL_HASTE 39853
|
||||
#define SPELL_GUIDE_HASTE 39854
|
||||
|
||||
//spellgroup ids
|
||||
#define SPELLGROUP_FRENZIED_BURNOUT 2754
|
||||
@@ -201,8 +232,22 @@
|
||||
#define INSTRUMENT_LUTE 13011
|
||||
#define INSTRUMENT_HORN 13012
|
||||
|
||||
//option types for the rule Spells:ResurrectionEffectBlock
|
||||
#define RES_EFFECTS_CANNOT_STACK -1
|
||||
#define NO_RES_EFFECTS_BLOCK 0
|
||||
#define RES_EFFECTS_BLOCK 1
|
||||
#define RES_EFFECTS_BLOCK_WITH_BUFFS 2
|
||||
#define MOVE_NEW_SLOT 2
|
||||
|
||||
const int Z_AGGRO=10;
|
||||
#define PARTIAL_DEATH_SAVE 1
|
||||
#define FULL_DEATH_SAVE 2
|
||||
|
||||
#define MAX_FAST_HEAL_CASTING_TIME 2000
|
||||
#define MAX_VERY_FAST_HEAL_CASTING_TIME 1000
|
||||
|
||||
#define DETRIMENTAL_EFFECT 0
|
||||
#define BENEFICIAL_EFFECT 1
|
||||
#define BENEFICIAL_EFFECT_GROUP_ONLY 2
|
||||
|
||||
const uint32 MobAISpellRange=100; // max range of buffs
|
||||
|
||||
@@ -1160,7 +1205,7 @@ typedef enum {
|
||||
#define SE_LimitUseMin 422 // implemented, @Ff Minium amount of numhits for a spell to be focused, base: numhit amt
|
||||
#define SE_LimitUseType 423 // implemented, @Ff Focus will only affect if has this numhits type, base: numhit type
|
||||
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
|
||||
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
|
||||
#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
|
||||
#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
|
||||
#define SE_SkillProcAttempt 427 // implemented - chance to proc when using a skill(ie taunt)
|
||||
#define SE_LimitToSkill 428 // implemented, @Procs, limits what combat skills will effect a skill proc, base: skill value, limit: none, max: none
|
||||
@@ -1443,7 +1488,7 @@ extern int32 SPDAT_RECORDS;
|
||||
bool IsTargetableAESpell(uint16 spell_id);
|
||||
bool IsSacrificeSpell(uint16 spell_id);
|
||||
bool IsLifetapSpell(uint16 spell_id);
|
||||
bool IsMezSpell(uint16 spell_id);
|
||||
bool IsMesmerizeSpell(uint16 spell_id);
|
||||
bool IsStunSpell(uint16 spell_id);
|
||||
bool IsSlowSpell(uint16 spell_id);
|
||||
bool IsHasteSpell(uint16 spell_id);
|
||||
@@ -1452,22 +1497,23 @@ bool IsPercentalHealSpell(uint16 spell_id);
|
||||
bool IsGroupOnlySpell(uint16 spell_id);
|
||||
bool IsBeneficialSpell(uint16 spell_id);
|
||||
bool IsDetrimentalSpell(uint16 spell_id);
|
||||
bool IsInvisSpell(uint16 spell_id);
|
||||
bool IsInvisibleSpell(uint16 spell_id);
|
||||
bool IsInvulnerabilitySpell(uint16 spell_id);
|
||||
bool IsCHDurationSpell(uint16 spell_id);
|
||||
bool IsCompleteHealDurationSpell(uint16 spell_id);
|
||||
bool IsPoisonCounterSpell(uint16 spell_id);
|
||||
bool IsDiseaseCounterSpell(uint16 spell_id);
|
||||
bool IsSummonItemSpell(uint16 spell_id);
|
||||
bool IsSummonSkeletonSpell(uint16 spell_id);
|
||||
bool IsSummonPetSpell(uint16 spell_id);
|
||||
bool IsSummonPCSpell(uint16 spell_id);
|
||||
bool IsPetSpell(uint16 spell_id);
|
||||
bool IsCharmSpell(uint16 spell_id);
|
||||
bool IsBlindSpell(uint16 spell_id);
|
||||
bool IsEffectHitpointsSpell(uint16 spell_id);
|
||||
bool IsReduceCastTimeSpell(uint16 spell_id);
|
||||
bool IsHealthSpell(uint16 spell_id);
|
||||
bool IsCastTimeReductionSpell(uint16 spell_id);
|
||||
bool IsIncreaseDurationSpell(uint16 spell_id);
|
||||
bool IsReduceManaSpell(uint16 spell_id);
|
||||
bool IsExtRangeSpell(uint16 spell_id);
|
||||
bool IsManaCostReductionSpell(uint16 spell_id);
|
||||
bool IsIncreaseRangeSpell(uint16 spell_id);
|
||||
bool IsImprovedHealingSpell(uint16 spell_id);
|
||||
bool IsImprovedDamageSpell(uint16 spell_id);
|
||||
bool IsAEDurationSpell(uint16 spell_id);
|
||||
@@ -1475,26 +1521,22 @@ bool IsPureNukeSpell(uint16 spell_id);
|
||||
bool IsAENukeSpell(uint16 spell_id);
|
||||
bool IsPBAENukeSpell(uint16 spell_id);
|
||||
bool IsAERainNukeSpell(uint16 spell_id);
|
||||
bool IsPartialCapableSpell(uint16 spell_id);
|
||||
bool IsPartialResistableSpell(uint16 spell_id);
|
||||
bool IsResistableSpell(uint16 spell_id);
|
||||
bool IsGroupSpell(uint16 spell_id);
|
||||
bool IsTGBCompatibleSpell(uint16 spell_id);
|
||||
bool IsBardSong(uint16 spell_id);
|
||||
bool IsEffectInSpell(uint16 spellid, int effect);
|
||||
uint16 GetTriggerSpellID(uint16 spell_id, uint32 effect);
|
||||
bool IsBlankSpellEffect(uint16 spellid, int effect_index);
|
||||
bool IsValidSpell(uint32 spellid);
|
||||
bool IsSummonSpell(uint16 spellid);
|
||||
bool IsEvacSpell(uint16 spellid);
|
||||
bool IsDamageSpell(uint16 spellid);
|
||||
bool IsFearSpell(uint16 spellid);
|
||||
bool IsCureSpell(uint16 spellid);
|
||||
bool BeneficialSpell(uint16 spell_id);
|
||||
bool GroupOnlySpell(uint16 spell_id);
|
||||
int GetSpellEffectIndex(uint16 spell_id, int effect);
|
||||
int CanUseSpell(uint16 spellid, int classa, int level);
|
||||
int GetMinLevel(uint16 spell_id);
|
||||
int GetSpellLevel(uint16 spell_id, int classa);
|
||||
bool IsEffectInSpell(uint16 spell_id, int effect_id);
|
||||
uint16 GetSpellTriggerSpellID(uint16 spell_id, int effect_id);
|
||||
bool IsBlankSpellEffect(uint16 spell_id, int effect_index);
|
||||
bool IsValidSpell(uint32 spell_id);
|
||||
bool IsSummonSpell(uint16 spell_id);
|
||||
bool IsDamageSpell(uint16 spell_id);
|
||||
bool IsFearSpell(uint16 spell_id);
|
||||
bool IsCureSpell(uint16 spell_id);
|
||||
int GetSpellEffectIndex(uint16 spell_id, int effect_id);
|
||||
uint8 GetSpellMinimumLevel(uint16 spell_id);
|
||||
uint8 GetSpellLevel(uint16 spell_id, uint8 class_id);
|
||||
int CalcBuffDuration_formula(int level, int formula, int duration);
|
||||
int32 CalculatePoisonCounters(uint16 spell_id);
|
||||
int32 CalculateDiseaseCounters(uint16 spell_id);
|
||||
@@ -1505,10 +1547,11 @@ bool IsDisciplineBuff(uint16 spell_id);
|
||||
bool IsDiscipline(uint16 spell_id);
|
||||
bool IsCombatSkill(uint16 spell_id);
|
||||
bool IsResurrectionEffects(uint16 spell_id);
|
||||
int8 GetSpellResurrectionSicknessCheck(uint16 spell_id_one, uint16 spell_id_two);
|
||||
bool IsRuneSpell(uint16 spell_id);
|
||||
bool IsMagicRuneSpell(uint16 spell_id);
|
||||
bool IsManaTapSpell(uint16 spell_id);
|
||||
bool IsAllianceSpellLine(uint16 spell_id);
|
||||
bool IsAllianceSpell(uint16 spell_id);
|
||||
bool IsDeathSaveSpell(uint16 spell_id);
|
||||
bool IsFullDeathSaveSpell(uint16 spell_id);
|
||||
bool IsPartialDeathSaveSpell(uint16 spell_id);
|
||||
@@ -1517,10 +1560,10 @@ bool IsSuccorSpell(uint16 spell_id);
|
||||
bool IsTeleportSpell(uint16 spell_id);
|
||||
bool IsTranslocateSpell(uint16 spell_id);
|
||||
bool IsGateSpell(uint16 spell_id);
|
||||
bool IsPlayerIllusionSpell(uint16 spell_id); // seveian 2008-09-23
|
||||
bool IsIllusionSpell(uint16 spell_id);
|
||||
bool IsLDoNObjectSpell(uint16 spell_id);
|
||||
int32 GetSpellResistType(uint16 spell_id);
|
||||
int32 GetSpellTargetType(uint16 spell_id);
|
||||
int GetSpellResistType(uint16 spell_id);
|
||||
int GetSpellTargetType(uint16 spell_id);
|
||||
bool IsHealOverTimeSpell(uint16 spell_id);
|
||||
bool IsCompleteHealSpell(uint16 spell_id);
|
||||
bool IsFastHealSpell(uint16 spell_id);
|
||||
@@ -1535,38 +1578,36 @@ bool IsSelfConversionSpell(uint16 spell_id);
|
||||
bool IsBuffSpell(uint16 spell_id);
|
||||
bool IsPersistDeathSpell(uint16 spell_id);
|
||||
bool IsSuspendableSpell(uint16 spell_id);
|
||||
uint32 GetMorphTrigger(uint32 spell_id);
|
||||
bool IsCastonFadeDurationSpell(uint16 spell_id);
|
||||
bool IsPowerDistModSpell(uint16 spell_id);
|
||||
uint32 GetPartialMeleeRuneReduction(uint32 spell_id);
|
||||
uint32 GetPartialMagicRuneReduction(uint32 spell_id);
|
||||
uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
|
||||
uint32 GetPartialMagicRuneAmount(uint32 spell_id);
|
||||
bool NoDetrimentalSpellAggro(uint16 spell_id);
|
||||
bool IsStackableDot(uint16 spell_id);
|
||||
bool IsBardOnlyStackEffect(int effect);
|
||||
bool IsCastWhileInvis(uint16 spell_id);
|
||||
bool IsEffectIgnoredInStacking(int spa);
|
||||
bool IsFocusLimit(int spa);
|
||||
bool SpellRequiresTarget(int target_type);
|
||||
bool IsVirusSpell(int32 spell_id);
|
||||
int GetViralMinSpreadTime(int32 spell_id);
|
||||
int GetViralMaxSpreadTime(int32 spell_id);
|
||||
int GetViralSpreadRange(int32 spell_id);
|
||||
bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect);
|
||||
bool IsPulsingBardSong(int32 spell_id);
|
||||
uint32 GetProcLimitTimer(int32 spell_id, int proc_type);
|
||||
bool IgnoreCastingRestriction(int32 spell_id);
|
||||
int CalcPetHp(int levelb, int classb, int STA = 75);
|
||||
int GetSpellEffectDescNum(uint16 spell_id);
|
||||
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
|
||||
bool DetrimentalSpellAllowsRest(uint16 spell_id);
|
||||
uint32 GetNimbusEffect(uint16 spell_id);
|
||||
int32 GetFuriousBash(uint16 spell_id);
|
||||
bool IsCastOnFadeDurationSpell(uint16 spell_id);
|
||||
bool IsDistanceModifierSpell(uint16 spell_id);
|
||||
int GetSpellPartialMeleeRuneReduction(uint16 spell_id);
|
||||
int GetSpellPartialMagicRuneReduction(uint16 spell_id);
|
||||
int GetSpellPartialMeleeRuneAmount(uint16 spell_id);
|
||||
int GetSpellPartialMagicRuneAmount(uint16 spell_id);
|
||||
bool IsNoDetrimentalSpellAggroSpell(uint16 spell_id);
|
||||
bool IsStackableDOT(uint16 spell_id);
|
||||
bool IsBardOnlyStackEffect(int effect_id);
|
||||
bool IsCastWhileInvisibleSpell(uint16 spell_id);
|
||||
bool IsEffectIgnoredInStacking(int effect_id);
|
||||
bool IsFocusLimit(int effect_id);
|
||||
bool IsTargetRequiredForSpell(uint16 spell_id);
|
||||
bool IsVirusSpell(uint16 spell_id);
|
||||
int GetSpellViralMinimumSpreadTime(uint16 spell_id);
|
||||
int GetSpellViralMaximumSpreadTime(uint16 spell_id);
|
||||
int GetSpellViralSpreadRange(uint16 spell_id);
|
||||
bool IsInstrumentModifierAppliedToSpellEffect(uint16 spell_id, int effect_id);
|
||||
bool IsPulsingBardSong(uint16 spell_id);
|
||||
int GetSpellProcLimitTimer(uint16 spell_id, int proc_type);
|
||||
bool IsCastNotStandingSpell(uint16 spell_id);
|
||||
int GetSpellEffectDescriptionNumber(uint16 spell_id);
|
||||
DmgShieldType GetDamageShieldType(uint16 spell_id, int damage_shield_type = 0);
|
||||
bool IsRestAllowedSpell(uint16 spell_id);
|
||||
int GetSpellNimbusEffect(uint16 spell_id);
|
||||
int GetSpellFuriousBash(uint16 spell_id);
|
||||
bool IsShortDurationBuff(uint16 spell_id);
|
||||
bool IsSpellUsableThisZoneType(uint16 spell_id, uint8 zone_type);
|
||||
bool IsSpellUsableInThisZoneType(uint16 spell_id, uint8 zone_type);
|
||||
const char *GetSpellName(uint16 spell_id);
|
||||
int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot = 0);
|
||||
bool CastRestrictedSpell(int spellid);
|
||||
int GetSpellStatValue(uint16 spell_id, const char* stat_identifier, uint8 slot = 0);
|
||||
bool IsCastRestrictedSpell(uint16 spell_id);
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user