mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 17:26:30 +00:00
Compare commits
336 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 22fb7b22b4 | |||
| dfb089b0c1 | |||
| d9d2d5d47c | |||
| ac4ffefa09 | |||
| c228604255 | |||
| 59292b15f6 | |||
| 843f6531a7 | |||
| 432452c5c7 | |||
| f3a2f97155 | |||
| 9e07d90664 | |||
| 4fe229c475 | |||
| 4658e7f60d | |||
| 95559b2e17 | |||
| 7ad63575c7 | |||
| bc6b21f601 | |||
| 05c7e6409d | |||
| 60ba76b39c | |||
| 41009aa19b | |||
| ed7023f336 | |||
| e0d95b4302 | |||
| 537b585791 | |||
| 1a48add20e | |||
| 1650efa787 | |||
| 0dde51f518 | |||
| 5cebc42f89 | |||
| 7021602bf4 | |||
| 752ac78c56 | |||
| e9678da311 | |||
| 51f25ed779 | |||
| 8f4f8368df | |||
| 21d27a1122 | |||
| 6519fb40c7 | |||
| ff2763785c | |||
| f1852e16b7 | |||
| 49917bfb13 | |||
| ff86cc3b8a | |||
| 91a0e14509 | |||
| 6fb919a16f | |||
| d1d6db3a09 | |||
| e3ab90695f | |||
| aa423e398a | |||
| 1cf7709c9d | |||
| f466964db8 | |||
| 4fda3c045e | |||
| 0a20100d12 | |||
| 29701d0ea7 | |||
| 4a38fd8829 | |||
| 08c8e0d81f | |||
| c966f26ac1 | |||
| fe66c24352 | |||
| bdcded7d45 | |||
| f939f25aa1 | |||
| 401f1038f3 | |||
| 95c6560e7c | |||
| 59f645b5c3 | |||
| bbfed8300c | |||
| 07c762068f | |||
| 6525051d2d | |||
| b7f94e8315 | |||
| d1f368ab7f | |||
| 1f3ac2dc4f | |||
| 7a226ca4ef | |||
| 119151c0e3 | |||
| faa8a492f7 | |||
| 2926b4df78 | |||
| 986eda44aa | |||
| b2f71f16fc | |||
| 861eac3660 | |||
| a376bc4471 | |||
| e83d0942ad | |||
| 31abaf8016 | |||
| 0acad18067 | |||
| 90c37390f1 | |||
| dba494cd8e | |||
| 37ced4b003 | |||
| d13c725a74 | |||
| 25826c6686 | |||
| 1a27127c39 | |||
| 75698a809f | |||
| 37a7b7fc41 | |||
| f21cc170df | |||
| d47bf687d0 | |||
| 035c51944f | |||
| c2ebc2540a | |||
| c82f1b9afc | |||
| 15684567cf | |||
| 533dc997fd | |||
| 03b30d5c7a | |||
| d89f9bdcc7 | |||
| 490cffb5ea | |||
| d95b64e0b8 | |||
| 1ed282f6ff | |||
| a3a498634f | |||
| c44596b38a | |||
| fe43d26dd6 | |||
| 3155b82abb | |||
| 4c6aaa6995 | |||
| c82dee575a | |||
| 33db85f2ee | |||
| b40e4ce7cd | |||
| 20ff325013 | |||
| 8a7d5e72cb | |||
| 4493ebebab | |||
| 77793f364e | |||
| e258aaa068 | |||
| 3b779ef301 | |||
| 3f3c0f2fda | |||
| 0f164c456e | |||
| 6172c49b08 | |||
| 66a7dd0143 | |||
| 5c6e7a8b09 | |||
| bd85fc96a0 | |||
| 8e40e5357c | |||
| 5f0b999ca9 | |||
| fe9df46a24 | |||
| 3d7cf4235c | |||
| 187ee10218 | |||
| 6bd758b3dd | |||
| 9938755517 | |||
| 630da0eee6 | |||
| 3158386aa3 | |||
| 12ada57ee8 | |||
| 7a841c11c5 | |||
| a49d1446b7 | |||
| b2d0fa6a2f | |||
| 62ac015fff | |||
| 4977a7c2e0 | |||
| 9967384ab8 | |||
| d3da2e5501 | |||
| 33f5c4c6a7 | |||
| e4aa6a6957 | |||
| e4d812f4b4 | |||
| bcedfe7032 | |||
| c1df3fbcb0 | |||
| 011e1d05e7 | |||
| 3f0f95976c | |||
| 77de9619b5 | |||
| 20d3ab2ac5 | |||
| 0ea47fadee | |||
| 1ce51ca3b0 | |||
| 25ef3d2cdb | |||
| 95249889a6 | |||
| 428cccfa50 | |||
| 41dd8a5754 | |||
| d02d766563 | |||
| dfd2729b28 | |||
| b92eafd21b | |||
| d6d5d992cb | |||
| d524cb6a5a | |||
| e6469878ce | |||
| 9583099ace | |||
| cf3483b402 | |||
| 311af7bbe9 | |||
| be42b73f5c | |||
| f76c798910 | |||
| ae198ae043 | |||
| 520943ebf1 | |||
| 9ac306fe67 | |||
| 7a1d69d0d4 | |||
| c873fe5a22 | |||
| e06b0c4b0c | |||
| ed2130f649 | |||
| 448a33a60c | |||
| 8f86cb353e | |||
| 178129443f | |||
| a7c3b41afc | |||
| a5a568d548 | |||
| e3198edb86 | |||
| 8568cf7d49 | |||
| 1fb7a860a1 | |||
| 7eaee2649e | |||
| a17f467b98 | |||
| 3359839a9b | |||
| 7e51e629f9 | |||
| dc6c28a52d | |||
| 78aee0780a | |||
| bcd943a964 | |||
| 56608e84bd | |||
| 8d23e710ce | |||
| 4d11077b21 | |||
| 5c0bdfdc4c | |||
| 6130e10831 | |||
| c3e1c531d2 | |||
| b52719a535 | |||
| 1af252466f | |||
| 699d22fc28 | |||
| 5d1fe68906 | |||
| 52dcf35425 | |||
| a7550fbd9e | |||
| cc0171dfe1 | |||
| 913c5da70f | |||
| 40fecbfaf5 | |||
| b1646381b0 | |||
| bb1578796b | |||
| 0e5a38f072 | |||
| 39876ab858 | |||
| ff16a76481 | |||
| ffd68eb63d | |||
| 76c1da1aad | |||
| a91e03fa43 | |||
| 453106439f | |||
| 3da24fffa4 | |||
| 8d8ef6d480 | |||
| 1f9c4b3a22 | |||
| 7dfda95d86 | |||
| 40738b29e3 | |||
| 080865faa2 | |||
| e2b545991a | |||
| b7f8d0f179 | |||
| e3588781aa | |||
| e9b84f4d11 | |||
| 4f03970fd1 | |||
| 4979da6932 | |||
| 9987029791 | |||
| eece0a92e3 | |||
| 057f96796a | |||
| f475cecdb1 | |||
| 6296ed6d41 | |||
| ac0f729aa2 | |||
| 2937852cf9 | |||
| 2cf5bae571 | |||
| 2feb05be18 | |||
| 421767e1e5 | |||
| 6e9ff52dce | |||
| aa700f8960 | |||
| 2ef959c5ed | |||
| e49ab924cc | |||
| fc3c691588 | |||
| d465a3deba | |||
| 40c9c8044b | |||
| 70a96ea098 | |||
| d5cbec714e | |||
| 6903205484 | |||
| 4c81321847 | |||
| e5cea73e0c | |||
| 23308192b5 | |||
| 29fdf7e2ae | |||
| 098498dedd | |||
| b6fb8daae8 | |||
| 563f7d5564 | |||
| 1e5abc456b | |||
| 3b0fa015a7 | |||
| c73a1e8bea | |||
| 3bfdc0cf71 | |||
| a23ac4628f | |||
| 5ef4612249 | |||
| 17f66c5d60 | |||
| 51eb95ed31 | |||
| 080abaede1 | |||
| 97e332819d | |||
| 1e41c5517e | |||
| c7a88af11a | |||
| d8ddd0aab9 | |||
| 95cbadade5 | |||
| a85f4fb703 | |||
| e63f34638b | |||
| 7918fed81c | |||
| ac24c9bf5a | |||
| 7b914c731b | |||
| 7362c0ebb5 | |||
| ae213a4e4b | |||
| 187288f3aa | |||
| abc8c3d886 | |||
| 0b2493beb8 | |||
| 9cebba5911 | |||
| 4478328b2a | |||
| 55a7e1646d | |||
| b6b8491060 | |||
| 850053a136 | |||
| 1aa8758b0a | |||
| b1aa087b9f | |||
| 1e57a0372f | |||
| 9614ea59ec | |||
| 7a648cce16 | |||
| 8640776a21 | |||
| 0c45d3b09e | |||
| 59e4adb117 | |||
| d5a06bfe2e | |||
| 0f0676824c | |||
| caa647dc6b | |||
| 76b9ce0ac1 | |||
| d01d091b47 | |||
| 47ddcb54f1 | |||
| dda0e410ff | |||
| eae05167f8 | |||
| 16f21893a3 | |||
| 4ca724956b | |||
| 217a80ee76 | |||
| 8b166bf5b9 | |||
| 4c614661e7 | |||
| 9392f86333 | |||
| 0d888268a8 | |||
| b044d8533e | |||
| d810cb02c3 | |||
| 992a5cc132 | |||
| c50fda0f73 | |||
| 1b15f16e3e | |||
| 983cc1e82a | |||
| fc79614fac | |||
| d767217461 | |||
| 1310c5d528 | |||
| b253fce0d5 | |||
| 421857026d | |||
| 68f40c9255 | |||
| 0bceee5622 | |||
| cd03152550 | |||
| 316fa54bd8 | |||
| 49957e3269 | |||
| 9638d9af3a | |||
| 87c207e862 | |||
| 2df5f3f55a | |||
| e803d3e1e1 | |||
| fccb205a1d | |||
| f70078d62a | |||
| 34ae3094d6 | |||
| c56742a2a8 | |||
| 3e34447172 | |||
| ca25122bfa | |||
| 13a7532ef8 | |||
| e1344039ff | |||
| 98b137154a | |||
| fc9ef2fb7b | |||
| 6dc661032f | |||
| 2586527157 | |||
| 3a51f04291 | |||
| 66af3d2f63 | |||
| 6bcd8fea18 | |||
| 0d1cbecb55 | |||
| e33e076b2a | |||
| e26d17182e | |||
| 7e40c5bac2 | |||
| ca69cc67e8 | |||
| 099c6d657b | |||
| c0a8fd097e | |||
| a80ab75260 | |||
| c87aadbf0c |
@@ -68,3 +68,4 @@ compile_flags.txt
|
|||||||
|
|
||||||
# CMake Files
|
# CMake Files
|
||||||
cmake-build-relwithdebinfo/*
|
cmake-build-relwithdebinfo/*
|
||||||
|
skill-caps.diff
|
||||||
|
|||||||
+639
@@ -1,3 +1,642 @@
|
|||||||
|
## [22.62.2] 2/1/2025
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add price change check to the Bazaar Search Window purchase mechanics ([#4632](https://github.com/EQEmu/Server/pull/4632)) @neckkola 2025-02-01
|
||||||
|
* NewBazaar Search Consumables ([#4631](https://github.com/EQEmu/Server/pull/4631)) @neckkola 2025-02-01
|
||||||
|
* Update the shard bazaar search feature ([#4630](https://github.com/EQEmu/Server/pull/4630)) @neckkola 2025-02-01
|
||||||
|
|
||||||
|
### Memory Leak
|
||||||
|
|
||||||
|
* Revert " Change raw pointer to unique_ptr to avoid potential leak in dbg stream " ([#4616](https://github.com/EQEmu/Server/pull/4616)) @Akkadius 2025-01-27
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Significantly Improve Client Network Resends ([#4629](https://github.com/EQEmu/Server/pull/4629)) @Akkadius 2025-02-01
|
||||||
|
|
||||||
|
## [22.62.1] 1/27/2025
|
||||||
|
|
||||||
|
### Memory Leak
|
||||||
|
|
||||||
|
* Revert "Change raw pointer to unique_ptr to avoid potential leak in dbg stream" ([#4616](https://github.com/EQEmu/Server/pull/4616)) @Akkadius 2025-01-27
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Re-use ClientUpdate packet memory ([#4619](https://github.com/EQEmu/Server/pull/4619)) @Akkadius 2025-01-27
|
||||||
|
* Re-use OP_Animation packet ([#4621](https://github.com/EQEmu/Server/pull/4621)) @Akkadius 2025-01-27
|
||||||
|
* Re-use OP_Damage packet memory ([#4625](https://github.com/EQEmu/Server/pull/4625)) @Akkadius 2025-01-27
|
||||||
|
* Re-use OP_HPUpdate packet memory ([#4622](https://github.com/EQEmu/Server/pull/4622)) @Akkadius 2025-01-27
|
||||||
|
* Re-use OP_PlayerStateAdd packet memory ([#4626](https://github.com/EQEmu/Server/pull/4626)) @Akkadius 2025-01-27
|
||||||
|
* Re-use OP_SendFindableNPCs packet memory ([#4623](https://github.com/EQEmu/Server/pull/4623)) @Akkadius 2025-01-27
|
||||||
|
|
||||||
|
### Repop
|
||||||
|
|
||||||
|
* Make #repop instant ([#4620](https://github.com/EQEmu/Server/pull/4620)) @Akkadius 2025-01-27
|
||||||
|
|
||||||
|
## [22.62.0] 1/26/2025
|
||||||
|
|
||||||
|
### Bazaar
|
||||||
|
|
||||||
|
* Improve Bazaar Search Performance ([#4615](https://github.com/EQEmu/Server/pull/4615)) @neckkola 2025-01-27
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
* Add --skip-backup to world database:updates ([#4605](https://github.com/EQEmu/Server/pull/4605)) @Akkadius 2025-01-22
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Change npc_types walkspeed to be of type float ([#4589](https://github.com/EQEmu/Server/pull/4589)) @Akkadius 2025-01-07
|
||||||
|
|
||||||
|
### Databuckets
|
||||||
|
|
||||||
|
* Add Account Scoped Databuckets ([#4603](https://github.com/EQEmu/Server/pull/4603)) @Akkadius 2025-01-21
|
||||||
|
* Implement Nested Databuckets ([#4604](https://github.com/EQEmu/Server/pull/4604)) @Akkadius 2025-01-27
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Alternate Bazaar Search Approach ([#4600](https://github.com/EQEmu/Server/pull/4600)) @neckkola 2025-01-20
|
||||||
|
* Add Support for Item Previews ([#4599](https://github.com/EQEmu/Server/pull/4599)) @Kinglykrab 2025-01-20
|
||||||
|
* Evolving Item Support for RoF2 ([#4496](https://github.com/EQEmu/Server/pull/4496)) @neckkola 2025-01-20
|
||||||
|
* Implement Custom Pet Names ([#4594](https://github.com/EQEmu/Server/pull/4594)) @catapultam-habeo 2025-01-22
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add Bazaar BulkSendTrader Limit for RoF2 ([#4590](https://github.com/EQEmu/Server/pull/4590)) @neckkola 2025-01-08
|
||||||
|
* CLI help menu from parsing correctly in World @Akkadius 2025-01-22
|
||||||
|
* Delete later in RemoveItem second case @Akkadius 2025-01-25
|
||||||
|
* Fix query error in character_evolving_items @Akkadius 2025-01-21
|
||||||
|
* Repair a memory leak in #summonitem ([#4591](https://github.com/EQEmu/Server/pull/4591)) @neckkola 2025-01-08
|
||||||
|
* Repair an incorrect safe_delete call memory leak. ([#4588](https://github.com/EQEmu/Server/pull/4588)) @neckkola 2025-01-07
|
||||||
|
* Repair levers opening the Evolving XP Transfer Window ([#4607](https://github.com/EQEmu/Server/pull/4607)) @neckkola 2025-01-23
|
||||||
|
* Update a few Bazaar RoF2 routines for memory leaks ([#4592](https://github.com/EQEmu/Server/pull/4592)) @neckkola 2025-01-08
|
||||||
|
* Update database version to match manifest @Akkadius 2025-01-21
|
||||||
|
* Update trader add/remove packets to limits for RoF2 ([#4595](https://github.com/EQEmu/Server/pull/4595)) @neckkola 2025-01-19
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
* Implement KSM Kernel Samepage Merging with Maps ([#4601](https://github.com/EQEmu/Server/pull/4601)) @Akkadius 2025-01-21
|
||||||
|
|
||||||
|
### Memory Leak
|
||||||
|
|
||||||
|
* Change raw pointer to unique_ptr to avoid potential leak in dbg stream ([#4616](https://github.com/EQEmu/Server/pull/4616)) @KimLS 2025-01-27
|
||||||
|
* Fix leak in BuyTraderItemOutsideBazaar ([#4609](https://github.com/EQEmu/Server/pull/4609)) @Akkadius 2025-01-24
|
||||||
|
* Fix leak in Client::RemoveDuplicateLore ([#4614](https://github.com/EQEmu/Server/pull/4614)) @Akkadius 2025-01-24
|
||||||
|
* Fix leak in NPC::RemoveItem ([#4611](https://github.com/EQEmu/Server/pull/4611)) @Akkadius 2025-01-24
|
||||||
|
* Fix leak in QuestManager::varlink ([#4610](https://github.com/EQEmu/Server/pull/4610)) @Akkadius 2025-01-24
|
||||||
|
* Fix leaks in Client::Handle_OP_AugmentItem ([#4612](https://github.com/EQEmu/Server/pull/4612)) @Akkadius 2025-01-24
|
||||||
|
* Fix memory leak in Client::Handle_OP_MoveMultipleItems ([#4613](https://github.com/EQEmu/Server/pull/4613)) @Akkadius 2025-01-24
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Client / NPC Position Update Optimizations ([#4602](https://github.com/EQEmu/Server/pull/4602)) @Akkadius 2025-01-21
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add SetAAEXPPercentage to Perl/Lua ([#4597](https://github.com/EQEmu/Server/pull/4597)) @Kinglykrab 2025-01-19
|
||||||
|
|
||||||
|
### Zone
|
||||||
|
|
||||||
|
* Implement zone player count sharding ([#4536](https://github.com/EQEmu/Server/pull/4536)) @Akkadius 2025-01-08
|
||||||
|
|
||||||
|
## [22.61.0] 1/6/2025
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Fix AA ranks to account for level ([#4567](https://github.com/EQEmu/Server/pull/4567)) @nytmyr 2024-12-07
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Convert Event Parses to Single Line ([#4569](https://github.com/EQEmu/Server/pull/4569)) @Kinglykrab 2024-12-12
|
||||||
|
* Fix GM Flag Spell Restriction Bypasses ([#4571](https://github.com/EQEmu/Server/pull/4571)) @Kinglykrab 2025-01-06
|
||||||
|
* Remove Unused Group Methods ([#4559](https://github.com/EQEmu/Server/pull/4559)) @Kinglykrab 2024-12-12
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #find bot Subcommand ([#4563](https://github.com/EQEmu/Server/pull/4563)) @Kinglykrab 2024-12-12
|
||||||
|
* Add #find ldon_theme Subcommand ([#4564](https://github.com/EQEmu/Server/pull/4564)) @Kinglykrab 2024-12-12
|
||||||
|
* Fix #copycharacter ([#4582](https://github.com/EQEmu/Server/pull/4582)) @Akkadius 2025-01-06
|
||||||
|
|
||||||
|
### Databuckets
|
||||||
|
|
||||||
|
* Improved Reliability and Performance of Databuckets ([#4562](https://github.com/EQEmu/Server/pull/4562)) @Akkadius 2024-12-12
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Enable bazaar window 'Find Trader' functionality ([#4560](https://github.com/EQEmu/Server/pull/4560)) @neckkola 2024-12-12
|
||||||
|
|
||||||
|
### Filesystem
|
||||||
|
|
||||||
|
* Path Manager Improvements ([#4557](https://github.com/EQEmu/Server/pull/4557)) @Akkadius 2025-01-06
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Allow Items in ROF2 to Stack to 32,767 ([#4556](https://github.com/EQEmu/Server/pull/4556)) @Kinglykrab 2024-12-12
|
||||||
|
* Fix EVENT_COMBAT on NPC Death ([#4558](https://github.com/EQEmu/Server/pull/4558)) @Kinglykrab 2024-11-28
|
||||||
|
* Guild Membership Update Fix ([#4581](https://github.com/EQEmu/Server/pull/4581)) @neckkola 2025-01-06
|
||||||
|
* Guild creation to propagate across zones ([#4575](https://github.com/EQEmu/Server/pull/4575)) @neckkola 2025-01-06
|
||||||
|
* Repair a EQEMUConfig Memory Leak ([#4584](https://github.com/EQEmu/Server/pull/4584)) @neckkola 2025-01-06
|
||||||
|
* Repair a LoadNPCEmote MemoryLeak ([#4586](https://github.com/EQEmu/Server/pull/4586)) @neckkola 2025-01-06
|
||||||
|
* Repair a memory leak in GuildsList ([#4585](https://github.com/EQEmu/Server/pull/4585)) @neckkola 2025-01-06
|
||||||
|
* Resolve a client crash when logging in or zoning ([#4572](https://github.com/EQEmu/Server/pull/4572)) @neckkola 2024-12-14
|
||||||
|
|
||||||
|
### Groups
|
||||||
|
|
||||||
|
* Fix AmIMainAssist incorrectly checking for MainTankName ([#4565](https://github.com/EQEmu/Server/pull/4565)) @nytmyr 2024-12-04
|
||||||
|
|
||||||
|
### Inventory
|
||||||
|
|
||||||
|
* Add GetInventorySlots() Method ([#4566](https://github.com/EQEmu/Server/pull/4566)) @Kinglykrab 2025-01-06
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
* Improve Crash log defaults ([#4579](https://github.com/EQEmu/Server/pull/4579)) @Akkadius 2025-01-06
|
||||||
|
|
||||||
|
### Maps
|
||||||
|
|
||||||
|
* Fix broken Map MMFS implementation ([#4576](https://github.com/EQEmu/Server/pull/4576)) @Akkadius 2025-01-06
|
||||||
|
|
||||||
|
### Network
|
||||||
|
|
||||||
|
* Prune / disconnect TCP connections gracefully ([#4574](https://github.com/EQEmu/Server/pull/4574)) @Akkadius 2025-01-06
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add rules for requiring custom files from client ([#4561](https://github.com/EQEmu/Server/pull/4561)) @knervous 2024-12-12
|
||||||
|
|
||||||
|
## [22.60.0] 11/25/2024
|
||||||
|
|
||||||
|
### Bazaar
|
||||||
|
|
||||||
|
* Further refinements for instanced bazaar ([#4544](https://github.com/EQEmu/Server/pull/4544)) @neckkola 2024-11-16
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Fix build with older C++ libraries ([#4549](https://github.com/EQEmu/Server/pull/4549)) @hgtw 2024-11-24
|
||||||
|
|
||||||
|
### Config
|
||||||
|
|
||||||
|
* Fix World TCP Address Configuration Default ([#4551](https://github.com/EQEmu/Server/pull/4551)) @Akkadius 2024-11-24
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix Issue with Perl EVENT_PAYLOAD ([#4545](https://github.com/EQEmu/Server/pull/4545)) @Kinglykrab 2024-11-24
|
||||||
|
* Fix Possible Item Loss in Trades ([#4554](https://github.com/EQEmu/Server/pull/4554)) @Kinglykrab 2024-11-24
|
||||||
|
* Fix Strings::Commify bug with #mystats ([#4547](https://github.com/EQEmu/Server/pull/4547)) @carolus21rex 2024-11-22
|
||||||
|
* Fix an edge case with augmented items inside parceled containers ([#4546](https://github.com/EQEmu/Server/pull/4546)) @neckkola 2024-11-21
|
||||||
|
* Fix for bazaar search of containers. ([#4540](https://github.com/EQEmu/Server/pull/4540)) @neckkola 2024-11-15
|
||||||
|
* Fix for mult-instanced bazaar zones ([#4541](https://github.com/EQEmu/Server/pull/4541)) @neckkola 2024-11-15
|
||||||
|
* Fix for sending money via Parcel, then changing your mind ([#4552](https://github.com/EQEmu/Server/pull/4552)) @neckkola 2024-11-24
|
||||||
|
* Fix issue where NPC's are being hidden as traders ([#4539](https://github.com/EQEmu/Server/pull/4539)) @Akkadius 2024-11-15
|
||||||
|
* Players could become flagged as a Trader when they were not trading ([#4553](https://github.com/EQEmu/Server/pull/4553)) @neckkola 2024-11-24
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Rule to Disable NPCs Facing Target ([#4543](https://github.com/EQEmu/Server/pull/4543)) @Kinglykrab 2024-11-24
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
* Update tasks in all zones if invalid zone set ([#4550](https://github.com/EQEmu/Server/pull/4550)) @hgtw 2024-11-25
|
||||||
|
|
||||||
|
## [22.59.1] 11/13/2024
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Fix faulty database migration condition with databuckets (9285)
|
||||||
|
|
||||||
|
## [22.59.0] 11/13/2024
|
||||||
|
|
||||||
|
### Databuckets
|
||||||
|
|
||||||
|
* Add database index to data_buckets ([#4535](https://github.com/EQEmu/Server/pull/4535)) @Akkadius 2024-11-09
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Bazaar two edge case issues resolved ([#4533](https://github.com/EQEmu/Server/pull/4533)) @neckkola 2024-11-09
|
||||||
|
* Check if the mob is already in the close mobs list before inserting @Akkadius 2024-11-11
|
||||||
|
* ScanCloseMobs - Ensure scanning mob has an entity ID @Akkadius 2024-11-10
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Improvements to ScanCloseMobs logic ([#4534](https://github.com/EQEmu/Server/pull/4534)) @Akkadius 2024-11-08
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Native Database Querying Interface ([#4531](https://github.com/EQEmu/Server/pull/4531)) @hgtw 2024-11-13
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Rule for restricting client versions to world server ([#4527](https://github.com/EQEmu/Server/pull/4527)) @knervous 2024-11-12
|
||||||
|
|
||||||
|
## [22.58.0] 11/5/2024
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Add mysql prepared statement support ([#4530](https://github.com/EQEmu/Server/pull/4530)) @hgtw 2024-11-06
|
||||||
|
* Update perlbind to 1.1.0 ([#4529](https://github.com/EQEmu/Server/pull/4529)) @hgtw 2024-11-06
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Focus Skill Attack Spells ([#4528](https://github.com/EQEmu/Server/pull/4528)) @mmcgarvey 2024-10-31
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add Missing Lua Registers ([#4525](https://github.com/EQEmu/Server/pull/4525)) @Kinglykrab 2024-10-24
|
||||||
|
* Fix cross_zone_set_entity_variable_by_char_id in Lua ([#4526](https://github.com/EQEmu/Server/pull/4526)) @Kinglykrab 2024-10-24
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Automatifc Opcode File Creation ([#4521](https://github.com/EQEmu/Server/pull/4521)) @KimLS 2024-10-22
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Spawn Circle/Grid Methods to Perl/Lua ([#4524](https://github.com/EQEmu/Server/pull/4524)) @Kinglykrab 2024-10-24
|
||||||
|
|
||||||
|
## [22.57.1] 10/22/2024
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Enable Bot Commands Only if Rule Enabled ([#4519](https://github.com/EQEmu/Server/pull/4519)) @Kinglykrab 2024-10-22
|
||||||
|
* Fix pet buffs from saving duplicates every save ([#4520](https://github.com/EQEmu/Server/pull/4520)) @nytmyr 2024-10-22
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Automatic Opcode File Creation ([#4521](https://github.com/EQEmu/Server/pull/4521)) @KimLS 2024-10-22
|
||||||
|
|
||||||
|
## [22.57.0] 10/20/2024
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add "silent" option to ^spawn and mute raid spawn ([#4494](https://github.com/EQEmu/Server/pull/4494)) @nytmyr 2024-10-05
|
||||||
|
* Add attack flag when told to attack ([#4490](https://github.com/EQEmu/Server/pull/4490)) @nytmyr 2024-09-29
|
||||||
|
* Fix timers loading on spawn and zone ([#4516](https://github.com/EQEmu/Server/pull/4516)) @nytmyr 2024-10-20
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Fixed a typo in Zoning.cpp ([#4515](https://github.com/EQEmu/Server/pull/4515)) @carolus21rex 2024-10-20
|
||||||
|
* Optimization Code Cleanup ([#4489](https://github.com/EQEmu/Server/pull/4489)) @Akkadius 2024-09-30
|
||||||
|
* Remove Extra Skill in EQ::skills::GetExtraDamageSkills() ([#4486](https://github.com/EQEmu/Server/pull/4486)) @Kinglykrab 2024-10-03
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fixes a crash when the faction_list db table is empty. ([#4511](https://github.com/EQEmu/Server/pull/4511)) @KimLS 2024-10-14
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add character_instance_safereturns to tables_to_zero_id ([#4485](https://github.com/EQEmu/Server/pull/4485)) @Morzain 2024-09-26
|
||||||
|
* Correctly limit max targets of PBAOE ([#4507](https://github.com/EQEmu/Server/pull/4507)) @catapultam-habeo 2024-10-11
|
||||||
|
* FindBestZ selecting false zone floor as bestz - Results in roambox failures ([#4504](https://github.com/EQEmu/Server/pull/4504)) @fryguy503 2024-10-13
|
||||||
|
* Fix #set motd Crash ([#4495](https://github.com/EQEmu/Server/pull/4495)) @Kinglykrab 2024-10-05
|
||||||
|
* Fix `character_exp_modifiers` Default Values ([#4502](https://github.com/EQEmu/Server/pull/4502)) @Kinglykrab 2024-10-09
|
||||||
|
* Fix a display error regarding a few trader/buyer query errors ([#4514](https://github.com/EQEmu/Server/pull/4514)) @neckkola 2024-10-17
|
||||||
|
* Fix Group ID 0 in Group::SaveGroupLeaderAA() ([#4487](https://github.com/EQEmu/Server/pull/4487)) @Kinglykrab 2024-10-03
|
||||||
|
* Fix Mercenary Encounter Crash ([#4509](https://github.com/EQEmu/Server/pull/4509)) @Kinglykrab 2024-10-12
|
||||||
|
* Fix NPC::CanTalk() Crash ([#4499](https://github.com/EQEmu/Server/pull/4499)) @Kinglykrab 2024-10-07
|
||||||
|
* Fix Spells:DefaultAOEMaxTargets Default Value ([#4508](https://github.com/EQEmu/Server/pull/4508)) @Kinglykrab 2024-10-12
|
||||||
|
* Fix Targeted AOE Max Targets Rule ([#4488](https://github.com/EQEmu/Server/pull/4488)) @Kinglykrab 2024-10-03
|
||||||
|
* fixed a bug where it would use npc value instead of faction value in the database. ([#4491](https://github.com/EQEmu/Server/pull/4491)) @regneq 2024-09-29
|
||||||
|
* Master of Disguise should apply to illusions casted by others. ([#4506](https://github.com/EQEmu/Server/pull/4506)) @fryguy503 2024-10-11
|
||||||
|
* Spells - Self Only (Yellow) cast when non group member is targeted ([#4503](https://github.com/EQEmu/Server/pull/4503)) @fryguy503 2024-10-11
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Larion loginserver support ([#4492](https://github.com/EQEmu/Server/pull/4492)) @KimLS 2024-10-03
|
||||||
|
* Login Fatal Error Spamming ([#4476](https://github.com/EQEmu/Server/pull/4476)) @KimLS 2024-10-09
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
* Add NPC Trades to Player Events ([#4505](https://github.com/EQEmu/Server/pull/4505)) @Kinglykrab 2024-10-13
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Buff Fade Methods to Perl/Lua ([#4501](https://github.com/EQEmu/Server/pull/4501)) @Kinglykrab 2024-10-09
|
||||||
|
* Add EVENT_READ_ITEM to Perl/Lua ([#4497](https://github.com/EQEmu/Server/pull/4497)) @Kinglykrab 2024-10-08
|
||||||
|
* Add NPC List Filter Methods to Perl/Lua ([#4493](https://github.com/EQEmu/Server/pull/4493)) @Kinglykrab 2024-10-04
|
||||||
|
* Add Scripting Support to Mercenaries ([#4500](https://github.com/EQEmu/Server/pull/4500)) @Kinglykrab 2024-10-11
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Rule to disable PVP Regions ([#4513](https://github.com/EQEmu/Server/pull/4513)) @Kinglykrab 2024-10-17
|
||||||
|
|
||||||
|
## [22.56.3] 9/23/2024
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix issue with Client::SaveDisciplines() not specifying character ID ([#4481](https://github.com/EQEmu/Server/pull/4477)) @Kinglykrab 2024-09-23
|
||||||
|
|
||||||
|
## [22.56.2] 9/20/2024
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix Issue with Database::ReserveName ([#4477](https://github.com/EQEmu/Server/pull/4477)) @Kinglykrab 2024-09-20
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add GrantAllAAPoints() Overload To Perl/Lua ([#4474](https://github.com/EQEmu/Server/pull/4474)) @Kinglykrab 2024-09-20
|
||||||
|
|
||||||
|
## [22.56.1] 9/20/2024
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix Untrained Disciplines in Client::SaveDisciplines() ([#4472](https://github.com/EQEmu/Server/pull/4472)) @Kinglykrab 2024-09-13
|
||||||
|
* Fix Infinite Loop in Adventure::Finished() ([#4473](https://github.com/EQEmu/Server/pull/4473)) @oddx2k 2024-09-13
|
||||||
|
|
||||||
|
## [22.56.0] 9/12/2024
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Add IsCloseToBanker method ([#4462](https://github.com/EQEmu/Server/pull/4462)) @Akkadius 2024-08-27
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Rule to Limit Task Update Messages ([#4459](https://github.com/EQEmu/Server/pull/4459)) @Kinglykrab 2024-08-28
|
||||||
|
* Allow NPCs to cast Sacrifice ([#4470](https://github.com/EQEmu/Server/pull/4470)) @fuzzlecutter 2024-09-12
|
||||||
|
* Lazy Load Bank Contents ([#4453](https://github.com/EQEmu/Server/pull/4453)) @catapultam-habeo 2024-08-27
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add RULE_STRING to RuleManager::ResetRules ([#4467](https://github.com/EQEmu/Server/pull/4467)) @Kinglykrab 2024-09-07
|
||||||
|
* Fix Bard Effect in Migration 9237 ([#4468](https://github.com/EQEmu/Server/pull/4468)) @Kinglykrab 2024-09-09
|
||||||
|
* ModernAAScalingEnabled() Calculation Error ([#4469](https://github.com/EQEmu/Server/pull/4469)) @carolus21rex 2024-09-11
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Move Discipline Loading to Client::CompleteConnect() ([#4466](https://github.com/EQEmu/Server/pull/4466)) @Kinglykrab 2024-09-09
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add a Bandolier Swap Delay Rule ([#4465](https://github.com/EQEmu/Server/pull/4465)) @Kinglykrab 2024-09-08
|
||||||
|
|
||||||
|
## [22.55.1] 8/26/2024
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Remove unused methods ([#4449](https://github.com/EQEmu/Server/pull/4449)) @Kinglykrab 2024-08-22
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Character:DefaultGuildRank Rule ([#4438](https://github.com/EQEmu/Server/pull/4438)) @Kinglykrab 2024-08-04
|
||||||
|
* Add Optional Return to EVENT_DAMAGE_TAKEN ([#4454](https://github.com/EQEmu/Server/pull/4454)) @Kinglykrab 2024-08-27
|
||||||
|
* Extend Spell Buckets Functionality ([#4441](https://github.com/EQEmu/Server/pull/4441)) @Kinglykrab 2024-08-22
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Apply Race & Class restrictions to Auto-Combines ([#4452](https://github.com/EQEmu/Server/pull/4452)) @catapultam-habeo 2024-08-20
|
||||||
|
* Attune Augments when Equipped ([#4446](https://github.com/EQEmu/Server/pull/4446)) @fryguy503 2024-08-10
|
||||||
|
* Correct missed maxlevel reference in exp.cpp ([#4463](https://github.com/EQEmu/Server/pull/4463)) @N0ctrnl 2024-08-27
|
||||||
|
* Ensure close of Tribute Item search ([#4439](https://github.com/EQEmu/Server/pull/4439)) @joligario 2024-08-04
|
||||||
|
* Fix AddCrystals() in Perl/Lua ([#4445](https://github.com/EQEmu/Server/pull/4445)) @Kinglykrab 2024-08-10
|
||||||
|
* Fix Bot Spell Entries IDs Capping at 32,767 ([#4444](https://github.com/EQEmu/Server/pull/4444)) @Kinglykrab 2024-08-27
|
||||||
|
* Fix Character ID of 0 being inserted into character_stats_record ([#4458](https://github.com/EQEmu/Server/pull/4458)) @Kinglykrab 2024-08-22
|
||||||
|
* Fix Issue with Removed #setfaction Command ([#4448](https://github.com/EQEmu/Server/pull/4448)) @Kinglykrab 2024-08-11
|
||||||
|
* Fix Lua Client FilteredMessage ([#4437](https://github.com/EQEmu/Server/pull/4437)) @Kinglykrab 2024-07-31
|
||||||
|
* Fix client hotbar exchanging items when zoning ([#4460](https://github.com/EQEmu/Server/pull/4460)) @neckkola 2024-08-27
|
||||||
|
* Fix issue with killed mob coordinates ([#4457](https://github.com/EQEmu/Server/pull/4457)) @Kinglykrab 2024-08-22
|
||||||
|
* Imitate Death should also clear zone feign aggro ([#4436](https://github.com/EQEmu/Server/pull/4436)) @fryguy503 2024-07-31
|
||||||
|
* client_max_level allow leveling to end of level ([#4455](https://github.com/EQEmu/Server/pull/4455)) @fryguy503 2024-08-20
|
||||||
|
|
||||||
|
### Improvement
|
||||||
|
|
||||||
|
* Filtered Messages Extension ([#4435](https://github.com/EQEmu/Server/pull/4435)) @fryguy503 2024-07-31
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add AreTasksCompleted() to Perl/Lua. ([#4456](https://github.com/EQEmu/Server/pull/4456)) @Kinglykrab 2024-08-23
|
||||||
|
* Add Area-Based Quest Methods to Perl/Lua ([#4447](https://github.com/EQEmu/Server/pull/4447)) @Kinglykrab 2024-08-27
|
||||||
|
* Add Several Door Methods to Perl/Lua ([#4451](https://github.com/EQEmu/Server/pull/4451)) @Kinglykrab 2024-08-16
|
||||||
|
|
||||||
|
### World
|
||||||
|
|
||||||
|
* Fix slow world bootup bug ([#4461](https://github.com/EQEmu/Server/pull/4461)) @Akkadius 2024-08-27
|
||||||
|
|
||||||
|
## [22.54.0] 7/30/2024
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Cleanup Client File Exporting ([#4348](https://github.com/EQEmu/Server/pull/4348)) @Kinglykrab 2024-07-31
|
||||||
|
* Cleanup Stance Code ([#4368](https://github.com/EQEmu/Server/pull/4368)) @Kinglykrab 2024-07-03
|
||||||
|
* Mask GM Show Buff message behind EntityVariable ([#4419](https://github.com/EQEmu/Server/pull/4419)) @nytmyr 2024-07-22
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Extend #devtools Functionality ([#4425](https://github.com/EQEmu/Server/pull/4425)) @Kinglykrab 2024-07-23
|
||||||
|
|
||||||
|
### Databuckets
|
||||||
|
|
||||||
|
* Remove memory reserve from bulk load ([#4427](https://github.com/EQEmu/Server/pull/4427)) @Akkadius 2024-07-23
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Barter/Buyer Features ([#4405](https://github.com/EQEmu/Server/pull/4405)) @neckkola 2024-07-30
|
||||||
|
* Add Parcel notification for online players when using the Quest API ([#4418](https://github.com/EQEmu/Server/pull/4418)) @neckkola 2024-07-22
|
||||||
|
* Implement Move Multiple Items ([#4259](https://github.com/EQEmu/Server/pull/4259)) @catapultam-habeo 2024-07-30
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Aegolism Spell line stacking ([#4399](https://github.com/EQEmu/Server/pull/4399)) @KayenEQ 2024-07-07
|
||||||
|
* AllowRaidTargetBlind logic backwards ([#4400](https://github.com/EQEmu/Server/pull/4400)) @fryguy503 2024-07-01
|
||||||
|
* AutoSplit unknown bug and cleanup. ([#4401](https://github.com/EQEmu/Server/pull/4401)) @fryguy503 2024-07-07
|
||||||
|
* Corpse Call removing Resurrection Effects ([#4410](https://github.com/EQEmu/Server/pull/4410)) @fryguy503 2024-07-22
|
||||||
|
* Fix #parcels add subcommand ([#4431](https://github.com/EQEmu/Server/pull/4431)) @neckkola 2024-07-29
|
||||||
|
* Fix #setlevel Allowing Skills Above Max ([#4423](https://github.com/EQEmu/Server/pull/4423)) @Kinglykrab 2024-07-23
|
||||||
|
* Fix Bot::SetBotStance ([#4426](https://github.com/EQEmu/Server/pull/4426)) @Kinglykrab 2024-07-23
|
||||||
|
* Fix Client::RemoveTitle ([#4421](https://github.com/EQEmu/Server/pull/4421)) @Kinglykrab 2024-07-23
|
||||||
|
* Fix EVENT_USE_SKILL with Sense Heading ([#4424](https://github.com/EQEmu/Server/pull/4424)) @Kinglykrab 2024-07-23
|
||||||
|
* Fix for random disconnects when a large number of guild members zone or disconnect ([#4402](https://github.com/EQEmu/Server/pull/4402)) @neckkola 2024-07-10
|
||||||
|
* Fix issue with quest::echo and quest::me ([#4433](https://github.com/EQEmu/Server/pull/4433)) @Kinglykrab 2024-07-30
|
||||||
|
* Personal tributes for bard items were not applying correctly ([#4416](https://github.com/EQEmu/Server/pull/4416)) @neckkola 2024-07-16
|
||||||
|
* Potential fix for some undesired ranged explotative behavior. ([#4413](https://github.com/EQEmu/Server/pull/4413)) @fryguy503 2024-07-22
|
||||||
|
* Proximity Aggro for Frustrated and Undead ([#4411](https://github.com/EQEmu/Server/pull/4411)) @fryguy503 2024-07-22
|
||||||
|
* Slay Adjustments ([#4389](https://github.com/EQEmu/Server/pull/4389)) @fryguy503 2024-07-07
|
||||||
|
* Stop DOSing ourselves with OP_WearChange ([#4432](https://github.com/EQEmu/Server/pull/4432)) @catapultam-habeo 2024-07-30
|
||||||
|
* [Quest API] Fix getraididbycharid and getgroupidbycharid ([#4417](https://github.com/EQEmu/Server/pull/4417)) @nytmyr 2024-07-16
|
||||||
|
|
||||||
|
### Improvement
|
||||||
|
|
||||||
|
* Flee Overhaul ([#4407](https://github.com/EQEmu/Server/pull/4407)) @fryguy503 2024-07-30
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add HasteCap and Hastev3Cap rules for NPCs, Bots and Mercs ([#4406](https://github.com/EQEmu/Server/pull/4406)) @nytmyr 2024-07-22
|
||||||
|
|
||||||
|
### Zone Instances
|
||||||
|
|
||||||
|
* Revert " Handle routing to instances when using evac/succor " (#4429) ([#4297](https://github.com/EQEmu/Server/pull/4297)) @Akkadius 2024-07-30
|
||||||
|
|
||||||
|
### Zoning
|
||||||
|
|
||||||
|
* Improve zone routing ([#4428](https://github.com/EQEmu/Server/pull/4428)) @Akkadius 2024-07-30
|
||||||
|
|
||||||
|
## [22.53.1] 6/16/2024
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix trader mode ([#4397](https://github.com/EQEmu/Server/pull/4397)) @joligario 2024-06-17
|
||||||
|
|
||||||
|
## [22.53.0] 6/14/2024
|
||||||
|
|
||||||
|
### Bug
|
||||||
|
|
||||||
|
* Anon players should not show in /who all ([#4392](https://github.com/EQEmu/Server/pull/4392)) @fryguy503 2024-06-14
|
||||||
|
* Escape should put player into SOS if owned. ([#4388](https://github.com/EQEmu/Server/pull/4388)) @fryguy503 2024-06-07
|
||||||
|
* Prevent Resurrection Spells from being resisted ([#4393](https://github.com/EQEmu/Server/pull/4393)) @fryguy503 2024-06-14
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Cleanup Account Status Code ([#4376](https://github.com/EQEmu/Server/pull/4376)) @Kinglykrab 2024-06-02
|
||||||
|
* Cleanup Body Type Code ([#4366](https://github.com/EQEmu/Server/pull/4366)) @Kinglykrab 2024-06-02
|
||||||
|
* Cleanup Object Type Code ([#4375](https://github.com/EQEmu/Server/pull/4375)) @Kinglykrab 2024-06-14
|
||||||
|
* Remove unused code in emu_constants.h ([#4384](https://github.com/EQEmu/Server/pull/4384)) @Kinglykrab 2024-06-14
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix #goto Target ([#4382](https://github.com/EQEmu/Server/pull/4382)) @Kinglykrab 2024-06-03
|
||||||
|
* Fix Swarm Pet Damage Messages ([#4383](https://github.com/EQEmu/Server/pull/4383)) @Kinglykrab 2024-06-04
|
||||||
|
* Fix for players having empty bazaar window dropdown list, even though trader is tagged as a trader. ([#4391](https://github.com/EQEmu/Server/pull/4391)) @neckkola 2024-06-14
|
||||||
|
* Fix potential trader crash when serialized item not found ([#4386](https://github.com/EQEmu/Server/pull/4386)) @joligario 2024-06-14
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Invisible Augment Rules ([#4385](https://github.com/EQEmu/Server/pull/4385)) @Kinglykrab 2024-06-14
|
||||||
|
* Classic Harm Touch Formula ([#4394](https://github.com/EQEmu/Server/pull/4394)) @fryguy503 2024-06-14
|
||||||
|
* Mend/Sneak allow success tuning ([#4390](https://github.com/EQEmu/Server/pull/4390)) @fryguy503 2024-06-14
|
||||||
|
* Snare Override Movement Bonus ([#4381](https://github.com/EQEmu/Server/pull/4381)) @fryguy503 2024-06-02
|
||||||
|
|
||||||
|
## [22.52.0] 6/1/2024
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Cleanup Bucket Comparison Code ([#4374](https://github.com/EQEmu/Server/pull/4374)) @Kinglykrab 2024-06-02
|
||||||
|
* Cleanup Bug Category Code ([#4367](https://github.com/EQEmu/Server/pull/4367)) @Kinglykrab 2024-06-01
|
||||||
|
* Cleanup Deity Code ([#4363](https://github.com/EQEmu/Server/pull/4363)) @Kinglykrab 2024-06-01
|
||||||
|
* Cleanup Special Ability Code ([#4365](https://github.com/EQEmu/Server/pull/4365)) @Kinglykrab 2024-06-01
|
||||||
|
* Remove unused code in common/eq_constants.h ([#4364](https://github.com/EQEmu/Server/pull/4364)) @Kinglykrab 2024-06-01
|
||||||
|
|
||||||
|
### Combat
|
||||||
|
|
||||||
|
* Adjustments to Crippling Blows/Slay Undead and Confirmed Critical Code ([#4354](https://github.com/EQEmu/Server/pull/4354)) @fryguy503 2024-05-27
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add protection to ensure adventure points award are only attempted on players ([#4371](https://github.com/EQEmu/Server/pull/4371)) @joligario 2024-05-31
|
||||||
|
* Adjust Kick/RoundKick Damage Lower levels ([#4355](https://github.com/EQEmu/Server/pull/4355)) @fryguy503 2024-05-28
|
||||||
|
* Bazaar Search not working correctly for Iksar, Vashir, Drakkin and Froglok races ([#4379](https://github.com/EQEmu/Server/pull/4379)) @neckkola 2024-06-02
|
||||||
|
* Fix Unescaped String in Client::GotoPlayer ([#4373](https://github.com/EQEmu/Server/pull/4373)) @Kinglykrab 2024-06-01
|
||||||
|
|
||||||
|
### NPC Spells
|
||||||
|
|
||||||
|
* Fixed an issue where the repository spell adj value was overriding the spell difficulty default value ([#4370](https://github.com/EQEmu/Server/pull/4370)) @regneq 2024-06-01
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Item Link Methods to Perl/Lua ([#4359](https://github.com/EQEmu/Server/pull/4359)) @Kinglykrab 2024-06-01
|
||||||
|
|
||||||
|
### Quests
|
||||||
|
|
||||||
|
* Fix Lua encounter double register ([#4369](https://github.com/EQEmu/Server/pull/4369)) @Akkadius 2024-05-31
|
||||||
|
* Fix issue with Lua encounters loading in certain circumstances ([#4378](https://github.com/EQEmu/Server/pull/4378)) @Akkadius 2024-06-01
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Skill Base Damage Rules ([#4360](https://github.com/EQEmu/Server/pull/4360)) @Kinglykrab 2024-06-01
|
||||||
|
|
||||||
|
### Skills
|
||||||
|
|
||||||
|
* Fix caps out of bounds issue ([#4377](https://github.com/EQEmu/Server/pull/4377)) @Akkadius 2024-06-01
|
||||||
|
|
||||||
|
## [22.51.1] 5/27/2024
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Adjust return for perl release check @Akkadius 2024-05-26
|
||||||
|
* Corrected issue with bazaar purchase via parcels where an incorrect quantity would be calculated. ([#4352](https://github.com/EQEmu/Server/pull/4352)) @neckkola 2024-05-27
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Improve SkillCaps::GetTrainLevel() Efficiency ([#4350](https://github.com/EQEmu/Server/pull/4350)) @Kinglykrab 2024-05-26
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Legacy Compute Defense against modern agi based defense. ([#4349](https://github.com/EQEmu/Server/pull/4349)) @fryguy503 2024-05-27
|
||||||
|
|
||||||
|
## [22.51.0] 5/26/2024
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* #npcspawn Changes ([#4311](https://github.com/EQEmu/Server/pull/4311)) @twincannon 2024-05-16
|
||||||
|
* Cleanup #resetaa Command ([#4310](https://github.com/EQEmu/Server/pull/4310)) @Kinglykrab 2024-05-22
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Add validation to RemoveXTarget ([#4324](https://github.com/EQEmu/Server/pull/4324)) @Akkadius 2024-05-25
|
||||||
|
* Fix Zone deconstructor crashes ([#4325](https://github.com/EQEmu/Server/pull/4325)) @Akkadius 2024-05-25
|
||||||
|
* Fix crash issue when dividing by zero in CalcHPRegen ([#4320](https://github.com/EQEmu/Server/pull/4320)) @Akkadius 2024-05-25
|
||||||
|
* Fix crash when map name is null ([#4322](https://github.com/EQEmu/Server/pull/4322)) @Akkadius 2024-05-25
|
||||||
|
* Fix player event crash in ITEM_DESTROY ([#4326](https://github.com/EQEmu/Server/pull/4326)) @Akkadius 2024-05-25
|
||||||
|
* Fix player events reload when out of bounds ([#4321](https://github.com/EQEmu/Server/pull/4321)) @Akkadius 2024-05-25
|
||||||
|
* Fix rarer crash in EntityList::MobProcess ([#4319](https://github.com/EQEmu/Server/pull/4319)) @Akkadius 2024-05-25
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add RoF2 Bazaar Support ([#4315](https://github.com/EQEmu/Server/pull/4315)) @neckkola 2024-05-26
|
||||||
|
* Add SE_IncreaseArchery and rules to tune archery ([#4335](https://github.com/EQEmu/Server/pull/4335)) @fryguy503 2024-05-26
|
||||||
|
* Add parcel container support ([#4305](https://github.com/EQEmu/Server/pull/4305)) @neckkola 2024-05-17
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Accuracy, Avoidance and Atk adjustments ([#4336](https://github.com/EQEmu/Server/pull/4336)) @fryguy503 2024-05-26
|
||||||
|
* Fix Crash with null Argument in #modifynpcstat ([#4318](https://github.com/EQEmu/Server/pull/4318)) @Kinglykrab 2024-05-24
|
||||||
|
* Fix RemoveAlternateCurrencyValue not updating Client ([#4317](https://github.com/EQEmu/Server/pull/4317)) @Kinglykrab 2024-05-23
|
||||||
|
* Fix Using Bind Wound Above 70% Health ([#4340](https://github.com/EQEmu/Server/pull/4340)) @Kinglykrab 2024-05-26
|
||||||
|
* Fix issue with #hotfix ([#4316](https://github.com/EQEmu/Server/pull/4316)) @Kinglykrab 2024-05-22
|
||||||
|
* Fix issue with #suspend ([#4314](https://github.com/EQEmu/Server/pull/4314)) @Kinglykrab 2024-05-23
|
||||||
|
* Fix issue with KeepOneRecordPerCompletedTask ([#4313](https://github.com/EQEmu/Server/pull/4313)) @Kinglykrab 2024-05-23
|
||||||
|
* Fix mistaken removed RULE_CATEGORY_END() ([#4341](https://github.com/EQEmu/Server/pull/4341)) @fryguy503 2024-05-26
|
||||||
|
* Missed a mob offense section for PR #4328 ([#4331](https://github.com/EQEmu/Server/pull/4331)) @fryguy503 2024-05-26
|
||||||
|
* Raid Targets should not be Blindable as this will break all spell casting AI. ([#4334](https://github.com/EQEmu/Server/pull/4334)) @fryguy503 2024-05-26
|
||||||
|
* When Mounts are allowed to zone, block them from zoning to disallowed zones. ([#4330](https://github.com/EQEmu/Server/pull/4330)) @fryguy503 2024-05-25
|
||||||
|
* When refreshing buffs, attempt to use the same buffslot if the buff still exists. ([#4338](https://github.com/EQEmu/Server/pull/4338)) @fryguy503 2024-05-26
|
||||||
|
|
||||||
|
### Lua Mod
|
||||||
|
|
||||||
|
* Fix issue with SetAAEXP and SetEXP firing when uninitialized ([#4345](https://github.com/EQEmu/Server/pull/4345)) @Akkadius 2024-05-26
|
||||||
|
|
||||||
|
### Merchants
|
||||||
|
|
||||||
|
* Add New Classic Greed/Faction/Charisma Prices Rule ([#4301](https://github.com/EQEmu/Server/pull/4301)) @noudess 2024-05-17
|
||||||
|
|
||||||
|
### Mobs
|
||||||
|
|
||||||
|
* Remove entity type checks from ScanCloseMobs ([#4323](https://github.com/EQEmu/Server/pull/4323)) @Akkadius 2024-05-25
|
||||||
|
|
||||||
|
### NPC Spells
|
||||||
|
|
||||||
|
* Fix an issue where procs wouldn't fire if no spell entries in list ([#4344](https://github.com/EQEmu/Server/pull/4344)) @Akkadius 2024-05-26
|
||||||
|
|
||||||
|
### Perl
|
||||||
|
|
||||||
|
* Linux /opt/eqemu-perl checks when using release binaries ([#4346](https://github.com/EQEmu/Server/pull/4346)) @Akkadius 2024-05-26
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Zone Uptime Exports to Perl/Lua ([#4339](https://github.com/EQEmu/Server/pull/4339)) @Kinglykrab 2024-05-26
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Added MeleeMitigation Level Difference Roll Adjusted for level diffs ([#4332](https://github.com/EQEmu/Server/pull/4332)) @fryguy503 2024-05-26
|
||||||
|
* Allow maximum per kill AA amount ([#4329](https://github.com/EQEmu/Server/pull/4329)) @fryguy503 2024-05-25
|
||||||
|
* Allow servers to adjust the filtering threshold for heals from damage (e.g. Mark of Kings). ([#4327](https://github.com/EQEmu/Server/pull/4327)) @fryguy503 2024-05-25
|
||||||
|
* Backstab Haste Correction ([#4337](https://github.com/EQEmu/Server/pull/4337)) @fryguy503 2024-05-26
|
||||||
|
* Mob Offensive and Weapon Skill static tables ([#4328](https://github.com/EQEmu/Server/pull/4328)) @fryguy503 2024-05-25
|
||||||
|
* Remove hard coded initial aggro in favor or an adjustable Rule ([#4333](https://github.com/EQEmu/Server/pull/4333)) @fryguy503 2024-05-26
|
||||||
|
|
||||||
|
### Scripts
|
||||||
|
|
||||||
|
* Fix zone data load ordering issue ([#4343](https://github.com/EQEmu/Server/pull/4343)) @Akkadius 2024-05-26
|
||||||
|
|
||||||
|
### Spells
|
||||||
|
|
||||||
|
* Add content filtering to NPC spells ([#4309](https://github.com/EQEmu/Server/pull/4309)) @Akkadius 2024-05-17
|
||||||
|
|
||||||
## [22.50.1] 5/12/2024
|
## [22.50.1] 5/12/2024
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ IF(EQEMU_ADD_PROFILER)
|
|||||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-as-needed,-lprofiler,--as-needed")
|
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-as-needed,-lprofiler,--as-needed")
|
||||||
ENDIF(EQEMU_ADD_PROFILER)
|
ENDIF(EQEMU_ADD_PROFILER)
|
||||||
|
|
||||||
|
IF(USE_MAP_MMFS)
|
||||||
|
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
|
||||||
|
ENDIF (USE_MAP_MMFS)
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
|||||||
+43
-142
@@ -29,15 +29,21 @@
|
|||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
#include "../../common/zone_store.h"
|
||||||
#include "../../common/path_manager.h"
|
#include "../../common/path_manager.h"
|
||||||
|
#include "../../common/repositories/base_data_repository.h"
|
||||||
|
#include "../../common/repositories/db_str_repository.h"
|
||||||
#include "../../common/repositories/skill_caps_repository.h"
|
#include "../../common/repositories/skill_caps_repository.h"
|
||||||
|
#include "../../common/repositories/spells_new_repository.h"
|
||||||
#include "../../common/file.h"
|
#include "../../common/file.h"
|
||||||
#include "../../common/events/player_event_logs.h"
|
#include "../../common/events/player_event_logs.h"
|
||||||
|
#include "../../common/skill_caps.h"
|
||||||
|
#include "../../common/evolving_items.h"
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
ZoneStore zone_store;
|
||||||
PathManager path;
|
PathManager path;
|
||||||
PlayerEventLogs player_event_logs;
|
PlayerEventLogs player_event_logs;
|
||||||
|
EvolvingItemsManager evolving_items_manager;
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase *db);
|
void ExportSpells(SharedDatabase *db);
|
||||||
void ExportSkillCaps(SharedDatabase *db);
|
void ExportSkillCaps(SharedDatabase *db);
|
||||||
@@ -98,25 +104,22 @@ int main(int argc, char **argv)
|
|||||||
->LoadLogDatabaseSettings()
|
->LoadLogDatabaseSettings()
|
||||||
->StartFileLogs();
|
->StartFileLogs();
|
||||||
|
|
||||||
std::string arg_1;
|
std::string export_type;
|
||||||
|
|
||||||
if (argv[1]) {
|
if (argv[1]) {
|
||||||
arg_1 = argv[1];
|
export_type = argv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg_1 == "spells") {
|
if (Strings::EqualFold(export_type, "spells")) {
|
||||||
ExportSpells(&content_db);
|
ExportSpells(&content_db);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (Strings::EqualFold(export_type, "skills")) {
|
||||||
if (arg_1 == "skills") {
|
|
||||||
ExportSkillCaps(&content_db);
|
ExportSkillCaps(&content_db);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (Strings::EqualFold(export_type, "basedata") || Strings::EqualFold(export_type, "base_data")) {
|
||||||
if (arg_1 == "basedata") {
|
|
||||||
ExportBaseData(&content_db);
|
ExportBaseData(&content_db);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (Strings::EqualFold(export_type, "dbstr") || Strings::EqualFold(export_type, "dbstring")) {
|
||||||
if (arg_1 == "dbstring") {
|
|
||||||
ExportDBStrings(&database);
|
ExportDBStrings(&database);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -133,179 +136,77 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
void ExportSpells(SharedDatabase* db)
|
void ExportSpells(SharedDatabase* db)
|
||||||
{
|
{
|
||||||
LogInfo("Exporting Spells");
|
std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
|
||||||
|
if (!file || !file.is_open()) {
|
||||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
|
||||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string query = "SELECT * FROM spells_new ORDER BY id";
|
const auto& lines = SpellsNewRepository::GetSpellFileLines(*db);
|
||||||
auto results = db->QueryDatabase(query);
|
|
||||||
|
|
||||||
if (results.Success()) {
|
const std::string& file_string = Strings::Implode("\n", lines);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
std::string line;
|
|
||||||
unsigned int fields = results.ColumnCount();
|
|
||||||
for (unsigned int i = 0; i < fields; ++i) {
|
|
||||||
if (i != 0) {
|
|
||||||
line.push_back('^');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row[i] != nullptr) {
|
file << file_string;
|
||||||
line += row[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "%s\n", line.c_str());
|
file.close();
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
LogInfo("Exported [{}] Spell{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||||
}
|
|
||||||
|
|
||||||
bool SkillUsable(SharedDatabase* db, int skill_id, int class_id)
|
|
||||||
{
|
|
||||||
const auto& l = SkillCapsRepository::GetWhere(
|
|
||||||
*db,
|
|
||||||
fmt::format(
|
|
||||||
"`class_id` = {} AND `skill_id` = {} ORDER BY `cap` DESC LIMIT 1",
|
|
||||||
class_id,
|
|
||||||
skill_id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return !l.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 GetSkill(SharedDatabase* db, int skill_id, int class_id, int level)
|
|
||||||
{
|
|
||||||
const auto& l = SkillCapsRepository::GetWhere(
|
|
||||||
*db,
|
|
||||||
fmt::format(
|
|
||||||
"`class_id` = {} AND `skill_id` = {} AND `level` = {}",
|
|
||||||
class_id,
|
|
||||||
skill_id,
|
|
||||||
level
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (l.empty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto e = l.front();
|
|
||||||
|
|
||||||
return e.cap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase* db)
|
void ExportSkillCaps(SharedDatabase* db)
|
||||||
{
|
{
|
||||||
LogInfo("Exporting Skill Caps");
|
|
||||||
|
|
||||||
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
||||||
if (!file || !file.is_open()) {
|
if (!file || !file.is_open()) {
|
||||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8 skill_cap_max_level = (
|
const auto& lines = SkillCapsRepository::GetSkillCapFileLines(*db);
|
||||||
RuleI(Character, SkillCapMaxLevel) > 0 ?
|
|
||||||
RuleI(Character, SkillCapMaxLevel) :
|
|
||||||
RuleI(Character, MaxLevel)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (uint8 class_id = Class::Warrior; class_id <= Class::Berserker; class_id++) {
|
const std::string& file_string = Strings::Implode("\n", lines);
|
||||||
for (uint8 skill_id = EQ::skills::Skill1HBlunt; skill_id <= EQ::skills::Skill2HPiercing; skill_id++) {
|
|
||||||
if (SkillUsable(db, skill_id, class_id)) {
|
|
||||||
uint32 previous_cap = 0;
|
|
||||||
for (uint8 level = 1; level <= skill_cap_max_level; level++) {
|
|
||||||
uint32 cap = GetSkill(db, skill_id, class_id, level);
|
|
||||||
if (cap < previous_cap) {
|
|
||||||
cap = previous_cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
file << fmt::format("{}^{}^{}^{}^0", class_id, skill_id, level, cap) << std::endl;
|
file << file_string;
|
||||||
|
|
||||||
previous_cap = cap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
LogInfo("Exported [{}] Skill Cap{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportBaseData(SharedDatabase *db)
|
void ExportBaseData(SharedDatabase *db)
|
||||||
{
|
{
|
||||||
LogInfo("Exporting Base Data");
|
std::ofstream file(fmt::format("{}/export/BaseData.txt", path.GetServerPath()));
|
||||||
|
if (!file || !file.is_open()) {
|
||||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
|
||||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string query = "SELECT * FROM base_data ORDER BY level, class";
|
const auto& lines = BaseDataRepository::GetBaseDataFileLines(*db);
|
||||||
auto results = db->QueryDatabase(query);
|
|
||||||
if (results.Success()) {
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
std::string line;
|
|
||||||
unsigned int fields = results.ColumnCount();
|
|
||||||
for (unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
|
||||||
if (rowIndex != 0) {
|
|
||||||
line.push_back('^');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row[rowIndex] != nullptr) {
|
const std::string& file_string = Strings::Implode("\n", lines);
|
||||||
line += row[rowIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "%s\n", line.c_str());
|
file << file_string;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
file.close();
|
||||||
|
|
||||||
|
LogInfo("Exported [{}] Base Data Entr{}", lines.size(), lines.size() != 1 ? "ies" : "y");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportDBStrings(SharedDatabase *db)
|
void ExportDBStrings(SharedDatabase *db)
|
||||||
{
|
{
|
||||||
LogInfo("Exporting DB Strings");
|
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", path.GetServerPath()));
|
||||||
|
if (!file || !file.is_open()) {
|
||||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
|
||||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "Major^Minor^String(New)\n");
|
const auto& lines = DbStrRepository::GetDBStrFileLines(*db);
|
||||||
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
|
|
||||||
auto results = db->QueryDatabase(query);
|
const std::string& file_string = Strings::Implode("\n", lines);
|
||||||
if (results.Success()) {
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
file << file_string;
|
||||||
std::string line;
|
|
||||||
unsigned int fields = results.ColumnCount();
|
file.close();
|
||||||
for (unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
|
||||||
if (rowIndex != 0) {
|
LogInfo("Exported [{}] Database String{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||||
line.push_back('^');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row[rowIndex] != nullptr) {
|
|
||||||
line += row[rowIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "%s\n", line.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,14 @@
|
|||||||
#include "../../common/repositories/base_data_repository.h"
|
#include "../../common/repositories/base_data_repository.h"
|
||||||
#include "../../common/file.h"
|
#include "../../common/file.h"
|
||||||
#include "../../common/events/player_event_logs.h"
|
#include "../../common/events/player_event_logs.h"
|
||||||
|
#include "../../common/evolving_items.h"
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
ZoneStore zone_store;
|
||||||
PathManager path;
|
PathManager path;
|
||||||
PlayerEventLogs player_event_logs;
|
PlayerEventLogs player_event_logs;
|
||||||
|
EvolvingItemsManager evolving_items_manager;
|
||||||
|
|
||||||
void ImportSpells(SharedDatabase *db);
|
void ImportSpells(SharedDatabase *db);
|
||||||
void ImportSkillCaps(SharedDatabase *db);
|
void ImportSkillCaps(SharedDatabase *db);
|
||||||
|
|||||||
+44
-1
@@ -2,6 +2,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
|||||||
|
|
||||||
SET(common_sources
|
SET(common_sources
|
||||||
base_packet.cpp
|
base_packet.cpp
|
||||||
|
bazaar.cpp
|
||||||
|
bodytypes.cpp
|
||||||
classes.cpp
|
classes.cpp
|
||||||
cli/eqemu_command_handler.cpp
|
cli/eqemu_command_handler.cpp
|
||||||
compression.cpp
|
compression.cpp
|
||||||
@@ -37,6 +39,7 @@ SET(common_sources
|
|||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
events/player_event_logs.cpp
|
events/player_event_logs.cpp
|
||||||
events/player_event_discord_formatter.cpp
|
events/player_event_discord_formatter.cpp
|
||||||
|
evolving_items.cpp
|
||||||
expedition_lockout_timer.cpp
|
expedition_lockout_timer.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
discord/discord_manager.cpp
|
discord/discord_manager.cpp
|
||||||
@@ -60,6 +63,7 @@ SET(common_sources
|
|||||||
mutex.cpp
|
mutex.cpp
|
||||||
mysql_request_result.cpp
|
mysql_request_result.cpp
|
||||||
mysql_request_row.cpp
|
mysql_request_row.cpp
|
||||||
|
mysql_stmt.cpp
|
||||||
opcode_map.cpp
|
opcode_map.cpp
|
||||||
opcodemgr.cpp
|
opcodemgr.cpp
|
||||||
packet_dump.cpp
|
packet_dump.cpp
|
||||||
@@ -85,6 +89,7 @@ SET(common_sources
|
|||||||
skills.cpp
|
skills.cpp
|
||||||
skill_caps.cpp
|
skill_caps.cpp
|
||||||
spdat.cpp
|
spdat.cpp
|
||||||
|
spdat_bot.cpp
|
||||||
strings.cpp
|
strings.cpp
|
||||||
struct_strategy.cpp
|
struct_strategy.cpp
|
||||||
textures.cpp
|
textures.cpp
|
||||||
@@ -94,6 +99,7 @@ SET(common_sources
|
|||||||
json/json.hpp
|
json/json.hpp
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
zone_store.cpp
|
zone_store.cpp
|
||||||
|
memory/ksm.hpp
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
net/console_server_connection.cpp
|
net/console_server_connection.cpp
|
||||||
net/crc32.cpp
|
net/crc32.cpp
|
||||||
@@ -156,6 +162,7 @@ SET(repositories
|
|||||||
repositories/base/base_bugs_repository.h
|
repositories/base/base_bugs_repository.h
|
||||||
repositories/base/base_bug_reports_repository.h
|
repositories/base/base_bug_reports_repository.h
|
||||||
repositories/base/base_buyer_repository.h
|
repositories/base/base_buyer_repository.h
|
||||||
|
repositories/base/base_buyer_trade_items_repository.h
|
||||||
repositories/base/base_character_activities_repository.h
|
repositories/base/base_character_activities_repository.h
|
||||||
repositories/base/base_character_alternate_abilities_repository.h
|
repositories/base/base_character_alternate_abilities_repository.h
|
||||||
repositories/base/base_character_alt_currency_repository.h
|
repositories/base/base_character_alt_currency_repository.h
|
||||||
@@ -168,6 +175,7 @@ SET(repositories
|
|||||||
repositories/base/base_character_currency_repository.h
|
repositories/base/base_character_currency_repository.h
|
||||||
repositories/base/base_character_data_repository.h
|
repositories/base/base_character_data_repository.h
|
||||||
repositories/base/base_character_disciplines_repository.h
|
repositories/base/base_character_disciplines_repository.h
|
||||||
|
repositories/base/base_character_evolving_items_repository.h
|
||||||
repositories/base/base_character_expedition_lockouts_repository.h
|
repositories/base/base_character_expedition_lockouts_repository.h
|
||||||
repositories/base/base_character_exp_modifiers_repository.h
|
repositories/base/base_character_exp_modifiers_repository.h
|
||||||
repositories/base/base_character_inspect_messages_repository.h
|
repositories/base/base_character_inspect_messages_repository.h
|
||||||
@@ -178,6 +186,7 @@ SET(repositories
|
|||||||
repositories/base/base_character_material_repository.h
|
repositories/base/base_character_material_repository.h
|
||||||
repositories/base/base_character_memmed_spells_repository.h
|
repositories/base/base_character_memmed_spells_repository.h
|
||||||
repositories/base/base_character_parcels_repository.h
|
repositories/base/base_character_parcels_repository.h
|
||||||
|
repositories/base/base_character_parcels_containers_repository.h
|
||||||
repositories/base/base_character_peqzone_flags_repository.h
|
repositories/base/base_character_peqzone_flags_repository.h
|
||||||
repositories/base/base_character_pet_buffs_repository.h
|
repositories/base/base_character_pet_buffs_repository.h
|
||||||
repositories/base/base_character_pet_info_repository.h
|
repositories/base/base_character_pet_info_repository.h
|
||||||
@@ -213,6 +222,7 @@ SET(repositories
|
|||||||
repositories/base/base_faction_list_repository.h
|
repositories/base/base_faction_list_repository.h
|
||||||
repositories/base/base_faction_list_mod_repository.h
|
repositories/base/base_faction_list_mod_repository.h
|
||||||
repositories/base/base_faction_values_repository.h
|
repositories/base/base_faction_values_repository.h
|
||||||
|
repositories/base/base_find_location_repository.h
|
||||||
repositories/base/base_fishing_repository.h
|
repositories/base/base_fishing_repository.h
|
||||||
repositories/base/base_forage_repository.h
|
repositories/base/base_forage_repository.h
|
||||||
repositories/base/base_friends_repository.h
|
repositories/base/base_friends_repository.h
|
||||||
@@ -235,6 +245,7 @@ SET(repositories
|
|||||||
repositories/base/base_inventory_snapshots_repository.h
|
repositories/base/base_inventory_snapshots_repository.h
|
||||||
repositories/base/base_ip_exemptions_repository.h
|
repositories/base/base_ip_exemptions_repository.h
|
||||||
repositories/base/base_items_repository.h
|
repositories/base/base_items_repository.h
|
||||||
|
repositories/base/base_items_evolving_details_repository.h
|
||||||
repositories/base/base_ldon_trap_entries_repository.h
|
repositories/base/base_ldon_trap_entries_repository.h
|
||||||
repositories/base/base_ldon_trap_templates_repository.h
|
repositories/base/base_ldon_trap_templates_repository.h
|
||||||
repositories/base/base_level_exp_mods_repository.h
|
repositories/base/base_level_exp_mods_repository.h
|
||||||
@@ -272,8 +283,20 @@ SET(repositories
|
|||||||
repositories/base/base_pets_equipmentset_repository.h
|
repositories/base/base_pets_equipmentset_repository.h
|
||||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||||
repositories/base/base_player_titlesets_repository.h
|
repositories/base/base_player_titlesets_repository.h
|
||||||
|
repositories/base/base_player_event_aa_purchase_repository.h
|
||||||
|
repositories/base/base_player_event_killed_npc_repository.h
|
||||||
|
repositories/base/base_player_event_killed_named_npc_repository.h
|
||||||
|
repositories/base/base_player_event_killed_raid_npc_repository.h
|
||||||
repositories/base/base_player_event_log_settings_repository.h
|
repositories/base/base_player_event_log_settings_repository.h
|
||||||
repositories/base/base_player_event_logs_repository.h
|
repositories/base/base_player_event_logs_repository.h
|
||||||
|
repositories/base/base_player_event_loot_items_repository.h
|
||||||
|
repositories/base/base_player_event_merchant_purchase_repository.h
|
||||||
|
repositories/base/base_player_event_merchant_sell_repository.h
|
||||||
|
repositories/base/base_player_event_npc_handin_repository.h
|
||||||
|
repositories/base/base_player_event_npc_handin_entries_repository.h
|
||||||
|
repositories/base/base_player_event_speech_repository.h
|
||||||
|
repositories/base/base_player_event_trade_repository.h
|
||||||
|
repositories/base/base_player_event_trade_entries_repository.h
|
||||||
repositories/base/base_quest_globals_repository.h
|
repositories/base/base_quest_globals_repository.h
|
||||||
repositories/base/base_raid_details_repository.h
|
repositories/base/base_raid_details_repository.h
|
||||||
repositories/base/base_raid_members_repository.h
|
repositories/base/base_raid_members_repository.h
|
||||||
@@ -336,7 +359,8 @@ SET(repositories
|
|||||||
repositories/books_repository.h
|
repositories/books_repository.h
|
||||||
repositories/bugs_repository.h
|
repositories/bugs_repository.h
|
||||||
repositories/bug_reports_repository.h
|
repositories/bug_reports_repository.h
|
||||||
repositories/buyer_repository.h
|
repositories/buyer_buy_lines_repository.h
|
||||||
|
repositories/buyer_trade_items_repository.h
|
||||||
repositories/character_activities_repository.h
|
repositories/character_activities_repository.h
|
||||||
repositories/character_alternate_abilities_repository.h
|
repositories/character_alternate_abilities_repository.h
|
||||||
repositories/character_alt_currency_repository.h
|
repositories/character_alt_currency_repository.h
|
||||||
@@ -349,6 +373,7 @@ SET(repositories
|
|||||||
repositories/character_currency_repository.h
|
repositories/character_currency_repository.h
|
||||||
repositories/character_data_repository.h
|
repositories/character_data_repository.h
|
||||||
repositories/character_disciplines_repository.h
|
repositories/character_disciplines_repository.h
|
||||||
|
repositories/character_evolving_items_repository.h
|
||||||
repositories/character_expedition_lockouts_repository.h
|
repositories/character_expedition_lockouts_repository.h
|
||||||
repositories/character_exp_modifiers_repository.h
|
repositories/character_exp_modifiers_repository.h
|
||||||
repositories/character_inspect_messages_repository.h
|
repositories/character_inspect_messages_repository.h
|
||||||
@@ -359,6 +384,7 @@ SET(repositories
|
|||||||
repositories/character_material_repository.h
|
repositories/character_material_repository.h
|
||||||
repositories/character_memmed_spells_repository.h
|
repositories/character_memmed_spells_repository.h
|
||||||
repositories/character_parcels_repository.h
|
repositories/character_parcels_repository.h
|
||||||
|
repositories/character_parcels_containers_repository.h
|
||||||
repositories/character_peqzone_flags_repository.h
|
repositories/character_peqzone_flags_repository.h
|
||||||
repositories/character_pet_buffs_repository.h
|
repositories/character_pet_buffs_repository.h
|
||||||
repositories/character_pet_info_repository.h
|
repositories/character_pet_info_repository.h
|
||||||
@@ -394,6 +420,7 @@ SET(repositories
|
|||||||
repositories/faction_list_repository.h
|
repositories/faction_list_repository.h
|
||||||
repositories/faction_list_mod_repository.h
|
repositories/faction_list_mod_repository.h
|
||||||
repositories/faction_values_repository.h
|
repositories/faction_values_repository.h
|
||||||
|
repositories/find_location_repository.h
|
||||||
repositories/fishing_repository.h
|
repositories/fishing_repository.h
|
||||||
repositories/forage_repository.h
|
repositories/forage_repository.h
|
||||||
repositories/friends_repository.h
|
repositories/friends_repository.h
|
||||||
@@ -416,6 +443,7 @@ SET(repositories
|
|||||||
repositories/inventory_snapshots_repository.h
|
repositories/inventory_snapshots_repository.h
|
||||||
repositories/ip_exemptions_repository.h
|
repositories/ip_exemptions_repository.h
|
||||||
repositories/items_repository.h
|
repositories/items_repository.h
|
||||||
|
repositories/items_evolving_details_repository.h
|
||||||
repositories/ldon_trap_entries_repository.h
|
repositories/ldon_trap_entries_repository.h
|
||||||
repositories/ldon_trap_templates_repository.h
|
repositories/ldon_trap_templates_repository.h
|
||||||
repositories/level_exp_mods_repository.h
|
repositories/level_exp_mods_repository.h
|
||||||
@@ -453,8 +481,20 @@ SET(repositories
|
|||||||
repositories/pets_equipmentset_repository.h
|
repositories/pets_equipmentset_repository.h
|
||||||
repositories/pets_equipmentset_entries_repository.h
|
repositories/pets_equipmentset_entries_repository.h
|
||||||
repositories/player_titlesets_repository.h
|
repositories/player_titlesets_repository.h
|
||||||
|
repositories/player_event_aa_purchase_repository.h
|
||||||
|
repositories/player_event_killed_npc_repository.h
|
||||||
|
repositories/player_event_killed_named_npc_repository.h
|
||||||
|
repositories/player_event_killed_raid_npc_repository.h
|
||||||
repositories/player_event_log_settings_repository.h
|
repositories/player_event_log_settings_repository.h
|
||||||
repositories/player_event_logs_repository.h
|
repositories/player_event_logs_repository.h
|
||||||
|
repositories/player_event_loot_items_repository.h
|
||||||
|
repositories/player_event_merchant_purchase_repository.h
|
||||||
|
repositories/player_event_merchant_sell_repository.h
|
||||||
|
repositories/player_event_npc_handin_repository.h
|
||||||
|
repositories/player_event_npc_handin_entries_repository.h
|
||||||
|
repositories/player_event_speech_repository.h
|
||||||
|
repositories/player_event_trade_repository.h
|
||||||
|
repositories/player_event_trade_entries_repository.h
|
||||||
repositories/quest_globals_repository.h
|
repositories/quest_globals_repository.h
|
||||||
repositories/raid_details_repository.h
|
repositories/raid_details_repository.h
|
||||||
repositories/raid_members_repository.h
|
repositories/raid_members_repository.h
|
||||||
@@ -499,6 +539,7 @@ SET(repositories
|
|||||||
|
|
||||||
SET(common_headers
|
SET(common_headers
|
||||||
additive_lagged_fibonacci_engine.h
|
additive_lagged_fibonacci_engine.h
|
||||||
|
bazaar.h
|
||||||
base_packet.h
|
base_packet.h
|
||||||
bodytypes.h
|
bodytypes.h
|
||||||
classes.h
|
classes.h
|
||||||
@@ -547,6 +588,7 @@ SET(common_headers
|
|||||||
events/player_event_discord_formatter.h
|
events/player_event_discord_formatter.h
|
||||||
events/player_events.h
|
events/player_events.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
|
evolving_items.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
extprofile.h
|
extprofile.h
|
||||||
faction.h
|
faction.h
|
||||||
@@ -579,6 +621,7 @@ SET(common_headers
|
|||||||
mutex.h
|
mutex.h
|
||||||
mysql_request_result.h
|
mysql_request_result.h
|
||||||
mysql_request_row.h
|
mysql_request_row.h
|
||||||
|
mysql_stmt.h
|
||||||
op_codes.h
|
op_codes.h
|
||||||
opcode_dispatch.h
|
opcode_dispatch.h
|
||||||
opcodemgr.h
|
opcodemgr.h
|
||||||
|
|||||||
@@ -0,0 +1,333 @@
|
|||||||
|
#include "bazaar.h"
|
||||||
|
|
||||||
|
#include "../../common/item_instance.h"
|
||||||
|
#include "repositories/trader_repository.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
std::vector<BazaarSearchResultsFromDB_Struct>
|
||||||
|
Bazaar::GetSearchResults(
|
||||||
|
Database &db,
|
||||||
|
Database &content_db,
|
||||||
|
BazaarSearchCriteria_Struct search,
|
||||||
|
uint32 char_zone_id,
|
||||||
|
int32 char_zone_instance_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LogTrading(
|
||||||
|
"Searching for items with search criteria - item_name [{}] min_cost [{}] max_cost [{}] min_level [{}] "
|
||||||
|
"max_level [{}] max_results [{}] prestige [{}] augment [{}] trader_entity_id [{}] trader_id [{}] "
|
||||||
|
"search_scope [{}] char_zone_id [{}], char_zone_instance_id [{}]",
|
||||||
|
search.item_name,
|
||||||
|
search.min_cost,
|
||||||
|
search.max_cost,
|
||||||
|
search.min_level,
|
||||||
|
search.max_level,
|
||||||
|
search.max_results,
|
||||||
|
search.prestige,
|
||||||
|
search.augment,
|
||||||
|
search.trader_entity_id,
|
||||||
|
search.trader_id,
|
||||||
|
search.search_scope,
|
||||||
|
char_zone_id,
|
||||||
|
char_zone_instance_id
|
||||||
|
);
|
||||||
|
|
||||||
|
static std::map<uint8, uint32> item_slot_searches_new = {
|
||||||
|
{EQ::invslot::slotCharm, 1},
|
||||||
|
{EQ::invslot::slotEar1, 2},
|
||||||
|
{EQ::invslot::slotHead, 4},
|
||||||
|
{EQ::invslot::slotFace, 8},
|
||||||
|
{EQ::invslot::slotEar2, 16},
|
||||||
|
{EQ::invslot::slotNeck, 32},
|
||||||
|
{EQ::invslot::slotShoulders, 64},
|
||||||
|
{EQ::invslot::slotArms, 128},
|
||||||
|
{EQ::invslot::slotBack, 256},
|
||||||
|
{EQ::invslot::slotWrist1, 512},
|
||||||
|
{EQ::invslot::slotWrist2, 1024},
|
||||||
|
{EQ::invslot::slotRange, 2048},
|
||||||
|
{EQ::invslot::slotHands, 4096},
|
||||||
|
{EQ::invslot::slotPrimary, 8192},
|
||||||
|
{EQ::invslot::slotSecondary, 16384},
|
||||||
|
{EQ::invslot::slotFinger1, 32768},
|
||||||
|
{EQ::invslot::slotFinger2, 65536},
|
||||||
|
{EQ::invslot::slotChest, 131072},
|
||||||
|
{EQ::invslot::slotLegs, 262144},
|
||||||
|
{EQ::invslot::slotFeet, 524288},
|
||||||
|
{EQ::invslot::slotWaist, 1048576},
|
||||||
|
{EQ::invslot::slotPowerSource, 2097152},
|
||||||
|
{EQ::invslot::slotAmmo, 4194304},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ItemSearchType {
|
||||||
|
EQ::item::ItemType type;
|
||||||
|
std::string condition;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<ItemSearchType> item_search_types_new = {
|
||||||
|
{EQ::item::ItemType::ItemTypeBook, " AND (items.itemclass = 2 or items.itemclass = 31)"},
|
||||||
|
{EQ::item::ItemType::ItemTypeContainer, " AND (items.itemclass = 1 or items.itemclass = 67)"},
|
||||||
|
{EQ::item::ItemType::ItemTypeAllEffects, " AND (items.scrolleffect > 0 && items.scrolleffect < 65000)"},
|
||||||
|
{EQ::item::ItemType::ItemTypeUnknown9, " AND items.worneffect = 998"},
|
||||||
|
{EQ::item::ItemType::ItemTypeUnknown10, " AND (items.worneffect >= 1298 && items.worneffect <= 1307)"},
|
||||||
|
{EQ::item::ItemType::ItemTypeFocusEffect, " AND items.focuseffect > 0"},
|
||||||
|
{EQ::item::ItemType::ItemTypeArmor, " AND items.itemtype = 10"},
|
||||||
|
{EQ::item::ItemType::ItemType1HBlunt, " AND items.itemtype = 3"},
|
||||||
|
{EQ::item::ItemType::ItemType1HPiercing, " AND items.itemtype = 2"},
|
||||||
|
{EQ::item::ItemType::ItemType1HSlash, " AND items.itemtype = 0"},
|
||||||
|
{EQ::item::ItemType::ItemType2HBlunt, " AND items.itemtype = 4"},
|
||||||
|
{EQ::item::ItemType::ItemType2HSlash, " AND items.itemtype = 1"},
|
||||||
|
{EQ::item::ItemType::ItemTypeBow, " AND items.itemtype = 5"},
|
||||||
|
{EQ::item::ItemType::ItemTypeShield, " AND items.itemtype = 8"},
|
||||||
|
{EQ::item::ItemType::ItemTypeMisc, " AND items.itemtype = 11"},
|
||||||
|
{EQ::item::ItemType::ItemTypeFood, " AND items.itemtype = 14"},
|
||||||
|
{EQ::item::ItemType::ItemTypeDrink, " AND items.itemtype = 15"},
|
||||||
|
{EQ::item::ItemType::ItemTypeLight, " AND items.itemtype = 16"},
|
||||||
|
{EQ::item::ItemType::ItemTypeCombinable, " AND items.itemtype = 17"},
|
||||||
|
{EQ::item::ItemType::ItemTypeBandage, " AND items.itemtype = 18"},
|
||||||
|
{EQ::item::ItemType::ItemTypeSmallThrowing, " AND (items.itemtype = 19 OR items.itemtype = 7)"},
|
||||||
|
{EQ::item::ItemType::ItemTypeSpell, " AND items.itemtype = 20"},
|
||||||
|
{EQ::item::ItemType::ItemTypePotion, " AND items.itemtype = 21"},
|
||||||
|
{EQ::item::ItemType::ItemTypeBrassInstrument, " AND items.itemtype = 25"},
|
||||||
|
{EQ::item::ItemType::ItemTypeWindInstrument, " AND items.itemtype = 23"},
|
||||||
|
{EQ::item::ItemType::ItemTypeStringedInstrument, " AND items.itemtype = 24"},
|
||||||
|
{EQ::item::ItemType::ItemTypePercussionInstrument, " AND items.itemtype = 26"},
|
||||||
|
{EQ::item::ItemType::ItemTypeArrow, " AND items.itemtype = 27"},
|
||||||
|
{EQ::item::ItemType::ItemTypeJewelry, " AND items.itemtype = 29"},
|
||||||
|
{EQ::item::ItemType::ItemTypeNote, " AND items.itemtype = 32"},
|
||||||
|
{EQ::item::ItemType::ItemTypeKey, " AND items.itemtype = 33"},
|
||||||
|
{EQ::item::ItemType::ItemType2HPiercing, " AND items.itemtype = 35"},
|
||||||
|
{EQ::item::ItemType::ItemTypeAlcohol, " AND items.itemtype = 38"},
|
||||||
|
{EQ::item::ItemType::ItemTypeMartial, " AND items.itemtype = 45"},
|
||||||
|
{EQ::item::ItemType::ItemTypeAugmentation, " AND items.itemtype = 54"},
|
||||||
|
{EQ::item::ItemType::ItemTypeAlternateAbility, " AND items.itemtype = 57"},
|
||||||
|
{EQ::item::ItemType::ItemTypeCount, " AND items.itemtype = 65"},
|
||||||
|
{EQ::item::ItemType::ItemTypeCollectible, " AND items.itemtype = 66"}
|
||||||
|
};
|
||||||
|
|
||||||
|
// item stat searches
|
||||||
|
struct ItemStatSearch {
|
||||||
|
std::string query_string;
|
||||||
|
EQ::skills::SkillType skill_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<uint32, ItemStatSearch> item_stat_searches_new = {
|
||||||
|
{STAT_AC, {" items.ac" , static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_AGI, {" items.aagi", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_CHA, {" items.acha", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_DEX, {" items.adex", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_INT, {" items.aint", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_STA, {" items.asta", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_STR, {" items.astr", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_WIS, {" items.awis", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_COLD, {" items.cr", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_DISEASE, {" items.dr", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_FIRE, {" items.fr", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_MAGIC, {" items.mr", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_POISON, {" items.pr", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HP, {" items.hp", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_MANA, {" items.mana", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_ENDURANCE, {" items.endur", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_ATTACK, {" items.attack", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HP_REGEN, {" items.regen", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_MANA_REGEN, {" items.manaregen", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HASTE, {" items.haste", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_DAMAGE_SHIELD, {" items.damageshield", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_DS_MITIGATION, {" items.dsmitigation", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEAL_AMOUNT, {" items.healamt", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_SPELL_DAMAGE, {" items.spelldmg", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_CLAIRVOYANCE, {" items.clairvoyance", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_AGILITY, {" items.heroic_agi", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_CHARISMA, {" items.heroic_cha", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_DEXTERITY, {" items.heroic_dex", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_INTELLIGENCE, {" items.heroic_int", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_STAMINA, {" items.heroic_sta", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_STRENGTH, {" items.heroic_str", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_HEROIC_WISDOM, {" items.heroic_wis", static_cast<EQ::skills::SkillType>(0)} },
|
||||||
|
{STAT_BASH, {" items.skillmodvalue", EQ::skills::SkillBash} },
|
||||||
|
{STAT_BACKSTAB, {" items.backstabdmg", EQ::skills::SkillBackstab} },
|
||||||
|
{STAT_DRAGON_PUNCH, {" items.skillmodvalue", EQ::skills::SkillDragonPunch} },
|
||||||
|
{STAT_EAGLE_STRIKE, {" items.skillmodvalue", EQ::skills::SkillEagleStrike} },
|
||||||
|
{STAT_FLYING_KICK, {" items.skillmodvalue", EQ::skills::SkillFlyingKick} },
|
||||||
|
{STAT_KICK, {" items.skillmodvalue", EQ::skills::SkillKick} },
|
||||||
|
{STAT_ROUND_KICK, {" items.skillmodvalue", EQ::skills::SkillRoundKick} },
|
||||||
|
{STAT_TIGER_CLAW, {" items.skillmodvalue", EQ::skills::SkillTigerClaw} },
|
||||||
|
{STAT_FRENZY, {" items.skillmodvalue", EQ::skills::SkillFrenzy} },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool convert = false;
|
||||||
|
std::string search_criteria_trader("TRUE");
|
||||||
|
std::string field_criteria_items("FALSE");
|
||||||
|
std::string where_criteria_items(" TRUE ");
|
||||||
|
|
||||||
|
if (search.search_scope == NonRoFBazaarSearchScope) {
|
||||||
|
search_criteria_trader.append(
|
||||||
|
fmt::format(
|
||||||
|
" AND trader.char_entity_id = {} AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
|
||||||
|
search.trader_entity_id,
|
||||||
|
Zones::BAZAAR,
|
||||||
|
char_zone_instance_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (search.search_scope == Local_Scope) {
|
||||||
|
search_criteria_trader.append(fmt::format(
|
||||||
|
" AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
|
||||||
|
char_zone_id,
|
||||||
|
char_zone_instance_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (search.trader_id > 0) {
|
||||||
|
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||||
|
if (search.trader_id >= TraderRepository::TRADER_CONVERT_ID) {
|
||||||
|
convert = true;
|
||||||
|
search_criteria_trader.append(fmt::format(
|
||||||
|
" AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
|
||||||
|
Zones::BAZAAR,
|
||||||
|
search.trader_id - TraderRepository::TRADER_CONVERT_ID)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.min_cost != 0) {
|
||||||
|
search_criteria_trader.append(fmt::format(" AND trader.item_cost >= {}", search.min_cost * 1000));
|
||||||
|
}
|
||||||
|
if (search.max_cost != 0) {
|
||||||
|
search_criteria_trader.append(fmt::format(" AND trader.item_cost <= {}", (uint64) search.max_cost * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.slot != std::numeric_limits<uint32>::max()) {
|
||||||
|
if (item_slot_searches_new.contains(search.slot)) {
|
||||||
|
where_criteria_items.append(
|
||||||
|
fmt::format(" AND items.slots & {0} = {0}", item_slot_searches_new[search.slot]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.type != std::numeric_limits<uint32>::max()) {
|
||||||
|
for (auto const &[type, condition]: item_search_types_new) {
|
||||||
|
if (type == search.type) {
|
||||||
|
where_criteria_items.append(condition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.race != std::numeric_limits<uint32>::max()) {
|
||||||
|
where_criteria_items.append(
|
||||||
|
fmt::format(" AND items.races & {0} = {0}", GetPlayerRaceBit(GetRaceIDFromPlayerRaceValue(search.race))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search._class != std::numeric_limits<uint32>::max()) {
|
||||||
|
where_criteria_items.append(fmt::format(" AND items.classes & {0} = {0}", GetPlayerClassBit(search._class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.item_stat != std::numeric_limits<uint32>::max()) {
|
||||||
|
if (item_stat_searches_new.contains(search.item_stat)) {
|
||||||
|
field_criteria_items = fmt::format("{}", item_stat_searches_new[search.item_stat].query_string);
|
||||||
|
if (item_stat_searches_new[search.item_stat].skill_type) {
|
||||||
|
where_criteria_items.append(
|
||||||
|
fmt::format(" AND items.skillmodtype = {} ", item_stat_searches_new[search.item_stat].skill_type));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
where_criteria_items.append(
|
||||||
|
fmt::format(" AND {} > 0 ", item_stat_searches_new[search.item_stat].query_string));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.augment) {
|
||||||
|
where_criteria_items.append(fmt::format(
|
||||||
|
" AND (items.augslot1type = {0} OR "
|
||||||
|
"items.augslot2type = {0} OR "
|
||||||
|
"items.augslot3type = {0} OR "
|
||||||
|
"items.augslot4type = {0} OR "
|
||||||
|
"items.augslot5type = {0} OR "
|
||||||
|
"items.augslot6type = {0})",
|
||||||
|
search.augment)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.min_level != 1) {
|
||||||
|
where_criteria_items.append(fmt::format(" AND items.reclevel >= {}", search.min_level));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search.max_level != 100) {
|
||||||
|
where_criteria_items.append(fmt::format(" AND items.reclevel <= {}", search.max_level));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BazaarSearchResultsFromDB_Struct> all_entries;
|
||||||
|
std::vector<std::string> trader_items_ids{};
|
||||||
|
|
||||||
|
auto const trader_results = TraderRepository::GetBazaarTraderDetails(db, search_criteria_trader);
|
||||||
|
if (trader_results.empty()) {
|
||||||
|
LogTradingDetail("Bazaar - No traders found in bazaar search.");
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const &i: trader_results) {
|
||||||
|
trader_items_ids.push_back(std::to_string(i.trader.item_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const item_results = ItemsRepository::GetItemsForBazaarSearch(
|
||||||
|
content_db,
|
||||||
|
trader_items_ids,
|
||||||
|
std::string(search.item_name),
|
||||||
|
field_criteria_items,
|
||||||
|
where_criteria_items
|
||||||
|
);
|
||||||
|
|
||||||
|
if (item_results.empty()) {
|
||||||
|
LogTradingDetail("Bazaar - No items found in bazaar search.");
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
all_entries.reserve(trader_results.size());
|
||||||
|
|
||||||
|
for (auto const& t:trader_results) {
|
||||||
|
if (!item_results.contains(t.trader.item_id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BazaarSearchResultsFromDB_Struct r{};
|
||||||
|
r.count = 1;
|
||||||
|
r.trader_id = t.trader.char_id;
|
||||||
|
r.serial_number = t.trader.item_sn;
|
||||||
|
r.cost = t.trader.item_cost;
|
||||||
|
r.slot_id = t.trader.slot_id;
|
||||||
|
r.charges = t.trader.item_charges;
|
||||||
|
r.stackable = item_results.at(t.trader.item_id).stackable;
|
||||||
|
r.icon_id = item_results.at(t.trader.item_id).icon;
|
||||||
|
r.trader_zone_id = t.trader.char_zone_id;
|
||||||
|
r.trader_zone_instance_id = t.trader.char_zone_instance_id;
|
||||||
|
r.trader_entity_id = t.trader.char_entity_id;
|
||||||
|
r.serial_number_RoF = fmt::format("{:016}\0", t.trader.item_sn);
|
||||||
|
r.item_name = fmt::format("{:.63}\0", item_results.at(t.trader.item_id).name);
|
||||||
|
r.trader_name = fmt::format("{:.63}\0", t.trader_name);
|
||||||
|
r.item_stat = item_results.at(t.trader.item_id).stats;
|
||||||
|
|
||||||
|
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
|
||||||
|
if (convert ||
|
||||||
|
char_zone_id != Zones::BAZAAR ||
|
||||||
|
(char_zone_id == Zones::BAZAAR && r.trader_zone_instance_id != char_zone_instance_id)
|
||||||
|
) {
|
||||||
|
r.trader_id = TraderRepository::TRADER_CONVERT_ID + r.trader_zone_instance_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
all_entries.push_back(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_entries.size() > search.max_results) {
|
||||||
|
all_entries.resize(search.max_results);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogTrading("Returning [{}] items from search results", all_entries.size());
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef EQEMU_BAZAAR_H
|
||||||
|
#define EQEMU_BAZAAR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "shareddb.h"
|
||||||
|
#include "../../common/item_instance.h"
|
||||||
|
|
||||||
|
class Bazaar {
|
||||||
|
public:
|
||||||
|
static std::vector<BazaarSearchResultsFromDB_Struct>
|
||||||
|
GetSearchResults(Database &content_db, Database &db, BazaarSearchCriteria_Struct search, unsigned int char_zone_id, int char_zone_instance_id);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //EQEMU_BAZAAR_H
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#include "../common/global_define.h"
|
||||||
|
#include "../common/bodytypes.h"
|
||||||
|
|
||||||
|
std::string BodyType::GetName(uint8 body_type_id)
|
||||||
|
{
|
||||||
|
return IsValid(body_type_id) ? body_type_names[body_type_id] : "UNKNOWN BODY TYPE";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BodyType::IsValid(uint8 body_type_id)
|
||||||
|
{
|
||||||
|
return body_type_names.find(body_type_id) != body_type_names.end();
|
||||||
|
}
|
||||||
+90
-46
@@ -18,52 +18,96 @@
|
|||||||
#ifndef BODYTYPES_H
|
#ifndef BODYTYPES_H
|
||||||
#define BODYTYPES_H
|
#define BODYTYPES_H
|
||||||
|
|
||||||
typedef enum {
|
#include "types.h"
|
||||||
BT_Humanoid = 1,
|
#include <map>
|
||||||
BT_Lycanthrope = 2,
|
#include <string>
|
||||||
BT_Undead = 3,
|
|
||||||
BT_Giant = 4,
|
|
||||||
BT_Construct = 5,
|
|
||||||
BT_Extraplanar = 6,
|
|
||||||
BT_Magical = 7, //this name might be a bit off,
|
|
||||||
BT_SummonedUndead = 8,
|
|
||||||
BT_RaidGiant = 9, //Velious era Raid Giant
|
|
||||||
BT_RaidColdain = 10, //Velious era Raid Coldain
|
|
||||||
BT_NoTarget = 11, //no name, can't target this bodytype
|
|
||||||
BT_Vampire = 12,
|
|
||||||
BT_Atenha_Ra = 13,
|
|
||||||
BT_Greater_Akheva = 14,
|
|
||||||
BT_Khati_Sha = 15,
|
|
||||||
BT_Seru = 16,
|
|
||||||
BT_Grieg_Veneficus = 17,
|
|
||||||
BT_Draz_Nurakk = 18,
|
|
||||||
BT_Zek = 19, //"creatures from the Plane of War."
|
|
||||||
BT_Luggald = 20,
|
|
||||||
BT_Animal = 21,
|
|
||||||
BT_Insect = 22,
|
|
||||||
BT_Monster = 23,
|
|
||||||
BT_Summoned = 24, //Elemental?
|
|
||||||
BT_Plant = 25,
|
|
||||||
BT_Dragon = 26,
|
|
||||||
BT_Summoned2 = 27,
|
|
||||||
BT_Summoned3 = 28,
|
|
||||||
BT_Dragon2 = 29, //database data indicates this is a dragon type (kunark and DoN?)
|
|
||||||
BT_VeliousDragon = 30, //might not be a tight set
|
|
||||||
BT_Familiar = 31,
|
|
||||||
BT_Dragon3 = 32,
|
|
||||||
BT_Boxes = 33,
|
|
||||||
BT_Muramite = 34, //tribal dudes
|
|
||||||
// ...
|
|
||||||
BT_NoTarget2 = 60,
|
|
||||||
// ...
|
|
||||||
BT_SwarmPet = 63, //Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
|
|
||||||
BT_MonsterSummon = 64,
|
|
||||||
// 65, trap or effect related?
|
|
||||||
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
|
|
||||||
BT_Special = 67
|
|
||||||
} bodyType;
|
|
||||||
/* bodytypes above 64 make the mob not show up */
|
|
||||||
|
|
||||||
constexpr int format_as(bodyType type) { return static_cast<int>(type); }
|
// body types above 64 make the mob invisible
|
||||||
|
namespace BodyType {
|
||||||
|
constexpr uint8 Humanoid = 1;
|
||||||
|
constexpr uint8 Lycanthrope = 2;
|
||||||
|
constexpr uint8 Undead = 3;
|
||||||
|
constexpr uint8 Giant = 4;
|
||||||
|
constexpr uint8 Construct = 5;
|
||||||
|
constexpr uint8 Extraplanar = 6;
|
||||||
|
constexpr uint8 Magical = 7; // this name might be a bit off,
|
||||||
|
constexpr uint8 SummonedUndead = 8;
|
||||||
|
constexpr uint8 RaidGiant = 9; // Velious era Raid Giant
|
||||||
|
constexpr uint8 RaidColdain = 10; // Velious era Raid Coldain
|
||||||
|
constexpr uint8 NoTarget = 11; // no name, can't target this bodytype
|
||||||
|
constexpr uint8 Vampire = 12;
|
||||||
|
constexpr uint8 AtenHaRa = 13;
|
||||||
|
constexpr uint8 GreaterAkheva = 14;
|
||||||
|
constexpr uint8 KhatiSha = 15;
|
||||||
|
constexpr uint8 Seru = 16;
|
||||||
|
constexpr uint8 GriegVeneficus = 17;
|
||||||
|
constexpr uint8 DrazNurakk = 18;
|
||||||
|
constexpr uint8 Zek = 19; //"creatures from the Plane of War."
|
||||||
|
constexpr uint8 Luggald = 20;
|
||||||
|
constexpr uint8 Animal = 21;
|
||||||
|
constexpr uint8 Insect = 22;
|
||||||
|
constexpr uint8 Monster = 23;
|
||||||
|
constexpr uint8 Summoned = 24; // Elemental?
|
||||||
|
constexpr uint8 Plant = 25;
|
||||||
|
constexpr uint8 Dragon = 26;
|
||||||
|
constexpr uint8 Summoned2 = 27;
|
||||||
|
constexpr uint8 Summoned3 = 28;
|
||||||
|
constexpr uint8 Dragon2 = 29; // database data indicates this is a dragon type (Kunark and DoN?)
|
||||||
|
constexpr uint8 VeliousDragon = 30; // might not be a tight set
|
||||||
|
constexpr uint8 Familiar = 31;
|
||||||
|
constexpr uint8 Dragon3 = 32;
|
||||||
|
constexpr uint8 Boxes = 33;
|
||||||
|
constexpr uint8 Muramite = 34; // tribal dudes
|
||||||
|
constexpr uint8 NoTarget2 = 60;
|
||||||
|
constexpr uint8 SwarmPet = 63; // Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
|
||||||
|
constexpr uint8 MonsterSummon = 64;
|
||||||
|
constexpr uint8 InvisibleMan = 66; // no name, seen on 'InvisMan', can be /targeted
|
||||||
|
constexpr uint8 Special = 67;
|
||||||
|
|
||||||
|
std::string GetName(uint8 body_type_id);
|
||||||
|
bool IsValid(uint8 body_type_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> body_type_names = {
|
||||||
|
{ BodyType::Humanoid, "Humanoid" },
|
||||||
|
{ BodyType::Lycanthrope, "Lycanthrope" },
|
||||||
|
{ BodyType::Undead, "Undead" },
|
||||||
|
{ BodyType::Giant, "Giant" },
|
||||||
|
{ BodyType::Construct, "Construct" },
|
||||||
|
{ BodyType::Extraplanar, "Extraplanar" },
|
||||||
|
{ BodyType::Magical, "Magical" },
|
||||||
|
{ BodyType::SummonedUndead, "Summoned Undead" },
|
||||||
|
{ BodyType::RaidGiant, "Raid Giant" },
|
||||||
|
{ BodyType::RaidColdain, "Raid Coldain" },
|
||||||
|
{ BodyType::NoTarget, "Untargetable" },
|
||||||
|
{ BodyType::Vampire, "Vampire" },
|
||||||
|
{ BodyType::AtenHaRa, "Aten Ha Ra" },
|
||||||
|
{ BodyType::GreaterAkheva, "Greater Akheva" },
|
||||||
|
{ BodyType::KhatiSha, "Khati Sha" },
|
||||||
|
{ BodyType::Seru, "Seru" },
|
||||||
|
{ BodyType::GriegVeneficus, "Grieg Veneficus" },
|
||||||
|
{ BodyType::DrazNurakk, "Draz Nurakk" },
|
||||||
|
{ BodyType::Zek, "Zek" },
|
||||||
|
{ BodyType::Luggald, "Luggald" },
|
||||||
|
{ BodyType::Animal, "Animal" },
|
||||||
|
{ BodyType::Insect, "Insect" },
|
||||||
|
{ BodyType::Monster, "Monster" },
|
||||||
|
{ BodyType::Summoned, "Summoned" },
|
||||||
|
{ BodyType::Plant, "Plant" },
|
||||||
|
{ BodyType::Dragon, "Dragon" },
|
||||||
|
{ BodyType::Summoned2, "Summoned 2" },
|
||||||
|
{ BodyType::Summoned3, "Summoned 3" },
|
||||||
|
{ BodyType::Dragon2, "Dragon 2" },
|
||||||
|
{ BodyType::VeliousDragon, "Velious Dragon" },
|
||||||
|
{ BodyType::Familiar, "Familiar" },
|
||||||
|
{ BodyType::Dragon3, "Dragon 3" },
|
||||||
|
{ BodyType::Boxes, "Boxes" },
|
||||||
|
{ BodyType::Muramite, "Muramite" },
|
||||||
|
{ BodyType::NoTarget2, "Untargetable 2" },
|
||||||
|
{ BodyType::SwarmPet, "Swarm Pet" },
|
||||||
|
{ BodyType::MonsterSummon, "Monster Summon" },
|
||||||
|
{ BodyType::InvisibleMan, "Invisible Man" },
|
||||||
|
{ BodyType::Special, "Special" },
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ static std::map<uint8, std::string> class_names = {
|
|||||||
#define ARMOR_TYPE_LAST ARMOR_TYPE_PLATE
|
#define ARMOR_TYPE_LAST ARMOR_TYPE_PLATE
|
||||||
#define ARMOR_TYPE_COUNT 5
|
#define ARMOR_TYPE_COUNT 5
|
||||||
|
|
||||||
|
#define BOT_CLASS_BASE_ID_PREFIX 3000
|
||||||
|
|
||||||
|
|
||||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../repositories/instance_list_repository.h"
|
#include "../repositories/instance_list_repository.h"
|
||||||
|
#include "../zone_store.h"
|
||||||
|
|
||||||
|
|
||||||
WorldContentService::WorldContentService()
|
WorldContentService::WorldContentService()
|
||||||
@@ -183,8 +184,8 @@ void WorldContentService::ReloadContentFlags()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetContentFlags(set_content_flags);
|
SetContentFlags(set_content_flags);
|
||||||
LoadZones();
|
|
||||||
LoadStaticGlobalZoneInstances();
|
LoadStaticGlobalZoneInstances();
|
||||||
|
zone_store.LoadZones(*m_content_database);
|
||||||
}
|
}
|
||||||
|
|
||||||
Database *WorldContentService::GetDatabase() const
|
Database *WorldContentService::GetDatabase() const
|
||||||
@@ -236,18 +237,6 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
|||||||
ReloadContentFlags();
|
ReloadContentFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleZoneRoutingMiddleware is meant to handle content and context aware zone routing
|
|
||||||
//
|
|
||||||
// example # 1
|
|
||||||
// lavastorm (pre-don) version 0 (classic)
|
|
||||||
// lavastorm (don) version 1
|
|
||||||
// we want to route players to the correct version of lavastorm based on the current server side expansion
|
|
||||||
// in order to do that the simplest and cleanest way we intercept the zoning process and route players to an "instance" of the zone
|
|
||||||
// the reason why we're doing this is because all of the zoning logic already is handled by two keys "zone_id" and "instance_id"
|
|
||||||
// we can leverage static, never expires instances to handle this but to the client they don't see it any other way than a public normal zone
|
|
||||||
// scripts handle all the same way, you don't have to think about instances, the middleware will handle the magic
|
|
||||||
// the versions of zones are represented by two zone entries that have potentially different min/max expansion and/or different content flags
|
|
||||||
// we decide to route the client to the correct version of the zone based on the current server side expansion
|
|
||||||
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
||||||
{
|
{
|
||||||
auto r = FindZone(zc->zoneID, zc->instanceID);
|
auto r = FindZone(zc->zoneID, zc->instanceID);
|
||||||
@@ -263,63 +252,59 @@ void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
|||||||
// these are used commonly in v1/v2/v3 versions of the same zone for expansion routing
|
// these are used commonly in v1/v2/v3 versions of the same zone for expansion routing
|
||||||
WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
|
WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
|
||||||
{
|
{
|
||||||
m_zone_instances = InstanceListRepository::GetWhere(*GetDatabase(), fmt::format("never_expires = 1 AND is_global = 1"));
|
m_zone_static_instances = InstanceListRepository::GetWhere(
|
||||||
|
*GetDatabase(),
|
||||||
LogInfo("Loaded [{}] zone_instances", m_zone_instances.size());
|
fmt::format("never_expires = 1 AND is_global = 1")
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadZones sets the zones for the world content service
|
|
||||||
// this is used for zone routing middleware
|
|
||||||
// we pull the zone list from the zone repository and feed from the zone store for now
|
|
||||||
// we're holding a copy in the content service - but we're talking 250kb of data in memory to handle routing of zoning
|
|
||||||
WorldContentService * WorldContentService::LoadZones()
|
|
||||||
{
|
|
||||||
m_zones = ZoneRepository::All(*GetContentDatabase());
|
|
||||||
|
|
||||||
LogInfo("Loaded [{}] zones", m_zones.size());
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindZone is critical to the zone routing middleware and any logic that needs to route players to the correct zone
|
|
||||||
// era contextual routing, multiple version of zones, etc
|
|
||||||
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
|
|
||||||
{
|
|
||||||
// if there's an active dynamic instance, we don't need to route
|
|
||||||
if (instance_id > 0) {
|
|
||||||
auto inst = InstanceListRepository::FindOne(*GetDatabase(), instance_id);
|
|
||||||
if (inst.id != 0 && !inst.is_global && !inst.never_expires) {
|
|
||||||
return WorldContentService::FindZoneResult{
|
|
||||||
.zone_id = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &z: m_zones) {
|
|
||||||
if (z.zoneidnumber == zone_id) {
|
|
||||||
auto f = ContentFlags{
|
|
||||||
.min_expansion = z.min_expansion,
|
|
||||||
.max_expansion = z.max_expansion,
|
|
||||||
.content_flags = z.content_flags,
|
|
||||||
.content_flags_disabled = z.content_flags_disabled
|
|
||||||
};
|
|
||||||
|
|
||||||
if (DoesPassContentFiltering(f)) {
|
|
||||||
LogInfo(
|
|
||||||
"Attempting to route player to zone [{}] ({}) version [{}] long_name [{}]",
|
|
||||||
z.short_name,
|
|
||||||
z.zoneidnumber,
|
|
||||||
z.version,
|
|
||||||
z.long_name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// first pass, explicit match on public static global zone instances
|
LogInfo("Loaded [{}] zone_instances", m_zone_static_instances.size());
|
||||||
for (auto &i: m_zone_instances) {
|
|
||||||
if (i.zone == zone_id && i.version == z.version) {
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindZone handles content and context aware zone routing (middleware)
|
||||||
|
//
|
||||||
|
// this is a middleware function that is meant to be used in the zone change process
|
||||||
|
// this hooks all core zone changes within the server and routes the player to the correct zone
|
||||||
|
// returning a zone_id of non-zero means the middleware will route the player
|
||||||
|
// returning a zone_id of 0 means the middleware will not route the player
|
||||||
|
// this is useful for handling multiple versions of the same zone
|
||||||
|
//
|
||||||
|
// implementation >
|
||||||
|
// the zoning and process spawning logic already is handled by two keys "zone_id" and "instance_id"
|
||||||
|
// we leverage static, never expires instances to handle this and client still sees it as a normal zone
|
||||||
|
//
|
||||||
|
// content awareness >
|
||||||
|
// simply use the zone_id, server content settings and the middleware will handle the rest
|
||||||
|
// you don't have to think about instances in any data tables (use instance_id 0)
|
||||||
|
// you don't have to keep track of instance ids in scripts (use instance_id 0)
|
||||||
|
// the versions of zones are represented by two zone entries that have potentially different min/max expansion and/or different content flags
|
||||||
|
// we decide to route the client to the correct version of the zone based on the current server side expansion
|
||||||
|
//
|
||||||
|
// example >
|
||||||
|
// we want to route players to the correct version of lavastorm based on the current server side expansion (DoesZonePassContentFiltering)
|
||||||
|
// lavastorm (pre-don) version 0 (classic)
|
||||||
|
// zone table entry for version = 0, min_expansion = 0, max_expansion = 8
|
||||||
|
// instance_list table entry for lavastorm has version = 0, is_global = 1, never_expires = 1
|
||||||
|
// lavastorm (don) version 1
|
||||||
|
// zone table entry for version = 1, min_expansion = 9, max_expansion = 99
|
||||||
|
// instance_list table entry for lavastorm has version = 1, is_global = 1, never_expires = 1
|
||||||
|
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
|
||||||
|
{
|
||||||
|
for (const auto &z: zone_store.GetZones()) {
|
||||||
|
for (auto &i: m_zone_static_instances) {
|
||||||
|
if (
|
||||||
|
z.zoneidnumber == zone_id &&
|
||||||
|
DoesZonePassContentFiltering(z) &&
|
||||||
|
i.zone == zone_id &&
|
||||||
|
i.version == z.version) {
|
||||||
|
|
||||||
|
if (instance_id > 0 && i.id != instance_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
LogInfo(
|
LogInfo(
|
||||||
"Routed player to instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
"Routed player to public static instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
||||||
i.id,
|
i.id,
|
||||||
z.short_name,
|
z.short_name,
|
||||||
z.zoneidnumber,
|
z.zoneidnumber,
|
||||||
@@ -335,23 +320,6 @@ WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(
|
|
||||||
"Routed player to non-instance zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
|
||||||
z.short_name,
|
|
||||||
z.zoneidnumber,
|
|
||||||
z.version,
|
|
||||||
z.long_name,
|
|
||||||
z.note
|
|
||||||
);
|
|
||||||
|
|
||||||
return WorldContentService::FindZoneResult{
|
|
||||||
.zone_id = static_cast<uint32>(z.zoneidnumber),
|
|
||||||
.instance = InstanceListRepository::NewEntity(),
|
|
||||||
.zone = z
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WorldContentService::FindZoneResult{.zone_id = 0};
|
return WorldContentService::FindZoneResult{.zone_id = 0};
|
||||||
@@ -359,7 +327,7 @@ WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id
|
|||||||
|
|
||||||
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
|
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
|
||||||
{
|
{
|
||||||
for (auto &i: m_zone_instances) {
|
for (auto &i: m_zone_static_instances) {
|
||||||
if (i.id == instance_id) {
|
if (i.id == instance_id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -367,3 +335,15 @@ bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WorldContentService::DoesZonePassContentFiltering(const ZoneRepository::Zone &z)
|
||||||
|
{
|
||||||
|
auto f = ContentFlags{
|
||||||
|
.min_expansion = z.min_expansion,
|
||||||
|
.max_expansion = z.max_expansion,
|
||||||
|
.content_flags = z.content_flags,
|
||||||
|
.content_flags_disabled = z.content_flags_disabled
|
||||||
|
};
|
||||||
|
|
||||||
|
return DoesPassContentFiltering(f);
|
||||||
|
}
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ public:
|
|||||||
WorldContentService * SetExpansionContext();
|
WorldContentService * SetExpansionContext();
|
||||||
|
|
||||||
bool DoesPassContentFiltering(const ContentFlags& f);
|
bool DoesPassContentFiltering(const ContentFlags& f);
|
||||||
|
bool DoesZonePassContentFiltering(const ZoneRepository::Zone& z);
|
||||||
|
|
||||||
WorldContentService * SetDatabase(Database *database);
|
WorldContentService * SetDatabase(Database *database);
|
||||||
Database *GetDatabase() const;
|
Database *GetDatabase() const;
|
||||||
@@ -189,10 +190,8 @@ private:
|
|||||||
Database *m_content_database;
|
Database *m_content_database;
|
||||||
|
|
||||||
// holds a record of the zone table from the database
|
// holds a record of the zone table from the database
|
||||||
std::vector<ZoneRepository::Zone> m_zones = {};
|
|
||||||
WorldContentService *LoadStaticGlobalZoneInstances();
|
WorldContentService *LoadStaticGlobalZoneInstances();
|
||||||
std::vector<InstanceListRepository::InstanceList> m_zone_instances;
|
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
|
||||||
WorldContentService * LoadZones();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WorldContentService content_service;
|
extern WorldContentService content_service;
|
||||||
|
|||||||
@@ -294,6 +294,8 @@ void print_trace()
|
|||||||
SendCrashReport(crash_report);
|
SendCrashReport(crash_report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogSys.CloseFileLogs();
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+146
-21
@@ -50,6 +50,7 @@
|
|||||||
#include "../common/repositories/raid_members_repository.h"
|
#include "../common/repositories/raid_members_repository.h"
|
||||||
#include "../common/repositories/reports_repository.h"
|
#include "../common/repositories/reports_repository.h"
|
||||||
#include "../common/repositories/variables_repository.h"
|
#include "../common/repositories/variables_repository.h"
|
||||||
|
#include "../common/repositories/character_pet_name_repository.h"
|
||||||
#include "../common/events/player_event_logs.h"
|
#include "../common/events/player_event_logs.h"
|
||||||
|
|
||||||
// Disgrace: for windows compile
|
// Disgrace: for windows compile
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
#include "data_verification.h"
|
||||||
#include "eq_packet_structs.h"
|
#include "eq_packet_structs.h"
|
||||||
#include "extprofile.h"
|
#include "extprofile.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
@@ -77,6 +79,8 @@
|
|||||||
#include "zone_store.h"
|
#include "zone_store.h"
|
||||||
#include "repositories/merchantlist_temp_repository.h"
|
#include "repositories/merchantlist_temp_repository.h"
|
||||||
#include "repositories/bot_data_repository.h"
|
#include "repositories/bot_data_repository.h"
|
||||||
|
#include "repositories/trader_repository.h"
|
||||||
|
#include "repositories/buyer_repository.h"
|
||||||
|
|
||||||
extern Client client;
|
extern Client client;
|
||||||
|
|
||||||
@@ -206,9 +210,19 @@ void Database::LoginIP(uint32 account_id, const std::string& login_ip)
|
|||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Database::CheckStatus(uint32 account_id)
|
int16 Database::GetAccountStatus(uint32 account_id)
|
||||||
{
|
{
|
||||||
return AccountRepository::GetAccountStatus(*this, account_id);
|
auto e = AccountRepository::FindOne(*this, account_id);
|
||||||
|
|
||||||
|
if (e.suspendeduntil > 0 && e.suspendeduntil < std::time(nullptr)) {
|
||||||
|
e.status = 0;
|
||||||
|
e.suspendeduntil = 0;
|
||||||
|
e.suspend_reason = "";
|
||||||
|
|
||||||
|
AccountRepository::UpdateOne(*this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::CreateAccount(
|
uint32 Database::CreateAccount(
|
||||||
@@ -272,16 +286,37 @@ bool Database::SetAccountStatus(const std::string& account_name, int16 status)
|
|||||||
|
|
||||||
bool Database::ReserveName(uint32 account_id, const std::string& name)
|
bool Database::ReserveName(uint32 account_id, const std::string& name)
|
||||||
{
|
{
|
||||||
const auto& l = CharacterDataRepository::GetWhere(
|
const std::string& where_filter = fmt::format(
|
||||||
*this,
|
|
||||||
fmt::format(
|
|
||||||
"`name` = '{}'",
|
"`name` = '{}'",
|
||||||
Strings::Escape(name)
|
Strings::Escape(name)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!l.empty()) {
|
if (RuleB(Bots, Enabled)) {
|
||||||
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
const auto& b = BotDataRepository::GetWhere(*this, where_filter);
|
||||||
|
|
||||||
|
if (!b.empty()) {
|
||||||
|
LogInfo("Account [{}] requested name [{}] but name is already taken by a bot", account_id, name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& c = CharacterDataRepository::GetWhere(*this, where_filter);
|
||||||
|
|
||||||
|
if (!c.empty()) {
|
||||||
|
LogInfo("Account [{}] requested name [{}] but name is already taken by a character", account_id, name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& n = NpcTypesRepository::GetWhere(*this, where_filter);
|
||||||
|
|
||||||
|
if (!n.empty()) {
|
||||||
|
LogInfo("Account [{}] requested name [{}] but name is already taken by an NPC", account_id, name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& p = CharacterPetNameRepository::GetWhere(*this, where_filter);
|
||||||
|
if (!p.empty()) {
|
||||||
|
LogInfo("Account [{}] requested name [{}] but name is already taken by an Pet", account_id, name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,13 +331,15 @@ bool Database::ReserveName(uint32 account_id, const std::string& name)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int guild_id = RuleI(Character, DefaultGuild);
|
const uint32 guild_id = RuleI(Character, DefaultGuild);
|
||||||
|
const uint8 guild_rank = EQ::Clamp(RuleI(Character, DefaultGuildRank), 0, 8);
|
||||||
if (guild_id != 0) {
|
if (guild_id != 0) {
|
||||||
if (e.id) {
|
if (e.id) {
|
||||||
auto g = GuildMembersRepository::NewEntity();
|
auto g = GuildMembersRepository::NewEntity();
|
||||||
|
|
||||||
g.char_id = e.id;
|
g.char_id = e.id;
|
||||||
g.guild_id = guild_id;
|
g.guild_id = guild_id;
|
||||||
|
g.rank_ = guild_rank;
|
||||||
|
|
||||||
GuildMembersRepository::InsertOne(*this, g);
|
GuildMembersRepository::InsertOne(*this, g);
|
||||||
}
|
}
|
||||||
@@ -741,7 +778,7 @@ bool Database::SetVariable(const std::string& name, const std::string& value)
|
|||||||
auto l = VariablesRepository::GetWhere(
|
auto l = VariablesRepository::GetWhere(
|
||||||
*this,
|
*this,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"`name` = '{}'",
|
"`varname` = '{}'",
|
||||||
Strings::Escape(name)
|
Strings::Escape(name)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -1618,16 +1655,29 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
|
|||||||
|
|
||||||
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
||||||
{
|
{
|
||||||
const auto& e = GroupIdRepository::FindOne(*this, character_id);
|
const auto& e = GroupIdRepository::GetWhere(
|
||||||
|
*this,
|
||||||
|
fmt::format(
|
||||||
|
"`character_id` = {}",
|
||||||
|
character_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return e.character_id ? e.group_id : 0;
|
return e.size() == 1 ? e.front().group_id : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetRaidIDByCharID(uint32 character_id)
|
uint32 Database::GetRaidIDByCharID(uint32 character_id)
|
||||||
{
|
{
|
||||||
const auto& e = RaidMembersRepository::FindOne(*this, character_id);
|
|
||||||
|
|
||||||
return e.charid ? e.raidid : 0;
|
const auto& e = RaidMembersRepository::GetWhere(
|
||||||
|
*this,
|
||||||
|
fmt::format(
|
||||||
|
"`charid` = {}",
|
||||||
|
character_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return e.size() == 1 ? e.front().raidid : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 Database::CountInvSnapshots()
|
int64 Database::CountInvSnapshots()
|
||||||
@@ -1817,7 +1867,35 @@ bool Database::CopyCharacter(
|
|||||||
|
|
||||||
const int64 new_character_id = (CharacterDataRepository::GetMaxId(*this) + 1);
|
const int64 new_character_id = (CharacterDataRepository::GetMaxId(*this) + 1);
|
||||||
|
|
||||||
std::vector<std::string> tables_to_zero_id = { "keyring", "data_buckets" };
|
// validate destination name doesn't exist already
|
||||||
|
const auto& destination_characters = CharacterDataRepository::GetWhere(
|
||||||
|
*this,
|
||||||
|
fmt::format(
|
||||||
|
"`name` = '{}' AND `deleted_at` IS NULL LIMIT 1",
|
||||||
|
Strings::Escape(destination_character_name)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (!destination_characters.empty()) {
|
||||||
|
LogError("Character [{}] already exists", destination_character_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> tables_to_zero_id = {
|
||||||
|
"keyring",
|
||||||
|
"data_buckets",
|
||||||
|
"character_instance_safereturns",
|
||||||
|
"character_expedition_lockouts",
|
||||||
|
"character_instance_lockouts",
|
||||||
|
"character_parcels",
|
||||||
|
"character_tribute",
|
||||||
|
"player_titlesets",
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> ignore_tables = {
|
||||||
|
"guilds",
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t total_rows_copied = 0;
|
||||||
|
|
||||||
TransactionBegin();
|
TransactionBegin();
|
||||||
|
|
||||||
@@ -1825,6 +1903,10 @@ bool Database::CopyCharacter(
|
|||||||
const std::string& table_name = t.first;
|
const std::string& table_name = t.first;
|
||||||
const std::string& character_id_column_name = t.second;
|
const std::string& character_id_column_name = t.second;
|
||||||
|
|
||||||
|
if (Strings::Contains(ignore_tables, table_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto results = QueryDatabase(
|
auto results = QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"SHOW COLUMNS FROM {}",
|
"SHOW COLUMNS FROM {}",
|
||||||
@@ -1875,6 +1957,10 @@ bool Database::CopyCharacter(
|
|||||||
value = std::to_string(destination_account_id);
|
value = std::to_string(destination_account_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Strings::IsNumber(value)) {
|
||||||
|
value = Strings::Escape(value);
|
||||||
|
}
|
||||||
|
|
||||||
new_values.emplace_back(value);
|
new_values.emplace_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1907,6 +1993,11 @@ bool Database::CopyCharacter(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
size_t rows_copied = insert_rows.size(); // Rows copied for this table
|
||||||
|
total_rows_copied += rows_copied; // Increment grand total
|
||||||
|
|
||||||
|
LogInfo("Copying table [{}] rows [{}]", table_name, Strings::Commify(rows_copied));
|
||||||
|
|
||||||
if (!insert.ErrorMessage().empty()) {
|
if (!insert.ErrorMessage().empty()) {
|
||||||
TransactionRollback();
|
TransactionRollback();
|
||||||
return false;
|
return false;
|
||||||
@@ -1916,6 +2007,13 @@ bool Database::CopyCharacter(
|
|||||||
|
|
||||||
TransactionCommit();
|
TransactionCommit();
|
||||||
|
|
||||||
|
LogInfo(
|
||||||
|
"Character [{}] copied to [{}] total rows [{}]",
|
||||||
|
source_character_name,
|
||||||
|
destination_character_name,
|
||||||
|
Strings::Commify(total_rows_copied)
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2059,12 +2157,12 @@ void Database::PurgeCharacterParcels()
|
|||||||
for (auto const &r: results) {
|
for (auto const &r: results) {
|
||||||
pd.from_name = r.from_name;
|
pd.from_name = r.from_name;
|
||||||
pd.item_id = r.item_id;
|
pd.item_id = r.item_id;
|
||||||
pd.aug_slot_1 = r.aug_slot_1;
|
pd.augment_1_id = r.aug_slot_1;
|
||||||
pd.aug_slot_2 = r.aug_slot_2;
|
pd.augment_2_id = r.aug_slot_2;
|
||||||
pd.aug_slot_3 = r.aug_slot_3;
|
pd.augment_3_id = r.aug_slot_3;
|
||||||
pd.aug_slot_4 = r.aug_slot_4;
|
pd.augment_4_id = r.aug_slot_4;
|
||||||
pd.aug_slot_5 = r.aug_slot_5;
|
pd.augment_5_id = r.aug_slot_5;
|
||||||
pd.aug_slot_6 = r.aug_slot_6;
|
pd.augment_6_id = r.aug_slot_6;
|
||||||
pd.note = r.note;
|
pd.note = r.note;
|
||||||
pd.quantity = r.quantity;
|
pd.quantity = r.quantity;
|
||||||
pd.sent_date = r.sent_date;
|
pd.sent_date = r.sent_date;
|
||||||
@@ -2094,3 +2192,30 @@ void Database::ClearGuildOnlineStatus()
|
|||||||
{
|
{
|
||||||
GuildMembersRepository::ClearOnlineStatus(*this);
|
GuildMembersRepository::ClearOnlineStatus(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::ClearTraderDetails()
|
||||||
|
{
|
||||||
|
TraderRepository::Truncate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::ClearBuyerDetails()
|
||||||
|
{
|
||||||
|
BuyerRepository::DeleteBuyer(*this, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Database::GetNextTableId(const std::string &table_name)
|
||||||
|
{
|
||||||
|
auto results = QueryDatabase(fmt::format("SHOW TABLE STATUS LIKE '{}'", table_name));
|
||||||
|
|
||||||
|
for (auto row: results) {
|
||||||
|
for (int row_index = 0; row_index < results.ColumnCount(); row_index++) {
|
||||||
|
std::string field_name = Strings::ToLower(results.FieldName(row_index));
|
||||||
|
if (field_name == "auto_increment") {
|
||||||
|
std::string value = row[row_index] ? row[row_index] : "null";
|
||||||
|
return Strings::ToUnsignedBigInt(value, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
+5
-1
@@ -170,7 +170,7 @@ public:
|
|||||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||||
bool SetLocalPassword(uint32 account_id, const std::string& password);
|
bool SetLocalPassword(uint32 account_id, const std::string& password);
|
||||||
bool UpdateLiveChar(const std::string& name, uint32 account_id);
|
bool UpdateLiveChar(const std::string& name, uint32 account_id);
|
||||||
int16 CheckStatus(uint32 account_id);
|
int16 GetAccountStatus(uint32 account_id);
|
||||||
void SetAccountCRCField(uint32 account_id, const std::string& field_name, uint64 checksum);
|
void SetAccountCRCField(uint32 account_id, const std::string& field_name, uint64 checksum);
|
||||||
uint32 CheckLogin(const std::string& name, const std::string& password, const std::string& loginserver, int16* status = 0);
|
uint32 CheckLogin(const std::string& name, const std::string& password, const std::string& loginserver, int16* status = 0);
|
||||||
uint32 CreateAccount(
|
uint32 CreateAccount(
|
||||||
@@ -244,6 +244,8 @@ public:
|
|||||||
|
|
||||||
void PurgeAllDeletedDataBuckets();
|
void PurgeAllDeletedDataBuckets();
|
||||||
void ClearGuildOnlineStatus();
|
void ClearGuildOnlineStatus();
|
||||||
|
void ClearTraderDetails();
|
||||||
|
void ClearBuyerDetails();
|
||||||
|
|
||||||
|
|
||||||
/* Database Variables */
|
/* Database Variables */
|
||||||
@@ -272,6 +274,8 @@ public:
|
|||||||
void Encode(std::string &in);
|
void Encode(std::string &in);
|
||||||
void Decode(std::string &in);
|
void Decode(std::string &in);
|
||||||
|
|
||||||
|
uint64_t GetNextTableId(const std::string& table_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex Mvarcache;
|
Mutex Mvarcache;
|
||||||
VarCache_Struct varcache;
|
VarCache_Struct varcache;
|
||||||
|
|||||||
@@ -136,11 +136,6 @@ std::string DatabaseDumpService::GetLoginTableList()
|
|||||||
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
|
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DatabaseDumpService::GetQueryServTables()
|
|
||||||
{
|
|
||||||
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DatabaseDumpService::GetSystemTablesList()
|
std::string DatabaseDumpService::GetSystemTablesList()
|
||||||
{
|
{
|
||||||
auto system_tables = DatabaseSchema::GetServerTables();
|
auto system_tables = DatabaseSchema::GetServerTables();
|
||||||
@@ -272,11 +267,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
tables_to_dump += GetLoginTableList() + " ";
|
tables_to_dump += GetLoginTableList() + " ";
|
||||||
dump_descriptor += "-login";
|
dump_descriptor += "-login";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDumpQueryServerTables()) {
|
|
||||||
tables_to_dump += GetQueryServTables();
|
|
||||||
dump_descriptor += "-queryserv";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDumpStaticInstanceData()) {
|
if (IsDumpStaticInstanceData()) {
|
||||||
@@ -401,7 +391,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||||
// LogDebug("[{}] query-serv", (IsDumpQueryServerTables() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
|
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
|
||||||
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
|
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
|
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
|
||||||
@@ -511,16 +500,6 @@ const std::string &DatabaseDumpService::GetDumpFileName() const
|
|||||||
return dump_file_name;
|
return dump_file_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpQueryServerTables() const
|
|
||||||
{
|
|
||||||
return dump_query_server_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpQueryServerTables(bool dump_query_server_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_query_server_tables = dump_query_server_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpOutputToConsole() const
|
bool DatabaseDumpService::IsDumpOutputToConsole() const
|
||||||
{
|
{
|
||||||
return dump_output_to_console;
|
return dump_output_to_console;
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ public:
|
|||||||
void SetDumpPath(const std::string &dump_path);
|
void SetDumpPath(const std::string &dump_path);
|
||||||
const std::string &GetDumpFileName() const;
|
const std::string &GetDumpFileName() const;
|
||||||
void SetDumpFileName(const std::string &dump_file_name);
|
void SetDumpFileName(const std::string &dump_file_name);
|
||||||
bool IsDumpQueryServerTables() const;
|
|
||||||
void SetDumpQueryServerTables(bool dump_query_server_tables);
|
|
||||||
bool IsDumpOutputToConsole() const;
|
bool IsDumpOutputToConsole() const;
|
||||||
void SetDumpOutputToConsole(bool dump_output_to_console);
|
void SetDumpOutputToConsole(bool dump_output_to_console);
|
||||||
bool IsDumpDropTableSyntaxOnly() const;
|
bool IsDumpDropTableSyntaxOnly() const;
|
||||||
@@ -96,7 +94,6 @@ private:
|
|||||||
bool HasCompressionBinary();
|
bool HasCompressionBinary();
|
||||||
std::string GetDumpFileNameWithPath();
|
std::string GetDumpFileNameWithPath();
|
||||||
std::string GetSetDumpPath();
|
std::string GetSetDumpPath();
|
||||||
std::string GetQueryServTables();
|
|
||||||
void RemoveSqlBackup();
|
void RemoveSqlBackup();
|
||||||
void BuildCredentialsFile();
|
void BuildCredentialsFile();
|
||||||
void RemoveCredentialsFile();
|
void RemoveCredentialsFile();
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
if (version_low != version_high) {
|
if (version_low != version_high) {
|
||||||
|
|
||||||
LogSys.DisableMySQLErrorLogs();
|
LogSys.DisableMySQLErrorLogs();
|
||||||
|
bool force_interactive = false;
|
||||||
for (int version = version_low + 1; version <= version_high; ++version) {
|
for (int version = version_low + 1; version <= version_high; ++version) {
|
||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
if (e.version == version) {
|
if (e.version == version) {
|
||||||
@@ -163,13 +164,20 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
prefix,
|
prefix,
|
||||||
e.description
|
e.description
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!has_migration && e.force_interactive) {
|
||||||
|
force_interactive = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogSys.EnableMySQLErrorLogs();
|
LogSys.EnableMySQLErrorLogs();
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
if (!missing_migrations.empty()) {
|
if (!missing_migrations.empty() && m_skip_backup) {
|
||||||
|
LogInfo("Skipping database backup");
|
||||||
|
}
|
||||||
|
else if (!missing_migrations.empty()) {
|
||||||
LogInfo("Automatically backing up database before applying updates");
|
LogInfo("Automatically backing up database before applying updates");
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
auto s = DatabaseDumpService();
|
auto s = DatabaseDumpService();
|
||||||
@@ -184,6 +192,42 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (force_interactive && !std::getenv("FORCE_INTERACTIVE")) {
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
LogInfo("Some migrations require user input. Running interactively");
|
||||||
|
LogInfo("This is usually due to a major change that could cause data loss");
|
||||||
|
LogInfo("Your server is automatically backed up before these updates are applied");
|
||||||
|
LogInfo("but you should also make sure you take a backup prior to running this update");
|
||||||
|
LogInfo("Would you like to run this update? [y/n] (Timeout 60s)");
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
|
// user input
|
||||||
|
std::string input;
|
||||||
|
bool gave_input = false;
|
||||||
|
time_t start_time = time(nullptr);
|
||||||
|
time_t wait_time_seconds = 60;
|
||||||
|
|
||||||
|
// spawn a concurrent thread that waits for input from std::cin
|
||||||
|
std::thread t1(
|
||||||
|
[&]() {
|
||||||
|
std::cin >> input;
|
||||||
|
gave_input = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
t1.detach();
|
||||||
|
|
||||||
|
// check the inputReceived flag once every 50ms for 10 seconds
|
||||||
|
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt for user skip
|
||||||
|
if (Strings::Trim(input) != "y") {
|
||||||
|
LogInfo("Exiting due to user input");
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &m: missing_migrations) {
|
for (auto &m: missing_migrations) {
|
||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
if (e.version == m) {
|
if (e.version == m) {
|
||||||
@@ -271,6 +315,13 @@ DatabaseUpdate *DatabaseUpdate::SetContentDatabase(Database *db)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatabaseUpdate *DatabaseUpdate::SetSkipBackup(bool skip)
|
||||||
|
{
|
||||||
|
m_skip_backup = skip;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||||
{
|
{
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ struct ManifestEntry {
|
|||||||
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
std::string 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
|
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||||
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
|
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
|
||||||
|
bool force_interactive; // if true, this migration will always be run interactively
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DatabaseVersion {
|
struct DatabaseVersion {
|
||||||
@@ -29,12 +30,15 @@ public:
|
|||||||
|
|
||||||
DatabaseUpdate *SetDatabase(Database *db);
|
DatabaseUpdate *SetDatabase(Database *db);
|
||||||
DatabaseUpdate *SetContentDatabase(Database *db);
|
DatabaseUpdate *SetContentDatabase(Database *db);
|
||||||
|
DatabaseUpdate *SetSkipBackup(bool skip);
|
||||||
bool HasPendingUpdates();
|
bool HasPendingUpdates();
|
||||||
private:
|
private:
|
||||||
|
bool m_skip_backup = false;
|
||||||
Database *m_database;
|
Database *m_database;
|
||||||
Database *m_content_database;
|
Database *m_content_database;
|
||||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
||||||
void InjectBotsVersionColumn();
|
void InjectBotsVersionColumn();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_DATABASE_UPDATE_H
|
#endif //EQEMU_DATABASE_UPDATE_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -114,7 +114,9 @@ bool Database::CheckInstanceExpired(uint16 instance_id)
|
|||||||
timeval tv{};
|
timeval tv{};
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
|
|
||||||
return (i.start_time + i.duration) <= tv.tv_sec;
|
// Use uint64_t for the addition to prevent overflow
|
||||||
|
uint64_t expiration_time = static_cast<uint64_t>(i.start_time) + static_cast<uint64_t>(i.duration);
|
||||||
|
return expiration_time <= tv.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
||||||
@@ -469,15 +471,13 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
|||||||
|
|
||||||
void Database::DeleteInstance(uint16 instance_id)
|
void Database::DeleteInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
|
// I'm not sure why this isn't in here but we should add it in a later change and make sure it's tested
|
||||||
|
// InstanceListRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
||||||
|
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||||
|
|
||||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||||
|
|
||||||
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||||
|
|
||||||
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
|
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-27
@@ -36,7 +36,6 @@ namespace DatabaseSchema {
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{"adventure_stats", "player_id"},
|
{"adventure_stats", "player_id"},
|
||||||
{"buyer", "charid"},
|
|
||||||
{"char_recipe_list", "char_id"},
|
{"char_recipe_list", "char_id"},
|
||||||
{"character_activities", "charid"},
|
{"character_activities", "charid"},
|
||||||
{"character_alt_currency", "char_id"},
|
{"character_alt_currency", "char_id"},
|
||||||
@@ -52,6 +51,7 @@ namespace DatabaseSchema {
|
|||||||
{"character_enabledtasks", "charid"},
|
{"character_enabledtasks", "charid"},
|
||||||
{"character_expedition_lockouts", "character_id"},
|
{"character_expedition_lockouts", "character_id"},
|
||||||
{"character_exp_modifiers", "character_id"},
|
{"character_exp_modifiers", "character_id"},
|
||||||
|
{"character_evolving_items", "character_id"},
|
||||||
{"character_inspect_messages", "id"},
|
{"character_inspect_messages", "id"},
|
||||||
{"character_instance_safereturns", "character_id"},
|
{"character_instance_safereturns", "character_id"},
|
||||||
{"character_item_recast", "id"},
|
{"character_item_recast", "id"},
|
||||||
@@ -60,9 +60,11 @@ namespace DatabaseSchema {
|
|||||||
{"character_material", "id"},
|
{"character_material", "id"},
|
||||||
{"character_memmed_spells", "id"},
|
{"character_memmed_spells", "id"},
|
||||||
{"character_parcels", "char_id"},
|
{"character_parcels", "char_id"},
|
||||||
|
{"character_parcels_containers", "id"},
|
||||||
{"character_pet_buffs", "char_id"},
|
{"character_pet_buffs", "char_id"},
|
||||||
{"character_pet_info", "char_id"},
|
{"character_pet_info", "char_id"},
|
||||||
{"character_pet_inventory", "char_id"},
|
{"character_pet_inventory", "char_id"},
|
||||||
|
{"character_pet_name", "character_id"},
|
||||||
{"character_peqzone_flags", "id"},
|
{"character_peqzone_flags", "id"},
|
||||||
{"character_potionbelt", "id"},
|
{"character_potionbelt", "id"},
|
||||||
{"character_skills", "id"},
|
{"character_skills", "id"},
|
||||||
@@ -106,6 +108,8 @@ namespace DatabaseSchema {
|
|||||||
"adventure_details",
|
"adventure_details",
|
||||||
"adventure_stats",
|
"adventure_stats",
|
||||||
"buyer",
|
"buyer",
|
||||||
|
"buyer_buy_lines",
|
||||||
|
"buyer_trade_items",
|
||||||
"char_recipe_list",
|
"char_recipe_list",
|
||||||
"character_activities",
|
"character_activities",
|
||||||
"character_alt_currency",
|
"character_alt_currency",
|
||||||
@@ -122,6 +126,7 @@ namespace DatabaseSchema {
|
|||||||
"character_enabledtasks",
|
"character_enabledtasks",
|
||||||
"character_expedition_lockouts",
|
"character_expedition_lockouts",
|
||||||
"character_exp_modifiers",
|
"character_exp_modifiers",
|
||||||
|
"character_evolving_items",
|
||||||
"character_inspect_messages",
|
"character_inspect_messages",
|
||||||
"character_instance_safereturns",
|
"character_instance_safereturns",
|
||||||
"character_item_recast",
|
"character_item_recast",
|
||||||
@@ -130,6 +135,7 @@ namespace DatabaseSchema {
|
|||||||
"character_material",
|
"character_material",
|
||||||
"character_memmed_spells",
|
"character_memmed_spells",
|
||||||
"character_parcels",
|
"character_parcels",
|
||||||
|
"character_parcels_containers",
|
||||||
"character_pet_buffs",
|
"character_pet_buffs",
|
||||||
"character_pet_info",
|
"character_pet_info",
|
||||||
"character_pet_inventory",
|
"character_pet_inventory",
|
||||||
@@ -209,6 +215,7 @@ namespace DatabaseSchema {
|
|||||||
"ground_spawns",
|
"ground_spawns",
|
||||||
"horses",
|
"horses",
|
||||||
"items",
|
"items",
|
||||||
|
"items_evolving_details",
|
||||||
"ldon_trap_entries",
|
"ldon_trap_entries",
|
||||||
"ldon_trap_templates",
|
"ldon_trap_templates",
|
||||||
"lootdrop",
|
"lootdrop",
|
||||||
@@ -284,32 +291,6 @@ namespace DatabaseSchema {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets QueryServer tables
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetQueryServerTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"qs_merchant_transaction_record",
|
|
||||||
"qs_merchant_transaction_record_entries",
|
|
||||||
"qs_player_aa_rate_hourly",
|
|
||||||
"qs_player_delete_record",
|
|
||||||
"qs_player_delete_record_entries",
|
|
||||||
"qs_player_events",
|
|
||||||
"qs_player_handin_record",
|
|
||||||
"qs_player_handin_record_entries",
|
|
||||||
"qs_player_move_record",
|
|
||||||
"qs_player_move_record_entries",
|
|
||||||
"qs_player_npc_kill_record",
|
|
||||||
"qs_player_npc_kill_record_entries",
|
|
||||||
"qs_player_speech",
|
|
||||||
"qs_player_trade_record",
|
|
||||||
"qs_player_trade_record_entries",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets state tables
|
* Gets state tables
|
||||||
* Tables that keep track of server state
|
* Tables that keep track of server state
|
||||||
@@ -323,6 +304,9 @@ namespace DatabaseSchema {
|
|||||||
"banned_ips",
|
"banned_ips",
|
||||||
"bug_reports",
|
"bug_reports",
|
||||||
"bugs",
|
"bugs",
|
||||||
|
"buyer",
|
||||||
|
"buyer_buy_lines",
|
||||||
|
"buyer_trade_items",
|
||||||
"completed_shared_task_activity_state",
|
"completed_shared_task_activity_state",
|
||||||
"completed_shared_task_members",
|
"completed_shared_task_members",
|
||||||
"completed_shared_tasks",
|
"completed_shared_tasks",
|
||||||
@@ -349,8 +333,20 @@ namespace DatabaseSchema {
|
|||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"server_scheduled_events",
|
||||||
"spawn2_disabled",
|
"spawn2_disabled",
|
||||||
|
"player_event_aa_purchase",
|
||||||
|
"player_event_killed_npc",
|
||||||
|
"player_event_killed_named_npc",
|
||||||
|
"player_event_killed_raid_npc",
|
||||||
"player_event_log_settings",
|
"player_event_log_settings",
|
||||||
"player_event_logs",
|
"player_event_logs",
|
||||||
|
"player_event_loot_items",
|
||||||
|
"player_event_merchant_purchase",
|
||||||
|
"player_event_merchant_sell",
|
||||||
|
"player_event_npc_handin",
|
||||||
|
"player_event_npc_handin_entries",
|
||||||
|
"player_event_speech",
|
||||||
|
"player_event_trade",
|
||||||
|
"player_event_trade_entries",
|
||||||
"shared_task_activity_state",
|
"shared_task_activity_state",
|
||||||
"shared_task_dynamic_zones",
|
"shared_task_dynamic_zones",
|
||||||
"shared_task_members",
|
"shared_task_members",
|
||||||
@@ -396,6 +392,7 @@ namespace DatabaseSchema {
|
|||||||
static std::vector<std::string> GetBotTables()
|
static std::vector<std::string> GetBotTables()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
"bot_blocked_buffs",
|
||||||
"bot_buffs",
|
"bot_buffs",
|
||||||
"bot_command_settings",
|
"bot_command_settings",
|
||||||
"bot_create_combinations",
|
"bot_create_combinations",
|
||||||
@@ -409,6 +406,7 @@ namespace DatabaseSchema {
|
|||||||
"bot_pet_buffs",
|
"bot_pet_buffs",
|
||||||
"bot_pet_inventories",
|
"bot_pet_inventories",
|
||||||
"bot_pets",
|
"bot_pets",
|
||||||
|
"bot_settings",
|
||||||
"bot_spell_casting_chances",
|
"bot_spell_casting_chances",
|
||||||
"bot_spell_settings",
|
"bot_spell_settings",
|
||||||
"bot_spells_entries",
|
"bot_spells_entries",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#include "dbcore.h"
|
#include "dbcore.h"
|
||||||
|
#include "mysql_stmt.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -436,3 +437,8 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
||||||
|
{
|
||||||
|
return mysql::PreparedStmt(*mysql, std::move(query), m_mutex);
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#define CR_SERVER_GONE_ERROR 2006
|
#define CR_SERVER_GONE_ERROR 2006
|
||||||
#define CR_SERVER_LOST 2013
|
#define CR_SERVER_LOST 2013
|
||||||
|
|
||||||
|
namespace mysql { class PreparedStmt; }
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
enum eStatus {
|
enum eStatus {
|
||||||
@@ -48,6 +50,11 @@ public:
|
|||||||
}
|
}
|
||||||
void SetMutex(Mutex *mutex);
|
void SetMutex(Mutex *mutex);
|
||||||
|
|
||||||
|
// only safe on connections shared with other threads if results buffered
|
||||||
|
// unsafe to use off main thread due to internal server logging
|
||||||
|
// throws std::runtime_error on failure
|
||||||
|
mysql::PreparedStmt Prepare(std::string query);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Open(
|
bool Open(
|
||||||
const char *iHost,
|
const char *iHost,
|
||||||
|
|||||||
+6
-70
@@ -19,81 +19,17 @@
|
|||||||
|
|
||||||
#include "deity.h"
|
#include "deity.h"
|
||||||
|
|
||||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
uint32 Deity::GetBitmask(uint32 deity_id)
|
||||||
{
|
{
|
||||||
switch (deity_type) {
|
return IsValid(deity_id) ? deity_bitmasks[deity_id] : Deity::Bitmask::All;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
|
std::string Deity::GetName(uint32 deity_id)
|
||||||
{
|
{
|
||||||
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
|
return IsValid(deity_id) ? deity_names[deity_id] : "UNKNOWN DEITY";
|
||||||
{ 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
bool Deity::IsValid(uint32 deity_id)
|
||||||
{
|
{
|
||||||
|
return deity_names.find(deity_id) != deity_names.end();
|
||||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
|
||||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
}
|
||||||
|
|||||||
+85
-52
@@ -23,62 +23,95 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace Deity {
|
||||||
|
constexpr uint32 Unknown = 0;
|
||||||
|
constexpr uint32 Agnostic1 = 140;
|
||||||
|
constexpr uint32 Bertoxxulous = 201;
|
||||||
|
constexpr uint32 BrellSirilis = 202;
|
||||||
|
constexpr uint32 CazicThule = 203;
|
||||||
|
constexpr uint32 ErollisiMarr = 204;
|
||||||
|
constexpr uint32 Bristlebane = 205;
|
||||||
|
constexpr uint32 Innoruuk = 206;
|
||||||
|
constexpr uint32 Karana = 207;
|
||||||
|
constexpr uint32 MithanielMarr = 208;
|
||||||
|
constexpr uint32 Prexus = 209;
|
||||||
|
constexpr uint32 Quellious = 210;
|
||||||
|
constexpr uint32 RallosZek = 211;
|
||||||
|
constexpr uint32 RodcetNife = 212;
|
||||||
|
constexpr uint32 SolusekRo = 213;
|
||||||
|
constexpr uint32 TheTribunal = 214;
|
||||||
|
constexpr uint32 Tunare = 215;
|
||||||
|
constexpr uint32 Veeshan = 216;
|
||||||
|
constexpr uint32 Agnostic2 = 396;
|
||||||
|
|
||||||
namespace EQ
|
namespace Bitmask {
|
||||||
{
|
constexpr uint32 Agnostic = 1;
|
||||||
namespace deity {
|
constexpr uint32 Bertoxxulous = 2;
|
||||||
enum DeityType {
|
constexpr uint32 BrellSirilis = 4;
|
||||||
DeityUnknown = 0,
|
constexpr uint32 CazicThule = 8;
|
||||||
DeityAgnostic_LB = 140,
|
constexpr uint32 ErollisiMarr = 16;
|
||||||
DeityBertoxxulous = 201,
|
constexpr uint32 Bristlebane = 32;
|
||||||
DeityBrellSirilis,
|
constexpr uint32 Innoruuk = 64;
|
||||||
DeityCazicThule,
|
constexpr uint32 Karana = 128;
|
||||||
DeityErollisiMarr,
|
constexpr uint32 MithanielMarr = 256;
|
||||||
DeityBristlebane,
|
constexpr uint32 Prexus = 512;
|
||||||
DeityInnoruuk,
|
constexpr uint32 Quellious = 1024;
|
||||||
DeityKarana,
|
constexpr uint32 RallosZek = 2048;
|
||||||
DeityMithanielMarr,
|
constexpr uint32 RodcetNife = 4096;
|
||||||
DeityPrexus,
|
constexpr uint32 SolusekRo = 8192;
|
||||||
DeityQuellious,
|
constexpr uint32 TheTribunal = 16384;
|
||||||
DeityRallosZek,
|
constexpr uint32 Tunare = 32768;
|
||||||
DeityRodcetNife,
|
constexpr uint32 Veeshan = 65536;
|
||||||
DeitySolusekRo,
|
constexpr uint32 All = std::numeric_limits<uint32>::max();
|
||||||
DeityTheTribunal,
|
}
|
||||||
DeityTunare,
|
|
||||||
DeityVeeshan,
|
uint32 GetBitmask(uint32 deity_id);
|
||||||
DeityAgnostic = 396
|
std::string GetName(uint32 deity_id);
|
||||||
|
bool IsValid(uint32 deity_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint32, std::string> deity_names = {
|
||||||
|
{ Deity::Agnostic1, "Agnostic" },
|
||||||
|
{ Deity::Agnostic2, "Agnostic" },
|
||||||
|
{ Deity::Bertoxxulous, "Bertoxxulous" },
|
||||||
|
{ Deity::BrellSirilis, "Brell Serilis" },
|
||||||
|
{ Deity::Bristlebane, "Bristlebane" },
|
||||||
|
{ Deity::CazicThule, "Cazic-Thule" },
|
||||||
|
{ Deity::ErollisiMarr, "Erollisi Marr" },
|
||||||
|
{ Deity::Innoruuk, "Innoruuk" },
|
||||||
|
{ Deity::Karana, "Karana" },
|
||||||
|
{ Deity::MithanielMarr, "Mithaniel Marr" },
|
||||||
|
{ Deity::Prexus, "Prexus" },
|
||||||
|
{ Deity::Quellious, "Quellious" },
|
||||||
|
{ Deity::RallosZek, "Rallos Zek" },
|
||||||
|
{ Deity::RodcetNife, "Rodcet Nife" },
|
||||||
|
{ Deity::SolusekRo, "Solusek Ro" },
|
||||||
|
{ Deity::TheTribunal, "The Tribunal" },
|
||||||
|
{ Deity::Tunare, "Tunare" },
|
||||||
|
{ Deity::Veeshan, "Veeshan" }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DeityTypeBit : uint32 {
|
static std::map<uint32, uint32> deity_bitmasks = {
|
||||||
bit_DeityAgnostic = 0x00000001,
|
{ Deity::Agnostic1, Deity::Bitmask::Agnostic },
|
||||||
bit_DeityBertoxxulous = 0x00000002,
|
{ Deity::Agnostic2, Deity::Bitmask::Agnostic },
|
||||||
bit_DeityBrellSirilis = 0x00000004,
|
{ Deity::Bertoxxulous, Deity::Bitmask::Bertoxxulous },
|
||||||
bit_DeityCazicThule = 0x00000008,
|
{ Deity::BrellSirilis, Deity::Bitmask::BrellSirilis },
|
||||||
bit_DeityErollisiMarr = 0x00000010,
|
{ Deity::CazicThule, Deity::Bitmask::CazicThule },
|
||||||
bit_DeityBristlebane = 0x00000020,
|
{ Deity::ErollisiMarr, Deity::Bitmask::ErollisiMarr },
|
||||||
bit_DeityInnoruuk = 0x00000040,
|
{ Deity::Bristlebane, Deity::Bitmask::Bristlebane },
|
||||||
bit_DeityKarana = 0x00000080,
|
{ Deity::Innoruuk, Deity::Bitmask::Innoruuk },
|
||||||
bit_DeityMithanielMarr = 0x00000100,
|
{ Deity::Karana, Deity::Bitmask::Karana },
|
||||||
bit_DeityPrexus = 0x00000200,
|
{ Deity::MithanielMarr, Deity::Bitmask::MithanielMarr },
|
||||||
bit_DeityQuellious = 0x00000400,
|
{ Deity::Prexus, Deity::Bitmask::Prexus },
|
||||||
bit_DeityRallosZek = 0x00000800,
|
{ Deity::Quellious, Deity::Bitmask::Quellious },
|
||||||
bit_DeityRodcetNife = 0x00001000,
|
{ Deity::RallosZek, Deity::Bitmask::RallosZek },
|
||||||
bit_DeitySolusekRo = 0x00002000,
|
{ Deity::RodcetNife, Deity::Bitmask::RodcetNife },
|
||||||
bit_DeityTheTribunal = 0x00004000,
|
{ Deity::SolusekRo, Deity::Bitmask::SolusekRo },
|
||||||
bit_DeityTunare = 0x00008000,
|
{ Deity::TheTribunal, Deity::Bitmask::TheTribunal },
|
||||||
bit_DeityVeeshan = 0x00010000,
|
{ Deity::Tunare, Deity::Bitmask::Tunare },
|
||||||
bit_DeityAll = UINT32_MAX
|
{ Deity::Veeshan, Deity::Bitmask::Veeshan }
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int format_as(DeityType type) { return static_cast<int>(type); }
|
|
||||||
|
|
||||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
|
||||||
extern std::string GetDeityName(DeityType deity_type);
|
|
||||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
|
||||||
|
|
||||||
} /*deity*/
|
|
||||||
|
|
||||||
} /*EQEmu*/
|
|
||||||
|
|
||||||
#endif /* COMMON_DEITY_H */
|
#endif /* COMMON_DEITY_H */
|
||||||
|
|||||||
+69
-354
@@ -59,103 +59,40 @@ int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
|||||||
return local_array[inv_type];
|
return local_array[inv_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* EQ::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
uint32 Bug::GetID(const std::string& category_name)
|
||||||
switch (category_id) {
|
{
|
||||||
case catVideo:
|
for (const auto& e : bug_category_names) {
|
||||||
return "Video";
|
if (e.second == category_name) {
|
||||||
case catAudio:
|
return e.first;
|
||||||
return "Audio";
|
|
||||||
case catPathing:
|
|
||||||
return "Pathing";
|
|
||||||
case catQuest:
|
|
||||||
return "Quest";
|
|
||||||
case catTradeskills:
|
|
||||||
return "Tradeskills";
|
|
||||||
case catSpellStacking:
|
|
||||||
return "Spell stacking";
|
|
||||||
case catDoorsPortals:
|
|
||||||
return "Doors/Portals";
|
|
||||||
case catItems:
|
|
||||||
return "Items";
|
|
||||||
case catNPC:
|
|
||||||
return "NPC";
|
|
||||||
case catDialogs:
|
|
||||||
return "Dialogs";
|
|
||||||
case catLoNTCG:
|
|
||||||
return "LoN - TCG";
|
|
||||||
case catMercenaries:
|
|
||||||
return "Mercenaries";
|
|
||||||
case catOther:
|
|
||||||
default:
|
|
||||||
return "Other";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::bug::CategoryID EQ::bug::CategoryNameToCategoryID(const char* category_name) {
|
return Bug::Category::Other;
|
||||||
if (!category_name)
|
|
||||||
return catOther;
|
|
||||||
|
|
||||||
if (!strcmp(category_name, "Video"))
|
|
||||||
return catVideo;
|
|
||||||
if (!strcmp(category_name, "Audio"))
|
|
||||||
return catAudio;
|
|
||||||
if (!strcmp(category_name, "Pathing"))
|
|
||||||
return catPathing;
|
|
||||||
if (!strcmp(category_name, "Quest"))
|
|
||||||
return catQuest;
|
|
||||||
if (!strcmp(category_name, "Tradeskills"))
|
|
||||||
return catTradeskills;
|
|
||||||
if (!strcmp(category_name, "Spell stacking"))
|
|
||||||
return catSpellStacking;
|
|
||||||
if (!strcmp(category_name, "Doors/Portals"))
|
|
||||||
return catDoorsPortals;
|
|
||||||
if (!strcmp(category_name, "Items"))
|
|
||||||
return catItems;
|
|
||||||
if (!strcmp(category_name, "NPC"))
|
|
||||||
return catNPC;
|
|
||||||
if (!strcmp(category_name, "Dialogs"))
|
|
||||||
return catDialogs;
|
|
||||||
if (!strcmp(category_name, "LoN - TCG"))
|
|
||||||
return catLoNTCG;
|
|
||||||
if (!strcmp(category_name, "Mercenaries"))
|
|
||||||
return catMercenaries;
|
|
||||||
|
|
||||||
return catOther;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
std::string Bug::GetName(uint32 category_id)
|
||||||
switch (stance_type) {
|
{
|
||||||
case stanceUnknown:
|
return IsValid(category_id) ? bug_category_names[category_id] : "UNKNOWN BUG CATEGORY";
|
||||||
return "Unknown";
|
|
||||||
case stancePassive:
|
|
||||||
return "Passive";
|
|
||||||
case stanceBalanced:
|
|
||||||
return "Balanced";
|
|
||||||
case stanceEfficient:
|
|
||||||
return "Efficient";
|
|
||||||
case stanceReactive:
|
|
||||||
return "Reactive";
|
|
||||||
case stanceAggressive:
|
|
||||||
return "Aggressive";
|
|
||||||
case stanceAssist:
|
|
||||||
return "Assist";
|
|
||||||
case stanceBurn:
|
|
||||||
return "Burn";
|
|
||||||
case stanceEfficient2:
|
|
||||||
return "Efficient2";
|
|
||||||
case stanceBurnAE:
|
|
||||||
return "BurnAE";
|
|
||||||
default:
|
|
||||||
return "Invalid";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
bool Bug::IsValid(uint32 category_id)
|
||||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
{
|
||||||
return (stance_type - EQ::constants::stancePassive);
|
return bug_category_names.find(category_id) != bug_category_names.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
std::string Stance::GetName(uint8 stance_id)
|
||||||
|
{
|
||||||
|
return IsValid(stance_id) ? stance_names[stance_id] : "UNKNOWN STANCE";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Stance::IsValid(uint8 stance_id)
|
||||||
|
{
|
||||||
|
return stance_names.find(stance_id) != stance_names.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Stance::GetIndex(uint8 stance_id)
|
||||||
|
{
|
||||||
|
return IsValid(stance_id) ? (stance_id - Stance::Passive) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
|
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
|
||||||
@@ -203,29 +140,6 @@ std::string EQ::constants::GetLanguageName(uint8 language_id)
|
|||||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint32, std::string> ldon_theme_map = {
|
|
||||||
{ LDoNThemes::Unused, "Unused" },
|
|
||||||
{ LDoNThemes::GUK, "Deepest Guk" },
|
|
||||||
{ LDoNThemes::MIR, "Miragul's Menagerie" },
|
|
||||||
{ LDoNThemes::MMC, "Mistmoore Catacombs" },
|
|
||||||
{ LDoNThemes::RUJ, "Rujarkian Hills" },
|
|
||||||
{ LDoNThemes::TAK, "Takish-Hiz" },
|
|
||||||
};
|
|
||||||
|
|
||||||
return ldon_theme_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
|
|
||||||
{
|
|
||||||
if (!EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
||||||
{
|
{
|
||||||
static const std::map<int8, std::string> flymode_map = {
|
static const std::map<int8, std::string> flymode_map = {
|
||||||
@@ -249,102 +163,6 @@ std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
|||||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
|
|
||||||
{
|
|
||||||
static const std::map<bodyType, std::string> bodytype_map = {
|
|
||||||
{ BT_Humanoid, "Humanoid" },
|
|
||||||
{ BT_Lycanthrope, "Lycanthrope" },
|
|
||||||
{ BT_Undead, "Undead" },
|
|
||||||
{ BT_Giant, "Giant" },
|
|
||||||
{ BT_Construct, "Construct" },
|
|
||||||
{ BT_Extraplanar, "Extraplanar" },
|
|
||||||
{ BT_Magical, "Magical" },
|
|
||||||
{ BT_SummonedUndead, "Summoned Undead" },
|
|
||||||
{ BT_RaidGiant, "Raid Giant" },
|
|
||||||
{ BT_RaidColdain, "Raid Coldain" },
|
|
||||||
{ BT_NoTarget, "Untargetable" },
|
|
||||||
{ BT_Vampire, "Vampire" },
|
|
||||||
{ BT_Atenha_Ra, "Aten Ha Ra" },
|
|
||||||
{ BT_Greater_Akheva, "Greater Akheva" },
|
|
||||||
{ BT_Khati_Sha, "Khati Sha" },
|
|
||||||
{ BT_Seru, "Seru" },
|
|
||||||
{ BT_Grieg_Veneficus, "Grieg Veneficus" },
|
|
||||||
{ BT_Draz_Nurakk, "Draz Nurakk" },
|
|
||||||
{ BT_Zek, "Zek" },
|
|
||||||
{ BT_Luggald, "Luggald" },
|
|
||||||
{ BT_Animal, "Animal" },
|
|
||||||
{ BT_Insect, "Insect" },
|
|
||||||
{ BT_Monster, "Monster" },
|
|
||||||
{ BT_Summoned, "Summoned" },
|
|
||||||
{ BT_Plant, "Plant" },
|
|
||||||
{ BT_Dragon, "Dragon" },
|
|
||||||
{ BT_Summoned2, "Summoned 2" },
|
|
||||||
{ BT_Summoned3, "Summoned 3" },
|
|
||||||
{ BT_Dragon2, "Dragon 2" },
|
|
||||||
{ BT_VeliousDragon, "Velious Dragon" },
|
|
||||||
{ BT_Familiar, "Familiar" },
|
|
||||||
{ BT_Dragon3, "Dragon 3" },
|
|
||||||
{ BT_Boxes, "Boxes" },
|
|
||||||
{ BT_Muramite, "Muramite" },
|
|
||||||
{ BT_NoTarget2, "Untargetable 2" },
|
|
||||||
{ BT_SwarmPet, "Swarm Pet" },
|
|
||||||
{ BT_MonsterSummon, "Monster Summon" },
|
|
||||||
{ BT_InvisMan, "Invisible Man" },
|
|
||||||
{ BT_Special, "Special" },
|
|
||||||
};
|
|
||||||
|
|
||||||
return bodytype_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
|
|
||||||
{
|
|
||||||
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
|
|
||||||
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> account_status_map = {
|
|
||||||
{ AccountStatus::Player, "Player" },
|
|
||||||
{ AccountStatus::Steward, "Steward" },
|
|
||||||
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
|
|
||||||
{ AccountStatus::Guide, "Guide" },
|
|
||||||
{ AccountStatus::QuestTroupe, "Quest Troupe" },
|
|
||||||
{ AccountStatus::SeniorGuide, "Senior Guide" },
|
|
||||||
{ AccountStatus::GMTester, "GM Tester" },
|
|
||||||
{ AccountStatus::EQSupport, "EQ Support" },
|
|
||||||
{ AccountStatus::GMStaff, "GM Staff" },
|
|
||||||
{ AccountStatus::GMAdmin, "GM Admin" },
|
|
||||||
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
|
|
||||||
{ AccountStatus::QuestMaster, "Quest Master" },
|
|
||||||
{ AccountStatus::GMAreas, "GM Areas" },
|
|
||||||
{ AccountStatus::GMCoder, "GM Coder" },
|
|
||||||
{ AccountStatus::GMMgmt, "GM Mgmt" },
|
|
||||||
{ AccountStatus::GMImpossible, "GM Impossible" },
|
|
||||||
{ AccountStatus::Max, "GM Max" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return account_status_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
|
|
||||||
{
|
|
||||||
for (
|
|
||||||
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
|
|
||||||
status_level != EQ::constants::GetAccountStatusMap().rend();
|
|
||||||
++status_level
|
|
||||||
) {
|
|
||||||
if (account_status >= status_level->first) {
|
|
||||||
return status_level->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
||||||
{
|
{
|
||||||
static const std::map<uint8, std::string> consider_level_map = {
|
static const std::map<uint8, std::string> consider_level_map = {
|
||||||
@@ -435,84 +253,6 @@ std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
|||||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
|
||||||
{
|
|
||||||
static const std::map<int, std::string> object_type_map = {
|
|
||||||
{ ObjectTypes::SmallBag, "Small Bag" },
|
|
||||||
{ ObjectTypes::LargeBag, "Large Bag" },
|
|
||||||
{ ObjectTypes::Quiver, "Quiver" },
|
|
||||||
{ ObjectTypes::BeltPouch, "Belt Pouch" },
|
|
||||||
{ ObjectTypes::WristPouch, "Wrist Pouch" },
|
|
||||||
{ ObjectTypes::Backpack, "Backpack" },
|
|
||||||
{ ObjectTypes::SmallChest, "Small Chest" },
|
|
||||||
{ ObjectTypes::LargeChest, "Large Chest" },
|
|
||||||
{ ObjectTypes::Bandolier, "Bandolier" },
|
|
||||||
{ ObjectTypes::Medicine, "Medicine" },
|
|
||||||
{ ObjectTypes::Tinkering, "Tinkering" },
|
|
||||||
{ ObjectTypes::Lexicon, "Lexicon" },
|
|
||||||
{ ObjectTypes::PoisonMaking, "Mortar and Pestle" },
|
|
||||||
{ ObjectTypes::Quest, "Quest" },
|
|
||||||
{ ObjectTypes::MixingBowl, "Mixing Bowl" },
|
|
||||||
{ ObjectTypes::Baking, "Baking" },
|
|
||||||
{ ObjectTypes::Tailoring, "Tailoring" },
|
|
||||||
{ ObjectTypes::Blacksmithing, "Blacksmithing" },
|
|
||||||
{ ObjectTypes::Fletching, "Fletching" },
|
|
||||||
{ ObjectTypes::Brewing, "Brewing" },
|
|
||||||
{ ObjectTypes::JewelryMaking, "Jewelry Making" },
|
|
||||||
{ ObjectTypes::Pottery, "Pottery" },
|
|
||||||
{ ObjectTypes::Kiln, "Kiln" },
|
|
||||||
{ ObjectTypes::KeyMaker, "Key Maker" },
|
|
||||||
{ ObjectTypes::ResearchWIZ, "Lexicon" },
|
|
||||||
{ ObjectTypes::ResearchMAG, "Lexicon" },
|
|
||||||
{ ObjectTypes::ResearchNEC, "Lexicon" },
|
|
||||||
{ ObjectTypes::ResearchENC, "Lexicon" },
|
|
||||||
{ ObjectTypes::Unknown, "Unknown" },
|
|
||||||
{ ObjectTypes::ResearchPractice, "Lexicon" },
|
|
||||||
{ ObjectTypes::Alchemy, "Alchemy" },
|
|
||||||
{ ObjectTypes::HighElfForge, "High Elf Forge" },
|
|
||||||
{ ObjectTypes::DarkElfForge, "Dark Elf Forge" },
|
|
||||||
{ ObjectTypes::OgreForge, "Ogre Forge" },
|
|
||||||
{ ObjectTypes::DwarfForge, "Dwarf Forge" },
|
|
||||||
{ ObjectTypes::GnomeForge, "Gnome Forge" },
|
|
||||||
{ ObjectTypes::BarbarianForge, "Barbarian Forge" },
|
|
||||||
{ ObjectTypes::IksarForge, "Iksar Forge" },
|
|
||||||
{ ObjectTypes::HumanForgeOne, "Human Forge" },
|
|
||||||
{ ObjectTypes::HumanForgeTwo, "Human Forge" },
|
|
||||||
{ ObjectTypes::HalflingTailoringOne, "Halfling Tailoring" },
|
|
||||||
{ ObjectTypes::HalflingTailoringTwo, "Halfling Tailoring" },
|
|
||||||
{ ObjectTypes::EruditeTailoring, "Erudite Tailoring" },
|
|
||||||
{ ObjectTypes::WoodElfTailoring, "Wood Elf Tailoring" },
|
|
||||||
{ ObjectTypes::WoodElfFletching, "Wood Elf Fletching" },
|
|
||||||
{ ObjectTypes::IksarPottery, "Iksar Pottery" },
|
|
||||||
{ ObjectTypes::Fishing, "Fishing" },
|
|
||||||
{ ObjectTypes::TrollForge, "Troll Forge" },
|
|
||||||
{ ObjectTypes::WoodElfForge, "Wood Elf Forge" },
|
|
||||||
{ ObjectTypes::HalflingForge, "Halfling Forge" },
|
|
||||||
{ ObjectTypes::EruditeForge, "Erudite Forge" },
|
|
||||||
{ ObjectTypes::Merchant, "Merchant" },
|
|
||||||
{ ObjectTypes::FroglokForge, "Froglok Forge" },
|
|
||||||
{ ObjectTypes::Augmenter, "Augmenter" },
|
|
||||||
{ ObjectTypes::Churn, "Churn" },
|
|
||||||
{ ObjectTypes::TransformationMold, "Transformation Mold" },
|
|
||||||
{ ObjectTypes::DetransformationMold, "Detransformation Mold" },
|
|
||||||
{ ObjectTypes::Unattuner, "Unattuner" },
|
|
||||||
{ ObjectTypes::TradeskillBag, "Tradeskill Bag" },
|
|
||||||
{ ObjectTypes::CollectibleBag, "Collectible Bag" },
|
|
||||||
{ ObjectTypes::NoDeposit, "No Deposit" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return object_type_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetObjectTypeName(int object_type)
|
|
||||||
{
|
|
||||||
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||||
{
|
{
|
||||||
static const std::map<uint8, std::string> weather_type_map = {
|
static const std::map<uint8, std::string> weather_type_map = {
|
||||||
@@ -640,79 +380,14 @@ std::string EQ::constants::GetAppearanceTypeName(uint32 appearance_type)
|
|||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint32, std::string>& EQ::constants::GetSpecialAbilityMap()
|
std::string SpecialAbility::GetName(int ability_id)
|
||||||
{
|
{
|
||||||
static const std::map<uint32, std::string> special_ability_map = {
|
return IsValid(ability_id) ? special_ability_names[ability_id] : "UNKNOWN SPECIAL ABILITY";
|
||||||
{ SPECATK_SUMMON, "Summon" },
|
|
||||||
{ SPECATK_ENRAGE, "Enrage" },
|
|
||||||
{ SPECATK_RAMPAGE, "Rampage" },
|
|
||||||
{ SPECATK_AREA_RAMPAGE, "Area Rampage" },
|
|
||||||
{ SPECATK_FLURRY, "Flurry" },
|
|
||||||
{ SPECATK_TRIPLE, "Triple Attack" },
|
|
||||||
{ SPECATK_QUAD, "Quadruple Attack" },
|
|
||||||
{ SPECATK_INNATE_DW, "Dual Wield" },
|
|
||||||
{ SPECATK_BANE, "Bane Attack" },
|
|
||||||
{ SPECATK_MAGICAL, "Magical Attack" },
|
|
||||||
{ SPECATK_RANGED_ATK, "Ranged Attack" },
|
|
||||||
{ UNSLOWABLE, "Immune to Slow" },
|
|
||||||
{ UNMEZABLE, "Immune to Mesmerize" },
|
|
||||||
{ UNCHARMABLE, "Immune to Charm" },
|
|
||||||
{ UNSTUNABLE, "Immune to Stun" },
|
|
||||||
{ UNSNAREABLE, "Immune to Snare" },
|
|
||||||
{ UNFEARABLE, "Immune to Fear" },
|
|
||||||
{ UNDISPELLABLE, "Immune to Dispell" },
|
|
||||||
{ IMMUNE_MELEE, "Immune to Melee" },
|
|
||||||
{ IMMUNE_MAGIC, "Immune to Magic" },
|
|
||||||
{ IMMUNE_FLEEING, "Immune to Fleeing" },
|
|
||||||
{ IMMUNE_MELEE_EXCEPT_BANE, "Immune to Melee except Bane" },
|
|
||||||
{ IMMUNE_MELEE_NONMAGICAL, "Immune to Non-Magical Melee" },
|
|
||||||
{ IMMUNE_AGGRO, "Immune to Aggro" },
|
|
||||||
{ IMMUNE_AGGRO_ON, "Immune to Being Aggro" },
|
|
||||||
{ IMMUNE_CASTING_FROM_RANGE, "Immune to Ranged Spells" },
|
|
||||||
{ IMMUNE_FEIGN_DEATH, "Immune to Feign Death" },
|
|
||||||
{ IMMUNE_TAUNT, "Immune to Taunt" },
|
|
||||||
{ NPC_TUNNELVISION, "Tunnel Vision" },
|
|
||||||
{ NPC_NO_BUFFHEAL_FRIENDS, "Does Not Heal of Buff Allies" },
|
|
||||||
{ IMMUNE_PACIFY, "Immune to Pacify" },
|
|
||||||
{ LEASH, "Leashed" },
|
|
||||||
{ TETHER, "Tethered" },
|
|
||||||
{ DESTRUCTIBLE_OBJECT, "Destructible Object" },
|
|
||||||
{ NO_HARM_FROM_CLIENT, "Immune to Harm from Client" },
|
|
||||||
{ ALWAYS_FLEE, "Always Flees" },
|
|
||||||
{ FLEE_PERCENT, "Flee Percentage" },
|
|
||||||
{ ALLOW_BENEFICIAL, "Allows Beneficial Spells" },
|
|
||||||
{ DISABLE_MELEE, "Melee is Disabled" },
|
|
||||||
{ NPC_CHASE_DISTANCE, "Chase Distance" },
|
|
||||||
{ ALLOW_TO_TANK, "Allowed to Tank" },
|
|
||||||
{ IGNORE_ROOT_AGGRO_RULES, "Ignores Root Aggro" },
|
|
||||||
{ CASTING_RESIST_DIFF, "Casting Resist Difficulty" },
|
|
||||||
{ COUNTER_AVOID_DAMAGE, "Counter Damage Avoidance" },
|
|
||||||
{ PROX_AGGRO, "Proximity Aggro" },
|
|
||||||
{ IMMUNE_RANGED_ATTACKS, "Immune to Ranged Attacks" },
|
|
||||||
{ IMMUNE_DAMAGE_CLIENT, "Immune to Client Damage" },
|
|
||||||
{ IMMUNE_DAMAGE_NPC, "Immune to NPC Damage" },
|
|
||||||
{ IMMUNE_AGGRO_CLIENT, "Immune to Client Aggro" },
|
|
||||||
{ IMMUNE_AGGRO_NPC, "Immune to NPC Aggro" },
|
|
||||||
{ MODIFY_AVOID_DAMAGE, "Modify Damage Avoidance" },
|
|
||||||
{ IMMUNE_FADING_MEMORIES, "Immune to Memory Fades" },
|
|
||||||
{ IMMUNE_OPEN, "Immune to Open" },
|
|
||||||
{ IMMUNE_ASSASSINATE, "Immune to Assassinate" },
|
|
||||||
{ IMMUNE_HEADSHOT, "Immune to Headshot" },
|
|
||||||
{ IMMUNE_AGGRO_BOT, "Immune to Bot Aggro" },
|
|
||||||
{ IMMUNE_DAMAGE_BOT, "Immune to Bot Damage" },
|
|
||||||
};
|
|
||||||
|
|
||||||
return special_ability_map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQ::constants::GetSpecialAbilityName(uint32 ability_id)
|
bool SpecialAbility::IsValid(int ability_id)
|
||||||
{
|
{
|
||||||
const auto& a = EQ::constants::GetSpecialAbilityMap().find(ability_id);
|
return special_ability_names.find(ability_id) != special_ability_names.end();
|
||||||
if (a != EQ::constants::GetSpecialAbilityMap().end()) {
|
|
||||||
return a->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint32, std::string>& EQ::constants::GetConsiderColorMap()
|
const std::map<uint32, std::string>& EQ::constants::GetConsiderColorMap()
|
||||||
@@ -736,3 +411,43 @@ std::string EQ::constants::GetConsiderColorName(uint32 consider_color)
|
|||||||
const auto& c = EQ::constants::GetConsiderColorMap().find(consider_color);
|
const auto& c = EQ::constants::GetConsiderColorMap().find(consider_color);
|
||||||
return c != EQ::constants::GetConsiderColorMap().end() ? c->second : std::string();
|
return c != EQ::constants::GetConsiderColorMap().end() ? c->second : std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string AccountStatus::GetName(uint8 account_status)
|
||||||
|
{
|
||||||
|
for (
|
||||||
|
auto e = account_status_names.rbegin();
|
||||||
|
e != account_status_names.rend();
|
||||||
|
++e
|
||||||
|
) {
|
||||||
|
if (account_status >= e->first) {
|
||||||
|
return e->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN ACCOUNT STATUS";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ComparisonType::GetName(uint8 type)
|
||||||
|
{
|
||||||
|
return IsValid(type) ? comparison_types[type] : "UNKNOWN COMPARISON TYPE";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ComparisonType::IsValid(uint8 type)
|
||||||
|
{
|
||||||
|
return comparison_types.find(type) != comparison_types.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 LDoNTheme::GetBitmask(uint32 theme_id)
|
||||||
|
{
|
||||||
|
return IsValid(theme_id) ? ldon_theme_names[theme_id].second : LDoNTheme::UnusedBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LDoNTheme::GetName(uint32 theme_id)
|
||||||
|
{
|
||||||
|
return IsValid(theme_id) ? ldon_theme_names[theme_id].first : "UNKNOWN LDON THEME";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDoNTheme::IsValid(uint32 theme_id)
|
||||||
|
{
|
||||||
|
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
|
||||||
|
}
|
||||||
|
|||||||
+339
-249
@@ -26,6 +26,76 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace AccountStatus {
|
||||||
|
constexpr uint8 Player = 0;
|
||||||
|
constexpr uint8 Steward = 10;
|
||||||
|
constexpr uint8 ApprenticeGuide = 20;
|
||||||
|
constexpr uint8 Guide = 50;
|
||||||
|
constexpr uint8 QuestTroupe = 80;
|
||||||
|
constexpr uint8 SeniorGuide = 81;
|
||||||
|
constexpr uint8 GMTester = 85;
|
||||||
|
constexpr uint8 EQSupport = 90;
|
||||||
|
constexpr uint8 GMStaff = 95;
|
||||||
|
constexpr uint8 GMAdmin = 100;
|
||||||
|
constexpr uint8 GMLeadAdmin = 150;
|
||||||
|
constexpr uint8 QuestMaster = 160;
|
||||||
|
constexpr uint8 GMAreas = 170;
|
||||||
|
constexpr uint8 GMCoder = 180;
|
||||||
|
constexpr uint8 GMMgmt = 200;
|
||||||
|
constexpr uint8 GMImpossible = 250;
|
||||||
|
constexpr uint8 Max = 255;
|
||||||
|
|
||||||
|
std::string GetName(uint8 account_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> account_status_names = {
|
||||||
|
{ AccountStatus::Player, "Player" },
|
||||||
|
{ AccountStatus::Steward, "Steward" },
|
||||||
|
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
|
||||||
|
{ AccountStatus::Guide, "Guide" },
|
||||||
|
{ AccountStatus::QuestTroupe, "Quest Troupe" },
|
||||||
|
{ AccountStatus::SeniorGuide, "Senior Guide" },
|
||||||
|
{ AccountStatus::GMTester, "GM Tester" },
|
||||||
|
{ AccountStatus::EQSupport, "EQ Support" },
|
||||||
|
{ AccountStatus::GMStaff, "GM Staff" },
|
||||||
|
{ AccountStatus::GMAdmin, "GM Admin" },
|
||||||
|
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
|
||||||
|
{ AccountStatus::QuestMaster, "Quest Master" },
|
||||||
|
{ AccountStatus::GMAreas, "GM Areas" },
|
||||||
|
{ AccountStatus::GMCoder, "GM Coder" },
|
||||||
|
{ AccountStatus::GMMgmt, "GM Mgmt" },
|
||||||
|
{ AccountStatus::GMImpossible, "GM Impossible" },
|
||||||
|
{ AccountStatus::Max, "GM Max" }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace ComparisonType {
|
||||||
|
constexpr uint8 Equal = 0;
|
||||||
|
constexpr uint8 NotEqual = 1;
|
||||||
|
constexpr uint8 GreaterOrEqual = 2;
|
||||||
|
constexpr uint8 LesserOrEqual = 3;
|
||||||
|
constexpr uint8 Greater = 4;
|
||||||
|
constexpr uint8 Lesser = 5;
|
||||||
|
constexpr uint8 Any = 6;
|
||||||
|
constexpr uint8 NotAny = 7;
|
||||||
|
constexpr uint8 Between = 8;
|
||||||
|
constexpr uint8 NotBetween = 9;
|
||||||
|
|
||||||
|
std::string GetName(uint8 type);
|
||||||
|
bool IsValid(uint8 type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> comparison_types = {
|
||||||
|
{ ComparisonType::Equal, "Equal" },
|
||||||
|
{ ComparisonType::NotEqual, "Not Equal" },
|
||||||
|
{ ComparisonType::GreaterOrEqual, "Greater or Equal" },
|
||||||
|
{ ComparisonType::LesserOrEqual, "Lesser or Equal" },
|
||||||
|
{ ComparisonType::Greater, "Greater" },
|
||||||
|
{ ComparisonType::Lesser, "Lesser" },
|
||||||
|
{ ComparisonType::Any, "Any" },
|
||||||
|
{ ComparisonType::NotAny, "Not Any" },
|
||||||
|
{ ComparisonType::Between, "Between" },
|
||||||
|
{ ComparisonType::NotBetween, "Not Between" },
|
||||||
|
};
|
||||||
|
|
||||||
// local definitions are the result of using hybrid-client or server-only values and methods
|
// local definitions are the result of using hybrid-client or server-only values and methods
|
||||||
namespace EQ
|
namespace EQ
|
||||||
@@ -62,7 +132,7 @@ namespace EQ
|
|||||||
using RoF2::invtype::KRONO_SIZE;
|
using RoF2::invtype::KRONO_SIZE;
|
||||||
using RoF2::invtype::OTHER_SIZE;
|
using RoF2::invtype::OTHER_SIZE;
|
||||||
|
|
||||||
using Titanium::invtype::TRADE_NPC_SIZE;
|
using RoF2::invtype::TRADE_NPC_SIZE;
|
||||||
|
|
||||||
using RoF2::invtype::TYPE_INVALID;
|
using RoF2::invtype::TYPE_INVALID;
|
||||||
using RoF2::invtype::TYPE_BEGIN;
|
using RoF2::invtype::TYPE_BEGIN;
|
||||||
@@ -89,7 +159,7 @@ namespace EQ
|
|||||||
using RoF2::invslot::SLOT_INVALID;
|
using RoF2::invslot::SLOT_INVALID;
|
||||||
using RoF2::invslot::SLOT_BEGIN;
|
using RoF2::invslot::SLOT_BEGIN;
|
||||||
|
|
||||||
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
|
using RoF2::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
|
||||||
|
|
||||||
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
|
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
|
||||||
|
|
||||||
@@ -109,25 +179,25 @@ namespace EQ
|
|||||||
using RoF2::invslot::BONUS_STAT_END;
|
using RoF2::invslot::BONUS_STAT_END;
|
||||||
using RoF2::invslot::BONUS_SKILL_END;
|
using RoF2::invslot::BONUS_SKILL_END;
|
||||||
|
|
||||||
using Titanium::invslot::BANK_BEGIN;
|
using RoF2::invslot::BANK_BEGIN;
|
||||||
using SoF::invslot::BANK_END;
|
using RoF2::invslot::BANK_END;
|
||||||
|
|
||||||
using Titanium::invslot::SHARED_BANK_BEGIN;
|
using RoF2::invslot::SHARED_BANK_BEGIN;
|
||||||
using Titanium::invslot::SHARED_BANK_END;
|
using RoF2::invslot::SHARED_BANK_END;
|
||||||
|
|
||||||
using Titanium::invslot::TRADE_BEGIN;
|
using RoF2::invslot::TRADE_BEGIN;
|
||||||
using Titanium::invslot::TRADE_END;
|
using RoF2::invslot::TRADE_END;
|
||||||
|
|
||||||
using Titanium::invslot::TRADE_NPC_END;
|
using RoF2::invslot::TRADE_NPC_END;
|
||||||
|
|
||||||
using Titanium::invslot::WORLD_BEGIN;
|
using RoF2::invslot::WORLD_BEGIN;
|
||||||
using Titanium::invslot::WORLD_END;
|
using RoF2::invslot::WORLD_END;
|
||||||
|
|
||||||
using Titanium::invslot::TRIBUTE_BEGIN;
|
using RoF2::invslot::TRIBUTE_BEGIN;
|
||||||
using Titanium::invslot::TRIBUTE_END;
|
using RoF2::invslot::TRIBUTE_END;
|
||||||
|
|
||||||
using Titanium::invslot::GUILD_TRIBUTE_BEGIN;
|
using RoF2::invslot::GUILD_TRIBUTE_BEGIN;
|
||||||
using Titanium::invslot::GUILD_TRIBUTE_END;
|
using RoF2::invslot::GUILD_TRIBUTE_END;
|
||||||
|
|
||||||
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
|
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
|
||||||
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
|
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
|
||||||
@@ -144,38 +214,40 @@ namespace EQ
|
|||||||
} // namespace invslot
|
} // namespace invslot
|
||||||
|
|
||||||
namespace invbag {
|
namespace invbag {
|
||||||
using Titanium::invbag::SLOT_INVALID;
|
using RoF2::invbag::SLOT_INVALID;
|
||||||
using Titanium::invbag::SLOT_BEGIN;
|
using RoF2::invbag::SLOT_BEGIN;
|
||||||
using Titanium::invbag::SLOT_END;
|
using RoF2::invbag::SLOT_END;
|
||||||
using Titanium::invbag::SLOT_COUNT;
|
using RoF2::invbag::SLOT_COUNT;
|
||||||
|
|
||||||
using Titanium::invbag::GENERAL_BAGS_BEGIN;
|
using RoF2::invslot::WORLD_END;
|
||||||
|
|
||||||
|
const int16 GENERAL_BAGS_BEGIN = WORLD_END + 1;
|
||||||
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
|
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
|
||||||
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
|
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
|
||||||
|
|
||||||
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
|
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
|
||||||
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
|
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
|
||||||
|
|
||||||
const int16 CURSOR_BAG_BEGIN = 351;
|
const int16 CURSOR_BAG_BEGIN = GENERAL_BAGS_END + 1;
|
||||||
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
|
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
|
||||||
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
|
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
|
||||||
|
|
||||||
using Titanium::invbag::BANK_BAGS_BEGIN;
|
const int16 BANK_BAGS_BEGIN = CURSOR_BAG_END + 1;
|
||||||
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
|
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
|
||||||
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
|
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
|
||||||
|
|
||||||
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
|
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
|
||||||
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
|
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
|
||||||
|
|
||||||
using Titanium::invbag::SHARED_BANK_BAGS_BEGIN;
|
const int16 SHARED_BANK_BAGS_BEGIN = BANK_BAGS_END + 1;
|
||||||
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
|
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
|
||||||
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
|
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
|
||||||
|
|
||||||
using Titanium::invbag::TRADE_BAGS_BEGIN;
|
const int16 TRADE_BAGS_BEGIN = SHARED_BANK_BAGS_END + 1;
|
||||||
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
|
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
|
||||||
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
|
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
|
||||||
|
|
||||||
using Titanium::invbag::GetInvBagIndexName;
|
using RoF2::invbag::GetInvBagIndexName;
|
||||||
|
|
||||||
} // namespace invbag
|
} // namespace invbag
|
||||||
|
|
||||||
@@ -204,19 +276,6 @@ namespace EQ
|
|||||||
const size_t SAY_LINK_CLOSER_SIZE = 1;
|
const size_t SAY_LINK_CLOSER_SIZE = 1;
|
||||||
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
|
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
|
||||||
|
|
||||||
enum StanceType : int {
|
|
||||||
stanceUnknown = 0,
|
|
||||||
stancePassive,
|
|
||||||
stanceBalanced,
|
|
||||||
stanceEfficient,
|
|
||||||
stanceReactive,
|
|
||||||
stanceAggressive,
|
|
||||||
stanceAssist,
|
|
||||||
stanceBurn,
|
|
||||||
stanceEfficient2,
|
|
||||||
stanceBurnAE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BotSpellIDs : int {
|
enum BotSpellIDs : int {
|
||||||
Warrior = 3001,
|
Warrior = 3001,
|
||||||
Cleric,
|
Cleric,
|
||||||
@@ -267,70 +326,6 @@ namespace EQ
|
|||||||
Looting
|
Looting
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ObjectTypes : int {
|
|
||||||
SmallBag,
|
|
||||||
LargeBag,
|
|
||||||
Quiver,
|
|
||||||
BeltPouch,
|
|
||||||
WristPouch,
|
|
||||||
Backpack,
|
|
||||||
SmallChest,
|
|
||||||
LargeChest,
|
|
||||||
Bandolier,
|
|
||||||
Medicine,
|
|
||||||
Tinkering,
|
|
||||||
Lexicon,
|
|
||||||
PoisonMaking,
|
|
||||||
Quest,
|
|
||||||
MixingBowl,
|
|
||||||
Baking,
|
|
||||||
Tailoring,
|
|
||||||
Blacksmithing,
|
|
||||||
Fletching,
|
|
||||||
Brewing,
|
|
||||||
JewelryMaking,
|
|
||||||
Pottery,
|
|
||||||
Kiln,
|
|
||||||
KeyMaker,
|
|
||||||
ResearchWIZ,
|
|
||||||
ResearchMAG,
|
|
||||||
ResearchNEC,
|
|
||||||
ResearchENC,
|
|
||||||
Unknown,
|
|
||||||
ResearchPractice,
|
|
||||||
Alchemy,
|
|
||||||
HighElfForge,
|
|
||||||
DarkElfForge,
|
|
||||||
OgreForge,
|
|
||||||
DwarfForge,
|
|
||||||
GnomeForge,
|
|
||||||
BarbarianForge,
|
|
||||||
IksarForge,
|
|
||||||
HumanForgeOne,
|
|
||||||
HumanForgeTwo,
|
|
||||||
HalflingTailoringOne,
|
|
||||||
HalflingTailoringTwo,
|
|
||||||
EruditeTailoring,
|
|
||||||
WoodElfTailoring,
|
|
||||||
WoodElfFletching,
|
|
||||||
IksarPottery,
|
|
||||||
Fishing,
|
|
||||||
TrollForge,
|
|
||||||
WoodElfForge,
|
|
||||||
HalflingForge,
|
|
||||||
EruditeForge,
|
|
||||||
Merchant,
|
|
||||||
FroglokForge,
|
|
||||||
Augmenter,
|
|
||||||
Churn,
|
|
||||||
TransformationMold,
|
|
||||||
DetransformationMold,
|
|
||||||
Unattuner,
|
|
||||||
TradeskillBag,
|
|
||||||
CollectibleBag,
|
|
||||||
NoDeposit
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WeatherTypes : uint8 {
|
enum WeatherTypes : uint8 {
|
||||||
None,
|
None,
|
||||||
Raining,
|
Raining,
|
||||||
@@ -356,24 +351,12 @@ namespace EQ
|
|||||||
Proximity
|
Proximity
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *GetStanceName(StanceType stance_type);
|
|
||||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetLanguageMap();
|
extern const std::map<uint8, std::string>& GetLanguageMap();
|
||||||
std::string GetLanguageName(uint8 language_id);
|
std::string GetLanguageName(uint8 language_id);
|
||||||
|
|
||||||
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
|
||||||
std::string GetLDoNThemeName(uint32 theme_id);
|
|
||||||
|
|
||||||
extern const std::map<int8, std::string>& GetFlyModeMap();
|
extern const std::map<int8, std::string>& GetFlyModeMap();
|
||||||
std::string GetFlyModeName(int8 flymode_id);
|
std::string GetFlyModeName(int8 flymode_id);
|
||||||
|
|
||||||
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
|
|
||||||
std::string GetBodyTypeName(bodyType bodytype_id);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetAccountStatusMap();
|
|
||||||
std::string GetAccountStatusName(uint8 account_status);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
||||||
std::string GetConsiderLevelName(uint8 consider_level);
|
std::string GetConsiderLevelName(uint8 consider_level);
|
||||||
|
|
||||||
@@ -386,9 +369,6 @@ namespace EQ
|
|||||||
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
|
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
|
||||||
std::string GetSpawnAnimationName(uint8 animation_id);
|
std::string GetSpawnAnimationName(uint8 animation_id);
|
||||||
|
|
||||||
extern const std::map<int, std::string>& GetObjectTypeMap();
|
|
||||||
std::string GetObjectTypeName(int object_type);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
|
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
|
||||||
std::string GetWeatherTypeName(uint8 weather_type);
|
std::string GetWeatherTypeName(uint8 weather_type);
|
||||||
|
|
||||||
@@ -401,16 +381,9 @@ namespace EQ
|
|||||||
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
||||||
std::string GetAppearanceTypeName(uint32 animation_type);
|
std::string GetAppearanceTypeName(uint32 animation_type);
|
||||||
|
|
||||||
extern const std::map<uint32, std::string>& GetSpecialAbilityMap();
|
|
||||||
std::string GetSpecialAbilityName(uint32 ability_id);
|
|
||||||
|
|
||||||
extern const std::map<uint32, std::string>& GetConsiderColorMap();
|
extern const std::map<uint32, std::string>& GetConsiderColorMap();
|
||||||
std::string GetConsiderColorName(uint32 consider_color);
|
std::string GetConsiderColorName(uint32 consider_color);
|
||||||
|
|
||||||
const int STANCE_TYPE_FIRST = stancePassive;
|
|
||||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
|
||||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
|
||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
namespace profile {
|
namespace profile {
|
||||||
@@ -464,37 +437,6 @@ namespace EQ
|
|||||||
|
|
||||||
} // namespace spells
|
} // namespace spells
|
||||||
|
|
||||||
namespace bug {
|
|
||||||
enum CategoryID : uint32 {
|
|
||||||
catOther = 0,
|
|
||||||
catVideo,
|
|
||||||
catAudio,
|
|
||||||
catPathing,
|
|
||||||
catQuest,
|
|
||||||
catTradeskills,
|
|
||||||
catSpellStacking,
|
|
||||||
catDoorsPortals,
|
|
||||||
catItems,
|
|
||||||
catNPC,
|
|
||||||
catDialogs,
|
|
||||||
catLoNTCG,
|
|
||||||
catMercenaries
|
|
||||||
};
|
|
||||||
|
|
||||||
enum OptionalInfoFlag : uint32 {
|
|
||||||
infoNoOptionalInfo = 0x0,
|
|
||||||
infoCanDuplicate = 0x1,
|
|
||||||
infoCrashBug = 0x2,
|
|
||||||
infoTargetInfo = 0x4,
|
|
||||||
infoCharacterFlags = 0x8,
|
|
||||||
infoUnknownValue = 0xFFFFFFF0
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* CategoryIDToCategoryName(CategoryID category_id);
|
|
||||||
CategoryID CategoryNameToCategoryID(const char* category_name);
|
|
||||||
|
|
||||||
} // namespace bug
|
|
||||||
|
|
||||||
enum WaypointStatus : int {
|
enum WaypointStatus : int {
|
||||||
RoamBoxPauseInProgress = -3,
|
RoamBoxPauseInProgress = -3,
|
||||||
QuestControlNoGrid = -2,
|
QuestControlNoGrid = -2,
|
||||||
@@ -508,7 +450,7 @@ namespace EQ
|
|||||||
Raid,
|
Raid,
|
||||||
Guild
|
Guild
|
||||||
};
|
};
|
||||||
}; // namespace consent
|
};
|
||||||
} /*EQEmu*/
|
} /*EQEmu*/
|
||||||
|
|
||||||
enum ServerLockType : int {
|
enum ServerLockType : int {
|
||||||
@@ -517,26 +459,6 @@ enum ServerLockType : int {
|
|||||||
Unlock
|
Unlock
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AccountStatus : uint8 {
|
|
||||||
Player = 0,
|
|
||||||
Steward = 10,
|
|
||||||
ApprenticeGuide = 20,
|
|
||||||
Guide = 50,
|
|
||||||
QuestTroupe = 80,
|
|
||||||
SeniorGuide = 81,
|
|
||||||
GMTester = 85,
|
|
||||||
EQSupport = 90,
|
|
||||||
GMStaff = 95,
|
|
||||||
GMAdmin = 100,
|
|
||||||
GMLeadAdmin = 150,
|
|
||||||
QuestMaster = 160,
|
|
||||||
GMAreas = 170,
|
|
||||||
GMCoder = 180,
|
|
||||||
GMMgmt = 200,
|
|
||||||
GMImpossible = 250,
|
|
||||||
Max = 255
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Invisibility : uint8 {
|
enum Invisibility : uint8 {
|
||||||
Visible,
|
Visible,
|
||||||
Invisible,
|
Invisible,
|
||||||
@@ -588,19 +510,6 @@ enum ReloadWorld : uint8 {
|
|||||||
ForceRepop
|
ForceRepop
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BucketComparison : uint8 {
|
|
||||||
BucketEqualTo = 0,
|
|
||||||
BucketNotEqualTo,
|
|
||||||
BucketGreaterThanOrEqualTo,
|
|
||||||
BucketLesserThanOrEqualTo,
|
|
||||||
BucketGreaterThan,
|
|
||||||
BucketLesserThan,
|
|
||||||
BucketIsAny,
|
|
||||||
BucketIsNotAny,
|
|
||||||
BucketIsBetween,
|
|
||||||
BucketIsNotBetween
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EntityFilterType {
|
enum class EntityFilterType {
|
||||||
All,
|
All,
|
||||||
Bots,
|
Bots,
|
||||||
@@ -614,67 +523,131 @@ enum class ApplySpellType {
|
|||||||
Raid
|
Raid
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
namespace SpecialAbility {
|
||||||
SPECATK_SUMMON = 1,
|
constexpr int Summon = 1;
|
||||||
SPECATK_ENRAGE = 2,
|
constexpr int Enrage = 2;
|
||||||
SPECATK_RAMPAGE = 3,
|
constexpr int Rampage = 3;
|
||||||
SPECATK_AREA_RAMPAGE = 4,
|
constexpr int AreaRampage = 4;
|
||||||
SPECATK_FLURRY = 5,
|
constexpr int Flurry = 5;
|
||||||
SPECATK_TRIPLE = 6,
|
constexpr int TripleAttack = 6;
|
||||||
SPECATK_QUAD = 7,
|
constexpr int QuadrupleAttack = 7;
|
||||||
SPECATK_INNATE_DW = 8,
|
constexpr int DualWield = 8;
|
||||||
SPECATK_BANE = 9,
|
constexpr int BaneAttack = 9;
|
||||||
SPECATK_MAGICAL = 10,
|
constexpr int MagicalAttack = 10;
|
||||||
SPECATK_RANGED_ATK = 11,
|
constexpr int RangedAttack = 11;
|
||||||
UNSLOWABLE = 12,
|
constexpr int SlowImmunity = 12;
|
||||||
UNMEZABLE = 13,
|
constexpr int MesmerizeImmunity = 13;
|
||||||
UNCHARMABLE = 14,
|
constexpr int CharmImmunity = 14;
|
||||||
UNSTUNABLE = 15,
|
constexpr int StunImmunity = 15;
|
||||||
UNSNAREABLE = 16,
|
constexpr int SnareImmunity = 16;
|
||||||
UNFEARABLE = 17,
|
constexpr int FearImmunity = 17;
|
||||||
UNDISPELLABLE = 18,
|
constexpr int DispellImmunity = 18;
|
||||||
IMMUNE_MELEE = 19,
|
constexpr int MeleeImmunity = 19;
|
||||||
IMMUNE_MAGIC = 20,
|
constexpr int MagicImmunity = 20;
|
||||||
IMMUNE_FLEEING = 21,
|
constexpr int FleeingImmunity = 21;
|
||||||
IMMUNE_MELEE_EXCEPT_BANE = 22,
|
constexpr int MeleeImmunityExceptBane = 22;
|
||||||
IMMUNE_MELEE_NONMAGICAL = 23,
|
constexpr int MeleeImmunityExceptMagical = 23;
|
||||||
IMMUNE_AGGRO = 24,
|
constexpr int AggroImmunity = 24;
|
||||||
IMMUNE_AGGRO_ON = 25,
|
constexpr int BeingAggroImmunity = 25;
|
||||||
IMMUNE_CASTING_FROM_RANGE = 26,
|
constexpr int CastingFromRangeImmunity = 26;
|
||||||
IMMUNE_FEIGN_DEATH = 27,
|
constexpr int FeignDeathImmunity = 27;
|
||||||
IMMUNE_TAUNT = 28,
|
constexpr int TauntImmunity = 28;
|
||||||
NPC_TUNNELVISION = 29,
|
constexpr int TunnelVision = 29;
|
||||||
NPC_NO_BUFFHEAL_FRIENDS = 30,
|
constexpr int NoBuffHealFriends = 30;
|
||||||
IMMUNE_PACIFY = 31,
|
constexpr int PacifyImmunity = 31;
|
||||||
LEASH = 32,
|
constexpr int Leash = 32;
|
||||||
TETHER = 33,
|
constexpr int Tether = 33;
|
||||||
DESTRUCTIBLE_OBJECT = 34,
|
constexpr int DestructibleObject = 34;
|
||||||
NO_HARM_FROM_CLIENT = 35,
|
constexpr int HarmFromClientImmunity = 35;
|
||||||
ALWAYS_FLEE = 36,
|
constexpr int AlwaysFlee = 36;
|
||||||
FLEE_PERCENT = 37,
|
constexpr int FleePercent = 37;
|
||||||
ALLOW_BENEFICIAL = 38,
|
constexpr int AllowBeneficial = 38;
|
||||||
DISABLE_MELEE = 39,
|
constexpr int DisableMelee = 39;
|
||||||
NPC_CHASE_DISTANCE = 40,
|
constexpr int NPCChaseDistance = 40;
|
||||||
ALLOW_TO_TANK = 41,
|
constexpr int AllowedToTank = 41;
|
||||||
IGNORE_ROOT_AGGRO_RULES = 42,
|
constexpr int IgnoreRootAggroRules = 42;
|
||||||
CASTING_RESIST_DIFF = 43,
|
constexpr int CastingResistDifficulty = 43;
|
||||||
COUNTER_AVOID_DAMAGE = 44, // Modify by percent NPC's opponents chance to riposte, block, parry or dodge individually, or for all skills
|
constexpr int CounterAvoidDamage = 44;
|
||||||
PROX_AGGRO = 45,
|
constexpr int ProximityAggro = 45;
|
||||||
IMMUNE_RANGED_ATTACKS = 46,
|
constexpr int RangedAttackImmunity = 46;
|
||||||
IMMUNE_DAMAGE_CLIENT = 47,
|
constexpr int ClientDamageImmunity = 47;
|
||||||
IMMUNE_DAMAGE_NPC = 48,
|
constexpr int NPCDamageImmunity = 48;
|
||||||
IMMUNE_AGGRO_CLIENT = 49,
|
constexpr int ClientAggroImmunity = 49;
|
||||||
IMMUNE_AGGRO_NPC = 50,
|
constexpr int NPCAggroImmunity = 50;
|
||||||
MODIFY_AVOID_DAMAGE = 51, // Modify by percent the NPCs chance to riposte, block, parry or dodge individually, or for all skills
|
constexpr int ModifyAvoidDamage = 51;
|
||||||
IMMUNE_FADING_MEMORIES = 52,
|
constexpr int MemoryFadeImmunity = 52;
|
||||||
IMMUNE_OPEN = 53,
|
constexpr int OpenImmunity = 53;
|
||||||
IMMUNE_ASSASSINATE = 54,
|
constexpr int AssassinateImmunity = 54;
|
||||||
IMMUNE_HEADSHOT = 55,
|
constexpr int HeadshotImmunity = 55;
|
||||||
IMMUNE_AGGRO_BOT = 56,
|
constexpr int BotAggroImmunity = 56;
|
||||||
IMMUNE_DAMAGE_BOT = 57,
|
constexpr int BotDamageImmunity = 57;
|
||||||
MAX_SPECIAL_ATTACK = 58
|
constexpr int Max = 58;
|
||||||
};
|
|
||||||
|
|
||||||
|
constexpr int MaxParameters = 9;
|
||||||
|
|
||||||
|
std::string GetName(int ability_id);
|
||||||
|
bool IsValid(int ability_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<int, std::string> special_ability_names = {
|
||||||
|
{ SpecialAbility::Summon, "Summon" },
|
||||||
|
{ SpecialAbility::Enrage, "Enrage" },
|
||||||
|
{ SpecialAbility::Rampage, "Rampage" },
|
||||||
|
{ SpecialAbility::AreaRampage, "Area Rampage" },
|
||||||
|
{ SpecialAbility::Flurry, "Flurry" },
|
||||||
|
{ SpecialAbility::TripleAttack, "Triple Attack" },
|
||||||
|
{ SpecialAbility::QuadrupleAttack, "Quadruple Attack" },
|
||||||
|
{ SpecialAbility::DualWield, "Dual Wield" },
|
||||||
|
{ SpecialAbility::BaneAttack, "Bane Attack" },
|
||||||
|
{ SpecialAbility::MagicalAttack, "Magical Attack" },
|
||||||
|
{ SpecialAbility::RangedAttack, "Ranged Attack" },
|
||||||
|
{ SpecialAbility::SlowImmunity, "Immune to Slow" },
|
||||||
|
{ SpecialAbility::MesmerizeImmunity, "Immune to Mesmerize" },
|
||||||
|
{ SpecialAbility::CharmImmunity, "Immune to Charm" },
|
||||||
|
{ SpecialAbility::StunImmunity, "Immune to Stun" },
|
||||||
|
{ SpecialAbility::SnareImmunity, "Immune to Snare" },
|
||||||
|
{ SpecialAbility::FearImmunity, "Immune to Fear" },
|
||||||
|
{ SpecialAbility::DispellImmunity, "Immune to Dispell" },
|
||||||
|
{ SpecialAbility::MeleeImmunity, "Immune to Melee" },
|
||||||
|
{ SpecialAbility::MagicImmunity, "Immune to Magic" },
|
||||||
|
{ SpecialAbility::FleeingImmunity, "Immune to Fleeing" },
|
||||||
|
{ SpecialAbility::MeleeImmunityExceptBane, "Immune to Melee except Bane" },
|
||||||
|
{ SpecialAbility::MeleeImmunityExceptMagical, "Immune to Non-Magical Melee" },
|
||||||
|
{ SpecialAbility::AggroImmunity, "Immune to Aggro" },
|
||||||
|
{ SpecialAbility::BeingAggroImmunity, "Immune to Being Aggro" },
|
||||||
|
{ SpecialAbility::CastingFromRangeImmunity, "Immune to Ranged Spells" },
|
||||||
|
{ SpecialAbility::FeignDeathImmunity, "Immune to Feign Death" },
|
||||||
|
{ SpecialAbility::TauntImmunity, "Immune to Taunt" },
|
||||||
|
{ SpecialAbility::TunnelVision, "Tunnel Vision" },
|
||||||
|
{ SpecialAbility::NoBuffHealFriends, "Does Not Heal or Buff Allies" },
|
||||||
|
{ SpecialAbility::PacifyImmunity, "Immune to Pacify" },
|
||||||
|
{ SpecialAbility::Leash, "Leashed" },
|
||||||
|
{ SpecialAbility::Tether, "Tethered" },
|
||||||
|
{ SpecialAbility::DestructibleObject, "Destructible Object" },
|
||||||
|
{ SpecialAbility::HarmFromClientImmunity, "Immune to Harm from Client" },
|
||||||
|
{ SpecialAbility::AlwaysFlee, "Always Flees" },
|
||||||
|
{ SpecialAbility::FleePercent, "Flee Percentage" },
|
||||||
|
{ SpecialAbility::AllowBeneficial, "Allows Beneficial Spells" },
|
||||||
|
{ SpecialAbility::DisableMelee, "Melee is Disabled" },
|
||||||
|
{ SpecialAbility::NPCChaseDistance, "Chase Distance" },
|
||||||
|
{ SpecialAbility::AllowedToTank, "Allowed to Tank" },
|
||||||
|
{ SpecialAbility::IgnoreRootAggroRules, "Ignores Root Aggro" },
|
||||||
|
{ SpecialAbility::CastingResistDifficulty, "Casting Resist Difficulty" },
|
||||||
|
{ SpecialAbility::CounterAvoidDamage, "Counter Damage Avoidance" },
|
||||||
|
{ SpecialAbility::ProximityAggro, "Proximity Aggro" },
|
||||||
|
{ SpecialAbility::RangedAttackImmunity, "Immune to Ranged Attacks" },
|
||||||
|
{ SpecialAbility::ClientDamageImmunity, "Immune to Client Damage" },
|
||||||
|
{ SpecialAbility::NPCDamageImmunity, "Immune to NPC Damage" },
|
||||||
|
{ SpecialAbility::ClientAggroImmunity, "Immune to Client Aggro" },
|
||||||
|
{ SpecialAbility::NPCAggroImmunity, "Immune to NPC Aggro" },
|
||||||
|
{ SpecialAbility::ModifyAvoidDamage, "Modify Damage Avoidance" },
|
||||||
|
{ SpecialAbility::MemoryFadeImmunity, "Immune to Memory Fades" },
|
||||||
|
{ SpecialAbility::OpenImmunity, "Immune to Open" },
|
||||||
|
{ SpecialAbility::AssassinateImmunity, "Immune to Assassinate" },
|
||||||
|
{ SpecialAbility::HeadshotImmunity, "Immune to Headshot" },
|
||||||
|
{ SpecialAbility::BotAggroImmunity, "Immune to Bot Aggro" },
|
||||||
|
{ SpecialAbility::BotDamageImmunity, "Immune to Bot Damage" },
|
||||||
|
};
|
||||||
|
|
||||||
namespace HeroicBonusBucket
|
namespace HeroicBonusBucket
|
||||||
{
|
{
|
||||||
@@ -700,4 +673,121 @@ namespace HeroicBonusBucket
|
|||||||
const std::string DexEnduranceRegen = "HDEX-EnduranceRegen";
|
const std::string DexEnduranceRegen = "HDEX-EnduranceRegen";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Bug {
|
||||||
|
namespace Category {
|
||||||
|
constexpr uint32 Other = 0;
|
||||||
|
constexpr uint32 Video = 1;
|
||||||
|
constexpr uint32 Audio = 2;
|
||||||
|
constexpr uint32 Pathing = 3;
|
||||||
|
constexpr uint32 Quest = 4;
|
||||||
|
constexpr uint32 Tradeskills = 5;
|
||||||
|
constexpr uint32 SpellStacking = 6;
|
||||||
|
constexpr uint32 DoorsPortals = 7;
|
||||||
|
constexpr uint32 Items = 8;
|
||||||
|
constexpr uint32 NPC = 9;
|
||||||
|
constexpr uint32 Dialogs = 10;
|
||||||
|
constexpr uint32 LoNTCG = 11;
|
||||||
|
constexpr uint32 Mercenaries = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace InformationFlag {
|
||||||
|
constexpr uint32 None = 0;
|
||||||
|
constexpr uint32 Repeatable = 1;
|
||||||
|
constexpr uint32 Crash = 2;
|
||||||
|
constexpr uint32 TargetInfo = 4;
|
||||||
|
constexpr uint32 CharacterFlags = 8;
|
||||||
|
constexpr uint32 Unknown = 4294967280;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetID(const std::string& category_name);
|
||||||
|
std::string GetName(uint32 category_id);
|
||||||
|
bool IsValid(uint32 category_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint32, std::string> bug_category_names = {
|
||||||
|
{ Bug::Category::Other, "Other" },
|
||||||
|
{ Bug::Category::Video, "Video" },
|
||||||
|
{ Bug::Category::Audio, "Audio" },
|
||||||
|
{ Bug::Category::Pathing, "Pathing" },
|
||||||
|
{ Bug::Category::Quest, "Quest" },
|
||||||
|
{ Bug::Category::Tradeskills, "Tradeskills" },
|
||||||
|
{ Bug::Category::SpellStacking, "Spell Stacking" },
|
||||||
|
{ Bug::Category::DoorsPortals, "Doors and Portals" },
|
||||||
|
{ Bug::Category::Items, "Items" },
|
||||||
|
{ Bug::Category::NPC, "NPC" },
|
||||||
|
{ Bug::Category::Dialogs, "Dialogs" },
|
||||||
|
{ Bug::Category::LoNTCG, "LoN - TCG" },
|
||||||
|
{ Bug::Category::Mercenaries, "Mercenaries" }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Stance {
|
||||||
|
constexpr uint32 Unknown = 0;
|
||||||
|
constexpr uint32 Passive = 1;
|
||||||
|
constexpr uint32 Balanced = 2;
|
||||||
|
constexpr uint32 Efficient = 3;
|
||||||
|
constexpr uint32 Reactive = 4;
|
||||||
|
constexpr uint32 Aggressive = 5;
|
||||||
|
constexpr uint32 Assist = 6;
|
||||||
|
constexpr uint32 Burn = 7;
|
||||||
|
constexpr uint32 Efficient2 = 8;
|
||||||
|
constexpr uint32 AEBurn = 9;
|
||||||
|
|
||||||
|
std::string GetName(uint8 stance_id);
|
||||||
|
uint8 GetIndex(uint8 stance_id);
|
||||||
|
bool IsValid(uint8 stance_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint32, std::string> stance_names = {
|
||||||
|
{ Stance::Unknown, "Unknown" },
|
||||||
|
{ Stance::Passive, "Passive" },
|
||||||
|
{ Stance::Balanced, "Balanced" },
|
||||||
|
{ Stance::Efficient, "Efficient" },
|
||||||
|
{ Stance::Reactive, "Reactive" },
|
||||||
|
{ Stance::Aggressive, "Aggressive" },
|
||||||
|
{ Stance::Assist, "Assist" },
|
||||||
|
{ Stance::Burn, "Burn" },
|
||||||
|
{ Stance::Efficient2, "Efficient" },
|
||||||
|
{ Stance::AEBurn, "AE Burn" }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace LDoNTheme {
|
||||||
|
constexpr uint32 Unused = 0;
|
||||||
|
constexpr uint32 GUK = 1;
|
||||||
|
constexpr uint32 MIR = 2;
|
||||||
|
constexpr uint32 MMC = 3;
|
||||||
|
constexpr uint32 RUJ = 4;
|
||||||
|
constexpr uint32 TAK = 5;
|
||||||
|
|
||||||
|
constexpr uint32 UnusedBit = 0;
|
||||||
|
constexpr uint32 GUKBit = 1;
|
||||||
|
constexpr uint32 MIRBit = 2;
|
||||||
|
constexpr uint32 MMCBit = 4;
|
||||||
|
constexpr uint32 RUJBit = 8;
|
||||||
|
constexpr uint32 TAKBit = 16;
|
||||||
|
|
||||||
|
uint32 GetBitmask(uint32 theme_id);
|
||||||
|
std::string GetName(uint32 theme_id);
|
||||||
|
bool IsValid(uint32 theme_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<uint32, std::pair<std::string, uint32>> ldon_theme_names = {
|
||||||
|
{ LDoNTheme::Unused, { "Unused", LDoNTheme::UnusedBit }, },
|
||||||
|
{ LDoNTheme::GUK, { "Deepest Guk", LDoNTheme::GUKBit }, },
|
||||||
|
{ LDoNTheme::MIR, { "Miragul's Menagerie", LDoNTheme::MIRBit }, },
|
||||||
|
{ LDoNTheme::MMC, { "Mistmoore Catacombs", LDoNTheme::MMCBit }, },
|
||||||
|
{ LDoNTheme::RUJ, { "Rujarkian Hills", LDoNTheme::RUJBit }, },
|
||||||
|
{ LDoNTheme::TAK, { "Takish-Hiz", LDoNTheme::TAKBit }, },
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PCNPCOnlyFlagType {
|
||||||
|
constexpr int PC = 1;
|
||||||
|
constexpr int NPC = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BookType {
|
||||||
|
constexpr uint8 Scroll = 0;
|
||||||
|
constexpr uint8 Book = 1;
|
||||||
|
constexpr uint8 ItemInfo = 2;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ N(OP_Buff),
|
|||||||
N(OP_BuffCreate),
|
N(OP_BuffCreate),
|
||||||
N(OP_BuffRemoveRequest),
|
N(OP_BuffRemoveRequest),
|
||||||
N(OP_Bug),
|
N(OP_Bug),
|
||||||
|
N(OP_BuyerItems),
|
||||||
N(OP_CameraEffect),
|
N(OP_CameraEffect),
|
||||||
N(OP_Camp),
|
N(OP_Camp),
|
||||||
N(OP_CancelSneakHide),
|
N(OP_CancelSneakHide),
|
||||||
@@ -76,6 +77,7 @@ N(OP_CashReward),
|
|||||||
N(OP_CastSpell),
|
N(OP_CastSpell),
|
||||||
N(OP_ChangeSize),
|
N(OP_ChangeSize),
|
||||||
N(OP_ChannelMessage),
|
N(OP_ChannelMessage),
|
||||||
|
N(OP_ChangePetName),
|
||||||
N(OP_CharacterCreate),
|
N(OP_CharacterCreate),
|
||||||
N(OP_CharacterCreateRequest),
|
N(OP_CharacterCreateRequest),
|
||||||
N(OP_CharInventory),
|
N(OP_CharInventory),
|
||||||
@@ -161,6 +163,7 @@ N(OP_EnduranceUpdate),
|
|||||||
N(OP_EnterChat),
|
N(OP_EnterChat),
|
||||||
N(OP_EnterWorld),
|
N(OP_EnterWorld),
|
||||||
N(OP_EnvDamage),
|
N(OP_EnvDamage),
|
||||||
|
N(OP_EvolveItem),
|
||||||
N(OP_ExpansionInfo),
|
N(OP_ExpansionInfo),
|
||||||
N(OP_ExpUpdate),
|
N(OP_ExpUpdate),
|
||||||
N(OP_FaceChange),
|
N(OP_FaceChange),
|
||||||
@@ -282,12 +285,15 @@ N(OP_InspectMessageUpdate),
|
|||||||
N(OP_InspectRequest),
|
N(OP_InspectRequest),
|
||||||
N(OP_InstillDoubt),
|
N(OP_InstillDoubt),
|
||||||
N(OP_InterruptCast),
|
N(OP_InterruptCast),
|
||||||
|
N(OP_InvokeChangePetName),
|
||||||
|
N(OP_InvokeChangePetNameImmediate),
|
||||||
N(OP_ItemLinkClick),
|
N(OP_ItemLinkClick),
|
||||||
N(OP_ItemLinkResponse),
|
N(OP_ItemLinkResponse),
|
||||||
N(OP_ItemLinkText),
|
N(OP_ItemLinkText),
|
||||||
N(OP_ItemName),
|
N(OP_ItemName),
|
||||||
N(OP_ItemPacket),
|
N(OP_ItemPacket),
|
||||||
N(OP_ItemPreview),
|
N(OP_ItemPreview),
|
||||||
|
N(OP_ItemPreviewRequest),
|
||||||
N(OP_ItemRecastDelay),
|
N(OP_ItemRecastDelay),
|
||||||
N(OP_ItemVerifyReply),
|
N(OP_ItemVerifyReply),
|
||||||
N(OP_ItemVerifyRequest),
|
N(OP_ItemVerifyRequest),
|
||||||
@@ -399,6 +405,8 @@ N(OP_PetitionSearchText),
|
|||||||
N(OP_PetitionUnCheckout),
|
N(OP_PetitionUnCheckout),
|
||||||
N(OP_PetitionUpdate),
|
N(OP_PetitionUpdate),
|
||||||
N(OP_PickPocket),
|
N(OP_PickPocket),
|
||||||
|
N(OP_PickZone),
|
||||||
|
N(OP_PickZoneWindow),
|
||||||
N(OP_PlayerProfile),
|
N(OP_PlayerProfile),
|
||||||
N(OP_PlayerStateAdd),
|
N(OP_PlayerStateAdd),
|
||||||
N(OP_PlayerStateRemove),
|
N(OP_PlayerStateRemove),
|
||||||
@@ -465,6 +473,7 @@ N(OP_SendAATable),
|
|||||||
N(OP_SendCharInfo),
|
N(OP_SendCharInfo),
|
||||||
N(OP_SendExpZonein),
|
N(OP_SendExpZonein),
|
||||||
N(OP_SendFindableNPCs),
|
N(OP_SendFindableNPCs),
|
||||||
|
N(OP_SendFindableLocations),
|
||||||
N(OP_SendGuildTributes),
|
N(OP_SendGuildTributes),
|
||||||
N(OP_SendLoginInfo),
|
N(OP_SendLoginInfo),
|
||||||
N(OP_SendMaxCharacters),
|
N(OP_SendMaxCharacters),
|
||||||
@@ -533,6 +542,7 @@ N(OP_Stamina),
|
|||||||
N(OP_Stun),
|
N(OP_Stun),
|
||||||
N(OP_Surname),
|
N(OP_Surname),
|
||||||
N(OP_SwapSpell),
|
N(OP_SwapSpell),
|
||||||
|
N(OP_SystemFingerprint),
|
||||||
N(OP_TargetBuffs),
|
N(OP_TargetBuffs),
|
||||||
N(OP_TargetCommand),
|
N(OP_TargetCommand),
|
||||||
N(OP_TargetHoTT),
|
N(OP_TargetHoTT),
|
||||||
@@ -557,6 +567,7 @@ N(OP_TradeBusy),
|
|||||||
N(OP_TradeCoins),
|
N(OP_TradeCoins),
|
||||||
N(OP_TradeMoneyUpdate),
|
N(OP_TradeMoneyUpdate),
|
||||||
N(OP_Trader),
|
N(OP_Trader),
|
||||||
|
N(OP_TraderBulkSend),
|
||||||
N(OP_TraderBuy),
|
N(OP_TraderBuy),
|
||||||
N(OP_TraderDelItem),
|
N(OP_TraderDelItem),
|
||||||
N(OP_TradeRequest),
|
N(OP_TradeRequest),
|
||||||
@@ -564,6 +575,7 @@ N(OP_TradeRequestAck),
|
|||||||
N(OP_TraderItemUpdate),
|
N(OP_TraderItemUpdate),
|
||||||
N(OP_TraderShop),
|
N(OP_TraderShop),
|
||||||
N(OP_TradeSkillCombine),
|
N(OP_TradeSkillCombine),
|
||||||
|
N(OP_TradeSkillRecipeInspect),
|
||||||
N(OP_Translocate),
|
N(OP_Translocate),
|
||||||
N(OP_TributeInfo),
|
N(OP_TributeInfo),
|
||||||
N(OP_TributeItem),
|
N(OP_TributeItem),
|
||||||
|
|||||||
+28
-62
@@ -758,10 +758,10 @@ typedef enum {
|
|||||||
FilterFocusEffects = 22, //0=show, 1=hide
|
FilterFocusEffects = 22, //0=show, 1=hide
|
||||||
FilterPetSpells = 23, //0=show, 1=hide
|
FilterPetSpells = 23, //0=show, 1=hide
|
||||||
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
||||||
FilterUnknown25 = 25,
|
FilterItemSpeech = 25, //0=show, 1=hide // RoF2 Confirmed
|
||||||
FilterUnknown26 = 26,
|
FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed
|
||||||
FilterUnknown27 = 27,
|
FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed
|
||||||
FilterUnknown28 = 28,
|
FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed
|
||||||
_FilterCount
|
_FilterCount
|
||||||
} eqFilterType;
|
} eqFilterType;
|
||||||
|
|
||||||
@@ -793,46 +793,26 @@ typedef enum {
|
|||||||
#define STAT_MANA_REGEN 18
|
#define STAT_MANA_REGEN 18
|
||||||
#define STAT_HASTE 19
|
#define STAT_HASTE 19
|
||||||
#define STAT_DAMAGE_SHIELD 20
|
#define STAT_DAMAGE_SHIELD 20
|
||||||
|
#define STAT_DS_MITIGATION 22
|
||||||
/*
|
#define STAT_HEAL_AMOUNT 23
|
||||||
** Recast timer types. Used as an off set to charProfileStruct timers.
|
#define STAT_SPELL_DAMAGE 24
|
||||||
**
|
#define STAT_CLAIRVOYANCE 25
|
||||||
** (Another orphaned enumeration...)
|
#define STAT_HEROIC_AGILITY 26
|
||||||
*/
|
#define STAT_HEROIC_CHARISMA 27
|
||||||
enum RecastTimerTypes
|
#define STAT_HEROIC_DEXTERITY 28
|
||||||
{
|
#define STAT_HEROIC_INTELLIGENCE 29
|
||||||
RecTimer_0 = 0,
|
#define STAT_HEROIC_STAMINA 30
|
||||||
RecTimer_1,
|
#define STAT_HEROIC_STRENGTH 31
|
||||||
RecTimer_WeaponHealClick, // 2
|
#define STAT_HEROIC_WISDOM 32
|
||||||
RecTimer_MuramiteBaneNukeClick, // 3
|
#define STAT_BASH 33
|
||||||
RecTimer_4,
|
#define STAT_BACKSTAB 34
|
||||||
RecTimer_DispellClick, // 5 (also click heal orbs?)
|
#define STAT_DRAGON_PUNCH 35
|
||||||
RecTimer_Epic, // 6
|
#define STAT_EAGLE_STRIKE 36
|
||||||
RecTimer_OoWBPClick, // 7
|
#define STAT_FLYING_KICK 37
|
||||||
RecTimer_VishQuestClassItem, // 8
|
#define STAT_KICK 38
|
||||||
RecTimer_HealPotion, // 9
|
#define STAT_ROUND_KICK 39
|
||||||
RecTimer_10,
|
#define STAT_TIGER_CLAW 40
|
||||||
RecTimer_11,
|
#define STAT_FRENZY 41
|
||||||
RecTimer_12,
|
|
||||||
RecTimer_13,
|
|
||||||
RecTimer_14,
|
|
||||||
RecTimer_15,
|
|
||||||
RecTimer_16,
|
|
||||||
RecTimer_17,
|
|
||||||
RecTimer_18,
|
|
||||||
RecTimer_ModRod, // 19
|
|
||||||
_RecTimerCount
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GroupUpdateAction
|
|
||||||
{
|
|
||||||
GUA_Joined = 0,
|
|
||||||
GUA_Left = 1,
|
|
||||||
GUA_LastLeft = 6,
|
|
||||||
GUA_FullGroupInfo = 7,
|
|
||||||
GUA_MakeLeader = 8,
|
|
||||||
GUA_Started = 9
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8 DamageTypeSomething = 0x1C; //0x1c is something...
|
static const uint8 DamageTypeSomething = 0x1C; //0x1c is something...
|
||||||
static const uint8 DamageTypeFalling = 0xFC;
|
static const uint8 DamageTypeFalling = 0xFC;
|
||||||
@@ -1013,24 +993,6 @@ enum class DynamicZoneMemberStatus : uint8_t
|
|||||||
LinkDead
|
LinkDead
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LDoNThemes {
|
|
||||||
Unused = 0,
|
|
||||||
GUK,
|
|
||||||
MIR,
|
|
||||||
MMC,
|
|
||||||
RUJ,
|
|
||||||
TAK
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LDoNThemeBits {
|
|
||||||
UnusedBit = 0,
|
|
||||||
GUKBit = 1,
|
|
||||||
MIRBit = 2,
|
|
||||||
MMCBit = 4,
|
|
||||||
RUJBit = 8,
|
|
||||||
TAKBit = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
enum StartZoneIndex {
|
enum StartZoneIndex {
|
||||||
Odus = 0,
|
Odus = 0,
|
||||||
Qeynos,
|
Qeynos,
|
||||||
@@ -1149,4 +1111,8 @@ enum ExpSource
|
|||||||
#define PARCEL_LIMIT 5
|
#define PARCEL_LIMIT 5
|
||||||
#define PARCEL_BEGIN_SLOT 1
|
#define PARCEL_BEGIN_SLOT 1
|
||||||
|
|
||||||
|
namespace DoorType {
|
||||||
|
constexpr uint32 BuyerStall = 155;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
+14
-6
@@ -47,6 +47,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
ClientUnknown::constants::EXPANSION_BIT,
|
ClientUnknown::constants::EXPANSION_BIT,
|
||||||
ClientUnknown::constants::EXPANSIONS_MASK,
|
ClientUnknown::constants::EXPANSIONS_MASK,
|
||||||
ClientUnknown::INULL,
|
ClientUnknown::INULL,
|
||||||
|
ClientUnknown::INULL,
|
||||||
ClientUnknown::INULL
|
ClientUnknown::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::Client62] =*/
|
/*[ClientVersion::Client62] =*/
|
||||||
@@ -55,6 +56,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
Client62::constants::EXPANSION_BIT,
|
Client62::constants::EXPANSION_BIT,
|
||||||
Client62::constants::EXPANSIONS_MASK,
|
Client62::constants::EXPANSIONS_MASK,
|
||||||
Client62::INULL,
|
Client62::INULL,
|
||||||
|
Client62::INULL,
|
||||||
Client62::INULL
|
Client62::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::Titanium] =*/
|
/*[ClientVersion::Titanium] =*/
|
||||||
@@ -63,7 +65,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
Titanium::constants::EXPANSION_BIT,
|
Titanium::constants::EXPANSION_BIT,
|
||||||
Titanium::constants::EXPANSIONS_MASK,
|
Titanium::constants::EXPANSIONS_MASK,
|
||||||
Titanium::constants::CHARACTER_CREATION_LIMIT,
|
Titanium::constants::CHARACTER_CREATION_LIMIT,
|
||||||
Titanium::constants::SAY_LINK_BODY_SIZE
|
Titanium::constants::SAY_LINK_BODY_SIZE,
|
||||||
|
Titanium::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::SoF] =*/
|
/*[ClientVersion::SoF] =*/
|
||||||
EQ::constants::LookupEntry(
|
EQ::constants::LookupEntry(
|
||||||
@@ -71,7 +74,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
SoF::constants::EXPANSION_BIT,
|
SoF::constants::EXPANSION_BIT,
|
||||||
SoF::constants::EXPANSIONS_MASK,
|
SoF::constants::EXPANSIONS_MASK,
|
||||||
SoF::constants::CHARACTER_CREATION_LIMIT,
|
SoF::constants::CHARACTER_CREATION_LIMIT,
|
||||||
SoF::constants::SAY_LINK_BODY_SIZE
|
SoF::constants::SAY_LINK_BODY_SIZE,
|
||||||
|
SoF::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::SoD] =*/
|
/*[ClientVersion::SoD] =*/
|
||||||
EQ::constants::LookupEntry(
|
EQ::constants::LookupEntry(
|
||||||
@@ -79,7 +83,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
SoD::constants::EXPANSION_BIT,
|
SoD::constants::EXPANSION_BIT,
|
||||||
SoD::constants::EXPANSIONS_MASK,
|
SoD::constants::EXPANSIONS_MASK,
|
||||||
SoD::constants::CHARACTER_CREATION_LIMIT,
|
SoD::constants::CHARACTER_CREATION_LIMIT,
|
||||||
SoD::constants::SAY_LINK_BODY_SIZE
|
SoD::constants::SAY_LINK_BODY_SIZE,
|
||||||
|
SoD::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::UF] =*/
|
/*[ClientVersion::UF] =*/
|
||||||
EQ::constants::LookupEntry(
|
EQ::constants::LookupEntry(
|
||||||
@@ -87,7 +92,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
UF::constants::EXPANSION_BIT,
|
UF::constants::EXPANSION_BIT,
|
||||||
UF::constants::EXPANSIONS_MASK,
|
UF::constants::EXPANSIONS_MASK,
|
||||||
UF::constants::CHARACTER_CREATION_LIMIT,
|
UF::constants::CHARACTER_CREATION_LIMIT,
|
||||||
UF::constants::SAY_LINK_BODY_SIZE
|
UF::constants::SAY_LINK_BODY_SIZE,
|
||||||
|
UF::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::RoF] =*/
|
/*[ClientVersion::RoF] =*/
|
||||||
EQ::constants::LookupEntry(
|
EQ::constants::LookupEntry(
|
||||||
@@ -95,7 +101,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
RoF::constants::EXPANSION_BIT,
|
RoF::constants::EXPANSION_BIT,
|
||||||
RoF::constants::EXPANSIONS_MASK,
|
RoF::constants::EXPANSIONS_MASK,
|
||||||
RoF::constants::CHARACTER_CREATION_LIMIT,
|
RoF::constants::CHARACTER_CREATION_LIMIT,
|
||||||
RoF::constants::SAY_LINK_BODY_SIZE
|
RoF::constants::SAY_LINK_BODY_SIZE,
|
||||||
|
RoF::INULL
|
||||||
),
|
),
|
||||||
/*[ClientVersion::RoF2] =*/
|
/*[ClientVersion::RoF2] =*/
|
||||||
EQ::constants::LookupEntry(
|
EQ::constants::LookupEntry(
|
||||||
@@ -103,7 +110,8 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
|||||||
RoF2::constants::EXPANSION_BIT,
|
RoF2::constants::EXPANSION_BIT,
|
||||||
RoF2::constants::EXPANSIONS_MASK,
|
RoF2::constants::EXPANSIONS_MASK,
|
||||||
RoF2::constants::CHARACTER_CREATION_LIMIT,
|
RoF2::constants::CHARACTER_CREATION_LIMIT,
|
||||||
RoF2::constants::SAY_LINK_BODY_SIZE
|
RoF2::constants::SAY_LINK_BODY_SIZE,
|
||||||
|
RoF2::constants::MAX_BAZAAR_TRADERS
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -42,6 +42,7 @@ namespace EQ
|
|||||||
uint32 ExpansionsMask;
|
uint32 ExpansionsMask;
|
||||||
int16 CharacterCreationLimit;
|
int16 CharacterCreationLimit;
|
||||||
size_t SayLinkBodySize;
|
size_t SayLinkBodySize;
|
||||||
|
uint32 BazaarTraderLimit;
|
||||||
|
|
||||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||||
LookupEntry(
|
LookupEntry(
|
||||||
@@ -49,13 +50,15 @@ namespace EQ
|
|||||||
uint32 ExpansionBit,
|
uint32 ExpansionBit,
|
||||||
uint32 ExpansionsMask,
|
uint32 ExpansionsMask,
|
||||||
int16 CharacterCreationLimit,
|
int16 CharacterCreationLimit,
|
||||||
size_t SayLinkBodySize
|
size_t SayLinkBodySize,
|
||||||
|
uint32 BazaarTraderLimit
|
||||||
) :
|
) :
|
||||||
Expansion(Expansion),
|
Expansion(Expansion),
|
||||||
ExpansionBit(ExpansionBit),
|
ExpansionBit(ExpansionBit),
|
||||||
ExpansionsMask(ExpansionsMask),
|
ExpansionsMask(ExpansionsMask),
|
||||||
CharacterCreationLimit(CharacterCreationLimit),
|
CharacterCreationLimit(CharacterCreationLimit),
|
||||||
SayLinkBodySize(SayLinkBodySize)
|
SayLinkBodySize(SayLinkBodySize),
|
||||||
|
BazaarTraderLimit(BazaarTraderLimit)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+653
-101
@@ -31,7 +31,6 @@
|
|||||||
#include "../cereal/include/cereal/types/string.hpp"
|
#include "../cereal/include/cereal/types/string.hpp"
|
||||||
#include "../cereal/include/cereal/types/vector.hpp"
|
#include "../cereal/include/cereal/types/vector.hpp"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 BUFF_COUNT = 42;
|
static const uint32 BUFF_COUNT = 42;
|
||||||
static const uint32 PET_BUFF_COUNT = 30;
|
static const uint32 PET_BUFF_COUNT = 30;
|
||||||
static const uint32 MAX_MERC = 100;
|
static const uint32 MAX_MERC = 100;
|
||||||
@@ -323,6 +322,8 @@ union
|
|||||||
bool targetable_with_hotkey;
|
bool targetable_with_hotkey;
|
||||||
bool show_name;
|
bool show_name;
|
||||||
bool guild_show;
|
bool guild_show;
|
||||||
|
bool trader;
|
||||||
|
bool buyer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerState_Struct {
|
struct PlayerState_Struct {
|
||||||
@@ -1119,7 +1120,7 @@ struct PlayerProfile_Struct
|
|||||||
/*19558*/ uint8 guildAutoconsent; // 0=off, 1=on
|
/*19558*/ uint8 guildAutoconsent; // 0=off, 1=on
|
||||||
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
|
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
|
||||||
/*19564*/ uint32 RestTimer;
|
/*19564*/ uint32 RestTimer;
|
||||||
/*19568*/
|
/*19568*/ uint32 char_id; // Found as part of bazaar revamp (5/15/2024)
|
||||||
|
|
||||||
// All player profile packets are translated and this overhead is ignored in out-bound packets
|
// All player profile packets are translated and this overhead is ignored in out-bound packets
|
||||||
PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { }
|
PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { }
|
||||||
@@ -1620,6 +1621,32 @@ struct MoveItem_Struct
|
|||||||
/*0012*/
|
/*0012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// New for RoF2 - Size: 12
|
||||||
|
struct InventorySlot_Struct
|
||||||
|
{
|
||||||
|
/*000*/ int16 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Delete Item = -1
|
||||||
|
/*002*/ int16 Unknown02;
|
||||||
|
/*004*/ int16 Slot;
|
||||||
|
/*006*/ int16 SubIndex;
|
||||||
|
/*008*/ int16 AugIndex; // Guessing - Seen 0xffff
|
||||||
|
/*010*/ int16 Unknown01; // Normally 0 - Seen 13262 when deleting an item, but didn't match item ID
|
||||||
|
/*012*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MultiMoveItemSub_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ InventorySlot_Struct from_slot;
|
||||||
|
/*0012*/ InventorySlot_Struct to_slot;
|
||||||
|
/*0024*/ uint32 number_in_stack;
|
||||||
|
/*0028*/ uint8 unknown[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MultiMoveItem_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ uint32 count;
|
||||||
|
/*0004*/ MultiMoveItemSub_Struct moves[0];
|
||||||
|
};
|
||||||
|
|
||||||
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
|
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
|
||||||
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
|
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
|
||||||
// info at the moment..but, it is forwarded on to the server for handling/future use)
|
// info at the moment..but, it is forwarded on to the server for handling/future use)
|
||||||
@@ -3032,31 +3059,41 @@ struct BazaarWindowStart_Struct {
|
|||||||
|
|
||||||
|
|
||||||
struct BazaarWelcome_Struct {
|
struct BazaarWelcome_Struct {
|
||||||
BazaarWindowStart_Struct Beginning;
|
uint32 action;
|
||||||
uint32 Traders;
|
uint32 traders;
|
||||||
uint32 Items;
|
uint32 items;
|
||||||
uint32 Unknown012;
|
uint32 unknown_012;
|
||||||
uint32 Unknown016;
|
uint32 unknown_016;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarSearch_Struct {
|
struct BazaarSearchCriteria_Struct {
|
||||||
BazaarWindowStart_Struct Beginning;
|
/*000*/ uint32 action{0};
|
||||||
uint32 TraderID;
|
/*004*/ uint32 search_scope{0}; // 1 all traders 0 local traders
|
||||||
uint32 Class_;
|
/*008*/ uint32 unknown_008{0};
|
||||||
uint32 Race;
|
/*012*/ uint32 unknown_012{0};
|
||||||
uint32 ItemStat;
|
/*016*/ uint32 trader_id{0};
|
||||||
uint32 Slot;
|
/*020*/ uint32 _class{0};
|
||||||
uint32 Type;
|
/*024*/ uint32 race{0};
|
||||||
char Name[64];
|
/*028*/ uint32 item_stat{0};
|
||||||
uint32 MinPrice;
|
/*032*/ uint32 slot{0};
|
||||||
uint32 MaxPrice;
|
/*036*/ uint32 type{0};
|
||||||
uint32 Minlevel;
|
/*040*/ char item_name[64]{""};
|
||||||
uint32 MaxLlevel;
|
/*104*/ uint32 min_cost{0};
|
||||||
|
/*108*/ uint32 max_cost{0};
|
||||||
|
/*112*/ uint32 min_level{1};
|
||||||
|
/*116*/ uint32 max_level{0};
|
||||||
|
/*120*/ uint32 max_results{0};
|
||||||
|
/*124*/ uint32 prestige{0};
|
||||||
|
/*128*/ uint32 augment{0};
|
||||||
|
/*132*/ uint32 trader_entity_id{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarInspect_Struct {
|
struct BazaarInspect_Struct {
|
||||||
uint32 ItemID;
|
uint32 action;
|
||||||
uint32 Unknown004;
|
char player_name[64];
|
||||||
char Name[64];
|
uint32 serial_number;
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 trader_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NewBazaarInspect_Struct {
|
struct NewBazaarInspect_Struct {
|
||||||
@@ -3076,6 +3113,14 @@ struct BazaarReturnDone_Struct{
|
|||||||
uint32 Unknown012;
|
uint32 Unknown012;
|
||||||
uint32 Unknown016;
|
uint32 Unknown016;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BazaarDeliveryCost_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint16 voucher_delivery_cost;
|
||||||
|
float parcel_deliver_cost; //percentage of item cost
|
||||||
|
uint32 unknown_010;
|
||||||
|
};
|
||||||
|
|
||||||
struct BazaarSearchResults_Struct {
|
struct BazaarSearchResults_Struct {
|
||||||
/*000*/ BazaarWindowStart_Struct Beginning;
|
/*000*/ BazaarWindowStart_Struct Beginning;
|
||||||
/*004*/ uint32 NumItems;
|
/*004*/ uint32 NumItems;
|
||||||
@@ -3088,16 +3133,21 @@ struct BazaarSearchResults_Struct {
|
|||||||
// New fields for SoD+, stripped off when encoding for older clients.
|
// New fields for SoD+, stripped off when encoding for older clients.
|
||||||
char SellerName[64];
|
char SellerName[64];
|
||||||
uint32 ItemID;
|
uint32 ItemID;
|
||||||
|
uint32 ItemID2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Barter/Buyer
|
// Barter/Buyer
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
enum {
|
#define MAX_BUYER_COMPENSATION_ITEMS 10
|
||||||
|
|
||||||
|
enum BarterBuyerActions {
|
||||||
Barter_BuyerSearch = 0,
|
Barter_BuyerSearch = 0,
|
||||||
Barter_SellerSearch = 1,
|
Barter_SellerSearch = 1,
|
||||||
Barter_BuyerModeOn = 2,
|
Barter_BuyerModeOn = 2,
|
||||||
Barter_BuyerModeOff = 3,
|
Barter_BuyerModeOff = 3,
|
||||||
|
Barter_BuyerItemStart = 4,
|
||||||
Barter_BuyerItemUpdate = 5,
|
Barter_BuyerItemUpdate = 5,
|
||||||
Barter_BuyerItemRemove = 6,
|
Barter_BuyerItemRemove = 6,
|
||||||
Barter_SellItem = 7,
|
Barter_SellItem = 7,
|
||||||
@@ -3112,41 +3162,348 @@ enum {
|
|||||||
Barter_BuyerSearchResults = 16,
|
Barter_BuyerSearchResults = 16,
|
||||||
Barter_Welcome = 17,
|
Barter_Welcome = 17,
|
||||||
Barter_WelcomeMessageUpdate = 19,
|
Barter_WelcomeMessageUpdate = 19,
|
||||||
|
Barter_Greeting = 20,
|
||||||
Barter_BuyerItemInspect = 21,
|
Barter_BuyerItemInspect = 21,
|
||||||
Barter_Unknown23 = 23
|
Barter_OpenBarterWindow = 23,
|
||||||
|
Barter_AddToBarterWindow = 26,
|
||||||
|
Barter_RemoveFromBarterWindow = 27,
|
||||||
|
Barter_RemoveFromMerchantWindow = 50, //Not a client item. Used for internal communications.
|
||||||
|
Barter_FailedTransaction = 51,
|
||||||
|
Barter_BuyerCouldNotBeFound = 52,
|
||||||
|
Barter_FailedBuyerChecks = 53,
|
||||||
|
Barter_SellerCouldNotBeFound = 54,
|
||||||
|
Barter_FailedSellerChecks = 55
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BarterBuyerSubActions {
|
||||||
|
Barter_Success = 0,
|
||||||
|
Barter_Failure = 1,
|
||||||
|
Barter_DataOutOfDate = 4,
|
||||||
|
Barter_SellerDoesNotHaveItem = 6,
|
||||||
|
Barter_SameZone = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BuyerBarter {
|
||||||
|
Off = 0,
|
||||||
|
On = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerRemoveItem_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 buy_slot_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerRemoveItemFromMerchantWindow_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
|
uint32 buy_slot_id;
|
||||||
|
uint32 unknown_012;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerGeneric_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char payload[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerMessaging_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 sub_action;
|
||||||
|
uint32 zone_id;
|
||||||
|
uint32 buyer_id;
|
||||||
|
uint32 buyer_entity_id;
|
||||||
|
char buyer_name[64];
|
||||||
|
uint32 buy_item_id;
|
||||||
|
uint32 buy_item_qty;
|
||||||
|
uint64 buy_item_cost;
|
||||||
|
uint32 buy_item_icon;
|
||||||
|
uint32 seller_entity_id;
|
||||||
|
char seller_name[64];
|
||||||
|
char item_name[64];
|
||||||
|
uint32 slot;
|
||||||
|
uint32 seller_quantity;
|
||||||
|
uint32 purchase_method; // 0 direct merchant, 1 via /barter window
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerAddBuyertoBarterWindow_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 zone_id;
|
||||||
|
uint32 buyer_id;
|
||||||
|
uint32 buyer_entity_id;
|
||||||
|
char buyer_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerRemoveBuyerFromBarterWindow_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 buyer_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerBrowsing_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char char_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerGreeting_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 buyer_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuyerWelcomeMessageUpdate_Struct {
|
struct BuyerWelcomeMessageUpdate_Struct {
|
||||||
/*000*/ uint32 Action;
|
uint32 action;
|
||||||
/*004*/ char WelcomeMessage[256];
|
char welcome_message[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuyerItemSearch_Struct {
|
struct BuyerLineTradeItems_Struct {
|
||||||
/*000*/ uint32 Unknown000;
|
uint32 item_id;
|
||||||
/*004*/ char SearchString[64];
|
uint32 item_quantity;
|
||||||
|
uint32 item_icon;
|
||||||
|
std::string item_name;
|
||||||
|
|
||||||
|
void operator*=(uint32 multiplier)
|
||||||
|
{
|
||||||
|
this->item_quantity *= multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_quantity),
|
||||||
|
CEREAL_NVP(item_icon),
|
||||||
|
CEREAL_NVP(item_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuyerItemSearchResultEntry_Struct {
|
struct BuyerLineItems_Struct {
|
||||||
/*000*/ char ItemName[64];
|
uint32 slot;
|
||||||
/*064*/ uint32 ItemID;
|
uint8 enabled;
|
||||||
/*068*/ uint32 Unknown068;
|
uint32 item_id;
|
||||||
/*072*/ uint32 Unknown072;
|
std::string item_name;
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 item_quantity;
|
||||||
|
uint8 item_toggle;
|
||||||
|
uint32 item_cost;
|
||||||
|
std::vector<BuyerLineTradeItems_Struct> trade_items;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(slot),
|
||||||
|
CEREAL_NVP(enabled),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(item_icon),
|
||||||
|
CEREAL_NVP(item_quantity),
|
||||||
|
CEREAL_NVP(item_toggle),
|
||||||
|
CEREAL_NVP(item_cost),
|
||||||
|
CEREAL_NVP(trade_items)
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_BUYER_ITEMSEARCH_RESULTS 200
|
struct BuyerBuyLines_Struct {
|
||||||
|
uint32 action;
|
||||||
|
union {
|
||||||
|
uint32 no_items;
|
||||||
|
uint32 string_length;
|
||||||
|
};
|
||||||
|
std::vector<BuyerLineItems_Struct> buy_lines;
|
||||||
|
|
||||||
struct BuyerItemSearchResults_Struct {
|
template<class Archive>
|
||||||
uint32 Action;
|
void serialize(Archive &archive)
|
||||||
uint32 ResultCount;
|
{
|
||||||
BuyerItemSearchResultEntry_Struct Results[MAX_BUYER_ITEMSEARCH_RESULTS];
|
archive(
|
||||||
|
CEREAL_NVP(action),
|
||||||
|
CEREAL_NVP(no_items),
|
||||||
|
CEREAL_NVP(buy_lines)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerLineSellItem_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 sub_action;
|
||||||
|
uint32 error_code;
|
||||||
|
uint32 purchase_method; // 0 direct merchant, 1 via /barter window
|
||||||
|
uint32 buyer_entity_id;
|
||||||
|
uint32 buyer_id;
|
||||||
|
std::string buyer_name;
|
||||||
|
uint32 seller_entity_id;
|
||||||
|
std::string seller_name;
|
||||||
|
uint32 slot;
|
||||||
|
uint8 enabled;
|
||||||
|
uint32 item_id;
|
||||||
|
char item_name[64];
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 item_quantity;
|
||||||
|
uint8 item_toggle;
|
||||||
|
uint32 item_cost;
|
||||||
|
uint32 no_trade_items;
|
||||||
|
std::vector<BuyerLineTradeItems_Struct> trade_items;
|
||||||
|
uint32 seller_quantity;
|
||||||
|
uint32 zone_id;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(action),
|
||||||
|
CEREAL_NVP(sub_action),
|
||||||
|
CEREAL_NVP(error_code),
|
||||||
|
CEREAL_NVP(purchase_method),
|
||||||
|
CEREAL_NVP(buyer_entity_id),
|
||||||
|
CEREAL_NVP(buyer_id),
|
||||||
|
CEREAL_NVP(buyer_name),
|
||||||
|
CEREAL_NVP(seller_entity_id),
|
||||||
|
CEREAL_NVP(seller_name),
|
||||||
|
CEREAL_NVP(slot),
|
||||||
|
CEREAL_NVP(enabled),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(item_icon),
|
||||||
|
CEREAL_NVP(item_quantity),
|
||||||
|
CEREAL_NVP(item_toggle),
|
||||||
|
CEREAL_NVP(item_cost),
|
||||||
|
CEREAL_NVP(no_trade_items),
|
||||||
|
CEREAL_NVP(trade_items),
|
||||||
|
CEREAL_NVP(seller_quantity),
|
||||||
|
CEREAL_NVP(zone_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerLineItemsSearch_Struct {
|
||||||
|
uint32 slot;
|
||||||
|
uint8 enabled;
|
||||||
|
uint32 item_id;
|
||||||
|
char item_name[64];
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 item_quantity;
|
||||||
|
uint8 item_toggle;
|
||||||
|
uint32 item_cost;
|
||||||
|
uint32 buyer_id;
|
||||||
|
uint32 buyer_entity_id;
|
||||||
|
uint32 buyer_zone_id;
|
||||||
|
uint32 buyer_zone_instance_id;
|
||||||
|
std::string buyer_name;
|
||||||
|
std::vector<BuyerLineTradeItems_Struct> trade_items;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(slot),
|
||||||
|
CEREAL_NVP(enabled),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(item_icon),
|
||||||
|
CEREAL_NVP(item_quantity),
|
||||||
|
CEREAL_NVP(item_toggle),
|
||||||
|
CEREAL_NVP(item_cost),
|
||||||
|
CEREAL_NVP(buyer_id),
|
||||||
|
CEREAL_NVP(buyer_entity_id),
|
||||||
|
CEREAL_NVP(buyer_zone_id),
|
||||||
|
CEREAL_NVP(buyer_zone_instance_id),
|
||||||
|
CEREAL_NVP(buyer_name),
|
||||||
|
CEREAL_NVP(trade_items)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerLineSearch_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 no_items;
|
||||||
|
std::string search_string;
|
||||||
|
uint32 transaction_id;
|
||||||
|
std::vector<BuyerLineItemsSearch_Struct> buy_line;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(action),
|
||||||
|
CEREAL_NVP(no_items),
|
||||||
|
CEREAL_NVP(search_string),
|
||||||
|
CEREAL_NVP(transaction_id),
|
||||||
|
CEREAL_NVP(buy_line)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerSetAppearance_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 entity_id;
|
||||||
|
uint32 status; // 0 off 1 on
|
||||||
|
char buyer_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BarterItemSearchLinkRequest_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 searcher_id;
|
||||||
|
uint32 unknown_008;
|
||||||
|
uint32 unknown_012;
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 unknown_020;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerInspectRequest_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 buyer_id;
|
||||||
|
uint32 approval;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BarterSearchRequest_Struct {
|
struct BarterSearchRequest_Struct {
|
||||||
uint32 Action;
|
uint32 action;
|
||||||
char SearchString[64];
|
char search_string[64];
|
||||||
uint32 SearchID;
|
uint32 transaction_id;
|
||||||
|
uint32 unknown_072;
|
||||||
|
uint32 buyer_id;
|
||||||
|
uint8 search_scope; //0 All Buyers, 1 Local Buyers
|
||||||
|
uint16 zone_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BuyerItemSearch_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char search_string[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerItemSearchResultEntry_Struct {
|
||||||
|
char item_name[64];
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 unknown_072;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_icon),
|
||||||
|
CEREAL_NVP(unknown_072)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerItemSearchResults_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 result_count;
|
||||||
|
std::vector<BuyerItemSearchResultEntry_Struct> results;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(action),
|
||||||
|
CEREAL_NVP(result_count),
|
||||||
|
CEREAL_NVP(results)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//old below here
|
||||||
struct BuyerItemSearchLinkRequest_Struct {
|
struct BuyerItemSearchLinkRequest_Struct {
|
||||||
/*000*/ uint32 Action; // 0x00000015
|
/*000*/ uint32 Action; // 0x00000015
|
||||||
/*004*/ uint32 ItemID;
|
/*004*/ uint32 ItemID;
|
||||||
@@ -3154,31 +3511,6 @@ struct BuyerItemSearchLinkRequest_Struct {
|
|||||||
/*012*/ uint32 Unknown012;
|
/*012*/ uint32 Unknown012;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BarterItemSearchLinkRequest_Struct {
|
|
||||||
/*000*/ uint32 Action; // 0x0000000E
|
|
||||||
/*004*/ uint32 SearcherID;
|
|
||||||
/*008*/ uint32 Unknown008;
|
|
||||||
/*012*/ uint32 Unknown012;
|
|
||||||
/*016*/ uint32 ItemID;
|
|
||||||
/*020*/ uint32 Unknown020;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BuyerInspectRequest_Struct {
|
|
||||||
uint32 Action;
|
|
||||||
uint32 BuyerID;
|
|
||||||
uint32 Approval;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BuyerBrowsing_Struct {
|
|
||||||
uint32 Action;
|
|
||||||
char PlayerName[64];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BuyerRemoveItem_Struct {
|
|
||||||
uint32 Action;
|
|
||||||
uint32 BuySlot;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ServerSideFilters_Struct {
|
struct ServerSideFilters_Struct {
|
||||||
uint8 clientattackfilters; // 0) No, 1) All (players) but self, 2) All (players) but group
|
uint8 clientattackfilters; // 0) No, 1) All (players) but self, 2) All (players) but group
|
||||||
uint8 npcattackfilters; // 0) No, 1) Ignore NPC misses (all), 2) Ignore NPC Misses + Attacks (all but self), 3) Ignores NPC Misses + Attacks (all but group)
|
uint8 npcattackfilters; // 0) No, 1) Ignore NPC misses (all), 2) Ignore NPC Misses + Attacks (all but self), 3) Ignores NPC Misses + Attacks (all but group)
|
||||||
@@ -3389,32 +3721,32 @@ struct WhoAllReturnStruct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_Struct {
|
struct Trader_Struct {
|
||||||
/*000*/ uint32 Code;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Unknown004;
|
/*004*/ uint32 unknown_004;
|
||||||
/*008*/ uint64 Items[80];
|
/*008*/ uint64 items[EQ::invtype::BAZAAR_SIZE];
|
||||||
/*648*/ uint32 ItemCost[80];
|
/*648*/ uint32 item_cost[EQ::invtype::BAZAAR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClickTrader_Struct {
|
struct ClickTrader_Struct {
|
||||||
/*000*/ uint32 Code;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Unknown004;
|
/*004*/ uint32 unknown_004;
|
||||||
/*008*/ int64 SerialNumber[80];
|
/*008*/ int64 serial_number[EQ::invtype::BAZAAR_SIZE] {};
|
||||||
/*648*/ uint32 ItemCost[80];
|
/*648*/ uint32 item_cost[EQ::invtype::BAZAAR_SIZE] {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GetItems_Struct{
|
struct GetItems_Struct{
|
||||||
uint32 Items[80];
|
uint32 items[EQ::invtype::BAZAAR_SIZE];
|
||||||
int32 SerialNumber[80];
|
int32 serial_number[EQ::invtype::BAZAAR_SIZE];
|
||||||
int32 Charges[80];
|
int32 charges[EQ::invtype::BAZAAR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BecomeTrader_Struct
|
struct BecomeTrader_Struct {
|
||||||
{
|
uint32 action;
|
||||||
/*000*/ uint32 ID;
|
uint16 zone_id;
|
||||||
/*004*/ uint32 Code;
|
uint16 zone_instance_id;
|
||||||
/*008*/ char Name[64];
|
uint32 trader_id;
|
||||||
/*072*/ uint32 Unknown072; // Observed 0x33,0x91 etc on zone-in, 0x00 when sent for a new trader after zone-in
|
uint32 entity_id;
|
||||||
/*076*/
|
char trader_name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderStatus_Struct{
|
struct TraderStatus_Struct{
|
||||||
@@ -3424,20 +3756,30 @@ struct TraderStatus_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_ShowItems_Struct{
|
struct Trader_ShowItems_Struct{
|
||||||
/*000*/ uint32 Code;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 TraderID;
|
/*004*/ uint32 entity_id;
|
||||||
/*008*/ uint32 Unknown08[3];
|
/*008*/ uint32 Unknown08[3];
|
||||||
/*020*/
|
/*020*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 TraderID;
|
/*004*/ uint32 method;
|
||||||
/*008*/ uint32 ItemID;
|
/*008*/ uint32 sub_action;
|
||||||
/*012*/ uint32 AlreadySold;
|
/*012*/ uint32 unknown_012;
|
||||||
/*016*/ uint32 Price;
|
/*016*/ uint32 trader_id;
|
||||||
/*020*/ uint32 Quantity;
|
/*020*/ char buyer_name[64];
|
||||||
/*024*/ char ItemName[64];
|
/*084*/ char seller_name[64];
|
||||||
|
/*148*/ char unknown_148[32];
|
||||||
|
/*180*/ char item_name[64];
|
||||||
|
/*244*/ char serial_number[17];
|
||||||
|
/*261*/ char unknown_261[3];
|
||||||
|
/*264*/ uint32 item_id;
|
||||||
|
/*268*/ uint32 price;
|
||||||
|
/*272*/ uint32 already_sold;
|
||||||
|
/*276*/ uint32 unknown_276;
|
||||||
|
/*280*/ uint32 quantity;
|
||||||
|
/*284*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderItemUpdate_Struct{
|
struct TraderItemUpdate_Struct{
|
||||||
@@ -3465,15 +3807,15 @@ struct MoneyUpdate_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderDelItem_Struct{
|
struct TraderDelItem_Struct{
|
||||||
uint32 Unknown000;
|
uint32 unknown_000;
|
||||||
uint32 TraderID;
|
uint32 trader_id;
|
||||||
uint32 ItemID;
|
uint32 item_id;
|
||||||
uint32 Unknown012;
|
uint32 unknown_012;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderClick_Struct{
|
struct TraderClick_Struct{
|
||||||
/*000*/ uint32 TraderID;
|
/*000*/ uint32 Code;
|
||||||
/*004*/ uint32 Code;
|
/*004*/ uint32 TraderID;
|
||||||
/*008*/ uint32 Unknown008;
|
/*008*/ uint32 Unknown008;
|
||||||
/*012*/ uint32 Approval;
|
/*012*/ uint32 Approval;
|
||||||
/*016*/
|
/*016*/
|
||||||
@@ -3941,6 +4283,10 @@ struct NewCombine_Struct {
|
|||||||
/*04*/
|
/*04*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TradeSkillRecipeInspect_Struct {
|
||||||
|
uint32 recipe_id;
|
||||||
|
uint32 padding[17]; // unknown
|
||||||
|
};
|
||||||
|
|
||||||
//client requesting favorite recipies
|
//client requesting favorite recipies
|
||||||
struct TradeskillFavorites_Struct {
|
struct TradeskillFavorites_Struct {
|
||||||
@@ -5477,6 +5823,21 @@ struct ChangeSize_Struct
|
|||||||
/*16*/
|
/*16*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChangePetName_Struct {
|
||||||
|
/*00*/ char new_pet_name[64];
|
||||||
|
/*40*/ char pet_owner_name[64];
|
||||||
|
/*80*/ int response_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChangePetNameResponse : int {
|
||||||
|
Denied = 0, // 5167 You have requested an invalid name or a Customer Service Representative has denied your name request. Please try another name.
|
||||||
|
Accepted = 1, // 5976 Your request for a name change was successful.
|
||||||
|
Timeout = -3, // 5979 You must wait longer before submitting another name request. Please try again in a few minutes.
|
||||||
|
NotEligible = -4, // 5980 Your character is not eligible for a name change.
|
||||||
|
Pending = -5, // 5193 You already have a name change pending. Please wait until it is fully processed before attempting another name change.
|
||||||
|
Unhandled = -1
|
||||||
|
};
|
||||||
|
|
||||||
// New OpCode/Struct for SoD+
|
// New OpCode/Struct for SoD+
|
||||||
struct GroupMakeLeader_Struct
|
struct GroupMakeLeader_Struct
|
||||||
{
|
{
|
||||||
@@ -5991,6 +6352,197 @@ struct UnderWorld {
|
|||||||
/* 16 */
|
/* 16 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BazaarTraderBarterActions {
|
||||||
|
TraderOff = 0,
|
||||||
|
TraderOn = 1,
|
||||||
|
PriceUpdate = 3,
|
||||||
|
EndTransaction = 4,
|
||||||
|
BazaarSearch = 7,
|
||||||
|
WelcomeMessage = 9,
|
||||||
|
BuyTraderItem = 10,
|
||||||
|
ListTraderItems = 11,
|
||||||
|
CustomerBrowsing = 13,
|
||||||
|
BazaarInspect = 18,
|
||||||
|
ItemMove = 19,
|
||||||
|
TraderAck2 = 22,
|
||||||
|
AddTraderToBazaarWindow = 24,
|
||||||
|
RemoveTraderFromBazaarWindow = 25,
|
||||||
|
FirstOpenSearch = 26,
|
||||||
|
ClickTrader = 28,
|
||||||
|
DeliveryCostUpdate = 29
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BazaarPurchaseActions {
|
||||||
|
BazaarByVendor = 0,
|
||||||
|
BazaarByParcel = 1,
|
||||||
|
BazaarByDirectToInventory = 2,
|
||||||
|
BarterByVendor = 0,
|
||||||
|
BarterInBazaar = 1,
|
||||||
|
BarterOutsideBazaar = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BazaarPurchaseSubActions {
|
||||||
|
Success = 0,
|
||||||
|
Failed = 1,
|
||||||
|
DataOutDated = 3,
|
||||||
|
TooManyParcels = 5,
|
||||||
|
TransactionInProgress = 6,
|
||||||
|
InsufficientFunds = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BazaarSearchScopes {
|
||||||
|
Local_Scope = 0,
|
||||||
|
AllTraders_Scope = 1,
|
||||||
|
NonRoFBazaarSearchScope = 99
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BazaarSearchResultsFromDB_Struct {
|
||||||
|
uint32 count;
|
||||||
|
uint32 trader_id;
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 serial_number;
|
||||||
|
uint32 charges;
|
||||||
|
uint32 cost;
|
||||||
|
uint32 slot_id;
|
||||||
|
uint32 icon_id;
|
||||||
|
uint32 sum_charges;
|
||||||
|
uint32 trader_zone_id;
|
||||||
|
int32 trader_zone_instance_id;
|
||||||
|
uint32 trader_entity_id;
|
||||||
|
uint32 item_stat;
|
||||||
|
bool stackable;
|
||||||
|
std::string item_name;
|
||||||
|
std::string serial_number_RoF;
|
||||||
|
std::string trader_name;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(count),
|
||||||
|
CEREAL_NVP(trader_id),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(serial_number),
|
||||||
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(cost),
|
||||||
|
CEREAL_NVP(slot_id),
|
||||||
|
CEREAL_NVP(icon_id),
|
||||||
|
CEREAL_NVP(sum_charges),
|
||||||
|
CEREAL_NVP(trader_zone_id),
|
||||||
|
CEREAL_NVP(trader_zone_instance_id),
|
||||||
|
CEREAL_NVP(trader_entity_id),
|
||||||
|
CEREAL_NVP(item_stat),
|
||||||
|
CEREAL_NVP(stackable),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(serial_number_RoF),
|
||||||
|
CEREAL_NVP(trader_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BazaarSearchMessaging_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char payload[];
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(action),
|
||||||
|
CEREAL_NVP(payload)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuylineItemDetails_Struct {
|
||||||
|
uint64 item_cost;
|
||||||
|
uint32 item_quantity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PickZoneEntry_Struct {
|
||||||
|
int16 zone_id;
|
||||||
|
int16 unknown;
|
||||||
|
int32 player_count;
|
||||||
|
int32 instance_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PickZoneWindow_Struct {
|
||||||
|
char padding000[64];
|
||||||
|
int64 session_id;
|
||||||
|
int8 option_count;
|
||||||
|
char padding073[23];
|
||||||
|
PickZoneEntry_Struct entries[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PickZone_Struct {
|
||||||
|
int64 session_id;
|
||||||
|
int32 selection_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveItemToggle {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
|
uint64 unique_id;
|
||||||
|
uint32 percentage;
|
||||||
|
uint32 activated;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveXPWindowReceive {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
|
uint64 item1_unique_id;
|
||||||
|
uint64 item2_unique_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveItemMessaging {
|
||||||
|
uint32 action;
|
||||||
|
char serialized_data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveXPWindowSend {
|
||||||
|
/*000*/ uint32 action;
|
||||||
|
/*004*/ uint64 item1_unique_id;
|
||||||
|
/*012*/ uint64 item2_unique_id;
|
||||||
|
/*020*/ uint32 compatibility;
|
||||||
|
/*024*/ uint32 max_transfer_level;
|
||||||
|
/*028*/ uint8 item1_present;
|
||||||
|
/*029*/ uint8 item2_present;
|
||||||
|
/*030*/ std::string serialize_item_1;
|
||||||
|
/*034*/ std::string serialize_item_2;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(action),
|
||||||
|
CEREAL_NVP(item1_unique_id),
|
||||||
|
CEREAL_NVP(item2_unique_id),
|
||||||
|
CEREAL_NVP(compatibility),
|
||||||
|
CEREAL_NVP(max_transfer_level),
|
||||||
|
CEREAL_NVP(item1_present),
|
||||||
|
CEREAL_NVP(item2_present),
|
||||||
|
CEREAL_NVP(serialize_item_1),
|
||||||
|
CEREAL_NVP(serialize_item_2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveTransfer {
|
||||||
|
uint32 item_from_id;
|
||||||
|
uint32 item_from_current_amount;
|
||||||
|
uint32 item_to_id;
|
||||||
|
uint32 item_to_current_amount;
|
||||||
|
uint32 compatibility;
|
||||||
|
uint32 max_transfer_level;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveGetNextItem {
|
||||||
|
uint32 new_item_id;
|
||||||
|
uint64 new_current_amount;
|
||||||
|
uint64 from_current_amount;
|
||||||
|
uint32 max_transfer_level;
|
||||||
|
};
|
||||||
|
|
||||||
// Restore structure packing to default
|
// Restore structure packing to default
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ void EQEmuConfig::parse_config()
|
|||||||
auto_database_updates = true;
|
auto_database_updates = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
WorldIP = _root["server"]["world"]["tcp"].get("ip", "127.0.0.1").asString();
|
||||||
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
||||||
|
|
||||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||||
@@ -147,6 +147,8 @@ void EQEmuConfig::parse_config()
|
|||||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||||
|
QSHost = _root["server"]["queryserver"].get("host", "localhost").asString();
|
||||||
|
QSPort = Strings::ToUnsignedInt(_root["server"]["queryserver"].get("port", "9500").asString());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zones
|
* Zones
|
||||||
@@ -171,6 +173,7 @@ void EQEmuConfig::parse_config()
|
|||||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||||
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
||||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||||
|
OpcodeDir = _root["server"]["directories"].get("opcodes", "./").asString();
|
||||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ class EQEmuConfig
|
|||||||
std::string QSDatabasePassword;
|
std::string QSDatabasePassword;
|
||||||
std::string QSDatabaseDB;
|
std::string QSDatabaseDB;
|
||||||
uint16 QSDatabasePort;
|
uint16 QSDatabasePort;
|
||||||
|
std::string QSHost;
|
||||||
|
int QSPort;
|
||||||
|
|
||||||
// From <files/>
|
// From <files/>
|
||||||
std::string SpellsFile;
|
std::string SpellsFile;
|
||||||
@@ -95,6 +97,7 @@ class EQEmuConfig
|
|||||||
std::string PluginDir;
|
std::string PluginDir;
|
||||||
std::string LuaModuleDir;
|
std::string LuaModuleDir;
|
||||||
std::string PatchDir;
|
std::string PatchDir;
|
||||||
|
std::string OpcodeDir;
|
||||||
std::string SharedMemDir;
|
std::string SharedMemDir;
|
||||||
std::string LogDir;
|
std::string LogDir;
|
||||||
|
|
||||||
@@ -136,9 +139,9 @@ class EQEmuConfig
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual ~EQEmuConfig() {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~EQEmuConfig() {}
|
||||||
|
|
||||||
// Produce a const singleton
|
// Produce a const singleton
|
||||||
static const EQEmuConfig *get()
|
static const EQEmuConfig *get()
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include "repositories/discord_webhooks_repository.h"
|
#include "repositories/discord_webhooks_repository.h"
|
||||||
#include "repositories/logsys_categories_repository.h"
|
#include "repositories/logsys_categories_repository.h"
|
||||||
#include "termcolor/rang.hpp"
|
#include "termcolor/rang.hpp"
|
||||||
|
#include "path_manager.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -85,6 +87,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
* Set Defaults
|
* Set Defaults
|
||||||
*/
|
*/
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
@@ -102,6 +105,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
log_settings[Logs::QuestErrors].log_to_console = 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_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::NpcHandin].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::NpcHandin].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RFC 5424
|
* RFC 5424
|
||||||
@@ -532,6 +537,11 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
{
|
{
|
||||||
EQEmuLogSys::CloseFileLogs();
|
EQEmuLogSys::CloseFileLogs();
|
||||||
|
|
||||||
|
if (!File::Exists(path.GetLogPath())) {
|
||||||
|
LogInfo("Logs directory not found, creating [{}]", path.GetLogPath());
|
||||||
|
File::Makedir(path.GetLogPath());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
|
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
|
||||||
*/
|
*/
|
||||||
@@ -591,6 +601,8 @@ void EQEmuLogSys::SilenceConsoleLogging()
|
|||||||
log_settings[log_index].is_category_enabled = 0;
|
log_settings[log_index].is_category_enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::MySQLError);
|
||||||
|
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::Error);
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -142,6 +142,13 @@ namespace Logs {
|
|||||||
EqTime,
|
EqTime,
|
||||||
Corpses,
|
Corpses,
|
||||||
XTargets,
|
XTargets,
|
||||||
|
EvolveItem,
|
||||||
|
PositionUpdate,
|
||||||
|
KSM,
|
||||||
|
BotSettings,
|
||||||
|
BotSpellChecks,
|
||||||
|
BotSpellTypeChecks,
|
||||||
|
NpcHandin,
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -242,7 +249,14 @@ namespace Logs {
|
|||||||
"Zoning",
|
"Zoning",
|
||||||
"EqTime",
|
"EqTime",
|
||||||
"Corpses",
|
"Corpses",
|
||||||
"XTargets"
|
"XTargets",
|
||||||
|
"EvolveItem",
|
||||||
|
"PositionUpdate",
|
||||||
|
"KSM", // Kernel Samepage Merging
|
||||||
|
"Bot Settings",
|
||||||
|
"Bot Spell Checks",
|
||||||
|
"Bot Spell Type Checks",
|
||||||
|
"NpcHandin"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,16 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogEvolveItem(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::EvolveItem))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::EvolveItem, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogEvolveItemDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EvolveItem))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::EvolveItem, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define LogGuilds(message, ...) do {\
|
#define LogGuilds(message, ...) do {\
|
||||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Guilds))\
|
if (LogSys.IsLogEnabled(Logs::General, Logs::Guilds))\
|
||||||
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
@@ -844,6 +854,66 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogPositionUpdate(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::PositionUpdate))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::PositionUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogPositionUpdateDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PositionUpdate))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::PositionUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogKSM(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::KSM))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::KSM, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogKSMDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::KSM))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::KSM, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogBotSettings(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSettings))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::BotSettings, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogBotSettingsDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSettings))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::BotSettings, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogBotSpellChecks(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSpellChecks))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::BotSpellChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogBotSpellChecksDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSpellChecks))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::BotSpellChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogBotSpellTypeChecks(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSpellTypeChecks))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::BotSpellTypeChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogBotSpellTypeChecksDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSpellTypeChecks))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::BotSpellTypeChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogNpcHandin(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::NpcHandin))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::NpcHandin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogNpcHandinDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::NpcHandin))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::NpcHandin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
|||||||
@@ -714,6 +714,18 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
|||||||
h.charges > 1 ? fmt::format(" Charges: {}", h.charges) : "",
|
h.charges > 1 ? fmt::format(" Charges: {}", h.charges) : "",
|
||||||
h.attuned ? " (Attuned)" : ""
|
h.attuned ? " (Attuned)" : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (int i = 0; i < h.augment_ids.size(); i++) {
|
||||||
|
if (!Strings::EqualFold(h.augment_names[i], "None")) {
|
||||||
|
const uint8 slot_id = (i + 1);
|
||||||
|
handin_items_info += fmt::format(
|
||||||
|
"Augment {}: {} ({})\n",
|
||||||
|
slot_id,
|
||||||
|
h.augment_names[i],
|
||||||
|
h.augment_ids[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,6 +739,18 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
|||||||
r.charges > 1 ? fmt::format(" Charges: {}", r.charges) : "",
|
r.charges > 1 ? fmt::format(" Charges: {}", r.charges) : "",
|
||||||
r.attuned ? " (Attuned)" : ""
|
r.attuned ? " (Attuned)" : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (int i = 0; i < r.augment_ids.size(); i++) {
|
||||||
|
if (!Strings::EqualFold(r.augment_names[i], "None")) {
|
||||||
|
const uint8 slot_id = (i + 1);
|
||||||
|
return_items_info += fmt::format(
|
||||||
|
"Augment {}: {} ({})\n",
|
||||||
|
slot_id,
|
||||||
|
r.augment_names[i],
|
||||||
|
r.augment_ids[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -789,50 +813,36 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string npc_info = fmt::format(
|
||||||
|
"{} ({})\n",
|
||||||
|
e.npc_name,
|
||||||
|
e.npc_id
|
||||||
|
);
|
||||||
|
|
||||||
|
npc_info += fmt::format(
|
||||||
|
"Is Quest Handin: {}",
|
||||||
|
e.is_quest_handin ? "Yes" : "No"
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<DiscordField> f = {};
|
std::vector<DiscordField> f = {};
|
||||||
|
|
||||||
|
|
||||||
|
BuildDiscordField(&f, "NPC", npc_info);
|
||||||
|
|
||||||
if (!handin_items_info.empty()) {
|
if (!handin_items_info.empty()) {
|
||||||
BuildDiscordField(
|
BuildDiscordField(&f, "Handin Items", handin_items_info);
|
||||||
&f,
|
|
||||||
"Handin Items",
|
|
||||||
fmt::format(
|
|
||||||
"{}",
|
|
||||||
handin_items_info
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handin_money_info.empty()) {
|
if (!handin_money_info.empty()) {
|
||||||
BuildDiscordField(
|
BuildDiscordField(&f, "Handin Money", handin_money_info);
|
||||||
&f,
|
|
||||||
"Handin Money",
|
|
||||||
fmt::format(
|
|
||||||
"{}",
|
|
||||||
handin_money_info
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!return_items_info.empty()) {
|
if (!return_items_info.empty()) {
|
||||||
BuildDiscordField(
|
BuildDiscordField(&f, "Return Items", return_items_info);
|
||||||
&f,
|
|
||||||
"Return Items",
|
|
||||||
fmt::format(
|
|
||||||
"{}",
|
|
||||||
return_items_info
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!return_money_info.empty()) {
|
if (!return_money_info.empty()) {
|
||||||
BuildDiscordField(
|
BuildDiscordField(&f, "Return Money", return_money_info);
|
||||||
&f,
|
|
||||||
"Return Money",
|
|
||||||
fmt::format(
|
|
||||||
"{}",
|
|
||||||
return_money_info
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DiscordEmbed> embeds = {};
|
std::vector<DiscordEmbed> embeds = {};
|
||||||
@@ -1071,51 +1081,51 @@ std::string PlayerEventDiscordFormatter::FormatTradeEvent(
|
|||||||
if (!e.character_1_give_items.empty()) {
|
if (!e.character_1_give_items.empty()) {
|
||||||
for (const auto &i: e.character_1_give_items) {
|
for (const auto &i: e.character_1_give_items) {
|
||||||
std::string augment_info;
|
std::string augment_info;
|
||||||
if (i.aug_1_item_id > 0) {
|
if (i.augment_1_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 1: {} ({})",
|
"Augment 1: {} ({})",
|
||||||
i.aug_1_item_name,
|
i.augment_1_name,
|
||||||
i.aug_1_item_id
|
i.augment_1_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_2_item_id > 0) {
|
if (i.augment_2_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 2: {} ({})",
|
"Augment 2: {} ({})",
|
||||||
i.aug_2_item_name,
|
i.augment_2_name,
|
||||||
i.aug_2_item_id
|
i.augment_2_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_3_item_id > 0) {
|
if (i.augment_3_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 3: {} ({})",
|
"Augment 3: {} ({})",
|
||||||
i.aug_3_item_name,
|
i.augment_3_name,
|
||||||
i.aug_3_item_id
|
i.augment_3_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_4_item_id > 0) {
|
if (i.augment_4_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 4: {} ({})\n",
|
"Augment 4: {} ({})\n",
|
||||||
i.aug_4_item_name,
|
i.augment_4_name,
|
||||||
i.aug_4_item_id
|
i.augment_4_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_5_item_id > 0) {
|
if (i.augment_5_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 5: {} ({})\n",
|
"Augment 5: {} ({})\n",
|
||||||
i.aug_5_item_name,
|
i.augment_5_name,
|
||||||
i.aug_5_item_id
|
i.augment_5_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_6_item_id > 0) {
|
if (i.augment_6_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 6: {} ({})",
|
"Augment 6: {} ({})",
|
||||||
i.aug_6_item_name,
|
i.augment_6_name,
|
||||||
i.aug_6_item_id
|
i.augment_6_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1136,51 +1146,51 @@ std::string PlayerEventDiscordFormatter::FormatTradeEvent(
|
|||||||
if (!e.character_2_give_items.empty()) {
|
if (!e.character_2_give_items.empty()) {
|
||||||
for (const auto &i: e.character_2_give_items) {
|
for (const auto &i: e.character_2_give_items) {
|
||||||
std::string augment_info;
|
std::string augment_info;
|
||||||
if (i.aug_1_item_id > 0) {
|
if (i.augment_1_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 1: {} ({})",
|
"Augment 1: {} ({})",
|
||||||
i.aug_1_item_name,
|
i.augment_1_name,
|
||||||
i.aug_1_item_id
|
i.augment_1_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_2_item_id > 0) {
|
if (i.augment_2_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 2: {} ({})",
|
"Augment 2: {} ({})",
|
||||||
i.aug_2_item_name,
|
i.augment_2_name,
|
||||||
i.aug_2_item_id
|
i.augment_2_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_3_item_id > 0) {
|
if (i.augment_3_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 3: {} ({})",
|
"Augment 3: {} ({})",
|
||||||
i.aug_3_item_name,
|
i.augment_3_name,
|
||||||
i.aug_3_item_id
|
i.augment_3_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_4_item_id > 0) {
|
if (i.augment_4_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 4: {} ({})\n",
|
"Augment 4: {} ({})\n",
|
||||||
i.aug_4_item_name,
|
i.augment_4_name,
|
||||||
i.aug_4_item_id
|
i.augment_4_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_5_item_id > 0) {
|
if (i.augment_5_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 5: {} ({})\n",
|
"Augment 5: {} ({})\n",
|
||||||
i.aug_5_item_name,
|
i.augment_5_name,
|
||||||
i.aug_5_item_id
|
i.augment_5_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.aug_6_item_id > 0) {
|
if (i.augment_6_id > 0) {
|
||||||
augment_info += fmt::format(
|
augment_info += fmt::format(
|
||||||
"Augment 6: {} ({})",
|
"Augment 6: {} ({})",
|
||||||
i.aug_6_item_name,
|
i.augment_6_name,
|
||||||
i.aug_6_item_id
|
i.augment_6_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include "player_event_logs.h"
|
#include "player_event_logs.h"
|
||||||
#include "player_event_discord_formatter.h"
|
#include <cereal/archives/json.hpp>
|
||||||
|
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
|
#include "player_event_discord_formatter.h"
|
||||||
|
#include "../repositories/player_event_loot_items_repository.h"
|
||||||
|
#include "../repositories/player_event_merchant_sell_repository.h"
|
||||||
|
#include "../repositories/player_event_merchant_purchase_repository.h"
|
||||||
|
#include "../repositories/player_event_npc_handin_repository.h"
|
||||||
|
#include "../repositories/player_event_npc_handin_entries_repository.h"
|
||||||
|
|
||||||
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
||||||
|
|
||||||
// general initialization routine
|
// general initialization routine
|
||||||
void PlayerEventLogs::Init()
|
void PlayerEventLogs::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
||||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
||||||
|
|
||||||
@@ -21,6 +28,7 @@ void PlayerEventLogs::Init()
|
|||||||
m_settings[i].event_enabled = 1;
|
m_settings[i].event_enabled = 1;
|
||||||
m_settings[i].retention_days = 0;
|
m_settings[i].retention_days = 0;
|
||||||
m_settings[i].discord_webhook_id = 0;
|
m_settings[i].discord_webhook_id = 0;
|
||||||
|
m_settings[i].etl_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSettingsDefaults();
|
SetSettingsDefaults();
|
||||||
@@ -65,6 +73,7 @@ void PlayerEventLogs::Init()
|
|||||||
c.event_name = PlayerEvent::EventName[i];
|
c.event_name = PlayerEvent::EventName[i];
|
||||||
c.event_enabled = m_settings[i].event_enabled;
|
c.event_enabled = m_settings[i].event_enabled;
|
||||||
c.retention_days = m_settings[i].retention_days;
|
c.retention_days = m_settings[i].retention_days;
|
||||||
|
c.etl_enabled = false;
|
||||||
settings_to_insert.emplace_back(c);
|
settings_to_insert.emplace_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,6 +82,8 @@ void PlayerEventLogs::Init()
|
|||||||
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
|
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoadEtlIds();
|
||||||
|
|
||||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||||
|
|
||||||
@@ -121,23 +132,319 @@ void PlayerEventLogs::ProcessBatchQueue()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::map<uint32, uint32> counter{};
|
||||||
|
counter.clear();
|
||||||
|
for (auto const &e: m_record_batch_queue) {
|
||||||
|
counter[e.event_type_id]++;
|
||||||
|
}
|
||||||
|
|
||||||
BenchTimer benchmark;
|
BenchTimer benchmark;
|
||||||
|
|
||||||
|
EtlQueues etl_queues{};
|
||||||
|
for (const auto &[type, count]: counter) {
|
||||||
|
if (count > 0) {
|
||||||
|
switch (type) {
|
||||||
|
case PlayerEvent::TRADE:
|
||||||
|
etl_queues.trade.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::SPEECH:
|
||||||
|
etl_queues.speech.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::LOOT_ITEM:
|
||||||
|
etl_queues.loot_items.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::KILLED_NPC:
|
||||||
|
etl_queues.killed_npc.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::NPC_HANDIN:
|
||||||
|
etl_queues.npc_handin.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::AA_PURCHASE:
|
||||||
|
etl_queues.aa_purchase.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::MERCHANT_SELL:
|
||||||
|
etl_queues.merchant_sell.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::KILLED_RAID_NPC:
|
||||||
|
etl_queues.killed_raid_npc.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::KILLED_NAMED_NPC:
|
||||||
|
etl_queues.killed_named_npc.reserve(count);
|
||||||
|
break;
|
||||||
|
case PlayerEvent::MERCHANT_PURCHASE:
|
||||||
|
etl_queues.merchant_purchase.reserve(count);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to deserialize event data
|
||||||
|
auto Deserialize = [](const std::string &data, auto &out) {
|
||||||
|
std::stringstream ss(data);
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
out.serialize(ar);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to assign ETL table ID
|
||||||
|
auto AssignEtlId = [&](
|
||||||
|
PlayerEventLogsRepository::PlayerEventLogs &r,
|
||||||
|
PlayerEvent::EventType type
|
||||||
|
) {
|
||||||
|
if (m_etl_settings.contains(type)) {
|
||||||
|
r.etl_table_id = m_etl_settings.at(type).next_id++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define event processors
|
||||||
|
std::unordered_map<PlayerEvent::EventType, std::function<void(PlayerEventLogsRepository::PlayerEventLogs &)>> event_processors = {
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::LOOT_ITEM, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::LootItemEvent in{};
|
||||||
|
PlayerEventLootItemsRepository::PlayerEventLootItems out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.charges = in.charges;
|
||||||
|
out.corpse_name = in.corpse_name;
|
||||||
|
out.item_id = in.item_id;
|
||||||
|
out.item_name = in.item_name;
|
||||||
|
out.augment_1_id = in.augment_1_id;
|
||||||
|
out.augment_2_id = in.augment_2_id;
|
||||||
|
out.augment_3_id = in.augment_3_id;
|
||||||
|
out.augment_4_id = in.augment_4_id;
|
||||||
|
out.augment_5_id = in.augment_5_id;
|
||||||
|
out.augment_6_id = in.augment_6_id;
|
||||||
|
out.npc_id = in.npc_id;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::LOOT_ITEM);
|
||||||
|
etl_queues.loot_items.push_back(out);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::MERCHANT_SELL, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::MerchantSellEvent in{};
|
||||||
|
PlayerEventMerchantSellRepository::PlayerEventMerchantSell out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.npc_id = in.npc_id;
|
||||||
|
out.merchant_name = in.merchant_name;
|
||||||
|
out.merchant_type = in.merchant_type;
|
||||||
|
out.item_id = in.item_id;
|
||||||
|
out.item_name = in.item_name;
|
||||||
|
out.charges = in.charges;
|
||||||
|
out.cost = in.cost;
|
||||||
|
out.alternate_currency_id = in.alternate_currency_id;
|
||||||
|
out.player_money_balance = in.player_money_balance;
|
||||||
|
out.player_currency_balance = in.player_currency_balance;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::MERCHANT_SELL);
|
||||||
|
etl_queues.merchant_sell.push_back(out);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::MERCHANT_PURCHASE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::MerchantPurchaseEvent in{};
|
||||||
|
PlayerEventMerchantPurchaseRepository::PlayerEventMerchantPurchase out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.npc_id = in.npc_id;
|
||||||
|
out.merchant_name = in.merchant_name;
|
||||||
|
out.merchant_type = in.merchant_type;
|
||||||
|
out.item_id = in.item_id;
|
||||||
|
out.item_name = in.item_name;
|
||||||
|
out.charges = in.charges;
|
||||||
|
out.cost = in.cost;
|
||||||
|
out.alternate_currency_id = in.alternate_currency_id;
|
||||||
|
out.player_money_balance = in.player_money_balance;
|
||||||
|
out.player_currency_balance = in.player_currency_balance;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::MERCHANT_PURCHASE);
|
||||||
|
etl_queues.merchant_purchase.push_back(out);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::NPC_HANDIN, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::HandinEvent in{};
|
||||||
|
PlayerEventNpcHandinRepository::PlayerEventNpcHandin out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.npc_id = in.npc_id;
|
||||||
|
out.npc_name = in.npc_name;
|
||||||
|
out.handin_copper = in.handin_money.copper;
|
||||||
|
out.handin_silver = in.handin_money.silver;
|
||||||
|
out.handin_gold = in.handin_money.gold;
|
||||||
|
out.handin_platinum = in.handin_money.platinum;
|
||||||
|
out.return_copper = in.return_money.copper;
|
||||||
|
out.return_silver = in.return_money.silver;
|
||||||
|
out.return_gold = in.return_money.gold;
|
||||||
|
out.return_platinum = in.return_money.platinum;
|
||||||
|
out.is_quest_handin = in.is_quest_handin;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::NPC_HANDIN);
|
||||||
|
etl_queues.npc_handin.push_back(out);
|
||||||
|
|
||||||
|
for (const auto &i: in.handin_items) {
|
||||||
|
PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries entry{};
|
||||||
|
entry.player_event_npc_handin_id = r.etl_table_id;
|
||||||
|
entry.item_id = i.item_id;
|
||||||
|
entry.charges = i.charges;
|
||||||
|
entry.type = 1;
|
||||||
|
etl_queues.npc_handin_entries.push_back(entry);
|
||||||
|
}
|
||||||
|
for (const auto &i: in.return_items) {
|
||||||
|
PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries entry{};
|
||||||
|
entry.player_event_npc_handin_id = r.etl_table_id;
|
||||||
|
entry.item_id = i.item_id;
|
||||||
|
entry.charges = i.charges;
|
||||||
|
entry.type = 2;
|
||||||
|
etl_queues.npc_handin_entries.push_back(entry);
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::TRADE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::TradeEvent in{};
|
||||||
|
PlayerEventTradeRepository::PlayerEventTrade out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.char1_id = in.character_1_id;
|
||||||
|
out.char2_id = in.character_2_id;
|
||||||
|
out.char1_copper = in.character_1_give_money.copper;
|
||||||
|
out.char1_silver = in.character_1_give_money.silver;
|
||||||
|
out.char1_gold = in.character_1_give_money.gold;
|
||||||
|
out.char1_platinum = in.character_1_give_money.platinum;
|
||||||
|
out.char2_copper = in.character_2_give_money.copper;
|
||||||
|
out.char2_silver = in.character_2_give_money.silver;
|
||||||
|
out.char2_gold = in.character_2_give_money.gold;
|
||||||
|
out.char2_platinum = in.character_2_give_money.platinum;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::TRADE);
|
||||||
|
etl_queues.trade.push_back(out);
|
||||||
|
|
||||||
|
for (const auto &i: in.character_1_give_items) {
|
||||||
|
PlayerEventTradeEntriesRepository::PlayerEventTradeEntries entry{};
|
||||||
|
entry.player_event_trade_id = r.etl_table_id;
|
||||||
|
entry.char_id = in.character_1_id;
|
||||||
|
entry.item_id = i.item_id;
|
||||||
|
entry.charges = i.charges;
|
||||||
|
entry.slot = i.slot;
|
||||||
|
etl_queues.trade_entries.push_back(entry);
|
||||||
|
}
|
||||||
|
for (const auto &i: in.character_2_give_items) {
|
||||||
|
PlayerEventTradeEntriesRepository::PlayerEventTradeEntries entry{};
|
||||||
|
entry.player_event_trade_id = r.etl_table_id;
|
||||||
|
entry.char_id = in.character_2_id;
|
||||||
|
entry.item_id = i.item_id;
|
||||||
|
entry.charges = i.charges;
|
||||||
|
entry.slot = i.slot;
|
||||||
|
etl_queues.trade_entries.push_back(entry);
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::SPEECH, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::PlayerSpeech in{};
|
||||||
|
PlayerEventSpeechRepository::PlayerEventSpeech out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.from_char_id = in.from;
|
||||||
|
out.to_char_id = in.to;
|
||||||
|
out.type = in.type;
|
||||||
|
out.min_status = in.min_status;
|
||||||
|
out.message = in.message;
|
||||||
|
out.guild_id = in.guild_id;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::SPEECH);
|
||||||
|
etl_queues.speech.push_back(out);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::KILLED_NPC, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::KilledNPCEvent in{};
|
||||||
|
PlayerEventKilledNpcRepository::PlayerEventKilledNpc out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.npc_id = in.npc_id;
|
||||||
|
out.npc_name = in.npc_name;
|
||||||
|
out.combat_time_seconds = in.combat_time_seconds;
|
||||||
|
out.total_damage_per_second_taken = in.total_damage_per_second_taken;
|
||||||
|
out.total_heal_per_second_taken = in.total_heal_per_second_taken;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::KILLED_NPC);
|
||||||
|
etl_queues.killed_npc.push_back(out);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::EventType::AA_PURCHASE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||||
|
PlayerEvent::AAPurchasedEvent in{};
|
||||||
|
PlayerEventAaPurchaseRepository::PlayerEventAaPurchase out{};
|
||||||
|
Deserialize(r.event_data, in);
|
||||||
|
|
||||||
|
out.aa_ability_id = in.aa_id;
|
||||||
|
out.cost = in.aa_cost;
|
||||||
|
out.previous_id = in.aa_previous_id;
|
||||||
|
out.next_id = in.aa_next_id;
|
||||||
|
out.created_at = r.created_at;
|
||||||
|
|
||||||
|
AssignEtlId(r, PlayerEvent::EventType::AA_PURCHASE);
|
||||||
|
etl_queues.aa_purchase.push_back(out);
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process the batch queue
|
||||||
|
for (auto &r: m_record_batch_queue) {
|
||||||
|
if (m_settings[r.event_type_id].etl_enabled) {
|
||||||
|
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
|
||||||
|
if (it != event_processors.end()) {
|
||||||
|
it->second(r); // Call the appropriate lambda
|
||||||
|
r.event_data = "{}"; // Clear event data
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogError("Non-Implemented ETL routing [{}]", r.event_type_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to flush and clear queues
|
||||||
|
auto flush_queue = [&](auto insert_many, auto &queue) {
|
||||||
|
if (!queue.empty()) {
|
||||||
|
insert_many(*m_database, queue);
|
||||||
|
queue.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// flush many
|
// flush many
|
||||||
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
||||||
LogPlayerEventsDetail(
|
|
||||||
|
// flush etl queues
|
||||||
|
flush_queue(PlayerEventLootItemsRepository::InsertMany, etl_queues.loot_items);
|
||||||
|
flush_queue(PlayerEventMerchantSellRepository::InsertMany, etl_queues.merchant_sell);
|
||||||
|
flush_queue(PlayerEventMerchantPurchaseRepository::InsertMany, etl_queues.merchant_purchase);
|
||||||
|
flush_queue(PlayerEventNpcHandinRepository::InsertMany, etl_queues.npc_handin);
|
||||||
|
flush_queue(PlayerEventNpcHandinEntriesRepository::InsertMany, etl_queues.npc_handin_entries);
|
||||||
|
flush_queue(PlayerEventTradeRepository::InsertMany, etl_queues.trade);
|
||||||
|
flush_queue(PlayerEventTradeEntriesRepository::InsertMany, etl_queues.trade_entries);
|
||||||
|
flush_queue(PlayerEventSpeechRepository::InsertMany, etl_queues.speech);
|
||||||
|
flush_queue(PlayerEventKilledNpcRepository::InsertMany, etl_queues.killed_npc);
|
||||||
|
flush_queue(PlayerEventKilledNamedNpcRepository::InsertMany, etl_queues.killed_named_npc);
|
||||||
|
flush_queue(PlayerEventKilledRaidNpcRepository::InsertMany, etl_queues.killed_raid_npc);
|
||||||
|
flush_queue(PlayerEventAaPurchaseRepository::InsertMany, etl_queues.aa_purchase);
|
||||||
|
|
||||||
|
LogPlayerEvents(
|
||||||
"Processing batch player event log queue of [{}] took [{}]",
|
"Processing batch player event log queue of [{}] took [{}]",
|
||||||
m_record_batch_queue.size(),
|
m_record_batch_queue.size(),
|
||||||
benchmark.elapsed()
|
benchmark.elapsed()
|
||||||
);
|
);
|
||||||
|
|
||||||
// empty
|
// empty
|
||||||
m_record_batch_queue = {};
|
m_record_batch_queue.clear();
|
||||||
m_batch_queue_lock.unlock();
|
m_batch_queue_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds a player event to the queue
|
// adds a player event to the queue
|
||||||
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
void PlayerEventLogs::AddToQueue(PlayerEventLogsRepository::PlayerEventLogs &log)
|
||||||
{
|
{
|
||||||
m_batch_queue_lock.lock();
|
m_batch_queue_lock.lock();
|
||||||
m_record_batch_queue.emplace_back(log);
|
m_record_batch_queue.emplace_back(log);
|
||||||
@@ -588,7 +895,7 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
LogInfo(
|
LogPlayerEventsDetail(
|
||||||
"Player event [{}] ({}) Discord formatter not implemented",
|
"Player event [{}] ({}) Discord formatter not implemented",
|
||||||
e.player_event_log.event_type_name,
|
e.player_event_log.event_type_name,
|
||||||
e.player_event_log.event_type_id
|
e.player_event_log.event_type_id
|
||||||
@@ -602,7 +909,8 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
|||||||
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
||||||
void PlayerEventLogs::Process()
|
void PlayerEventLogs::Process()
|
||||||
{
|
{
|
||||||
if (m_process_batch_events_timer.Check() || m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
if (m_process_batch_events_timer.Check() ||
|
||||||
|
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
||||||
ProcessBatchQueue();
|
ProcessBatchQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,35 +921,125 @@ void PlayerEventLogs::Process()
|
|||||||
|
|
||||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||||
{
|
{
|
||||||
LogPlayerEvents("Running truncation");
|
LogPlayerEventsDetail("Running truncation");
|
||||||
|
|
||||||
|
// Map of repository-specific deletion functions
|
||||||
|
std::unordered_map<PlayerEvent::EventType, std::function<uint32(const std::string &)>> repository_deleters = {
|
||||||
|
{
|
||||||
|
PlayerEvent::LOOT_ITEM, [&](const std::string &condition) {
|
||||||
|
return PlayerEventLootItemsRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::MERCHANT_SELL, [&](const std::string &condition) {
|
||||||
|
return PlayerEventMerchantSellRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::MERCHANT_PURCHASE, [&](const std::string &condition) {
|
||||||
|
return PlayerEventMerchantPurchaseRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::NPC_HANDIN, [&](const std::string &condition) {
|
||||||
|
uint32 deleted_count = PlayerEventNpcHandinRepository::DeleteWhere(*m_database, condition);
|
||||||
|
deleted_count += PlayerEventNpcHandinEntriesRepository::DeleteWhere(*m_database, condition);
|
||||||
|
return deleted_count;
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::TRADE, [&](const std::string &condition) {
|
||||||
|
uint32 deleted_count = PlayerEventTradeRepository::DeleteWhere(*m_database, condition);
|
||||||
|
deleted_count += PlayerEventTradeEntriesRepository::DeleteWhere(*m_database, condition);
|
||||||
|
return deleted_count;
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::SPEECH, [&](const std::string &condition) {
|
||||||
|
return PlayerEventSpeechRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::KILLED_NPC, [&](const std::string &condition) {
|
||||||
|
return PlayerEventKilledNpcRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::KILLED_NAMED_NPC, [&](const std::string &condition) {
|
||||||
|
return PlayerEventKilledNamedNpcRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::KILLED_RAID_NPC, [&](const std::string &condition) {
|
||||||
|
return PlayerEventKilledRaidNpcRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}},
|
||||||
|
{
|
||||||
|
PlayerEvent::AA_PURCHASE, [&](const std::string &condition) {
|
||||||
|
return PlayerEventAaPurchaseRepository::DeleteWhere(*m_database, condition);
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Group event types by retention interval
|
||||||
|
std::unordered_map<int, std::vector<int>> retention_groups;
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
if (m_settings[i].retention_days > 0) {
|
if (m_settings[i].retention_days > 0) {
|
||||||
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
retention_groups[m_settings[i].retention_days].push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &[retention_days, event_types]: retention_groups) {
|
||||||
|
std::string condition = fmt::format(
|
||||||
|
"created_at < (NOW() - INTERVAL {} DAY)",
|
||||||
|
retention_days
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle ETL deletions for each event type in the group
|
||||||
|
uint32 total_deleted_count = 0;
|
||||||
|
for (int event_type_id: event_types) {
|
||||||
|
if (m_settings[event_type_id].etl_enabled) {
|
||||||
|
auto it = repository_deleters.find(static_cast<PlayerEvent::EventType>(m_settings[event_type_id].id));
|
||||||
|
if (it != repository_deleters.end()) {
|
||||||
|
total_deleted_count += it->second(condition);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogError("Non-Implemented ETL Event Type [{}]", static_cast<uint32>(m_settings[event_type_id].id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_deleted_count > 0) {
|
||||||
|
LogInfo(
|
||||||
|
"Truncated [{}] ETL events older than [{}] days",
|
||||||
|
total_deleted_count,
|
||||||
|
retention_days
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Batch deletion for player_event_logs
|
||||||
|
std::string event_type_ids = fmt::format(
|
||||||
|
"({})",
|
||||||
|
fmt::join(event_types, ", ")
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32 deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
||||||
*m_database,
|
*m_database,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
|
"event_type_id IN {} AND {}",
|
||||||
i,
|
event_type_ids,
|
||||||
m_settings[i].retention_days
|
condition
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (deleted_count > 0) {
|
if (deleted_count > 0) {
|
||||||
LogInfo(
|
LogInfo(
|
||||||
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
|
"Truncated [{}] events of types [{}] older than [{}] days",
|
||||||
deleted_count,
|
deleted_count,
|
||||||
PlayerEvent::EventName[i],
|
event_type_ids,
|
||||||
i,
|
retention_days
|
||||||
m_settings[i].retention_days
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerEventLogs::ReloadSettings()
|
void PlayerEventLogs::ReloadSettings()
|
||||||
{
|
{
|
||||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
||||||
|
if (e.id >= PlayerEvent::MAX || e.id < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
m_settings[e.id] = e;
|
m_settings[e.id] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -702,8 +1100,145 @@ void PlayerEventLogs::SetSettingsDefaults()
|
|||||||
m_settings[PlayerEvent::PARCEL_SEND].event_enabled = 1;
|
m_settings[PlayerEvent::PARCEL_SEND].event_enabled = 1;
|
||||||
m_settings[PlayerEvent::PARCEL_RETRIEVE].event_enabled = 1;
|
m_settings[PlayerEvent::PARCEL_RETRIEVE].event_enabled = 1;
|
||||||
m_settings[PlayerEvent::PARCEL_DELETE].event_enabled = 1;
|
m_settings[PlayerEvent::PARCEL_DELETE].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::BARTER_TRANSACTION].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::EVOLVE_ITEM].event_enabled = 1;
|
||||||
|
m_settings[PlayerEvent::SPEECH].event_enabled = 0;
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerEventLogs::LoadEtlIds()
|
||||||
|
{
|
||||||
|
auto e = [&](auto p) -> bool {
|
||||||
|
for (PlayerEventLogSettingsRepository::PlayerEventLogSettings const &c: m_settings) {
|
||||||
|
if (c.id == p) {
|
||||||
|
return c.etl_enabled ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
m_etl_settings.clear();
|
||||||
|
m_etl_settings = {
|
||||||
|
{
|
||||||
|
PlayerEvent::LOOT_ITEM,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::LOOT_ITEM),
|
||||||
|
.table_name = "player_event_loot_items",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventLootItemsRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::MERCHANT_SELL,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::MERCHANT_SELL),
|
||||||
|
.table_name = "player_event_merchant_sell",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventMerchantSellRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::MERCHANT_PURCHASE,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::MERCHANT_PURCHASE),
|
||||||
|
.table_name = "player_event_merchant_purchase",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventMerchantPurchaseRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::NPC_HANDIN,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::NPC_HANDIN),
|
||||||
|
.table_name = "player_event_npc_handin",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventNpcHandinRepository::TableName()))
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::TRADE,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::TRADE),
|
||||||
|
.table_name = "player_event_trade",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventTradeRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::SPEECH,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::SPEECH),
|
||||||
|
.table_name = "player_event_speech",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventSpeechRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::KILLED_NPC,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::KILLED_NPC),
|
||||||
|
.table_name = "player_event_killed_npc",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledNpcRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::KILLED_NAMED_NPC,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::KILLED_NAMED_NPC),
|
||||||
|
.table_name = "player_event_killed_named_npc",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledNamedNpcRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::KILLED_RAID_NPC,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::KILLED_RAID_NPC),
|
||||||
|
.table_name = "player_event_killed_raid_npc",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledRaidNpcRepository::TableName()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlayerEvent::AA_PURCHASE,
|
||||||
|
{
|
||||||
|
.enabled = e(PlayerEvent::AA_PURCHASE),
|
||||||
|
.table_name = "player_event_aa_purchase",
|
||||||
|
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventAaPurchaseRepository::TableName()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &e: m_etl_settings) {
|
||||||
|
LogPlayerEventsDetail(
|
||||||
|
"ETL Settings [{}] Enabled [{}] Table [{}] NextId [{}]",
|
||||||
|
PlayerEvent::EventName[e.first],
|
||||||
|
e.second.enabled,
|
||||||
|
e.second.table_name,
|
||||||
|
e.second.next_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerEventLogs::LoadDatabaseConnection()
|
||||||
|
{
|
||||||
|
const auto c = EQEmuConfig::get();
|
||||||
|
|
||||||
|
LogInfo(
|
||||||
|
"Connecting to MySQL for PlayerEvents [{}]@[{}]:[{}]",
|
||||||
|
c->DatabaseUsername.c_str(),
|
||||||
|
c->DatabaseHost.c_str(),
|
||||||
|
c->DatabasePort
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!player_event_database.Connect(
|
||||||
|
c->DatabaseHost.c_str(),
|
||||||
|
c->DatabaseUsername.c_str(),
|
||||||
|
c->DatabasePassword.c_str(),
|
||||||
|
c->DatabaseDB.c_str(),
|
||||||
|
c->DatabasePort
|
||||||
|
)) {
|
||||||
|
LogError("Cannot continue without a database connection for player events.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDatabase(&player_event_database);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,19 +1,38 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
||||||
#define EQEMU_PLAYER_EVENT_LOGS_H
|
#define EQEMU_PLAYER_EVENT_LOGS_H
|
||||||
|
|
||||||
#include "../repositories/player_event_log_settings_repository.h"
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../servertalk.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../timer.h"
|
|
||||||
#include "../json/json_archive_single_line.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
#include <cereal/archives/json.hpp>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "../json/json_archive_single_line.h"
|
||||||
|
#include "../servertalk.h"
|
||||||
|
#include "../timer.h"
|
||||||
|
#include "../eqemu_config.h"
|
||||||
|
|
||||||
|
#include "../repositories/player_event_log_settings_repository.h"
|
||||||
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
|
#include "../repositories/player_event_loot_items_repository.h"
|
||||||
|
#include "../repositories/player_event_merchant_purchase_repository.h"
|
||||||
|
#include "../repositories/player_event_merchant_sell_repository.h"
|
||||||
|
#include "../repositories/player_event_npc_handin_repository.h"
|
||||||
|
#include "../repositories/player_event_npc_handin_entries_repository.h"
|
||||||
|
#include "../repositories/player_event_trade_repository.h"
|
||||||
|
#include "../repositories/player_event_trade_entries_repository.h"
|
||||||
|
#include "../repositories/player_event_speech_repository.h"
|
||||||
|
#include "../repositories/player_event_killed_npc_repository.h"
|
||||||
|
#include "../repositories/player_event_killed_named_npc_repository.h"
|
||||||
|
#include "../repositories/player_event_killed_raid_npc_repository.h"
|
||||||
|
#include "../repositories/player_event_aa_purchase_repository.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PlayerEventLogs {
|
class PlayerEventLogs {
|
||||||
public:
|
public:
|
||||||
|
Database player_event_database{};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
bool LoadDatabaseConnection();
|
||||||
void ReloadSettings();
|
void ReloadSettings();
|
||||||
|
void LoadEtlIds();
|
||||||
PlayerEventLogs *SetDatabase(Database *db);
|
PlayerEventLogs *SetDatabase(Database *db);
|
||||||
bool ValidateDatabaseConnection();
|
bool ValidateDatabaseConnection();
|
||||||
bool IsEventEnabled(PlayerEvent::EventType event);
|
bool IsEventEnabled(PlayerEvent::EventType event);
|
||||||
@@ -21,7 +40,7 @@ public:
|
|||||||
void Process();
|
void Process();
|
||||||
|
|
||||||
// batch queue
|
// batch queue
|
||||||
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
void AddToQueue(PlayerEventLogsRepository::PlayerEventLogs &logs);
|
||||||
|
|
||||||
// main event record generic function
|
// main event record generic function
|
||||||
// can ingest any struct event types
|
// can ingest any struct event types
|
||||||
@@ -59,7 +78,29 @@ public:
|
|||||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
||||||
|
|
||||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
||||||
|
|
||||||
|
struct EtlQueues {
|
||||||
|
std::vector<PlayerEventLootItemsRepository::PlayerEventLootItems> loot_items;
|
||||||
|
std::vector<PlayerEventMerchantPurchaseRepository::PlayerEventMerchantPurchase> merchant_purchase;
|
||||||
|
std::vector<PlayerEventMerchantSellRepository::PlayerEventMerchantSell> merchant_sell;
|
||||||
|
std::vector<PlayerEventNpcHandinRepository::PlayerEventNpcHandin> npc_handin;
|
||||||
|
std::vector<PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries> npc_handin_entries;
|
||||||
|
std::vector<PlayerEventTradeRepository::PlayerEventTrade> trade;
|
||||||
|
std::vector<PlayerEventTradeEntriesRepository::PlayerEventTradeEntries> trade_entries;
|
||||||
|
std::vector<PlayerEventSpeechRepository::PlayerEventSpeech> speech;
|
||||||
|
std::vector<PlayerEventKilledNpcRepository::PlayerEventKilledNpc> killed_npc;
|
||||||
|
std::vector<PlayerEventKilledNamedNpcRepository::PlayerEventKilledNamedNpc> killed_named_npc;
|
||||||
|
std::vector<PlayerEventKilledRaidNpcRepository::PlayerEventKilledRaidNpc> killed_raid_npc;
|
||||||
|
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct EtlSettings {
|
||||||
|
bool enabled;
|
||||||
|
std::string table_name;
|
||||||
|
int64 next_id;
|
||||||
|
};
|
||||||
|
|
||||||
Database *m_database; // reference to database
|
Database *m_database; // reference to database
|
||||||
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
||||||
|
|
||||||
@@ -69,6 +110,8 @@ private:
|
|||||||
static std::unique_ptr<ServerPacket>
|
static std::unique_ptr<ServerPacket>
|
||||||
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
||||||
|
|
||||||
|
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
Timer m_process_batch_events_timer; // events processing timer
|
Timer m_process_batch_events_timer; // events processing timer
|
||||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
||||||
@@ -78,6 +121,9 @@ private:
|
|||||||
void ProcessBatchQueue();
|
void ProcessBatchQueue();
|
||||||
void ProcessRetentionTruncation();
|
void ProcessRetentionTruncation();
|
||||||
void SetSettingsDefaults();
|
void SetSettingsDefaults();
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PlayerEventLogs player_event_logs;
|
extern PlayerEventLogs player_event_logs;
|
||||||
|
|||||||
+306
-91
@@ -4,6 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <cereal/cereal.hpp>
|
#include <cereal/cereal.hpp>
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include "../rulesys.h"
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
|
|
||||||
namespace PlayerEvent {
|
namespace PlayerEvent {
|
||||||
@@ -61,6 +62,9 @@ namespace PlayerEvent {
|
|||||||
PARCEL_SEND,
|
PARCEL_SEND,
|
||||||
PARCEL_RETRIEVE,
|
PARCEL_RETRIEVE,
|
||||||
PARCEL_DELETE,
|
PARCEL_DELETE,
|
||||||
|
BARTER_TRANSACTION,
|
||||||
|
SPEECH,
|
||||||
|
EVOLVE_ITEM,
|
||||||
MAX // dont remove
|
MAX // dont remove
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -122,7 +126,10 @@ namespace PlayerEvent {
|
|||||||
"Guild Tribute Donate Platinum",
|
"Guild Tribute Donate Platinum",
|
||||||
"Parcel Item Sent",
|
"Parcel Item Sent",
|
||||||
"Parcel Item Retrieved",
|
"Parcel Item Retrieved",
|
||||||
"Parcel Prune Routine"
|
"Parcel Prune Routine",
|
||||||
|
"Barter Transaction",
|
||||||
|
"Player Speech",
|
||||||
|
"Evolve Item Update"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic struct used by all events
|
// Generic struct used by all events
|
||||||
@@ -202,12 +209,12 @@ namespace PlayerEvent {
|
|||||||
std::string item_name;
|
std::string item_name;
|
||||||
uint16 to_slot;
|
uint16 to_slot;
|
||||||
int16 charges;
|
int16 charges;
|
||||||
uint32 aug1;
|
uint32 augment_1_id;
|
||||||
uint32 aug2;
|
uint32 augment_2_id;
|
||||||
uint32 aug3;
|
uint32 augment_3_id;
|
||||||
uint32 aug4;
|
uint32 augment_4_id;
|
||||||
uint32 aug5;
|
uint32 augment_5_id;
|
||||||
uint32 aug6;
|
uint32 augment_6_id;
|
||||||
bool attuned;
|
bool attuned;
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
@@ -219,56 +226,57 @@ namespace PlayerEvent {
|
|||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(to_slot),
|
CEREAL_NVP(to_slot),
|
||||||
CEREAL_NVP(charges),
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(aug1),
|
CEREAL_NVP(augment_1_id),
|
||||||
CEREAL_NVP(aug2),
|
CEREAL_NVP(augment_2_id),
|
||||||
CEREAL_NVP(aug3),
|
CEREAL_NVP(augment_3_id),
|
||||||
CEREAL_NVP(aug4),
|
CEREAL_NVP(augment_4_id),
|
||||||
CEREAL_NVP(aug5),
|
CEREAL_NVP(augment_5_id),
|
||||||
CEREAL_NVP(aug6),
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(attuned)
|
CEREAL_NVP(attuned)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// used in Trade event
|
// used in Trade event
|
||||||
struct TradeItem {
|
// struct TradeItem {
|
||||||
int64 item_id;
|
// int64 item_id;
|
||||||
std::string item_name;
|
// std::string item_name;
|
||||||
int32 slot;
|
// int32 slot;
|
||||||
|
//
|
||||||
// cereal
|
// // cereal
|
||||||
template<class Archive>
|
// template<class Archive>
|
||||||
void serialize(Archive &ar)
|
// void serialize(Archive &ar)
|
||||||
{
|
// {
|
||||||
ar(
|
// ar(
|
||||||
CEREAL_NVP(item_id),
|
// CEREAL_NVP(item_id),
|
||||||
CEREAL_NVP(item_name),
|
// CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(slot)
|
// CEREAL_NVP(slot)
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
// used in Trade event
|
// used in Trade event
|
||||||
class TradeItemEntry {
|
class TradeItemEntry {
|
||||||
public:
|
public:
|
||||||
uint16 slot;
|
uint16 slot;
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
std::string augment_1_name;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
std::string augment_2_name;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
std::string augment_3_name;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
std::string augment_4_name;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
std::string augment_5_name;
|
||||||
|
uint32 augment_6_id;
|
||||||
|
std::string augment_6_name;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
uint16 charges;
|
uint16 charges;
|
||||||
uint32 aug_1_item_id;
|
|
||||||
std::string aug_1_item_name;
|
|
||||||
uint32 aug_2_item_id;
|
|
||||||
std::string aug_2_item_name;
|
|
||||||
uint32 aug_3_item_id;
|
|
||||||
std::string aug_3_item_name;
|
|
||||||
uint32 aug_4_item_id;
|
|
||||||
std::string aug_4_item_name;
|
|
||||||
uint32 aug_5_item_id;
|
|
||||||
std::string aug_5_item_name;
|
|
||||||
uint32 aug_6_item_id;
|
|
||||||
std::string aug_6_item_name;
|
|
||||||
bool in_bag;
|
bool in_bag;
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void serialize(Archive &ar)
|
void serialize(Archive &ar)
|
||||||
@@ -276,12 +284,20 @@ namespace PlayerEvent {
|
|||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(slot),
|
CEREAL_NVP(slot),
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_1_name),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_2_name),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_1_name),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_4_name),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_5_name),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
|
CEREAL_NVP(augment_6_name),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(charges),
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(aug_1_item_id),
|
|
||||||
CEREAL_NVP(aug_2_item_id),
|
|
||||||
CEREAL_NVP(aug_3_item_id),
|
|
||||||
CEREAL_NVP(aug_4_item_id),
|
|
||||||
CEREAL_NVP(aug_5_item_id),
|
|
||||||
CEREAL_NVP(in_bag)
|
CEREAL_NVP(in_bag)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -414,6 +430,12 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct ForageSuccessEvent {
|
struct ForageSuccessEvent {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
@@ -422,6 +444,12 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(item_name)
|
CEREAL_NVP(item_name)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -429,6 +457,12 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct FishSuccessEvent {
|
struct FishSuccessEvent {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
@@ -437,6 +471,12 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(item_name)
|
CEREAL_NVP(item_name)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -446,6 +486,13 @@ namespace PlayerEvent {
|
|||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
int16 charges;
|
int16 charges;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
|
bool attuned;
|
||||||
std::string reason;
|
std::string reason;
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
@@ -455,8 +502,15 @@ namespace PlayerEvent {
|
|||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(reason),
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(charges)
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
|
CEREAL_NVP(attuned),
|
||||||
|
CEREAL_NVP(reason)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -499,6 +553,12 @@ namespace PlayerEvent {
|
|||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
int16 charges;
|
int16 charges;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
uint32 npc_id;
|
uint32 npc_id;
|
||||||
std::string corpse_name;
|
std::string corpse_name;
|
||||||
|
|
||||||
@@ -510,6 +570,12 @@ namespace PlayerEvent {
|
|||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(charges),
|
CEREAL_NVP(charges),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(npc_id),
|
CEREAL_NVP(npc_id),
|
||||||
CEREAL_NVP(corpse_name)
|
CEREAL_NVP(corpse_name)
|
||||||
);
|
);
|
||||||
@@ -722,6 +788,12 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct DroppedItemEvent {
|
struct DroppedItemEvent {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
int16 slot_id;
|
int16 slot_id;
|
||||||
uint32 charges;
|
uint32 charges;
|
||||||
@@ -732,6 +804,12 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(slot_id),
|
CEREAL_NVP(slot_id),
|
||||||
CEREAL_NVP(charges)
|
CEREAL_NVP(charges)
|
||||||
@@ -787,6 +865,12 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct TraderPurchaseEvent {
|
struct TraderPurchaseEvent {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
uint32 trader_id;
|
uint32 trader_id;
|
||||||
std::string trader_name;
|
std::string trader_name;
|
||||||
@@ -802,6 +886,12 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(trader_id),
|
CEREAL_NVP(trader_id),
|
||||||
CEREAL_NVP(trader_name),
|
CEREAL_NVP(trader_name),
|
||||||
@@ -815,6 +905,12 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct TraderSellEvent {
|
struct TraderSellEvent {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
uint32 buyer_id;
|
uint32 buyer_id;
|
||||||
std::string buyer_name;
|
std::string buyer_name;
|
||||||
@@ -830,6 +926,12 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
CEREAL_NVP(buyer_id),
|
CEREAL_NVP(buyer_id),
|
||||||
CEREAL_NVP(buyer_name),
|
CEREAL_NVP(buyer_name),
|
||||||
@@ -860,6 +962,8 @@ namespace PlayerEvent {
|
|||||||
public:
|
public:
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
std::string item_name;
|
std::string item_name;
|
||||||
|
std::vector<uint32> augment_ids;
|
||||||
|
std::vector<std::string> augment_names;
|
||||||
uint16 charges;
|
uint16 charges;
|
||||||
bool attuned;
|
bool attuned;
|
||||||
|
|
||||||
@@ -870,6 +974,8 @@ namespace PlayerEvent {
|
|||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
CEREAL_NVP(item_name),
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(augment_ids),
|
||||||
|
CEREAL_NVP(augment_names),
|
||||||
CEREAL_NVP(charges),
|
CEREAL_NVP(charges),
|
||||||
CEREAL_NVP(attuned)
|
CEREAL_NVP(attuned)
|
||||||
);
|
);
|
||||||
@@ -903,6 +1009,7 @@ namespace PlayerEvent {
|
|||||||
HandinMoney handin_money;
|
HandinMoney handin_money;
|
||||||
std::vector<HandinEntry> return_items;
|
std::vector<HandinEntry> return_items;
|
||||||
HandinMoney return_money;
|
HandinMoney return_money;
|
||||||
|
bool is_quest_handin;
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
@@ -914,7 +1021,8 @@ namespace PlayerEvent {
|
|||||||
CEREAL_NVP(handin_items),
|
CEREAL_NVP(handin_items),
|
||||||
CEREAL_NVP(handin_money),
|
CEREAL_NVP(handin_money),
|
||||||
CEREAL_NVP(return_items),
|
CEREAL_NVP(return_items),
|
||||||
CEREAL_NVP(return_money)
|
CEREAL_NVP(return_money),
|
||||||
|
CEREAL_NVP(is_quest_handin)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -955,6 +1063,14 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct GuildTributeDonateItem {
|
struct GuildTributeDonateItem {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
|
int16 charges;
|
||||||
|
bool attuned;
|
||||||
uint32 guild_favor;
|
uint32 guild_favor;
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
@@ -963,6 +1079,12 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(guild_favor)
|
CEREAL_NVP(guild_favor)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -985,15 +1107,15 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
struct ParcelRetrieve {
|
struct ParcelRetrieve {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
uint32 quantity;
|
uint32 quantity;
|
||||||
std::string from_player_name;
|
std::string from_player_name;
|
||||||
uint32 sent_date;
|
uint32 sent_date;
|
||||||
uint32 aug_slot_1;
|
|
||||||
uint32 aug_slot_2;
|
|
||||||
uint32 aug_slot_3;
|
|
||||||
uint32 aug_slot_4;
|
|
||||||
uint32 aug_slot_5;
|
|
||||||
uint32 aug_slot_6;
|
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
@@ -1001,31 +1123,31 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(quantity),
|
CEREAL_NVP(quantity),
|
||||||
CEREAL_NVP(from_player_name),
|
CEREAL_NVP(from_player_name),
|
||||||
CEREAL_NVP(sent_date),
|
CEREAL_NVP(sent_date)
|
||||||
CEREAL_NVP(aug_slot_1),
|
|
||||||
CEREAL_NVP(aug_slot_2),
|
|
||||||
CEREAL_NVP(aug_slot_3),
|
|
||||||
CEREAL_NVP(aug_slot_4),
|
|
||||||
CEREAL_NVP(aug_slot_5),
|
|
||||||
CEREAL_NVP(aug_slot_6)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParcelSend {
|
struct ParcelSend {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
uint32 quantity;
|
uint32 quantity;
|
||||||
std::string from_player_name;
|
std::string from_player_name;
|
||||||
std::string to_player_name;
|
std::string to_player_name;
|
||||||
uint32 sent_date;
|
uint32 sent_date;
|
||||||
uint32 aug_slot_1;
|
|
||||||
uint32 aug_slot_2;
|
|
||||||
uint32 aug_slot_3;
|
|
||||||
uint32 aug_slot_4;
|
|
||||||
uint32 aug_slot_5;
|
|
||||||
uint32 aug_slot_6;
|
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
@@ -1033,33 +1155,33 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(quantity),
|
CEREAL_NVP(quantity),
|
||||||
CEREAL_NVP(from_player_name),
|
CEREAL_NVP(from_player_name),
|
||||||
CEREAL_NVP(to_player_name),
|
CEREAL_NVP(to_player_name),
|
||||||
CEREAL_NVP(sent_date),
|
CEREAL_NVP(sent_date)
|
||||||
CEREAL_NVP(aug_slot_1),
|
|
||||||
CEREAL_NVP(aug_slot_2),
|
|
||||||
CEREAL_NVP(aug_slot_3),
|
|
||||||
CEREAL_NVP(aug_slot_4),
|
|
||||||
CEREAL_NVP(aug_slot_5),
|
|
||||||
CEREAL_NVP(aug_slot_6)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParcelDelete {
|
struct ParcelDelete {
|
||||||
uint32 item_id;
|
|
||||||
uint32 quantity;
|
|
||||||
uint32 char_id;
|
uint32 char_id;
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 augment_1_id;
|
||||||
|
uint32 augment_2_id;
|
||||||
|
uint32 augment_3_id;
|
||||||
|
uint32 augment_4_id;
|
||||||
|
uint32 augment_5_id;
|
||||||
|
uint32 augment_6_id;
|
||||||
|
uint32 quantity;
|
||||||
|
uint32 sent_date;
|
||||||
std::string from_name;
|
std::string from_name;
|
||||||
std::string note;
|
std::string note;
|
||||||
uint32 sent_date;
|
|
||||||
uint32 aug_slot_1;
|
|
||||||
uint32 aug_slot_2;
|
|
||||||
uint32 aug_slot_3;
|
|
||||||
uint32 aug_slot_4;
|
|
||||||
uint32 aug_slot_5;
|
|
||||||
uint32 aug_slot_6;
|
|
||||||
|
|
||||||
// cereal
|
// cereal
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
@@ -1067,17 +1189,88 @@ namespace PlayerEvent {
|
|||||||
{
|
{
|
||||||
ar(
|
ar(
|
||||||
CEREAL_NVP(item_id),
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(augment_1_id),
|
||||||
|
CEREAL_NVP(augment_2_id),
|
||||||
|
CEREAL_NVP(augment_3_id),
|
||||||
|
CEREAL_NVP(augment_4_id),
|
||||||
|
CEREAL_NVP(augment_5_id),
|
||||||
|
CEREAL_NVP(augment_6_id),
|
||||||
CEREAL_NVP(quantity),
|
CEREAL_NVP(quantity),
|
||||||
CEREAL_NVP(char_id),
|
CEREAL_NVP(char_id),
|
||||||
CEREAL_NVP(from_name),
|
CEREAL_NVP(from_name),
|
||||||
CEREAL_NVP(note),
|
CEREAL_NVP(note),
|
||||||
CEREAL_NVP(sent_date),
|
CEREAL_NVP(sent_date)
|
||||||
CEREAL_NVP(aug_slot_1),
|
);
|
||||||
CEREAL_NVP(aug_slot_2),
|
}
|
||||||
CEREAL_NVP(aug_slot_3),
|
};
|
||||||
CEREAL_NVP(aug_slot_4),
|
|
||||||
CEREAL_NVP(aug_slot_5),
|
struct BarterTransaction {
|
||||||
CEREAL_NVP(aug_slot_6)
|
std::string status;
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 item_quantity;
|
||||||
|
std::string item_name;
|
||||||
|
std::vector<BuyerLineTradeItems_Struct> trade_items;
|
||||||
|
std::string buyer_name;
|
||||||
|
std::string seller_name;
|
||||||
|
uint64 total_cost;
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(status),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(item_quantity),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(trade_items),
|
||||||
|
CEREAL_NVP(buyer_name),
|
||||||
|
CEREAL_NVP(seller_name),
|
||||||
|
CEREAL_NVP(total_cost)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveItem {
|
||||||
|
std::string status;
|
||||||
|
uint32 item_id;
|
||||||
|
uint64 unique_id;
|
||||||
|
std::string item_name;
|
||||||
|
uint32 level;
|
||||||
|
double progression;
|
||||||
|
|
||||||
|
// cereal
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(status),
|
||||||
|
CEREAL_NVP(item_id),
|
||||||
|
CEREAL_NVP(unique_id),
|
||||||
|
CEREAL_NVP(item_name),
|
||||||
|
CEREAL_NVP(level),
|
||||||
|
CEREAL_NVP(progression)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerSpeech {
|
||||||
|
std::string to;
|
||||||
|
std::string from;
|
||||||
|
uint32 guild_id;
|
||||||
|
int16 min_status;
|
||||||
|
uint32 type;
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &ar)
|
||||||
|
{
|
||||||
|
ar(
|
||||||
|
CEREAL_NVP(to),
|
||||||
|
CEREAL_NVP(from),
|
||||||
|
CEREAL_NVP(guild_id),
|
||||||
|
CEREAL_NVP(min_status),
|
||||||
|
CEREAL_NVP(type),
|
||||||
|
CEREAL_NVP(message)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1087,6 +1280,16 @@ namespace PlayerEvent {
|
|||||||
|
|
||||||
#define RecordPlayerEventLog(event_type, event_data) do {\
|
#define RecordPlayerEventLog(event_type, event_data) do {\
|
||||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||||
|
if (RuleB(Logging, PlayerEventsQSProcess)) {\
|
||||||
|
QServ->SendPacket(\
|
||||||
|
player_event_logs.RecordEvent(\
|
||||||
|
event_type,\
|
||||||
|
GetPlayerEvent(),\
|
||||||
|
event_data\
|
||||||
|
).get()\
|
||||||
|
);\
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
worldserver.SendPacket(\
|
worldserver.SendPacket(\
|
||||||
player_event_logs.RecordEvent(\
|
player_event_logs.RecordEvent(\
|
||||||
event_type,\
|
event_type,\
|
||||||
@@ -1095,10 +1298,21 @@ namespace PlayerEvent {
|
|||||||
).get()\
|
).get()\
|
||||||
);\
|
);\
|
||||||
}\
|
}\
|
||||||
|
}\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
||||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||||
|
if (RuleB(Logging, PlayerEventsQSProcess)) {\
|
||||||
|
QServ->SendPacket(\
|
||||||
|
player_event_logs.RecordEvent(\
|
||||||
|
event_type,\
|
||||||
|
(c)->GetPlayerEvent(),\
|
||||||
|
event_data\
|
||||||
|
).get()\
|
||||||
|
);\
|
||||||
|
}\
|
||||||
|
else {\
|
||||||
worldserver.SendPacket(\
|
worldserver.SendPacket(\
|
||||||
player_event_logs.RecordEvent(\
|
player_event_logs.RecordEvent(\
|
||||||
event_type,\
|
event_type,\
|
||||||
@@ -1107,4 +1321,5 @@ namespace PlayerEvent {
|
|||||||
).get()\
|
).get()\
|
||||||
);\
|
);\
|
||||||
}\
|
}\
|
||||||
|
}\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|||||||
@@ -0,0 +1,303 @@
|
|||||||
|
#include "evolving_items.h"
|
||||||
|
#include "item_instance.h"
|
||||||
|
#include "events/player_event_logs.h"
|
||||||
|
#include "repositories/character_evolving_items_repository.h"
|
||||||
|
|
||||||
|
EvolvingItemsManager::EvolvingItemsManager()
|
||||||
|
{
|
||||||
|
m_db = nullptr;
|
||||||
|
m_content_db = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvolvingItemsManager::LoadEvolvingItems() const
|
||||||
|
{
|
||||||
|
auto const &results = ItemsEvolvingDetailsRepository::All(*m_content_db);
|
||||||
|
|
||||||
|
if (results.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ranges::transform(
|
||||||
|
results.begin(),
|
||||||
|
results.end(),
|
||||||
|
std::inserter(
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache(),
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache().end()
|
||||||
|
),
|
||||||
|
[](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &x) {
|
||||||
|
return std::make_pair(x.item_id, x);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvolvingItemsManager::SetDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvolvingItemsManager::SetContentDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_content_db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
double EvolvingItemsManager::CalculateProgression(const uint64 current_amount, const uint32 item_id)
|
||||||
|
{
|
||||||
|
if (!evolving_items_manager.GetEvolvingItemsCache().contains(item_id)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount > 0
|
||||||
|
? static_cast<double>(current_amount)
|
||||||
|
/ static_cast<double>(evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount) * 100
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_id, const EQ::ItemInstance &inst) const
|
||||||
|
{
|
||||||
|
inst.SetEvolveEquipped(false);
|
||||||
|
if (inst.IsEvolving() && slot_id <= EQ::invslot::EQUIPMENT_END && slot_id >= EQ::invslot::EQUIPMENT_BEGIN) {
|
||||||
|
inst.SetEvolveEquipped(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inst.IsEvolving()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inst.GetEvolveUniqueID()) {
|
||||||
|
auto e = CharacterEvolvingItemsRepository::NewEntity();
|
||||||
|
|
||||||
|
e.character_id = char_id;
|
||||||
|
e.item_id = inst.GetID();
|
||||||
|
e.equipped = inst.GetEvolveEquipped();
|
||||||
|
e.final_item_id = evolving_items_manager.GetFinalItemID(inst);
|
||||||
|
|
||||||
|
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
||||||
|
e.id = r.id;
|
||||||
|
|
||||||
|
inst.SetEvolveUniqueID(e.id);
|
||||||
|
inst.SetEvolveCharID(e.character_id);
|
||||||
|
inst.SetEvolveItemID(e.item_id);
|
||||||
|
inst.SetEvolveFinalItemID(e.final_item_id);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterEvolvingItemsRepository::SetEquipped(*m_db, inst.GetEvolveUniqueID(), inst.GetEvolveEquipped());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 EvolvingItemsManager::GetFinalItemID(const EQ::ItemInstance &inst) const
|
||||||
|
{
|
||||||
|
const auto start_iterator = std::ranges::find_if(
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
||||||
|
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
||||||
|
return a.second.item_evo_id == inst.GetEvolveLoreID();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (start_iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto final_id = std::ranges::max_element(
|
||||||
|
start_iterator,
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
||||||
|
[&](
|
||||||
|
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a,
|
||||||
|
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &b
|
||||||
|
) {
|
||||||
|
return a.second.item_evo_id == b.second.item_evo_id &&
|
||||||
|
a.second.item_evolve_level < b.second.item_evolve_level;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return final_id->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 EvolvingItemsManager::GetNextEvolveItemID(const EQ::ItemInstance &inst) const
|
||||||
|
{
|
||||||
|
int8 const current_level = inst.GetEvolveLvl();
|
||||||
|
|
||||||
|
const auto iterator = std::ranges::find_if(
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
|
||||||
|
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
||||||
|
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
||||||
|
return a.second.item_evo_id == inst.GetEvolveLoreID() &&
|
||||||
|
a.second.item_evolve_level == current_level + 1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterator->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails EvolvingItemsManager::GetEvolveItemDetails(const uint64 unique_id)
|
||||||
|
{
|
||||||
|
if (GetEvolvingItemsCache().contains(unique_id)) {
|
||||||
|
return GetEvolvingItemsCache().at(unique_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ItemsEvolvingDetailsRepository::NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> EvolvingItemsManager::GetEvolveIDItems(
|
||||||
|
const uint32 evolve_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> e{};
|
||||||
|
|
||||||
|
for (auto const &[key, value]: GetEvolvingItemsCache()) {
|
||||||
|
if (value.item_evo_id == evolve_id) {
|
||||||
|
e.push_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ranges::sort(
|
||||||
|
e.begin(),
|
||||||
|
e.end(),
|
||||||
|
[&](
|
||||||
|
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails const &a,
|
||||||
|
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails const &b
|
||||||
|
) {
|
||||||
|
return a.item_evolve_level < b.item_evolve_level;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 EvolvingItemsManager::GetTotalEarnedXP(const EQ::ItemInstance &inst)
|
||||||
|
{
|
||||||
|
if (!inst) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 xp = inst.GetEvolveCurrentAmount();
|
||||||
|
auto evolve_id_item_cache = GetEvolveIDItems(inst.GetEvolveLoreID());
|
||||||
|
auto current_level = inst.GetEvolveLvl();
|
||||||
|
|
||||||
|
for (auto const &i: evolve_id_item_cache) {
|
||||||
|
if (i.item_evolve_level < current_level) {
|
||||||
|
xp += i.required_amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvolveGetNextItem EvolvingItemsManager::GetNextItemByXP(const EQ::ItemInstance &inst_in, const int64 in_xp)
|
||||||
|
{
|
||||||
|
EvolveGetNextItem ets{};
|
||||||
|
const auto evolve_items = GetEvolveIDItems(inst_in.GetEvolveLoreID());
|
||||||
|
uint32 max_transfer_level = 0;
|
||||||
|
int64 xp = in_xp;
|
||||||
|
|
||||||
|
for (auto const &e: evolve_items) {
|
||||||
|
if (e.item_evolve_level < inst_in.GetEvolveLvl()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 have = 0;
|
||||||
|
if (e.item_evolve_level == inst_in.GetEvolveLvl()) {
|
||||||
|
have = inst_in.GetEvolveCurrentAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto required = e.required_amount;
|
||||||
|
const int64 need = required - have;
|
||||||
|
const int64 balance = xp - need;
|
||||||
|
|
||||||
|
if (balance <= 0) {
|
||||||
|
ets.new_current_amount = have + xp;
|
||||||
|
ets.new_item_id = e.item_id;
|
||||||
|
ets.from_current_amount = 0;
|
||||||
|
ets.max_transfer_level = max_transfer_level;
|
||||||
|
return ets;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp = balance;
|
||||||
|
max_transfer_level += 1;
|
||||||
|
|
||||||
|
ets.new_current_amount = required;
|
||||||
|
ets.new_item_id = e.item_id;
|
||||||
|
ets.from_current_amount = balance - required;
|
||||||
|
ets.max_transfer_level = max_transfer_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ets;
|
||||||
|
}
|
||||||
|
|
||||||
|
EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
|
||||||
|
const EQ::ItemInstance &inst_from,
|
||||||
|
const EQ::ItemInstance &inst_to
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EvolveTransfer ets{};
|
||||||
|
|
||||||
|
auto evolving_details_inst_from = evolving_items_manager.GetEvolveItemDetails(inst_from.GetID());
|
||||||
|
auto evolving_details_inst_to = evolving_items_manager.GetEvolveItemDetails(inst_to.GetID());
|
||||||
|
|
||||||
|
if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) {
|
||||||
|
return ets;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evolving_details_inst_from.type == evolving_details_inst_to.type) {
|
||||||
|
uint32 compatibility = 0;
|
||||||
|
uint64 xp = 0;
|
||||||
|
if (evolving_details_inst_from.sub_type == evolving_details_inst_to.sub_type) {
|
||||||
|
compatibility = 100;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compatibility = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp = evolving_items_manager.GetTotalEarnedXP(inst_from) * compatibility / 100;
|
||||||
|
auto results = evolving_items_manager.GetNextItemByXP(inst_to, xp);
|
||||||
|
|
||||||
|
ets.item_from_id = evolving_items_manager.GetFirstItemInLoreGroup(inst_from.GetEvolveLoreID());
|
||||||
|
ets.item_from_current_amount = results.from_current_amount;
|
||||||
|
ets.item_to_id = results.new_item_id;
|
||||||
|
ets.item_to_current_amount = results.new_current_amount;
|
||||||
|
ets.compatibility = compatibility;
|
||||||
|
ets.max_transfer_level = results.max_transfer_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ets;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 EvolvingItemsManager::GetFirstItemInLoreGroup(const uint32 lore_id)
|
||||||
|
{
|
||||||
|
for (auto const &[key, value]: GetEvolvingItemsCache()) {
|
||||||
|
if (value.item_evo_id == lore_id && value.item_evolve_level == 1) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 EvolvingItemsManager::GetFirstItemInLoreGroupByItemID(const uint32 item_id)
|
||||||
|
{
|
||||||
|
for (auto const &[key, value]: GetEvolvingItemsCache()) {
|
||||||
|
if (value.item_id == item_id) {
|
||||||
|
for (auto const &[key2, value2]: GetEvolvingItemsCache()) {
|
||||||
|
if (value2.item_evo_id == value.item_evo_id && value2.item_evolve_level == 1) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvolvingItemsManager::LoadPlayerEvent(const EQ::ItemInstance &inst, PlayerEvent::EvolveItem &e)
|
||||||
|
{
|
||||||
|
e.item_id = inst.GetID();
|
||||||
|
e.item_name = inst.GetItem() ? inst.GetItem()->Name : std::string();
|
||||||
|
e.level = inst.GetEvolveLvl();
|
||||||
|
e.progression = inst.GetEvolveProgression();
|
||||||
|
e.unique_id = inst.GetEvolveUniqueID();
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#ifndef EVOLVING_H
|
||||||
|
#define EVOLVING_H
|
||||||
|
|
||||||
|
#include "shareddb.h"
|
||||||
|
#include "events/player_events.h"
|
||||||
|
#include "repositories/items_evolving_details_repository.h"
|
||||||
|
|
||||||
|
namespace EQ {
|
||||||
|
class ItemInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace EvolvingItems {
|
||||||
|
namespace Actions {
|
||||||
|
constexpr int8 UPDATE_ITEMS = 0;
|
||||||
|
constexpr int8 TRANSFER_WINDOW_OPEN = 1;
|
||||||
|
constexpr int8 TRANSFER_WINDOW_DETAILS = 2;
|
||||||
|
constexpr int8 TRANSFER_XP = 3;
|
||||||
|
constexpr int8 FINAL_RESULT = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Types {
|
||||||
|
constexpr int8 AMOUNT_OF_EXP = 1;
|
||||||
|
constexpr int8 NUMBER_OF_KILLS = 2;
|
||||||
|
constexpr int8 SPECIFIC_MOB_RACE = 3;
|
||||||
|
constexpr int8 SPECIFIC_ZONE_ID = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SubTypes {
|
||||||
|
constexpr int8 ALL_EXP = 0;
|
||||||
|
constexpr int8 SOLO_EXP = 1;
|
||||||
|
constexpr int8 GROUP_EXP = 2;
|
||||||
|
constexpr int8 RAID_EXP = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EvolvingItemsManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EvolvingItemsManager();
|
||||||
|
void SetDatabase(Database *db);
|
||||||
|
void SetContentDatabase(Database *db);
|
||||||
|
|
||||||
|
void LoadEvolvingItems() const;
|
||||||
|
void DoLootChecks(uint32 char_id, uint16 slot_id, const EQ::ItemInstance &inst) const;
|
||||||
|
uint32 GetFinalItemID(const EQ::ItemInstance &inst) const;
|
||||||
|
uint32 GetNextEvolveItemID(const EQ::ItemInstance &inst) const;
|
||||||
|
uint32 GetFirstItemInLoreGroup(uint32 lore_id);
|
||||||
|
uint32 GetFirstItemInLoreGroupByItemID(uint32 item_id);
|
||||||
|
uint64 GetTotalEarnedXP(const EQ::ItemInstance &inst);
|
||||||
|
static double CalculateProgression(uint64 current_amount, uint32 item_id);
|
||||||
|
static void LoadPlayerEvent(const EQ::ItemInstance &inst, PlayerEvent::EvolveItem &e);
|
||||||
|
|
||||||
|
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails GetEvolveItemDetails(uint64 id);
|
||||||
|
EvolveTransfer DetermineTransferResults(const EQ::ItemInstance& inst_from, const EQ::ItemInstance& inst_to);
|
||||||
|
EvolveGetNextItem GetNextItemByXP(const EQ::ItemInstance &inst_in, int64 in_xp);
|
||||||
|
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails>& GetEvolvingItemsCache() { return evolving_items_cache; }
|
||||||
|
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> evolving_items_cache;
|
||||||
|
Database * m_db;
|
||||||
|
Database * m_content_db;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern EvolvingItemsManager evolving_items_manager;
|
||||||
|
|
||||||
|
#endif //EVOLVING_H
|
||||||
+727
-442
File diff suppressed because it is too large
Load Diff
+15
-11
@@ -57,6 +57,8 @@ public:
|
|||||||
|
|
||||||
inline std::list<EQ::ItemInstance*>::const_iterator cbegin() { return m_list.cbegin(); }
|
inline std::list<EQ::ItemInstance*>::const_iterator cbegin() { return m_list.cbegin(); }
|
||||||
inline std::list<EQ::ItemInstance*>::const_iterator cend() { return m_list.cend(); }
|
inline std::list<EQ::ItemInstance*>::const_iterator cend() { return m_list.cend(); }
|
||||||
|
inline std::list<EQ::ItemInstance*>::iterator begin() { return m_list.begin(); }
|
||||||
|
inline std::list<EQ::ItemInstance*>::iterator end() { return m_list.end(); }
|
||||||
|
|
||||||
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
|
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
|
||||||
inline bool empty() { return m_list.empty(); }
|
inline bool empty() { return m_list.empty(); }
|
||||||
@@ -132,7 +134,7 @@ namespace EQ
|
|||||||
|
|
||||||
// Swap items in inventory
|
// Swap items in inventory
|
||||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = Race::Doug, uint8 class_id = Class::None, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = Race::Doug, uint8 class_id = Class::None, uint32 deity_id = Deity::Unknown, uint8 level = 0);
|
||||||
|
|
||||||
// Remove item from inventory
|
// Remove item from inventory
|
||||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
||||||
@@ -147,13 +149,13 @@ namespace EQ
|
|||||||
bool HasItemEquippedByID(uint32 item_id);
|
bool HasItemEquippedByID(uint32 item_id);
|
||||||
|
|
||||||
// Check how many of a specific item the player has equipped by Item ID
|
// Check how many of a specific item the player has equipped by Item ID
|
||||||
int CountItemEquippedByID(uint32 item_id);
|
uint32 CountItemEquippedByID(uint32 item_id);
|
||||||
|
|
||||||
// Check if player has a specific augment equipped by Item ID
|
// Check if player has a specific augment equipped by Item ID
|
||||||
bool HasAugmentEquippedByID(uint32 item_id);
|
bool HasAugmentEquippedByID(uint32 item_id);
|
||||||
|
|
||||||
// Check how many of a specific augment the player has equipped by Item ID
|
// Check how many of a specific augment the player has equipped by Item ID
|
||||||
int CountAugmentEquippedByID(uint32 item_id);
|
uint32 CountAugmentEquippedByID(uint32 item_id);
|
||||||
|
|
||||||
// Get a list of augments from a specific slot ID
|
// Get a list of augments from a specific slot ID
|
||||||
std::vector<uint32> GetAugmentIDsBySlotID(int16 slot_id);
|
std::vector<uint32> GetAugmentIDsBySlotID(int16 slot_id);
|
||||||
@@ -176,6 +178,7 @@ namespace EQ
|
|||||||
// Locate an available inventory slot
|
// Locate an available inventory slot
|
||||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
||||||
|
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
|
||||||
|
|
||||||
// Calculate slot_id for an item within a bag
|
// Calculate slot_id for an item within a bag
|
||||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||||
@@ -197,26 +200,25 @@ namespace EQ
|
|||||||
|
|
||||||
uint8 FindBrightestLightType();
|
uint8 FindBrightestLightType();
|
||||||
|
|
||||||
void dumpEntireInventory();
|
|
||||||
void dumpWornItems();
|
|
||||||
void dumpInventory();
|
|
||||||
void dumpBankItems();
|
|
||||||
void dumpSharedBankItems();
|
|
||||||
|
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
|
||||||
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
|
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
|
||||||
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
|
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
|
||||||
|
|
||||||
|
std::map<int16, ItemInstance*>& GetWorn() { return m_worn; }
|
||||||
|
std::map<int16, ItemInstance*>& GetPersonal() { return m_inv; }
|
||||||
|
int16 HasEvolvingItem(uint64 evolve_unique_id, uint8 quantity, uint8 where);
|
||||||
|
|
||||||
|
inline int16 PushItem(int16 slot_id, ItemInstance* inst) { return _PutItem(slot_id, inst); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Protected Methods
|
// Protected Methods
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
|
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
|
||||||
void dumpItemCollection(const std::map<int16, ItemInstance*> &collection);
|
|
||||||
void dumpBagContents(ItemInstance *inst, std::map<int16, ItemInstance*>::const_iterator *it);
|
|
||||||
|
|
||||||
// Retrieves item within an inventory bucket
|
// Retrieves item within an inventory bucket
|
||||||
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
|
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
|
||||||
@@ -231,6 +233,8 @@ namespace EQ
|
|||||||
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
|
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
|
||||||
int16 _HasItemByLoreGroup(std::map<int16, ItemInstance*>& bucket, uint32 loregroup);
|
int16 _HasItemByLoreGroup(std::map<int16, ItemInstance*>& bucket, uint32 loregroup);
|
||||||
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
|
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
|
||||||
|
int16 _HasEvolvingItem(std::map<int16, ItemInstance*>& bucket, uint64 evolve_unique_id, uint8 quantity);
|
||||||
|
int16 _HasEvolvingItem(ItemInstQueue& iqueue, uint64 evolve_unique_id, uint8 quantity);
|
||||||
|
|
||||||
|
|
||||||
// Player inventory
|
// Player inventory
|
||||||
|
|||||||
+53
-19
@@ -81,45 +81,79 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets local address - pings google to inspect what interface was used locally
|
#ifdef _WIN32
|
||||||
* @return
|
#include <winsock2.h>
|
||||||
*/
|
#include <ws2tcpip.h>
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
#else
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
std::string IpUtil::GetLocalIPAddress()
|
std::string IpUtil::GetLocalIPAddress()
|
||||||
{
|
{
|
||||||
char my_ip_address[16];
|
#ifdef _WIN32
|
||||||
unsigned int my_port;
|
WSADATA wsaData;
|
||||||
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char my_ip_address[INET_ADDRSTRLEN];
|
||||||
struct sockaddr_in server_address{};
|
struct sockaddr_in server_address{};
|
||||||
struct sockaddr_in my_address{};
|
struct sockaddr_in my_address{};
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
|
||||||
// Connect to server
|
// Create a UDP socket
|
||||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
#ifdef _WIN32
|
||||||
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sockfd == INVALID_SOCKET) {
|
||||||
|
WSACleanup();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sockfd < 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set server_addr
|
// Set server_addr (dummy address)
|
||||||
memset(&server_address, 0, sizeof(server_address));
|
memset(&server_address, 0, sizeof(server_address));
|
||||||
server_address.sin_family = AF_INET;
|
server_address.sin_family = AF_INET;
|
||||||
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
|
server_address.sin_addr.s_addr = inet_addr("8.8.8.8"); // Google DNS
|
||||||
server_address.sin_port = htons(80);
|
server_address.sin_port = htons(53); // DNS port
|
||||||
|
|
||||||
// Connect to server
|
// Perform a dummy connection to the server (UDP)
|
||||||
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
|
connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
|
||||||
close(sockfd);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get my ip address and port
|
// Get my IP address
|
||||||
memset(&my_address, 0, sizeof(my_address));
|
memset(&my_address, 0, sizeof(my_address));
|
||||||
socklen_t len = sizeof(my_address);
|
socklen_t len = sizeof(my_address);
|
||||||
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
|
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
|
||||||
inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address));
|
inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address));
|
||||||
my_port = ntohs(my_address.sin_port);
|
|
||||||
|
|
||||||
return fmt::format("{}", my_ip_address);
|
#ifdef _WIN32
|
||||||
|
closesocket(sockfd);
|
||||||
|
WSACleanup();
|
||||||
|
#else
|
||||||
|
close(sockfd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LogInfo("Local IP Address [{}]", my_ip_address);
|
||||||
|
|
||||||
|
return std::string(my_ip_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets public address
|
* Gets public address
|
||||||
* Uses various websites as options to return raw public IP back to the client
|
* Uses various websites as options to return raw public IP back to the client
|
||||||
|
|||||||
@@ -220,6 +220,34 @@ bool EQ::ItemData::IsType1HWeapon() const
|
|||||||
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing) || (ItemType == item::ItemTypeMartial));
|
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing) || (ItemType == item::ItemTypeMartial));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQ::ItemData::IsPetUsable() const
|
||||||
|
{
|
||||||
|
if (ItemClass == item::ItemClassBag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's a misc item and has slots, it's wearable
|
||||||
|
// this item type is conflated with many other item types
|
||||||
|
if (ItemClass == item::ItemTypeMisc && Slots != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ItemType) {
|
||||||
|
case item::ItemType1HBlunt:
|
||||||
|
case item::ItemType1HSlash:
|
||||||
|
case item::ItemType1HPiercing:
|
||||||
|
case item::ItemType2HBlunt:
|
||||||
|
case item::ItemType2HSlash:
|
||||||
|
case item::ItemTypeMartial:
|
||||||
|
case item::ItemTypeShield:
|
||||||
|
case item::ItemTypeArmor:
|
||||||
|
case item::ItemTypeJewelry:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool EQ::ItemData::IsType2HWeapon() const
|
bool EQ::ItemData::IsType2HWeapon() const
|
||||||
{
|
{
|
||||||
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
|
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
|
||||||
|
|||||||
+8
-4
@@ -104,10 +104,10 @@ namespace EQ
|
|||||||
/*----*/ ItemTypeUnknown6,
|
/*----*/ ItemTypeUnknown6,
|
||||||
/*----*/ ItemTypeUnknown7,
|
/*----*/ ItemTypeUnknown7,
|
||||||
/*5522*/ ItemTypeMartial, // 45
|
/*5522*/ ItemTypeMartial, // 45
|
||||||
/*----*/ ItemTypeUnknown8,
|
/*----*/ ItemTypeAllEffects,
|
||||||
/*----*/ ItemTypeUnknown9,
|
/*----*/ ItemTypeUnknown9,
|
||||||
/*----*/ ItemTypeUnknown10,
|
/*----*/ ItemTypeUnknown10,
|
||||||
/*----*/ ItemTypeUnknown11,
|
/*----*/ ItemTypeFocusEffect,
|
||||||
/*----*/ ItemTypeSinging, // 50
|
/*----*/ ItemTypeSinging, // 50
|
||||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||||
/*5776*/ ItemTypeCharm,
|
/*5776*/ ItemTypeCharm,
|
||||||
@@ -115,7 +115,7 @@ namespace EQ
|
|||||||
/*----*/ ItemTypeAugmentation,
|
/*----*/ ItemTypeAugmentation,
|
||||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||||
/*----*/ ItemTypeAugmentationDistiller,
|
/*----*/ ItemTypeAugmentationDistiller,
|
||||||
/*----*/ ItemTypeUnknown12,
|
/*----*/ ItemTypeAlternateAbility,
|
||||||
/*----*/ ItemTypeFellowshipKit,
|
/*----*/ ItemTypeFellowshipKit,
|
||||||
/*----*/ ItemTypeUnknown13,
|
/*----*/ ItemTypeUnknown13,
|
||||||
/*----*/ ItemTypeRecipe, // 60
|
/*----*/ ItemTypeRecipe, // 60
|
||||||
@@ -123,7 +123,10 @@ namespace EQ
|
|||||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||||
/*----*/ ItemTypeCount
|
/*----*/ ItemTypeCount,
|
||||||
|
/*----*/ ItemTypeCollectible,
|
||||||
|
/*----*/ ItemTypeContainer,
|
||||||
|
/*----*/ ItemTypeAll = 0xFF
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unknowns:
|
Unknowns:
|
||||||
@@ -547,6 +550,7 @@ namespace EQ
|
|||||||
bool IsType1HWeapon() const;
|
bool IsType1HWeapon() const;
|
||||||
bool IsType2HWeapon() const;
|
bool IsType2HWeapon() const;
|
||||||
bool IsTypeShield() const;
|
bool IsTypeShield() const;
|
||||||
|
bool IsPetUsable() const;
|
||||||
bool IsQuestItem() const;
|
bool IsQuestItem() const;
|
||||||
|
|
||||||
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
||||||
|
|||||||
+241
-85
@@ -25,6 +25,7 @@
|
|||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
#include "shareddb.h"
|
#include "shareddb.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
#include "evolving_items.h"
|
||||||
|
|
||||||
//#include "../common/light_source.h"
|
//#include "../common/light_source.h"
|
||||||
|
|
||||||
@@ -32,10 +33,11 @@
|
|||||||
|
|
||||||
//#include <iostream>
|
//#include <iostream>
|
||||||
|
|
||||||
int32 NextItemInstSerialNumber = 1;
|
int32 next_item_serial_number = 1;
|
||||||
|
std::unordered_set<uint64> guids{};
|
||||||
static inline int32 GetNextItemInstSerialNumber() {
|
|
||||||
|
|
||||||
|
static inline int32 GetNextItemInstSerialNumber()
|
||||||
|
{
|
||||||
// The Bazaar relies on each item a client has up for Trade having a unique
|
// The Bazaar relies on each item a client has up for Trade having a unique
|
||||||
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
||||||
// is used in Bazaar packets to identify the item a player is buying or inspecting.
|
// is used in Bazaar packets to identify the item a player is buying or inspecting.
|
||||||
@@ -46,12 +48,18 @@ static inline int32 GetNextItemInstSerialNumber() {
|
|||||||
// NextItemInstSerialNumber is the next one to hand out.
|
// NextItemInstSerialNumber is the next one to hand out.
|
||||||
//
|
//
|
||||||
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
||||||
if(NextItemInstSerialNumber >= INT_MAX)
|
if (next_item_serial_number >= INT32_MAX) {
|
||||||
NextItemInstSerialNumber = 1;
|
next_item_serial_number = 1;
|
||||||
else
|
}
|
||||||
NextItemInstSerialNumber++;
|
else {
|
||||||
|
next_item_serial_number++;
|
||||||
|
}
|
||||||
|
|
||||||
return NextItemInstSerialNumber;
|
while (guids.contains(next_item_serial_number)) {
|
||||||
|
next_item_serial_number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_item_serial_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -69,6 +77,10 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
|||||||
m_color = m_item->Color;
|
m_color = m_item->Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsEvolving()) {
|
||||||
|
SetTimer("evolve", RuleI(EvolvingItems, DelayUponEquipping));
|
||||||
|
}
|
||||||
|
|
||||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +100,10 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
|
|||||||
m_color = 0;
|
m_color = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsEvolving()) {
|
||||||
|
SetTimer("evolve", RuleI(EvolvingItems, DelayUponEquipping));
|
||||||
|
}
|
||||||
|
|
||||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +155,6 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
|
|
||||||
m_exp = copy.m_exp;
|
m_exp = copy.m_exp;
|
||||||
m_evolveLvl = copy.m_evolveLvl;
|
m_evolveLvl = copy.m_evolveLvl;
|
||||||
m_activated = copy.m_activated;
|
|
||||||
|
|
||||||
if (copy.m_scaledItem) {
|
if (copy.m_scaledItem) {
|
||||||
m_scaledItem = new ItemData(*copy.m_scaledItem);
|
m_scaledItem = new ItemData(*copy.m_scaledItem);
|
||||||
@@ -147,12 +162,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
m_scaledItem = nullptr;
|
m_scaledItem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy.m_evolveInfo) {
|
m_evolving_details = copy.m_evolving_details;
|
||||||
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
|
|
||||||
} else {
|
|
||||||
m_evolveInfo = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_scaling = copy.m_scaling;
|
m_scaling = copy.m_scaling;
|
||||||
m_ornamenticon = copy.m_ornamenticon;
|
m_ornamenticon = copy.m_ornamenticon;
|
||||||
m_ornamentidfile = copy.m_ornamentidfile;
|
m_ornamentidfile = copy.m_ornamentidfile;
|
||||||
@@ -167,7 +177,6 @@ EQ::ItemInstance::~ItemInstance()
|
|||||||
Clear();
|
Clear();
|
||||||
safe_delete(m_item);
|
safe_delete(m_item);
|
||||||
safe_delete(m_scaledItem);
|
safe_delete(m_scaledItem);
|
||||||
safe_delete(m_evolveInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query item type
|
// Query item type
|
||||||
@@ -303,47 +312,34 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
|||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i = invaug::SOCKET_BEGIN;
|
for (int16 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||||
for (; i <= invaug::SOCKET_END; ++i) {
|
if (IsAugmentSlotAvailable(augment_type, slot_id)) {
|
||||||
if (GetItem(i)) {
|
return slot_id;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
augment_type == -1 ||
|
|
||||||
(
|
|
||||||
m_item->AugSlotType[i] &&
|
|
||||||
((1 << (m_item->AugSlotType[i] - 1)) & augment_type)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon() || GetItem(slot)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
return (
|
||||||
(
|
(
|
||||||
!GetItem(slot) &&
|
|
||||||
m_item->AugSlotVisible[slot]
|
|
||||||
) &&
|
|
||||||
augment_type == -1 ||
|
augment_type == -1 ||
|
||||||
(
|
(
|
||||||
m_item->AugSlotType[slot] &&
|
m_item->AugSlotType[slot] &&
|
||||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||||
)
|
)
|
||||||
) {
|
) &&
|
||||||
return true;
|
(
|
||||||
}
|
RuleB(Items, AugmentItemAllowInvisibleAugments) ||
|
||||||
|
m_item->AugSlotVisible[slot]
|
||||||
return false;
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve item inside container
|
// Retrieve item inside container
|
||||||
@@ -1036,29 +1032,6 @@ void EQ::ItemInstance::ScaleItem() {
|
|||||||
m_scaledItem->CharmFileID = 0; // this stops the client from trying to scale the item itself.
|
m_scaledItem->CharmFileID = 0; // this stops the client from trying to scale the item itself.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::EvolveOnAllKills() const {
|
|
||||||
return (m_evolveInfo && m_evolveInfo->AllKills);
|
|
||||||
}
|
|
||||||
|
|
||||||
int8 EQ::ItemInstance::GetMaxEvolveLvl() const {
|
|
||||||
if (m_evolveInfo)
|
|
||||||
return m_evolveInfo->MaxLvl;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 EQ::ItemInstance::GetKillsNeeded(uint8 currentlevel) {
|
|
||||||
uint32 kills = -1; // default to -1 (max uint32 value) because this value is usually divided by, so we don't want to ever return zero.
|
|
||||||
if (m_evolveInfo)
|
|
||||||
if (currentlevel != m_evolveInfo->MaxLvl)
|
|
||||||
kills = m_evolveInfo->LvlKills[currentlevel - 1];
|
|
||||||
|
|
||||||
if (kills == 0)
|
|
||||||
kills = -1;
|
|
||||||
|
|
||||||
return kills;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::ItemInstance::SetTimer(std::string name, uint32 time) {
|
void EQ::ItemInstance::SetTimer(std::string name, uint32 time) {
|
||||||
Timer t(time);
|
Timer t(time);
|
||||||
t.Start(time, false);
|
t.Start(time, false);
|
||||||
@@ -1292,7 +1265,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
|||||||
return race;
|
return race;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
|
int EQ::ItemInstance::GetItemBaneDamageBody(uint8 against, bool augments) const
|
||||||
{
|
{
|
||||||
int64 damage = 0;
|
int64 damage = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
@@ -1812,28 +1785,211 @@ std::vector<uint32> EQ::ItemInstance::GetAugmentIDs() const
|
|||||||
return augments;
|
return augments;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
std::vector<std::string> EQ::ItemInstance::GetAugmentNames() const
|
||||||
// class EvolveInfo
|
{
|
||||||
//
|
std::vector<std::string> augment_names;
|
||||||
EvolveInfo::EvolveInfo() {
|
|
||||||
// nothing here yet
|
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
|
||||||
|
const auto augment = GetAugment(slot_id);
|
||||||
|
augment_names.push_back(augment ? augment->GetItem()->Name : "None");
|
||||||
}
|
}
|
||||||
|
|
||||||
EvolveInfo::EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10) {
|
return augment_names;
|
||||||
FirstItem = first;
|
|
||||||
MaxLvl = max;
|
|
||||||
AllKills = allkills;
|
|
||||||
LvlKills[0] = L2;
|
|
||||||
LvlKills[1] = L3;
|
|
||||||
LvlKills[2] = L4;
|
|
||||||
LvlKills[3] = L5;
|
|
||||||
LvlKills[4] = L6;
|
|
||||||
LvlKills[5] = L7;
|
|
||||||
LvlKills[6] = L8;
|
|
||||||
LvlKills[7] = L9;
|
|
||||||
LvlKills[8] = L10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EvolveInfo::~EvolveInfo() {
|
int EQ::ItemInstance::GetItemRegen(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->Regen;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemRegen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemManaRegen(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->ManaRegen;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemManaRegen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemDamageShield(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->DamageShield;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemDamageShield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemDSMitigation(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->DSMitigation;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemDSMitigation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemHealAmt(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->HealAmt;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemHealAmt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemSpellDamage(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->SpellDmg;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemSpellDamage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemClairvoyance(bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->Clairvoyance;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemClairvoyance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ::ItemInstance::GetItemSkillsStat(EQ::skills::SkillType skill, bool augments) const
|
||||||
|
{
|
||||||
|
int stat = 0;
|
||||||
|
const auto item = GetItem();
|
||||||
|
if (item) {
|
||||||
|
stat = item->ExtraDmgSkill == skill ? item->ExtraDmgAmt : 0;
|
||||||
|
if (augments) {
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||||
|
if (GetAugment(i)) {
|
||||||
|
stat += GetAugment(i)->GetItemSkillsStat(skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::ItemInstance::AddGUIDToMap(uint64 existing_serial_number)
|
||||||
|
{
|
||||||
|
guids.emplace(existing_serial_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::ItemInstance::ClearGUIDMap()
|
||||||
|
{
|
||||||
|
guids.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQ::ItemInstance::TransferOwnership(Database &db, const uint32 to_char_id) const
|
||||||
|
{
|
||||||
|
if (!to_char_id || !IsEvolving()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEvolveCharID(to_char_id);
|
||||||
|
CharacterEvolvingItemsRepository::UpdateCharID(db, GetEvolveUniqueID(), to_char_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 EQ::ItemInstance::GetAugmentEvolveUniqueID(uint8 augment_index) const
|
||||||
|
{
|
||||||
|
if (!m_item || !m_item->IsClassCommon()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto item = GetItem(augment_index);
|
||||||
|
if (item) {
|
||||||
|
return item->GetEvolveUniqueID();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::ItemInstance::SetTimer(std::string name, uint32 time) const{
|
||||||
|
Timer t(time);
|
||||||
|
t.Start(time, false);
|
||||||
|
m_timers[name] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::ItemInstance::SetEvolveEquipped(const bool in) const
|
||||||
|
{
|
||||||
|
if (!IsEvolving()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_evolving_details.equipped = in;
|
||||||
|
if (in && !GetTimers().contains("evolve")) {
|
||||||
|
SetTimer("evolve", RuleI(EvolvingItems, DelayUponEquipping));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in) {
|
||||||
|
GetTimers().at("evolve").SetTimer(RuleI(EvolvingItems, DelayUponEquipping));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTimers().at("evolve").Disable();
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-27
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#ifndef COMMON_ITEM_INSTANCE_H
|
#ifndef COMMON_ITEM_INSTANCE_H
|
||||||
#define COMMON_ITEM_INSTANCE_H
|
#define COMMON_ITEM_INSTANCE_H
|
||||||
|
#include "evolving_items.h"
|
||||||
|
|
||||||
|
|
||||||
class ItemParse; // Parses item packets
|
class ItemParse; // Parses item packets
|
||||||
@@ -34,6 +35,7 @@ class EvolveInfo; // Stores information about an evolving item family
|
|||||||
#include "../common/bodytypes.h"
|
#include "../common/bodytypes.h"
|
||||||
#include "../common/deity.h"
|
#include "../common/deity.h"
|
||||||
#include "../common/memory_buffer.h"
|
#include "../common/memory_buffer.h"
|
||||||
|
#include "../common/repositories/character_evolving_items_repository.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@@ -205,13 +207,9 @@ namespace EQ
|
|||||||
bool IsDroppable(bool recurse = true) const;
|
bool IsDroppable(bool recurse = true) const;
|
||||||
|
|
||||||
bool IsScaling() const { return m_scaling; }
|
bool IsScaling() const { return m_scaling; }
|
||||||
bool IsEvolving() const { return (m_evolveLvl >= 1); }
|
|
||||||
uint32 GetExp() const { return m_exp; }
|
uint32 GetExp() const { return m_exp; }
|
||||||
void SetExp(uint32 exp) { m_exp = exp; }
|
void SetExp(uint32 exp) { m_exp = exp; }
|
||||||
void AddExp(uint32 exp) { m_exp += exp; }
|
void AddExp(uint32 exp) { m_exp += exp; }
|
||||||
bool IsActivated() { return m_activated; }
|
|
||||||
void SetActivated(bool activated) { m_activated = activated; }
|
|
||||||
int8 GetEvolveLvl() const { return m_evolveLvl; }
|
|
||||||
void SetScaling(bool v) { m_scaling = v; }
|
void SetScaling(bool v) { m_scaling = v; }
|
||||||
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
|
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
|
||||||
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
|
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
|
||||||
@@ -226,9 +224,6 @@ namespace EQ
|
|||||||
|
|
||||||
void Initialize(SharedDatabase *db = nullptr);
|
void Initialize(SharedDatabase *db = nullptr);
|
||||||
void ScaleItem();
|
void ScaleItem();
|
||||||
bool EvolveOnAllKills() const;
|
|
||||||
int8 GetMaxEvolveLvl() const;
|
|
||||||
uint32 GetKillsNeeded(uint8 currentlevel);
|
|
||||||
|
|
||||||
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
||||||
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
||||||
@@ -236,8 +231,9 @@ namespace EQ
|
|||||||
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
||||||
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
||||||
|
|
||||||
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
|
std::map<std::string, ::Timer>& GetTimers() const { return m_timers; }
|
||||||
void SetTimer(std::string name, uint32 time);
|
void SetTimer(std::string name, uint32 time);
|
||||||
|
void SetTimer(std::string name, uint32 time) const;
|
||||||
void StopTimer(std::string name);
|
void StopTimer(std::string name);
|
||||||
void ClearTimers();
|
void ClearTimers();
|
||||||
|
|
||||||
@@ -265,11 +261,12 @@ namespace EQ
|
|||||||
// these two are just quick checks
|
// these two are just quick checks
|
||||||
int GetItemBaneDamageBody(bool augments = false) const;
|
int GetItemBaneDamageBody(bool augments = false) const;
|
||||||
int GetItemBaneDamageRace(bool augments = false) const;
|
int GetItemBaneDamageRace(bool augments = false) const;
|
||||||
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
|
int GetItemBaneDamageBody(uint8 against, bool augments = false) const;
|
||||||
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
|
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
|
||||||
int GetItemMagical(bool augments = false) const;
|
int GetItemMagical(bool augments = false) const;
|
||||||
int GetItemHP(bool augments = false) const;
|
int GetItemHP(bool augments = false) const;
|
||||||
int GetItemMana(bool augments = false) const;
|
int GetItemMana(bool augments = false) const;
|
||||||
|
int GetItemManaRegen(bool augments = false) const;
|
||||||
int GetItemEndur(bool augments = false) const;
|
int GetItemEndur(bool augments = false) const;
|
||||||
int GetItemAttack(bool augments = false) const;
|
int GetItemAttack(bool augments = false) const;
|
||||||
int GetItemStr(bool augments = false) const;
|
int GetItemStr(bool augments = false) const;
|
||||||
@@ -299,8 +296,46 @@ namespace EQ
|
|||||||
int GetItemHeroicDR(bool augments = false) const;
|
int GetItemHeroicDR(bool augments = false) const;
|
||||||
int GetItemHeroicCorrup(bool augments = false) const;
|
int GetItemHeroicCorrup(bool augments = false) const;
|
||||||
int GetItemHaste(bool augments = false) const;
|
int GetItemHaste(bool augments = false) const;
|
||||||
|
int GetItemRegen(bool augments = false) const;
|
||||||
|
int GetItemDamageShield(bool augments = false) const;
|
||||||
|
int GetItemDSMitigation(bool augments = false) const;
|
||||||
|
int GetItemHealAmt(bool augments = false) const;
|
||||||
|
int GetItemSpellDamage(bool augments = false) const;
|
||||||
|
int GetItemClairvoyance(bool augments = false) const;
|
||||||
|
int GetItemSkillsStat(EQ::skills::SkillType skill, bool augments = false) const;
|
||||||
uint32 GetItemGuildFavor() const;
|
uint32 GetItemGuildFavor() const;
|
||||||
std::vector<uint32> GetAugmentIDs() const;
|
std::vector<uint32> GetAugmentIDs() const;
|
||||||
|
std::vector<std::string> GetAugmentNames() const;
|
||||||
|
static void AddGUIDToMap(uint64 existing_serial_number);
|
||||||
|
static void ClearGUIDMap();
|
||||||
|
|
||||||
|
// evolving items stuff
|
||||||
|
CharacterEvolvingItemsRepository::CharacterEvolvingItems &GetEvolvingDetails() const { return m_evolving_details; }
|
||||||
|
|
||||||
|
int8 GetEvolveLvl() const { if (GetItem()) { return GetItem()->EvolvingLevel; } return false; }
|
||||||
|
bool IsEvolving() const { if (GetItem()) { return GetItem()->EvolvingItem; } return false; }
|
||||||
|
int8 GetMaxEvolveLvl() const { if (GetItem()) { return GetItem()->EvolvingMax; } return false; }
|
||||||
|
bool GetEvolveActivated() const { return m_evolving_details.activated ? true : false; }
|
||||||
|
bool GetEvolveEquipped() const { return m_evolving_details.equipped ? true : false; }
|
||||||
|
double GetEvolveProgression() const { return m_evolving_details.progression; }
|
||||||
|
uint64 GetEvolveUniqueID() const { return m_evolving_details.id; }
|
||||||
|
uint32 GetEvolveCharID() const { return m_evolving_details.character_id; }
|
||||||
|
uint32 GetEvolveItemID() const { return m_evolving_details.item_id; }
|
||||||
|
uint32 GetEvolveLoreID() const { if (GetItem()) { return GetItem()->EvolvingID; } return false; }
|
||||||
|
uint64 GetEvolveCurrentAmount() const { return m_evolving_details.current_amount; }
|
||||||
|
uint32 GetEvolveFinalItemID() const { return m_evolving_details.final_item_id; }
|
||||||
|
uint32 GetAugmentEvolveUniqueID(uint8 augment_index) const;
|
||||||
|
void SetEvolveEquipped(const bool in) const;
|
||||||
|
void SetEvolveActivated(const bool in) const { m_evolving_details.activated = in; }
|
||||||
|
void SetEvolveProgression(const double in) const { m_evolving_details.progression = in; }
|
||||||
|
void SetEvolveUniqueID(const uint64 in) const { m_evolving_details.id = in; }
|
||||||
|
void SetEvolveCharID(const uint32 in) const { m_evolving_details.character_id = in; }
|
||||||
|
void SetEvolveItemID(const uint32 in) const { m_evolving_details.item_id = in; }
|
||||||
|
void SetEvolveCurrentAmount(const uint64 in) const { m_evolving_details.current_amount = in; }
|
||||||
|
void SetEvolveAddToCurrentAmount(const uint64 in) const { m_evolving_details.current_amount += in; }
|
||||||
|
void SetEvolveFinalItemID(const uint32 in) const { m_evolving_details.final_item_id = in; }
|
||||||
|
bool TransferOwnership(Database& db, const uint32 to_char_id) const;
|
||||||
|
void CalculateEvolveProgression() const { m_evolving_details.progression = evolving_items_manager.CalculateProgression(GetEvolveCurrentAmount(), GetID()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
@@ -325,9 +360,7 @@ namespace EQ
|
|||||||
int32 m_SerialNumber{0}; // Unique identifier for this instance of an item. Needed for Bazaar.
|
int32 m_SerialNumber{0}; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||||
uint32 m_exp{0};
|
uint32 m_exp{0};
|
||||||
int8 m_evolveLvl{0};
|
int8 m_evolveLvl{0};
|
||||||
bool m_activated {false};
|
|
||||||
ItemData * m_scaledItem{nullptr};
|
ItemData * m_scaledItem{nullptr};
|
||||||
::EvolveInfo* m_evolveInfo {nullptr};
|
|
||||||
bool m_scaling{false};
|
bool m_scaling{false};
|
||||||
uint32 m_ornamenticon{0};
|
uint32 m_ornamenticon{0};
|
||||||
uint32 m_ornamentidfile{0};
|
uint32 m_ornamentidfile{0};
|
||||||
@@ -335,26 +368,12 @@ namespace EQ
|
|||||||
uint32 m_ornament_hero_model{0};
|
uint32 m_ornament_hero_model{0};
|
||||||
uint32 m_recast_timestamp{0};
|
uint32 m_recast_timestamp{0};
|
||||||
int m_task_delivered_count{0};
|
int m_task_delivered_count{0};
|
||||||
|
mutable CharacterEvolvingItemsRepository::CharacterEvolvingItems m_evolving_details{};
|
||||||
|
|
||||||
// Items inside of this item (augs or contents) {};
|
// Items inside of this item (augs or contents) {};
|
||||||
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
|
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
|
||||||
std::map<std::string, std::string> m_custom_data {};
|
std::map<std::string, std::string> m_custom_data {};
|
||||||
std::map<std::string, ::Timer> m_timers {};
|
mutable std::map<std::string, ::Timer> m_timers {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class EvolveInfo {
|
|
||||||
public:
|
|
||||||
friend class EQ::ItemInstance;
|
|
||||||
//temporary
|
|
||||||
uint16 LvlKills[9];
|
|
||||||
uint32 FirstItem;
|
|
||||||
uint8 MaxLvl;
|
|
||||||
bool AllKills;
|
|
||||||
|
|
||||||
EvolveInfo();
|
|
||||||
EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10);
|
|
||||||
~EvolveInfo();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*COMMON_ITEM_INSTANCE_H*/
|
#endif /*COMMON_ITEM_INSTANCE_H*/
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
#ifndef EQEMU_KSM_HPP
|
||||||
|
#define EQEMU_KSM_HPP
|
||||||
|
|
||||||
|
#include "../eqemu_logsys.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstring>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <malloc.h> // For _aligned_malloc, _aligned_free
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h> // For madvise
|
||||||
|
#include <unistd.h> // For sysconf, sbrk
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Page-aligned allocator for std::vector
|
||||||
|
template <typename T>
|
||||||
|
class PageAlignedAllocator {
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
PageAlignedAllocator() noexcept = default;
|
||||||
|
template <typename U>
|
||||||
|
PageAlignedAllocator(const PageAlignedAllocator<U>&) noexcept {}
|
||||||
|
|
||||||
|
T* allocate(std::size_t n) {
|
||||||
|
void* ptr = nullptr;
|
||||||
|
size_t size = n * sizeof(T);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Simply allocate memory without alignment
|
||||||
|
ptr = malloc(size);
|
||||||
|
if (!ptr) throw std::bad_alloc();
|
||||||
|
#else
|
||||||
|
size_t alignment = getPageSize(); // Get the system's page size
|
||||||
|
if (posix_memalign(&ptr, alignment, size) != 0) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return static_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T* p, std::size_t) noexcept {
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t getPageSize() const
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SYSTEM_INFO sysInfo;
|
||||||
|
GetSystemInfo(&sysInfo);
|
||||||
|
return sysInfo.dwPageSize; // Page size in bytes
|
||||||
|
#else
|
||||||
|
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool operator==(const PageAlignedAllocator<T>&, const PageAlignedAllocator<U>&) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool operator!=(const PageAlignedAllocator<T>&, const PageAlignedAllocator<U>&) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kernel Samepage Merging (KSM) functionality
|
||||||
|
namespace KSM {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Windows-specific placeholder functions (no-op)
|
||||||
|
inline void CheckPageAlignment(void* ptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* AllocatePageAligned(size_t size) {
|
||||||
|
return memset(malloc(size), 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MarkMemoryForKSM(void* start, size_t size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AlignHeapToPageBoundary() {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* MarkHeapStart() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t MeasureHeapUsage(void* start) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Linux-specific functionality
|
||||||
|
inline void CheckPageAlignment(void* ptr) {
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
if (reinterpret_cast<uintptr_t>(ptr) % page_size == 0) {
|
||||||
|
LogKSMDetail("Memory is page-aligned [{}]", ptr);
|
||||||
|
} else {
|
||||||
|
LogKSMDetail("Memory is NOT page-aligned [{}]", ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* AllocatePageAligned(size_t size) {
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
void* aligned_ptr = nullptr;
|
||||||
|
if (posix_memalign(&aligned_ptr, page_size, size) != 0) {
|
||||||
|
LogKSM("Failed to allocate page-aligned memory on Linux. page_size [{}] size [{}] bytes", page_size, size);
|
||||||
|
}
|
||||||
|
std::memset(aligned_ptr, 0, size);
|
||||||
|
return aligned_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MarkMemoryForKSM(void* start, size_t size) {
|
||||||
|
if (madvise(start, size, MADV_MERGEABLE) == 0) {
|
||||||
|
LogKSM("Marked memory for KSM | start [{}] size [{}] bytes", start, size);
|
||||||
|
} else {
|
||||||
|
perror("madvise failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AlignHeapToPageBoundary() {
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
if (page_size == 0) {
|
||||||
|
LogKSM("Failed to retrieve page size SC_PAGESIZE [{}]", page_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* current_break = sbrk(0);
|
||||||
|
if (current_break == (void*)-1) {
|
||||||
|
LogKSM("Failed to retrieve the current program break");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t current_address = reinterpret_cast<uintptr_t>(current_break);
|
||||||
|
size_t misalignment = current_address % page_size;
|
||||||
|
|
||||||
|
if (misalignment != 0) {
|
||||||
|
size_t adjustment = page_size - misalignment;
|
||||||
|
if (sbrk(adjustment) == (void*)-1) {
|
||||||
|
LogKSM("Failed to align heap to page boundary. adjustment [{}] bytes", adjustment);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogKSMDetail("Heap aligned to next page boundary. Current break [{}]", sbrk(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* MarkHeapStart() {
|
||||||
|
void* current_pos = sbrk(0);
|
||||||
|
AlignHeapToPageBoundary();
|
||||||
|
return current_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t MeasureHeapUsage(void* start) {
|
||||||
|
void* current_break = sbrk(0);
|
||||||
|
return static_cast<char*>(current_break) - static_cast<char*>(start);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t getPageSize()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SYSTEM_INFO sysInfo;
|
||||||
|
GetSystemInfo(&sysInfo);
|
||||||
|
return sysInfo.dwPageSize; // Page size in bytes
|
||||||
|
#else
|
||||||
|
return static_cast<size_t>(sysconf(_SC_PAGESIZE)); // POSIX page size
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void PageAlignVectorAligned(std::vector<T, PageAlignedAllocator<T>>& vec) {
|
||||||
|
if (vec.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t page_size = getPageSize();
|
||||||
|
void* start = vec.data();
|
||||||
|
size_t size = vec.size() * sizeof(T);
|
||||||
|
|
||||||
|
// Check if the memory is page-aligned
|
||||||
|
if (reinterpret_cast<std::uintptr_t>(start) % page_size != 0) {
|
||||||
|
// Allocate a new aligned vector
|
||||||
|
std::vector<T, PageAlignedAllocator<T>> aligned_vec(vec.get_allocator());
|
||||||
|
aligned_vec.reserve(vec.capacity()); // Match capacity to avoid reallocation during copy
|
||||||
|
|
||||||
|
// Copy elements from the original vector
|
||||||
|
aligned_vec.insert(aligned_vec.end(), vec.begin(), vec.end());
|
||||||
|
|
||||||
|
// Swap the aligned vector with the original vector
|
||||||
|
vec.swap(aligned_vec);
|
||||||
|
|
||||||
|
// Clear the temporary aligned vector to free its memory
|
||||||
|
aligned_vec.clear();
|
||||||
|
|
||||||
|
// Verify the new alignment
|
||||||
|
start = vec.data();
|
||||||
|
if (reinterpret_cast<std::uintptr_t>(start) % page_size != 0) {
|
||||||
|
throw std::runtime_error("Failed to align vector memory to page boundaries.");
|
||||||
|
}
|
||||||
|
|
||||||
|
LogKSMDetail("Vector reallocated to ensure page alignment. start [{}] size [{}] bytes", start, size);
|
||||||
|
} else {
|
||||||
|
LogKSMDetail("Vector is already page-aligned. start [{}] size [{}] bytes", start, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Mark memory for KSM (only on non-Windows systems)
|
||||||
|
MarkMemoryForKSM(start, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EQEMU_KSM_HPP
|
||||||
@@ -0,0 +1,600 @@
|
|||||||
|
#include "mysql_stmt.h"
|
||||||
|
#include "eqemu_logsys.h"
|
||||||
|
#include "mutex.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include <charconv>
|
||||||
|
|
||||||
|
namespace mysql
|
||||||
|
{
|
||||||
|
|
||||||
|
void PreparedStmt::StmtDeleter::operator()(MYSQL_STMT* stmt) noexcept
|
||||||
|
{
|
||||||
|
// The connection must be locked when closing the stmt to avoid mysql errors
|
||||||
|
// in case another thread tries to use it during the close. If the mutex is
|
||||||
|
// changed to one that throws then exceptions need to be caught here.
|
||||||
|
LockMutex lock(mutex);
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts)
|
||||||
|
: m_stmt(mysql_stmt_init(&mysql), { mutex }), m_query(std::move(query)), m_mutex(mutex), m_options(opts)
|
||||||
|
{
|
||||||
|
LockMutex lock(m_mutex);
|
||||||
|
if (mysql_stmt_prepare(m_stmt.get(), m_query.c_str(), static_cast<unsigned long>(m_query.size())) != 0)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Prepare error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_params.resize(mysql_stmt_param_count(m_stmt.get()));
|
||||||
|
m_inputs.resize(m_params.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreparedStmt::ThrowError(const std::string& error)
|
||||||
|
{
|
||||||
|
LogMySQLError("{}", error);
|
||||||
|
throw std::runtime_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PreparedStmt::GetStmtError()
|
||||||
|
{
|
||||||
|
auto err = mysql_stmt_errno(m_stmt.get());
|
||||||
|
auto str = mysql_stmt_error(m_stmt.get());
|
||||||
|
return fmt::format("({}) [{}] for query [{}]", err, str, m_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void PreparedStmt::BindInput(size_t index, T value)
|
||||||
|
{
|
||||||
|
if (index >= m_inputs.size())
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Cannot bind input, index {} out of range", index));
|
||||||
|
}
|
||||||
|
|
||||||
|
impl::Bind& arg = m_inputs[index];
|
||||||
|
arg.is_null = std::is_same_v<T, std::nullptr_t>;
|
||||||
|
|
||||||
|
MYSQL_BIND& bind = m_params[index];
|
||||||
|
bind.is_unsigned = std::is_unsigned_v<T>;
|
||||||
|
bind.is_null = &arg.is_null;
|
||||||
|
bind.length = &arg.length;
|
||||||
|
|
||||||
|
auto old_type = bind.buffer_type;
|
||||||
|
|
||||||
|
if constexpr (std::is_arithmetic_v<T>)
|
||||||
|
{
|
||||||
|
if (arg.buffer.size() < sizeof(T))
|
||||||
|
{
|
||||||
|
arg.buffer.resize(std::max(sizeof(T), sizeof(int64_t)));
|
||||||
|
bind.buffer = arg.buffer.data();
|
||||||
|
m_need_bind = true;
|
||||||
|
}
|
||||||
|
memcpy(arg.buffer.data(), &value, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, int8_t> || std::is_same_v<T, uint8_t> || std::is_same_v<T, bool>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_TINY;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, int16_t> || std::is_same_v<T, uint16_t>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_SHORT;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_LONG;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_LONGLONG;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, float>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_FLOAT;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, double>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_DOUBLE;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, std::string_view>)
|
||||||
|
{
|
||||||
|
bind.buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
if (arg.buffer.empty() || arg.buffer.size() < value.size())
|
||||||
|
{
|
||||||
|
arg.buffer.resize(static_cast<size_t>((value.size() + 1) * 1.5));
|
||||||
|
bind.buffer = arg.buffer.data();
|
||||||
|
bind.buffer_length = static_cast<unsigned long>(arg.buffer.size());
|
||||||
|
m_need_bind = true;
|
||||||
|
}
|
||||||
|
std::copy(value.begin(), value.end(), arg.buffer.begin());
|
||||||
|
arg.length = static_cast<unsigned long>(value.size());
|
||||||
|
}
|
||||||
|
else if constexpr (!std::is_same_v<T, std::nullptr_t>)
|
||||||
|
{
|
||||||
|
static_assert(false_v<T>, "Cannot bind unsupported type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_type != bind.buffer_type)
|
||||||
|
{
|
||||||
|
m_need_bind = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreparedStmt::BindInput(size_t index, const char* str)
|
||||||
|
{
|
||||||
|
BindInput(index, std::string_view(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreparedStmt::BindInput(size_t index, const std::string& str)
|
||||||
|
{
|
||||||
|
BindInput(index, std::string_view(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
StmtResult PreparedStmt::Execute()
|
||||||
|
{
|
||||||
|
CheckArgs(0);
|
||||||
|
return DoExecute();
|
||||||
|
}
|
||||||
|
|
||||||
|
StmtResult PreparedStmt::Execute(const std::vector<param_t>& args)
|
||||||
|
{
|
||||||
|
CheckArgs(args.size());
|
||||||
|
for (size_t i = 0; i < args.size(); ++i)
|
||||||
|
{
|
||||||
|
std::visit([&](const auto& arg) { BindInput(i, arg); }, args[i]);
|
||||||
|
}
|
||||||
|
return DoExecute();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
StmtResult PreparedStmt::Execute(const std::vector<T>& args)
|
||||||
|
{
|
||||||
|
CheckArgs(args.size());
|
||||||
|
for (size_t i = 0; i < args.size(); ++i)
|
||||||
|
{
|
||||||
|
BindInput(i, args[i]);
|
||||||
|
}
|
||||||
|
return DoExecute();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreparedStmt::CheckArgs(size_t argc)
|
||||||
|
{
|
||||||
|
if (argc != m_params.size())
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Bad arg count (got {}, expected {}) for [{}]", argc, m_params.size(), m_query));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StmtResult PreparedStmt::DoExecute()
|
||||||
|
{
|
||||||
|
BenchTimer timer;
|
||||||
|
LockMutex lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_need_bind && mysql_stmt_bind_param(m_stmt.get(), m_params.data()) != 0)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Bind param error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_need_bind = false;
|
||||||
|
|
||||||
|
if (mysql_stmt_execute(m_stmt.get()) != 0)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Execute error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
my_bool attr = m_options.use_max_length;
|
||||||
|
mysql_stmt_attr_set(m_stmt.get(), STMT_ATTR_UPDATE_MAX_LENGTH, &attr);
|
||||||
|
|
||||||
|
if (m_options.buffer_results && mysql_stmt_store_result(m_stmt.get()) != 0)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Store result error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result buffers are bound on first execute and re-used if needed
|
||||||
|
if (m_results.empty())
|
||||||
|
{
|
||||||
|
BindResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
StmtResult res(m_stmt.get(), m_results.size());
|
||||||
|
|
||||||
|
if (m_results.empty())
|
||||||
|
{
|
||||||
|
LogMySQLQuery("{} -- ({} row(s) affected) ({:.6f}s)", m_query, res.RowsAffected(), timer.elapsed());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogMySQLQuery("{} -- ({} row(s) returned) ({:.6f}s)", m_query, res.RowCount(), timer.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreparedStmt::BindResults()
|
||||||
|
{
|
||||||
|
MYSQL_RES* res = mysql_stmt_result_metadata(m_stmt.get());
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
return; // did not produce a result set
|
||||||
|
}
|
||||||
|
|
||||||
|
MYSQL_FIELD* fields = mysql_fetch_fields(res);
|
||||||
|
m_columns.resize(mysql_num_fields(res));
|
||||||
|
m_results.resize(m_columns.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < static_cast<int>(m_columns.size()); ++i)
|
||||||
|
{
|
||||||
|
impl::BindColumn& col = m_columns[i].m_col;
|
||||||
|
MYSQL_BIND& bind = m_results[i];
|
||||||
|
|
||||||
|
col.index = i;
|
||||||
|
col.name = fields[i].name;
|
||||||
|
col.buffer_type = fields[i].type;
|
||||||
|
col.is_unsigned = (fields[i].flags & UNSIGNED_FLAG) != 0;
|
||||||
|
col.buffer.resize(GetResultBufferSize(fields[i]));
|
||||||
|
|
||||||
|
bind.buffer_type = col.buffer_type;
|
||||||
|
bind.buffer = col.buffer.data();
|
||||||
|
bind.buffer_length = static_cast<unsigned long>(col.buffer.size());
|
||||||
|
bind.is_unsigned = col.is_unsigned;
|
||||||
|
bind.is_null = &col.is_null;
|
||||||
|
bind.length = &col.length;
|
||||||
|
bind.error = &col.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_free_result(res);
|
||||||
|
|
||||||
|
if (!m_results.empty() && mysql_stmt_bind_result(m_stmt.get(), m_results.data()) != 0)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Bind result error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PreparedStmt::GetResultBufferSize(const MYSQL_FIELD& field) const
|
||||||
|
{
|
||||||
|
switch (field.type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_TINY:
|
||||||
|
return sizeof(int8_t);
|
||||||
|
case MYSQL_TYPE_SHORT:
|
||||||
|
return sizeof(int16_t);
|
||||||
|
case MYSQL_TYPE_INT24:
|
||||||
|
case MYSQL_TYPE_LONG:
|
||||||
|
return sizeof(int32_t);
|
||||||
|
case MYSQL_TYPE_LONGLONG:
|
||||||
|
return sizeof(int64_t);
|
||||||
|
case MYSQL_TYPE_FLOAT:
|
||||||
|
return sizeof(float);
|
||||||
|
case MYSQL_TYPE_DOUBLE:
|
||||||
|
return sizeof(double);
|
||||||
|
case MYSQL_TYPE_TIME:
|
||||||
|
case MYSQL_TYPE_DATE:
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
case MYSQL_TYPE_TIMESTAMP:
|
||||||
|
return sizeof(MYSQL_TIME);
|
||||||
|
default: // if max_length is unavailable for strings buffers are resized on fetch
|
||||||
|
return field.max_length + 1; // ensure valid buffer created
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StmtRow PreparedStmt::Fetch()
|
||||||
|
{
|
||||||
|
StmtRow row;
|
||||||
|
if (!m_columns.empty())
|
||||||
|
{
|
||||||
|
int rc = mysql_stmt_fetch(m_stmt.get());
|
||||||
|
if (rc == 1)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Fetch error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != MYSQL_NO_DATA)
|
||||||
|
{
|
||||||
|
if (rc == MYSQL_DATA_TRUNCATED)
|
||||||
|
{
|
||||||
|
FetchTruncated();
|
||||||
|
}
|
||||||
|
row = StmtRow(m_columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreparedStmt::FetchTruncated()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < static_cast<int>(m_columns.size()); ++i)
|
||||||
|
{
|
||||||
|
impl::BindColumn& col = m_columns[i].m_col;
|
||||||
|
if (col.error)
|
||||||
|
{
|
||||||
|
MYSQL_BIND& bind = m_results[i];
|
||||||
|
col.buffer.resize(static_cast<size_t>(col.length * 1.5));
|
||||||
|
bind.buffer = col.buffer.data();
|
||||||
|
bind.buffer_length = static_cast<unsigned long>(col.buffer.size());
|
||||||
|
|
||||||
|
mysql_stmt_fetch_column(m_stmt.get(), &bind, i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mysql_stmt_bind_result(m_stmt.get(), m_results.data()) != 0)
|
||||||
|
{
|
||||||
|
ThrowError(fmt::format("Fetch rebind result error: {}", GetStmtError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
StmtResult::StmtResult(MYSQL_STMT* stmt, size_t columns)
|
||||||
|
{
|
||||||
|
m_num_cols = static_cast<int>(columns);
|
||||||
|
m_num_rows = mysql_stmt_num_rows(stmt); // requires buffered results
|
||||||
|
m_affected = mysql_stmt_affected_rows(stmt);
|
||||||
|
m_insert_id = mysql_stmt_insert_id(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const StmtColumn* StmtRow::GetColumn(size_t index) const
|
||||||
|
{
|
||||||
|
return index < m_columns.size() ? &m_columns[index] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StmtColumn* StmtRow::GetColumn(std::string_view name) const
|
||||||
|
{
|
||||||
|
auto it = std::ranges::find_if(m_columns,
|
||||||
|
[name](const StmtColumn& col) { return col.Name() == name; });
|
||||||
|
|
||||||
|
return it != m_columns.end() ? &(*it) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> StmtRow::operator[](size_t index) const
|
||||||
|
{
|
||||||
|
return GetStr(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> StmtRow::operator[](std::string_view name) const
|
||||||
|
{
|
||||||
|
return GetStr(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> StmtRow::GetStr(size_t index) const
|
||||||
|
{
|
||||||
|
const StmtColumn* col = GetColumn(index);
|
||||||
|
return col ? col->GetStr() : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> StmtRow::GetStr(std::string_view name) const
|
||||||
|
{
|
||||||
|
const StmtColumn* col = GetColumn(name);
|
||||||
|
return col ? col->GetStr() : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires std::is_arithmetic_v<T>
|
||||||
|
std::optional<T> StmtRow::Get(size_t index) const
|
||||||
|
{
|
||||||
|
const StmtColumn* col = GetColumn(index);
|
||||||
|
return col ? col->Get<T>() : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires std::is_arithmetic_v<T>
|
||||||
|
std::optional<T> StmtRow::Get(std::string_view name) const
|
||||||
|
{
|
||||||
|
const StmtColumn* col = GetColumn(name);
|
||||||
|
return col ? col->Get<T>() : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static time_t MakeTime(const MYSQL_TIME& mt)
|
||||||
|
{
|
||||||
|
// buffer mt given in mysql session time zone (assumes local)
|
||||||
|
std::tm tm{};
|
||||||
|
tm.tm_year = mt.year - 1900;
|
||||||
|
tm.tm_mon = mt.month - 1;
|
||||||
|
tm.tm_mday = mt.day;
|
||||||
|
tm.tm_hour = mt.hour;
|
||||||
|
tm.tm_min = mt.minute;
|
||||||
|
tm.tm_sec = mt.second;
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
return std::mktime(&tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int MakeSeconds(const MYSQL_TIME& mt)
|
||||||
|
{
|
||||||
|
return (mt.neg ? -1 : 1) * static_cast<int>(mt.hour * 3600 + mt.minute * 60 + mt.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t MakeBits(std::span<const uint8_t> data)
|
||||||
|
{
|
||||||
|
// byte stream for bits is in big endian
|
||||||
|
uint64_t bits = 0;
|
||||||
|
for (size_t i = 0; i < data.size() && i < sizeof(uint64_t); ++i)
|
||||||
|
{
|
||||||
|
bits |= static_cast<uint64_t>(data[data.size() - i - 1] & 0xff) << (i * 8);
|
||||||
|
}
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept has_from_chars = requires (const char* first, const char* last, T value)
|
||||||
|
{
|
||||||
|
std::from_chars(first, last, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T FromString(std::string_view sv)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<T, bool>)
|
||||||
|
{
|
||||||
|
// return false for empty (zero-length) strings
|
||||||
|
return !sv.empty();
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, float> && !has_from_chars<T>)
|
||||||
|
{
|
||||||
|
return std::strtof(std::string(sv).c_str(), nullptr);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, double> && !has_from_chars<T>)
|
||||||
|
{
|
||||||
|
return std::strtod(std::string(sv).c_str(), nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// non numbers return a zero initialized T (could return nullopt instead)
|
||||||
|
T value = {};
|
||||||
|
std::from_chars(sv.data(), sv.data() + sv.size(), value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string FormatTime(enum_field_types type, const MYSQL_TIME& mt)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_TIME: // hhh:mm:ss '-838:59:59' to '838:59:59'
|
||||||
|
return fmt::format("{}{:02d}:{:02d}:{:02d}", mt.neg ? "-" : "", mt.hour, mt.minute, mt.second);
|
||||||
|
case MYSQL_TYPE_DATE: // YYYY-MM-DD '1000-01-01' to '9999-12-31'
|
||||||
|
return fmt::format("{}-{:02d}-{:02d}", mt.year, mt.month, mt.day);
|
||||||
|
case MYSQL_TYPE_DATETIME: // YYYY-MM-DD hh:mm:ss '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
|
||||||
|
case MYSQL_TYPE_TIMESTAMP: // YYYY-MM-DD hh:mm:ss '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC
|
||||||
|
return fmt::format("{}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}", mt.year, mt.month, mt.day, mt.hour, mt.minute, mt.second);
|
||||||
|
default:
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string_view> StmtColumn::GetStrView() const
|
||||||
|
{
|
||||||
|
if (m_col.is_null)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_col.buffer_type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
return std::make_optional<std::string_view>(reinterpret_cast<const char*>(m_col.buffer.data()), m_col.length);
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> StmtColumn::GetStr() const
|
||||||
|
{
|
||||||
|
if (m_col.is_null)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_col.buffer_type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_TINY:
|
||||||
|
return m_col.is_unsigned ? fmt::format_int(BitCast<uint8_t>()).c_str() : fmt::format_int(BitCast<int8_t>()).c_str();
|
||||||
|
case MYSQL_TYPE_SHORT:
|
||||||
|
return m_col.is_unsigned ? fmt::format_int(BitCast<uint16_t>()).c_str() : fmt::format_int(BitCast<int16_t>()).c_str();
|
||||||
|
case MYSQL_TYPE_INT24:
|
||||||
|
case MYSQL_TYPE_LONG:
|
||||||
|
return m_col.is_unsigned ? fmt::format_int(BitCast<uint32_t>()).c_str() : fmt::format_int(BitCast<int32_t>()).c_str();
|
||||||
|
case MYSQL_TYPE_LONGLONG:
|
||||||
|
return m_col.is_unsigned ? fmt::format_int(BitCast<uint64_t>()).c_str() : fmt::format_int(BitCast<int64_t>()).c_str();
|
||||||
|
case MYSQL_TYPE_FLOAT:
|
||||||
|
return fmt::format("{}", BitCast<float>());
|
||||||
|
case MYSQL_TYPE_DOUBLE:
|
||||||
|
return fmt::format("{}", BitCast<double>());
|
||||||
|
case MYSQL_TYPE_TIME:
|
||||||
|
case MYSQL_TYPE_DATE:
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
case MYSQL_TYPE_TIMESTAMP:
|
||||||
|
return FormatTime(m_col.buffer_type, BitCast<MYSQL_TIME>());
|
||||||
|
case MYSQL_TYPE_BIT:
|
||||||
|
return fmt::format_int(*Get<uint64_t>()).c_str();
|
||||||
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
return std::make_optional<std::string>(reinterpret_cast<const char*>(m_col.buffer.data()), m_col.length);
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires std::is_arithmetic_v<T>
|
||||||
|
std::optional<T> StmtColumn::Get() const
|
||||||
|
{
|
||||||
|
if (m_col.is_null)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_col.buffer_type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_TINY:
|
||||||
|
return m_col.is_unsigned ? static_cast<T>(BitCast<uint8_t>()) : static_cast<T>(BitCast<int8_t>());
|
||||||
|
case MYSQL_TYPE_SHORT:
|
||||||
|
return m_col.is_unsigned ? static_cast<T>(BitCast<uint16_t>()) : static_cast<T>(BitCast<int16_t>());
|
||||||
|
case MYSQL_TYPE_INT24:
|
||||||
|
case MYSQL_TYPE_LONG:
|
||||||
|
return m_col.is_unsigned ? static_cast<T>(BitCast<uint32_t>()) : static_cast<T>(BitCast<int32_t>());
|
||||||
|
case MYSQL_TYPE_LONGLONG:
|
||||||
|
return m_col.is_unsigned ? static_cast<T>(BitCast<uint64_t>()) : static_cast<T>(BitCast<int64_t>());
|
||||||
|
case MYSQL_TYPE_FLOAT:
|
||||||
|
return static_cast<T>(BitCast<float>());
|
||||||
|
case MYSQL_TYPE_DOUBLE:
|
||||||
|
return static_cast<T>(BitCast<double>());
|
||||||
|
case MYSQL_TYPE_TIME: // return as total seconds
|
||||||
|
return static_cast<T>(MakeSeconds(BitCast<MYSQL_TIME>()));
|
||||||
|
case MYSQL_TYPE_DATE:
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
case MYSQL_TYPE_TIMESTAMP: // return as epoch timestamp
|
||||||
|
return static_cast<T>(MakeTime(BitCast<MYSQL_TIME>()));
|
||||||
|
case MYSQL_TYPE_BIT:
|
||||||
|
return static_cast<T>(MakeBits({ m_col.buffer.data(), m_col.length }));
|
||||||
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
return FromString<T>({ reinterpret_cast<const char*>(m_col.buffer.data()), m_col.length });
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// explicit template instantiations for supported types
|
||||||
|
template void PreparedStmt::BindInput(size_t, std::string_view);
|
||||||
|
template void PreparedStmt::BindInput(size_t, std::nullptr_t);
|
||||||
|
template StmtResult PreparedStmt::Execute(const std::vector<std::string_view>&);
|
||||||
|
template StmtResult PreparedStmt::Execute(const std::vector<std::string>&);
|
||||||
|
template StmtResult PreparedStmt::Execute(const std::vector<const char*>&);
|
||||||
|
|
||||||
|
#define INSTANTIATE(T) \
|
||||||
|
template void PreparedStmt::BindInput(size_t, T); \
|
||||||
|
template StmtResult PreparedStmt::Execute(const std::vector<T>&); \
|
||||||
|
template std::optional<T> StmtRow::Get(size_t) const; \
|
||||||
|
template std::optional<T> StmtRow::Get(std::string_view) const; \
|
||||||
|
template std::optional<T> StmtColumn::Get() const;
|
||||||
|
|
||||||
|
INSTANTIATE(bool);
|
||||||
|
INSTANTIATE(int8_t);
|
||||||
|
INSTANTIATE(uint8_t);
|
||||||
|
INSTANTIATE(int16_t);
|
||||||
|
INSTANTIATE(uint16_t);
|
||||||
|
INSTANTIATE(int32_t);
|
||||||
|
INSTANTIATE(uint32_t);
|
||||||
|
INSTANTIATE(int64_t);
|
||||||
|
INSTANTIATE(uint64_t);
|
||||||
|
INSTANTIATE(float);
|
||||||
|
INSTANTIATE(double);
|
||||||
|
|
||||||
|
} // namespace mysql
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mysql.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <span>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Mutex;
|
||||||
|
|
||||||
|
namespace mysql
|
||||||
|
{
|
||||||
|
|
||||||
|
// support MySQL 8.0.1+ API which removed the my_bool type
|
||||||
|
#if !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 80001
|
||||||
|
using my_bool = bool;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
inline constexpr bool false_v = false;
|
||||||
|
|
||||||
|
namespace impl
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Bind
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> buffer;
|
||||||
|
unsigned long length = 0;
|
||||||
|
my_bool is_null = false;
|
||||||
|
my_bool error = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BindColumn : Bind
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
std::string name;
|
||||||
|
bool is_unsigned = false;
|
||||||
|
enum_field_types buffer_type = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace impl
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct StmtOptions
|
||||||
|
{
|
||||||
|
// Enable buffering (storing) entire result set after executing a statement
|
||||||
|
bool buffer_results = true;
|
||||||
|
|
||||||
|
// Enable MySQL to update max_length of fields in execute result set (requires buffering)
|
||||||
|
bool use_max_length = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Holds ownership of bound column value buffer
|
||||||
|
class StmtColumn
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int Index() const { return m_col.index; }
|
||||||
|
bool IsNull() const { return m_col.is_null; }
|
||||||
|
bool IsUnsigned() const { return m_col.is_unsigned; }
|
||||||
|
enum_field_types Type() const { return m_col.buffer_type; }
|
||||||
|
const std::string& Name() const { return m_col.name; }
|
||||||
|
|
||||||
|
// Get view of column value buffer
|
||||||
|
std::span<const uint8_t> GetBuf() const { return { m_col.buffer.data(), m_col.length }; }
|
||||||
|
|
||||||
|
// Get view of column string value. Returns nullopt if value is NULL or not a string
|
||||||
|
std::optional<std::string_view> GetStrView() const;
|
||||||
|
|
||||||
|
// Get column value as string. Returns nullopt if value is NULL or field type unsupported
|
||||||
|
std::optional<std::string> GetStr() const;
|
||||||
|
|
||||||
|
// Get column value as numeric T. Returns nullopt if value NULL or field type unsupported
|
||||||
|
template <typename T> requires std::is_arithmetic_v<T>
|
||||||
|
std::optional<T> Get() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// uses memcpy for type punning buffer data to avoid UB with strict aliasing
|
||||||
|
template <typename T>
|
||||||
|
T BitCast() const
|
||||||
|
{
|
||||||
|
T val;
|
||||||
|
assert(sizeof(T) == m_col.length);
|
||||||
|
memcpy(&val, m_col.buffer.data(), sizeof(T));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class PreparedStmt; // access to allocate and bind buffers
|
||||||
|
friend class StmtResult; // access to resize truncated buffers
|
||||||
|
impl::BindColumn m_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Provides a non-owning view of PreparedStmt column value buffers
|
||||||
|
// Evaluates false if it does not contain a valid row
|
||||||
|
class StmtRow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StmtRow() = default;
|
||||||
|
StmtRow(std::span<const StmtColumn> columns) : m_columns(columns) {};
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept { return !m_columns.empty(); }
|
||||||
|
|
||||||
|
int ColumnCount() const { return static_cast<int>(m_columns.size()); }
|
||||||
|
const StmtColumn* GetColumn(size_t index) const;
|
||||||
|
const StmtColumn* GetColumn(std::string_view name) const;
|
||||||
|
|
||||||
|
// Get specified column value as string
|
||||||
|
// Returns nullopt if column invalid, value is NULL, or field type unsupported
|
||||||
|
std::optional<std::string> operator[](size_t index) const;
|
||||||
|
std::optional<std::string> operator[](std::string_view name) const;
|
||||||
|
std::optional<std::string> GetStr(size_t index) const;
|
||||||
|
std::optional<std::string> GetStr(std::string_view name) const;
|
||||||
|
|
||||||
|
// Get specified column value as numeric T
|
||||||
|
// Returns nullopt if column invalid, value is NULL, or field type unsupported
|
||||||
|
template <typename T> requires std::is_arithmetic_v<T>
|
||||||
|
std::optional<T> Get(size_t index) const;
|
||||||
|
|
||||||
|
template <typename T> requires std::is_arithmetic_v<T>
|
||||||
|
std::optional<T> Get(std::string_view name) const;
|
||||||
|
|
||||||
|
auto begin() const { return m_columns.begin(); }
|
||||||
|
auto end() const { return m_columns.end(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::span<const StmtColumn> m_columns;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Result meta data for an executed prepared statement
|
||||||
|
class StmtResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StmtResult() = default;
|
||||||
|
StmtResult(MYSQL_STMT* stmt, size_t columns);
|
||||||
|
|
||||||
|
int ColumnCount() const { return m_num_cols; }
|
||||||
|
uint64_t RowCount() const { return m_num_rows; }
|
||||||
|
uint64_t RowsAffected() const { return m_affected; }
|
||||||
|
uint64_t LastInsertID() const { return m_insert_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_num_cols = 0;
|
||||||
|
uint64_t m_num_rows = 0;
|
||||||
|
uint64_t m_affected = 0;
|
||||||
|
uint64_t m_insert_id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class PreparedStmt
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Supported argument types for execute
|
||||||
|
using param_t = std::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
|
||||||
|
int64_t, uint64_t, float, double, bool, std::string_view, std::nullptr_t>;
|
||||||
|
|
||||||
|
PreparedStmt() = delete;
|
||||||
|
PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts = {});
|
||||||
|
|
||||||
|
const std::string& GetQuery() const { return m_query; }
|
||||||
|
StmtOptions GetOptions() const { return m_options; }
|
||||||
|
void SetOptions(StmtOptions options) { m_options = options; }
|
||||||
|
void FreeResult() { mysql_stmt_free_result(m_stmt.get()); }
|
||||||
|
|
||||||
|
// Execute the prepared statement with specified arguments
|
||||||
|
// Throws exception on error
|
||||||
|
template <typename T>
|
||||||
|
StmtResult Execute(const std::vector<T>& args);
|
||||||
|
StmtResult Execute(const std::vector<param_t>& args);
|
||||||
|
StmtResult Execute();
|
||||||
|
|
||||||
|
// Fetch the next row into column buffers (overwrites previous row values)
|
||||||
|
// Return value evaluates false if no more rows to fetch
|
||||||
|
// Throws exception on error
|
||||||
|
StmtRow Fetch();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CheckArgs(size_t argc);
|
||||||
|
StmtResult DoExecute();
|
||||||
|
void BindResults();
|
||||||
|
void FetchTruncated();
|
||||||
|
int GetResultBufferSize(const MYSQL_FIELD& field) const;
|
||||||
|
void ThrowError(const std::string& error);
|
||||||
|
std::string GetStmtError();
|
||||||
|
|
||||||
|
// bind an input value to a query parameter by index
|
||||||
|
template <typename T>
|
||||||
|
void BindInput(size_t index, T value);
|
||||||
|
void BindInput(size_t index, const char* str);
|
||||||
|
void BindInput(size_t index, const std::string& str);
|
||||||
|
|
||||||
|
struct StmtDeleter
|
||||||
|
{
|
||||||
|
Mutex* mutex = nullptr;
|
||||||
|
void operator()(MYSQL_STMT* stmt) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<MYSQL_STMT, StmtDeleter> m_stmt;
|
||||||
|
std::vector<MYSQL_BIND> m_params; // input binds
|
||||||
|
std::vector<MYSQL_BIND> m_results; // result binds
|
||||||
|
std::vector<impl::Bind> m_inputs; // execute buffers (addresses bound)
|
||||||
|
std::vector<StmtColumn> m_columns; // fetch buffers (addresses bound)
|
||||||
|
std::string m_query;
|
||||||
|
StmtOptions m_options = {};
|
||||||
|
bool m_need_bind = true;
|
||||||
|
Mutex* m_mutex = nullptr; // connection mutex
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mysql
|
||||||
@@ -1091,49 +1091,81 @@ void EQ::Net::DaybreakConnection::ProcessResend()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// observed client receive window is 300 packets, 140KB
|
||||||
|
constexpr size_t MAX_CLIENT_RECV_PACKETS_PER_WINDOW = 300;
|
||||||
|
constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||||
{
|
{
|
||||||
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resends = 0;
|
if (m_streams[stream].sent_packets.empty()) {
|
||||||
auto now = Clock::now();
|
|
||||||
auto s = &m_streams[stream];
|
|
||||||
for (auto &entry : s->sent_packets) {
|
|
||||||
auto time_since_last_send = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.last_sent);
|
|
||||||
if (entry.second.times_resent == 0) {
|
|
||||||
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
|
|
||||||
auto &p = entry.second.packet;
|
|
||||||
if (p.Length() >= DaybreakHeader::size()) {
|
|
||||||
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
|
||||||
m_stats.resent_fragments++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_stats.resent_full++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_stats.resent_full++;
|
|
||||||
}
|
|
||||||
m_stats.resent_packets++;
|
|
||||||
|
|
||||||
InternalBufferedSend(p);
|
|
||||||
entry.second.last_sent = now;
|
|
||||||
entry.second.times_resent++;
|
|
||||||
entry.second.resend_delay = EQ::Clamp(entry.second.resend_delay * 2, m_owner->m_options.resend_delay_min, m_owner->m_options.resend_delay_max);
|
|
||||||
resends++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.first_sent);
|
|
||||||
if (time_since_first_sent.count() >= m_owner->m_options.resend_timeout) {
|
|
||||||
Close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
|
m_resend_packets_sent = 0;
|
||||||
auto &p = entry.second.packet;
|
m_resend_bytes_sent = 0;
|
||||||
|
|
||||||
|
auto now = Clock::now(); // Current time
|
||||||
|
auto s = &m_streams[stream];
|
||||||
|
|
||||||
|
// Get a reference resend delay (assume first packet represents the typical case)
|
||||||
|
if (!s->sent_packets.empty()) {
|
||||||
|
// Check if the first packet has timed out
|
||||||
|
auto &first_packet = s->sent_packets.begin()->second;
|
||||||
|
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - first_packet.first_sent).count();
|
||||||
|
|
||||||
|
// make sure that the first_packet in the list first_sent time is within the resend_delay and now
|
||||||
|
// if it is not, then we need to resend all packets in the list
|
||||||
|
if (time_since_first_sent <= first_packet.resend_delay && !m_acked_since_last_resend) {
|
||||||
|
LogNetcodeDetail(
|
||||||
|
"Not resending packets for stream [{}] time since first sent [{}] resend delay [{}] m_acked_since_last_resend [{}]",
|
||||||
|
stream,
|
||||||
|
time_since_first_sent,
|
||||||
|
first_packet.resend_delay,
|
||||||
|
m_acked_since_last_resend
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_since_first_sent >= m_owner->m_options.resend_timeout) {
|
||||||
|
Close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Netcode)) {
|
||||||
|
size_t total_size = 0;
|
||||||
|
for (auto &e: s->sent_packets) {
|
||||||
|
total_size += e.second.packet.Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogNetcodeDetail(
|
||||||
|
"Resending packets for stream [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
|
||||||
|
stream,
|
||||||
|
s->sent_packets.size(),
|
||||||
|
total_size,
|
||||||
|
m_acked_since_last_resend
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &e: s->sent_packets) {
|
||||||
|
if (m_resend_packets_sent >= MAX_CLIENT_RECV_PACKETS_PER_WINDOW ||
|
||||||
|
m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) {
|
||||||
|
LogNetcodeDetail(
|
||||||
|
"Stopping resend because we hit thresholds m_resend_packets_sent [{}] max [{}] m_resend_bytes_sent [{}] max [{}]",
|
||||||
|
m_resend_packets_sent,
|
||||||
|
MAX_CLIENT_RECV_PACKETS_PER_WINDOW,
|
||||||
|
m_resend_bytes_sent,
|
||||||
|
MAX_CLIENT_RECV_BYTES_PER_WINDOW
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &sp = e.second;
|
||||||
|
auto &p = sp.packet;
|
||||||
if (p.Length() >= DaybreakHeader::size()) {
|
if (p.Length() >= DaybreakHeader::size()) {
|
||||||
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
||||||
m_stats.resent_fragments++;
|
m_stats.resent_fragments++;
|
||||||
@@ -1147,14 +1179,21 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
}
|
}
|
||||||
m_stats.resent_packets++;
|
m_stats.resent_packets++;
|
||||||
|
|
||||||
|
// Resend the packet
|
||||||
InternalBufferedSend(p);
|
InternalBufferedSend(p);
|
||||||
entry.second.last_sent = now;
|
|
||||||
entry.second.times_resent++;
|
m_resend_packets_sent++;
|
||||||
entry.second.resend_delay = EQ::Clamp(entry.second.resend_delay * 2, m_owner->m_options.resend_delay_min, m_owner->m_options.resend_delay_max);
|
m_resend_bytes_sent += p.Length();
|
||||||
resends++;
|
sp.last_sent = now;
|
||||||
}
|
sp.times_resent++;
|
||||||
}
|
sp.resend_delay = EQ::Clamp(
|
||||||
|
sp.resend_delay * 2,
|
||||||
|
m_owner->m_options.resend_delay_min,
|
||||||
|
m_owner->m_options.resend_delay_max
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_acked_since_last_resend = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
||||||
@@ -1175,6 +1214,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
|||||||
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
||||||
|
|
||||||
iter = s->sent_packets.erase(iter);
|
iter = s->sent_packets.erase(iter);
|
||||||
|
m_acked_since_last_resend = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++iter;
|
++iter;
|
||||||
|
|||||||
@@ -181,6 +181,11 @@ namespace EQ
|
|||||||
Timestamp m_close_time;
|
Timestamp m_close_time;
|
||||||
double m_outgoing_budget;
|
double m_outgoing_budget;
|
||||||
|
|
||||||
|
// resend tracking
|
||||||
|
size_t m_resend_packets_sent = 0;
|
||||||
|
size_t m_resend_bytes_sent = 0;
|
||||||
|
bool m_acked_since_last_resend = false;
|
||||||
|
|
||||||
struct DaybreakSentPacket
|
struct DaybreakSentPacket
|
||||||
{
|
{
|
||||||
DynamicPacket packet;
|
DynamicPacket packet;
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ namespace EQ
|
|||||||
bool Connected() const { return m_connecting != true; }
|
bool Connected() const { return m_connecting != true; }
|
||||||
|
|
||||||
std::shared_ptr<EQ::Net::TCPConnection> Handle() { return m_connection; }
|
std::shared_ptr<EQ::Net::TCPConnection> Handle() { return m_connection; }
|
||||||
|
|
||||||
|
const std::unique_ptr<EQ::Timer> &GetTimer() const { return m_timer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Connect();
|
void Connect();
|
||||||
void ProcessData(EQ::Net::TCPConnection *c, const unsigned char *data, size_t length);
|
void ProcessData(EQ::Net::TCPConnection *c, const unsigned char *data, size_t length);
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
|
|||||||
{
|
{
|
||||||
size_t current = 0;
|
size_t current = 0;
|
||||||
size_t total = m_buffer.size();
|
size_t total = m_buffer.size();
|
||||||
constexpr size_t ls_info_size = sizeof(ServerNewLSInfo_Struct);
|
constexpr size_t ls_info_size = sizeof(LoginserverNewWorldRequest);
|
||||||
|
|
||||||
while (current < total) {
|
while (current < total) {
|
||||||
auto left = total - current;
|
auto left = total - current;
|
||||||
@@ -138,7 +138,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
|
|||||||
//this creates a small edge case where the exact size of a
|
//this creates a small edge case where the exact size of a
|
||||||
//packet from the modern protocol can't be "43061256"
|
//packet from the modern protocol can't be "43061256"
|
||||||
//so in send we pad it one byte if that's the case
|
//so in send we pad it one byte if that's the case
|
||||||
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(ServerNewLSInfo_Struct)) {
|
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(LoginserverNewWorldRequest)) {
|
||||||
m_legacy_mode = true;
|
m_legacy_mode = true;
|
||||||
m_identifier = "World";
|
m_identifier = "World";
|
||||||
m_parent->ConnectionIdentified(this);
|
m_parent->ConnectionIdentified(this);
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ void EQ::Net::TCPConnection::Start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nread == UV_EOF) {
|
else if (nread == UV_EOF) {
|
||||||
|
connection->Disconnect();
|
||||||
|
|
||||||
if (buf->base) {
|
if (buf->base) {
|
||||||
delete[] buf->base;
|
delete[] buf->base;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ IN(OP_RecipeDetails, uint32);
|
|||||||
//there is also a complicated OP_RecipeDetails reply struct OUT
|
//there is also a complicated OP_RecipeDetails reply struct OUT
|
||||||
IN(OP_RecipeAutoCombine, RecipeAutoCombine_Struct);
|
IN(OP_RecipeAutoCombine, RecipeAutoCombine_Struct);
|
||||||
IN(OP_TradeSkillCombine, NewCombine_Struct);
|
IN(OP_TradeSkillCombine, NewCombine_Struct);
|
||||||
|
IN(OP_TradeSkillRecipeInspect, TradeSkillRecipeInspect_Struct);
|
||||||
IN(OP_ItemName, ItemNamePacket_Struct);
|
IN(OP_ItemName, ItemNamePacket_Struct);
|
||||||
IN(OP_AugmentItem, AugmentItem_Struct);
|
IN(OP_AugmentItem, AugmentItem_Struct);
|
||||||
IN(OP_ClickDoor, ClickDoor_Struct);
|
IN(OP_ClickDoor, ClickDoor_Struct);
|
||||||
@@ -250,6 +251,7 @@ IN(OP_TraderBuy, TraderBuy_Struct);
|
|||||||
IN(OP_Trader, Trader_ShowItems_Struct);
|
IN(OP_Trader, Trader_ShowItems_Struct);
|
||||||
IN(OP_GMFind, GMSummon_Struct);
|
IN(OP_GMFind, GMSummon_Struct);
|
||||||
IN(OP_PickPocket, PickPocket_Struct);
|
IN(OP_PickPocket, PickPocket_Struct);
|
||||||
|
IN(OP_PickZone, PickZone_Struct);
|
||||||
IN(OP_Bind_Wound, BindWound_Struct);
|
IN(OP_Bind_Wound, BindWound_Struct);
|
||||||
INr(OP_TrackTarget);
|
INr(OP_TrackTarget);
|
||||||
INr(OP_Track);
|
INr(OP_Track);
|
||||||
|
|||||||
+32
-27
@@ -3494,14 +3494,13 @@ namespace RoF
|
|||||||
ENCODE_LENGTH_EXACT(ClickTrader_Struct);
|
ENCODE_LENGTH_EXACT(ClickTrader_Struct);
|
||||||
SETUP_DIRECT_ENCODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
SETUP_DIRECT_ENCODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||||
|
|
||||||
eq->Code = emu->Code;
|
eq->Code = emu->action;
|
||||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
for (uint32 i = 0; i < RoF::invtype::BAZAAR_SIZE; i++)
|
||||||
for (uint32 i = 0; i < 200; i++)
|
|
||||||
{
|
{
|
||||||
strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
||||||
eq->items[i].Unknown18 = 0;
|
eq->items[i].Unknown18 = 0;
|
||||||
if (i < 80) {
|
if (i < 80) {
|
||||||
eq->ItemCost[i] = emu->ItemCost[i];
|
eq->ItemCost[i] = emu->item_cost[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
eq->ItemCost[i] = 0;
|
eq->ItemCost[i] = 0;
|
||||||
@@ -3515,9 +3514,9 @@ namespace RoF
|
|||||||
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
|
||||||
eq->Code = emu->Code;
|
eq->Code = emu->action;
|
||||||
strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
||||||
eq->TraderID = emu->TraderID;
|
eq->TraderID = emu->entity_id;
|
||||||
eq->Stacksize = 0;
|
eq->Stacksize = 0;
|
||||||
eq->Price = 0;
|
eq->Price = 0;
|
||||||
|
|
||||||
@@ -3543,13 +3542,13 @@ namespace RoF
|
|||||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
|
||||||
OUT(Action);
|
OUT(action);
|
||||||
OUT(Price);
|
OUT(price);
|
||||||
OUT(TraderID);
|
OUT(trader_id);
|
||||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
OUT(ItemID);
|
OUT(item_id);
|
||||||
OUT(Quantity);
|
OUT(quantity);
|
||||||
OUT(AlreadySold);
|
OUT(already_sold);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -5041,12 +5040,11 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||||
MEMSET_IN(ClickTrader_Struct);
|
MEMSET_IN(ClickTrader_Struct);
|
||||||
|
|
||||||
emu->Code = eq->Code;
|
emu->action = eq->Code;
|
||||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
for (uint32 i = 0; i < RoF::invtype::BAZAAR_SIZE; i++)
|
||||||
for (uint32 i = 0; i < 80; i++)
|
|
||||||
{
|
{
|
||||||
emu->SerialNumber[i] = 0; // eq->SerialNumber[i];
|
emu->serial_number[i] = 0; // eq->SerialNumber[i];
|
||||||
emu->ItemCost[i] = eq->ItemCost[i];
|
emu->item_cost[i] = eq->ItemCost[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
@@ -5057,8 +5055,8 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
MEMSET_IN(Trader_ShowItems_Struct);
|
MEMSET_IN(Trader_ShowItems_Struct);
|
||||||
|
|
||||||
emu->Code = eq->Code;
|
emu->action = eq->Code;
|
||||||
emu->TraderID = eq->TraderID;
|
emu->entity_id = eq->TraderID;
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -5080,12 +5078,12 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
MEMSET_IN(TraderBuy_Struct);
|
MEMSET_IN(TraderBuy_Struct);
|
||||||
|
|
||||||
IN(Action);
|
IN(action);
|
||||||
IN(Price);
|
IN(price);
|
||||||
IN(TraderID);
|
IN(trader_id);
|
||||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||||
IN(ItemID);
|
IN(item_id);
|
||||||
IN(Quantity);
|
IN(quantity);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -5190,7 +5188,14 @@ namespace RoF
|
|||||||
|
|
||||||
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
||||||
|
|
||||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
|
strn0cpy(
|
||||||
|
hdr.unknown000,
|
||||||
|
fmt::format(
|
||||||
|
"{:016}\0",
|
||||||
|
packet_type == ItemPacketInvalid ? 0 : inst->GetSerialNumber()
|
||||||
|
).c_str(),
|
||||||
|
sizeof(hdr.unknown000)
|
||||||
|
);
|
||||||
|
|
||||||
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
|
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
|
||||||
hdr.unknown004 = 0;
|
hdr.unknown004 = 0;
|
||||||
|
|||||||
+1156
-248
File diff suppressed because it is too large
Load Diff
@@ -86,7 +86,7 @@ namespace RoF2
|
|||||||
const int16 TRIBUTE_SIZE = 5;
|
const int16 TRIBUTE_SIZE = 5;
|
||||||
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
|
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
|
||||||
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
|
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
|
||||||
const int16 MERCHANT_SIZE = 200;
|
const int16 MERCHANT_SIZE = 500;
|
||||||
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
|
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
|
||||||
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
|
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
|
||||||
const int16 BAZAAR_SIZE = 200;
|
const int16 BAZAAR_SIZE = 200;
|
||||||
@@ -162,9 +162,30 @@ namespace RoF2
|
|||||||
} // namespace enum_
|
} // namespace enum_
|
||||||
using namespace enum_;
|
using namespace enum_;
|
||||||
|
|
||||||
|
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||||
const int16 SLOT_INVALID = IINVALID;
|
const int16 SLOT_INVALID = IINVALID;
|
||||||
const int16 SLOT_BEGIN = INULL;
|
const int16 SLOT_BEGIN = INULL;
|
||||||
|
|
||||||
|
const int16 BANK_BEGIN = 2000;
|
||||||
|
const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1;
|
||||||
|
|
||||||
|
const int16 SHARED_BANK_BEGIN = 2500;
|
||||||
|
const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1;
|
||||||
|
|
||||||
|
const int16 TRADE_BEGIN = 3000;
|
||||||
|
const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1;
|
||||||
|
|
||||||
|
const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication
|
||||||
|
|
||||||
|
const int16 WORLD_BEGIN = 4000;
|
||||||
|
const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1;
|
||||||
|
|
||||||
|
const int16 TRIBUTE_BEGIN = 400;
|
||||||
|
const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1;
|
||||||
|
|
||||||
|
const int16 GUILD_TRIBUTE_BEGIN = 450;
|
||||||
|
const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1;
|
||||||
|
|
||||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||||
const int16 POSSESSIONS_END = slotCursor;
|
const int16 POSSESSIONS_END = slotCursor;
|
||||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||||
@@ -199,10 +220,21 @@ namespace RoF2
|
|||||||
namespace invbag {
|
namespace invbag {
|
||||||
inline EQ::versions::ClientVersion GetInvBagRef() { return EQ::versions::ClientVersion::RoF2; }
|
inline EQ::versions::ClientVersion GetInvBagRef() { return EQ::versions::ClientVersion::RoF2; }
|
||||||
|
|
||||||
|
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||||
const int16 SLOT_INVALID = IINVALID;
|
const int16 SLOT_INVALID = IINVALID;
|
||||||
const int16 SLOT_BEGIN = INULL;
|
const int16 SLOT_BEGIN = INULL;
|
||||||
const int16 SLOT_END = 9; //254;
|
const int16 SLOT_COUNT = 200;
|
||||||
const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test)
|
const int16 SLOT_END = SLOT_COUNT - 1;
|
||||||
|
|
||||||
|
const int16 GENERAL_BAGS_BEGIN = 251;
|
||||||
|
|
||||||
|
const int16 CURSOR_BAG_BEGIN = 351;
|
||||||
|
|
||||||
|
const int16 BANK_BAGS_BEGIN = 2031;
|
||||||
|
|
||||||
|
const int16 SHARED_BANK_BAGS_BEGIN = 2531;
|
||||||
|
|
||||||
|
const int16 TRADE_BAGS_BEGIN = 3031;
|
||||||
|
|
||||||
const char* GetInvBagIndexName(int16 bag_index);
|
const char* GetInvBagIndexName(int16 bag_index);
|
||||||
|
|
||||||
@@ -272,6 +304,7 @@ namespace RoF2
|
|||||||
|
|
||||||
const size_t SAY_LINK_BODY_SIZE = 56;
|
const size_t SAY_LINK_BODY_SIZE = 56;
|
||||||
const uint32 MAX_GUILD_ID = 50000;
|
const uint32 MAX_GUILD_ID = 50000;
|
||||||
|
const uint32 MAX_BAZAAR_TRADERS = 600;
|
||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,12 @@ E(OP_ApplyPoison)
|
|||||||
E(OP_AugmentInfo)
|
E(OP_AugmentInfo)
|
||||||
E(OP_Barter)
|
E(OP_Barter)
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_BecomeTrader)
|
||||||
E(OP_BeginCast)
|
E(OP_BeginCast)
|
||||||
E(OP_BlockedBuffs)
|
E(OP_BlockedBuffs)
|
||||||
E(OP_Buff)
|
E(OP_Buff)
|
||||||
E(OP_BuffCreate)
|
E(OP_BuffCreate)
|
||||||
|
E(OP_BuyerItems)
|
||||||
E(OP_CancelTrade)
|
E(OP_CancelTrade)
|
||||||
E(OP_CastSpell)
|
E(OP_CastSpell)
|
||||||
E(OP_ChannelMessage)
|
E(OP_ChannelMessage)
|
||||||
@@ -68,6 +70,7 @@ E(OP_DzMemberListName)
|
|||||||
E(OP_DzMemberListStatus)
|
E(OP_DzMemberListStatus)
|
||||||
E(OP_DzSetLeaderName)
|
E(OP_DzSetLeaderName)
|
||||||
E(OP_Emote)
|
E(OP_Emote)
|
||||||
|
E(OP_EvolveItem)
|
||||||
E(OP_ExpansionInfo)
|
E(OP_ExpansionInfo)
|
||||||
E(OP_FormattedMessage)
|
E(OP_FormattedMessage)
|
||||||
E(OP_GMLastName)
|
E(OP_GMLastName)
|
||||||
@@ -89,6 +92,7 @@ E(OP_InspectBuffs)
|
|||||||
E(OP_InspectRequest)
|
E(OP_InspectRequest)
|
||||||
E(OP_ItemLinkResponse)
|
E(OP_ItemLinkResponse)
|
||||||
E(OP_ItemPacket)
|
E(OP_ItemPacket)
|
||||||
|
E(OP_ItemPreviewRequest)
|
||||||
E(OP_ItemVerifyReply)
|
E(OP_ItemVerifyReply)
|
||||||
E(OP_LeadershipExpUpdate)
|
E(OP_LeadershipExpUpdate)
|
||||||
E(OP_LogServer)
|
E(OP_LogServer)
|
||||||
@@ -148,11 +152,13 @@ D(OP_Animation)
|
|||||||
D(OP_ApplyPoison)
|
D(OP_ApplyPoison)
|
||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
|
D(OP_Barter)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
D(OP_BlockedBuffs)
|
D(OP_BlockedBuffs)
|
||||||
D(OP_BookButton)
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_BuffRemoveRequest)
|
D(OP_BuffRemoveRequest)
|
||||||
|
D(OP_BuyerItems)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
|
|||||||
+289
-110
@@ -354,15 +354,15 @@ struct Spawn_Struct_Bitfields
|
|||||||
/*29*/ unsigned showname:1;
|
/*29*/ unsigned showname:1;
|
||||||
/*30*/ unsigned idleanimationsoff:1; // what we called statue?
|
/*30*/ unsigned idleanimationsoff:1; // what we called statue?
|
||||||
/*31*/ unsigned untargetable:1; // bClickThrough
|
/*31*/ unsigned untargetable:1; // bClickThrough
|
||||||
/* do these later
|
// byte 5
|
||||||
32 unsigned buyer:1;
|
/*32 unsigned buyer:1;
|
||||||
33 unsigned offline:1;
|
/*33 unsigned offline:1;
|
||||||
34 unsigned interactiveobject:1;
|
/*34 unsigned interactiveobject:1;
|
||||||
35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
/*35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
||||||
36 unsigned title:1;
|
/*36 unsigned title:1;
|
||||||
37 unsigned suffix:1;
|
/*37 unsigned suffix:1;
|
||||||
38 unsigned padding1:1;
|
/*38 unsigned padding1:1;
|
||||||
39 unsigned padding2:1;
|
/*39 unsigned padding2:1;
|
||||||
40 unsinged padding3:1;
|
40 unsinged padding3:1;
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
@@ -3106,6 +3106,142 @@ struct EnvDamage2_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Bazaar Stuff
|
//Bazaar Stuff
|
||||||
|
enum RoF2BazaarTraderBuyerActions {
|
||||||
|
Zero = 0,
|
||||||
|
BeginTraderMode = 1,
|
||||||
|
EndTraderMode = 2,
|
||||||
|
PriceUpdate = 3,
|
||||||
|
EndTransaction = 4,
|
||||||
|
BazaarSearch = 7,
|
||||||
|
WelcomeMessage = 9,
|
||||||
|
BuyTraderItem = 10,
|
||||||
|
ListTraderItems = 11,
|
||||||
|
BazaarInspect = 18,
|
||||||
|
ClickTrader = 28,
|
||||||
|
ItemMove = 19,
|
||||||
|
ReconcileItems = 20,
|
||||||
|
FirstOpenSearch = 26
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RoF2BuyerActions {
|
||||||
|
BuyerSearchResults = 0x00,
|
||||||
|
BuyerBuyLine = 0x06,
|
||||||
|
BuyerModifyBuyLine = 0x07,
|
||||||
|
BuyerRemoveItem = 0x08,
|
||||||
|
BuyerSellItem = 0x09,
|
||||||
|
BuyerBuyItem = 0x0a,
|
||||||
|
BuyerInspectBegin = 0x0b,
|
||||||
|
BuyerInspectEnd = 0x0c,
|
||||||
|
BuyerAppearance = 0x0d,
|
||||||
|
BuyerSendBuyLine = 0x0e,
|
||||||
|
BuyerItemInspect = 0x0f,
|
||||||
|
BuyerBrowsingBuyLine = 0x10,
|
||||||
|
BarterWelcomeMessage = 0x11,
|
||||||
|
BuyerWelcomeMessage = 0x13,
|
||||||
|
BuyerGreeting = 0x14,
|
||||||
|
BuyerInventoryFull = 0x16
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BarterItemSearchLinkRequest_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
|
uint32 seller_id;
|
||||||
|
uint32 buyer_id;
|
||||||
|
uint32 unknown_016;
|
||||||
|
uint32 slot_id; // 0xffffffff main buy line 0x0 trade_item_1, 0x1 trade_item_2
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 unknown_028;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerWelcomeMessageUpdate_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char unknown_004[64];
|
||||||
|
uint32 unknown_068;
|
||||||
|
char welcome_message[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Buyer_SetAppearance_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 entity_id;
|
||||||
|
char unknown[64];
|
||||||
|
uint32 enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerRemoveItem_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown004;
|
||||||
|
uint32 slot_id;
|
||||||
|
uint32 toggle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerLineSellItem_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 purchase_method; // 0 direct merchant, 1 via /barter window
|
||||||
|
uint32 unknown008;
|
||||||
|
uint32 buyer_entity_id;
|
||||||
|
uint32 seller_entity_id;
|
||||||
|
char unknown[15];
|
||||||
|
uint32 slot;
|
||||||
|
uint8 enabled;
|
||||||
|
uint32 item_id;
|
||||||
|
char item_name[64];
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 item_quantity;
|
||||||
|
uint8 item_toggle;
|
||||||
|
uint32 item_cost;
|
||||||
|
uint32 no_trade_items;
|
||||||
|
BuyerLineTradeItems_Struct trade_items[10];
|
||||||
|
char unknown2[13];
|
||||||
|
uint32 seller_quantity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerLineItemsSearch_Struct {
|
||||||
|
uint32 slot;
|
||||||
|
uint8 enabled;
|
||||||
|
uint32 item_id;
|
||||||
|
char item_name[64];
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 item_quantity;
|
||||||
|
uint8 item_toggle;
|
||||||
|
uint32 item_cost;
|
||||||
|
uint32 buyer_id;
|
||||||
|
BuyerLineTradeItems_Struct trade_items[MAX_BUYER_COMPENSATION_ITEMS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerLineSearch_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 no_items;
|
||||||
|
std::vector<BuyerLineItemsSearch_Struct> buy_line;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerStart_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint16 no_buyer_lines;
|
||||||
|
uint32 slot;
|
||||||
|
uint8 enabled;
|
||||||
|
uint32 item_id;
|
||||||
|
char item_name[1]; // vary length
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 item_quantity;
|
||||||
|
uint8 toggle;
|
||||||
|
uint32 item_cost;
|
||||||
|
uint32 no_trade_items;
|
||||||
|
BuyerLineTradeItems_Struct trade_items[1]; // size is actually no_trade_items. If 0, then this is not in packet
|
||||||
|
char unknown[13];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerItemSearchResultEntry_Struct {
|
||||||
|
char item_name[64];
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 item_icon;
|
||||||
|
uint32 unknown_072;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuyerItemSearchResults_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 result_count;
|
||||||
|
BuyerItemSearchResultEntry_Struct results[];
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BazaarTrader_StartTraderMode = 1,
|
BazaarTrader_StartTraderMode = 1,
|
||||||
@@ -3136,34 +3272,51 @@ struct BazaarWindowStart_Struct {
|
|||||||
uint16 Unknown002;
|
uint16 Unknown002;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BazaarDeliveryCost_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 voucher_delivery_cost;
|
||||||
|
float parcel_deliver_cost; //percentage of item cost
|
||||||
|
uint32 unknown_010;
|
||||||
|
};
|
||||||
|
|
||||||
struct BazaarWelcome_Struct {
|
struct BazaarWelcome_Struct {
|
||||||
uint32 Code;
|
uint32 action;
|
||||||
uint32 EntityID;
|
uint32 unknown_004;
|
||||||
uint32 Traders;
|
uint32 num_of_traders;
|
||||||
uint32 Items;
|
uint32 num_of_items;
|
||||||
uint32 Traders2;
|
|
||||||
uint32 Items2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarSearch_Struct {
|
struct BazaarSearch_Struct {
|
||||||
BazaarWindowStart_Struct Beginning;
|
/*000*/ uint32 action;
|
||||||
uint32 TraderID;
|
/*004*/ uint8 search_scope;//1 all traders 0 local traders
|
||||||
uint32 Class_;
|
/*005*/ uint8 unknown_005{0};
|
||||||
uint32 Race;
|
/*006*/ uint16 unknown_006{0};
|
||||||
uint32 ItemStat;
|
/*008*/ uint32 unknown_008{0};
|
||||||
uint32 Slot;
|
/*012*/ uint32 unknown_012{0};
|
||||||
uint32 Type;
|
/*016*/ uint32 trader_id;
|
||||||
char Name[64];
|
/*020*/ uint32 _class;
|
||||||
uint32 MinPrice;
|
/*024*/ uint32 race;
|
||||||
uint32 MaxPrice;
|
/*028*/ uint32 item_stat;
|
||||||
uint32 Minlevel;
|
/*032*/ uint32 slot;
|
||||||
uint32 MaxLlevel;
|
/*036*/ uint32 type;
|
||||||
|
/*040*/ char item_name[64];
|
||||||
|
/*104*/ uint32 min_cost;
|
||||||
|
/*108*/ uint32 max_cost;
|
||||||
|
/*112*/ uint32 min_level;
|
||||||
|
/*116*/ uint32 max_level;
|
||||||
|
/*120*/ uint32 max_results;
|
||||||
|
/*124*/ uint32 prestige;
|
||||||
|
/*128*/ uint32 augment;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarInspect_Struct {
|
struct BazaarInspect_Struct {
|
||||||
uint32 ItemID;
|
uint32 action;
|
||||||
uint32 Unknown004;
|
uint32 unknown_004;
|
||||||
char Name[64];
|
uint32 trader_id;
|
||||||
|
char serial_number[17];
|
||||||
|
char unknown_029[3];
|
||||||
|
uint32 item_id;
|
||||||
|
uint32 unknown_036;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NewBazaarInspect_Struct {
|
struct NewBazaarInspect_Struct {
|
||||||
@@ -3184,18 +3337,23 @@ struct BazaarReturnDone_Struct{
|
|||||||
uint32 Unknown016;
|
uint32 Unknown016;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarSearchResults_Struct {
|
struct BazaarSearchDetails_Struct { //24+name+17
|
||||||
/*000*/ BazaarWindowStart_Struct Beginning;
|
/*014*/ uint32 trader_id;
|
||||||
/*004*/ uint32 SellerID;
|
/*018*/ char serial_num[17];
|
||||||
/*008*/ char SellerName[64];
|
/*022*/ uint32 cost;
|
||||||
/*072*/ uint32 NumItems;
|
/*026*/ uint32 quanity;
|
||||||
/*076*/ uint32 ItemID;
|
/*030*/ uint32 id;
|
||||||
/*080*/ uint32 SerialNumber;
|
/*034*/ uint32 icon;
|
||||||
/*084*/ uint32 Unknown084;
|
/*038*/ char name[1];
|
||||||
/*088*/ char ItemName[64];
|
/*039*/ uint32 stat;
|
||||||
/*152*/ uint32 Cost;
|
};
|
||||||
/*156*/ uint32 ItemStat;
|
|
||||||
/*160*/
|
struct BazaarSearchResults_Struct { //14
|
||||||
|
/*000*/ uint32 unknown000;
|
||||||
|
/*004*/ uint16 zone_id;
|
||||||
|
/*006*/ uint32 entity_id;
|
||||||
|
/*010*/ uint32 num_items;
|
||||||
|
/*014*/ BazaarSearchDetails_Struct items[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerSideFilters_Struct {
|
struct ServerSideFilters_Struct {
|
||||||
@@ -3398,21 +3556,26 @@ struct WhoAllPlayerPart4 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderItemSerial_Struct {
|
struct TraderItemSerial_Struct {
|
||||||
char SerialNumber[17];
|
char serial_number[17];
|
||||||
uint8 Unknown18;
|
uint8 unknown_018;
|
||||||
|
|
||||||
|
void operator=(uint32 a) {
|
||||||
|
auto _tmp = fmt::format("{:016}", a);
|
||||||
|
strn0cpy(this->serial_number, _tmp.c_str(), sizeof(this->serial_number));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_Struct {
|
struct BeginTrader_Struct {
|
||||||
/*0000*/ uint32 Code;
|
/*0000*/ uint32 action;
|
||||||
/*0004*/ TraderItemSerial_Struct items[200];
|
/*0004*/ TraderItemSerial_Struct items[200];
|
||||||
/*3604*/ uint32 ItemCost[200];
|
/*3604*/ uint32 item_cost[200];
|
||||||
/*4404*/
|
/*4404*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClickTrader_Struct {
|
struct ClickTrader_Struct {
|
||||||
/*0000*/ uint32 Code;
|
/*0000*/ uint32 action;
|
||||||
/*0004*/ TraderItemSerial_Struct items[200];
|
/*0004*/ TraderItemSerial_Struct items[200];
|
||||||
/*3604*/ uint32 ItemCost[200];
|
/*3604*/ uint32 item_cost[200];
|
||||||
/*4404*/
|
/*4404*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3421,69 +3584,57 @@ struct GetItems_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BecomeTrader_Struct {
|
struct BecomeTrader_Struct {
|
||||||
uint32 id;
|
uint32 entity_id;
|
||||||
uint32 code;
|
uint32 action;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BazaarWindowRemoveTrader_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 trader_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraderPriceUpdate_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char serial_number[17];
|
||||||
|
char unknown_021[3];
|
||||||
|
uint32 unknown_024;
|
||||||
|
uint32 new_price;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_ShowItems_Struct {
|
struct Trader_ShowItems_Struct {
|
||||||
/*000*/ uint32 Code;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint16 TraderID;
|
/*004*/ uint32 entity_id;
|
||||||
/*008*/ uint32 Unknown08;
|
/*008*/ uint32 unknown_008;
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_ShowItems_Struct_WIP {
|
|
||||||
/*000*/ uint32 Code;
|
|
||||||
/*004*/ char SerialNumber[17];
|
|
||||||
/*021*/ uint8 Unknown21;
|
|
||||||
/*022*/ uint16 TraderID;
|
|
||||||
/*026*/ uint32 Stacksize;
|
|
||||||
/*030*/ uint32 Price;
|
|
||||||
/*032*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraderStatus_Struct {
|
struct TraderStatus_Struct {
|
||||||
/*000*/ uint32 Code;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Uknown04;
|
/*004*/ uint32 sub_action;
|
||||||
/*008*/ uint32 Uknown08;
|
/*008*/ uint32 uknown_008;
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Unknown004;
|
/*004*/ uint32 method;
|
||||||
/*008*/ uint32 Unknown008;
|
/*008*/ uint32 sub_action;
|
||||||
/*012*/ uint32 Unknown012;
|
/*012*/ uint32 unknown_012;
|
||||||
/*016*/ uint32 TraderID;
|
/*016*/ uint32 trader_id;
|
||||||
/*020*/ char BuyerName[64];
|
/*020*/ char buyer_name[64];
|
||||||
/*084*/ char SellerName[64];
|
/*084*/ char seller_name[64];
|
||||||
/*148*/ char Unknown148[32];
|
/*148*/ char unknown_148[32];
|
||||||
/*180*/ char ItemName[64];
|
/*180*/ char item_name[64];
|
||||||
/*244*/ char SerialNumber[16];
|
/*244*/ char serial_number[17];
|
||||||
/*260*/ uint32 Unknown076;
|
/*261*/ char unknown_261[3];
|
||||||
/*264*/ uint32 ItemID;
|
/*264*/ uint32 item_id;
|
||||||
/*268*/ uint32 Price;
|
/*268*/ uint32 price;
|
||||||
/*272*/ uint32 AlreadySold;
|
/*272*/ uint32 already_sold;
|
||||||
/*276*/ uint32 Unknown276;
|
/*276*/ uint32 unknown_276;
|
||||||
/*280*/ uint32 Quantity;
|
/*280*/ uint32 quantity;
|
||||||
/*284*/
|
/*284*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct_OLD {
|
|
||||||
/*000*/ uint32 Action;
|
|
||||||
/*004*/ uint32 Unknown004;
|
|
||||||
/*008*/ uint32 Price;
|
|
||||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
|
||||||
/*016*/ uint32 TraderID;
|
|
||||||
/*020*/ char ItemName[64];
|
|
||||||
/*084*/ uint32 Unknown076;
|
|
||||||
/*088*/ uint32 ItemID;
|
|
||||||
/*092*/ uint32 AlreadySold;
|
|
||||||
/*096*/ uint32 Quantity;
|
|
||||||
/*100*/ uint32 Unknown092;
|
|
||||||
/*104*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraderItemUpdate_Struct{
|
struct TraderItemUpdate_Struct{
|
||||||
uint32 unknown0;
|
uint32 unknown0;
|
||||||
uint32 traderid;
|
uint32 traderid;
|
||||||
@@ -3502,15 +3653,15 @@ struct MoneyUpdate_Struct{
|
|||||||
struct TraderDelItem_Struct{
|
struct TraderDelItem_Struct{
|
||||||
/*000*/ uint32 Unknown000;
|
/*000*/ uint32 Unknown000;
|
||||||
/*004*/ uint32 TraderID;
|
/*004*/ uint32 TraderID;
|
||||||
/*008*/ char SerialNumber[16];
|
/*008*/ char SerialNumber[17];
|
||||||
/*024*/ uint32 Unknown012;
|
/*024*/ uint32 Unknown012;
|
||||||
/*028*/
|
/*028*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderClick_Struct{
|
struct TraderClick_Struct{
|
||||||
/*000*/ uint32 Code;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 TraderID;
|
/*004*/ uint32 trader_id;
|
||||||
/*008*/ uint32 Approval;
|
/*008*/ uint32 unknown_008;
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3784,6 +3935,11 @@ struct NewCombine_Struct
|
|||||||
/*24*/
|
/*24*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TradeSkillRecipeInspect_Struct {
|
||||||
|
uint32 recipe_id;
|
||||||
|
uint32 padding[17];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//client requesting favorite recipies
|
//client requesting favorite recipies
|
||||||
struct TradeskillFavorites_Struct {
|
struct TradeskillFavorites_Struct {
|
||||||
@@ -4595,15 +4751,12 @@ struct ItemSerializationHeader
|
|||||||
uint8 isEvolving;
|
uint8 isEvolving;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EvolvingItem {
|
struct EvolvingItem_Struct {
|
||||||
uint8 unknown001;
|
uint32 final_item_id;
|
||||||
uint8 unknown002;
|
int32 evolve_level;
|
||||||
uint8 unknown003;
|
|
||||||
uint8 unknown004;
|
|
||||||
int32 evoLevel;
|
|
||||||
double progress;
|
double progress;
|
||||||
uint8 Activated;
|
uint8 activated;
|
||||||
int32 evomaxlevel;
|
int32 evolve_max_level;
|
||||||
uint8 unknown005[4];
|
uint8 unknown005[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5277,6 +5430,32 @@ struct Parcel_Struct
|
|||||||
};
|
};
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
|
struct EvolveItemToggle_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
|
uint64 unique_id;
|
||||||
|
uint32 percentage;
|
||||||
|
uint32 activated;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveXPWindowReceive_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
|
uint64 item1_unique_id;
|
||||||
|
uint64 item2_unique_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EvolveXPWindowSendDetails_Struct {
|
||||||
|
/*000*/ uint32 action;
|
||||||
|
/*004*/ uint64 item1_unique_id;
|
||||||
|
/*012*/ uint64 item2_unique_id;
|
||||||
|
/*020*/ uint32 compatibility;
|
||||||
|
/*024*/ uint32 max_transfer_level;
|
||||||
|
/*028*/ uint8 item1_present;
|
||||||
|
/*029*/ uint8 item2_present;
|
||||||
|
/*030*/ char serialize_data[];
|
||||||
|
};
|
||||||
|
|
||||||
}; /*RoF2*/
|
}; /*RoF2*/
|
||||||
|
|
||||||
#endif /*COMMON_ROF2_STRUCTS_H*/
|
#endif /*COMMON_ROF2_STRUCTS_H*/
|
||||||
|
|||||||
@@ -3376,17 +3376,17 @@ struct TraderStatus_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Unknown004;
|
/*004*/ uint32 unknown_004;
|
||||||
/*008*/ uint32 Price;
|
/*008*/ uint32 price;
|
||||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
/*012*/ uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||||
/*016*/ uint32 TraderID;
|
/*016*/ uint32 trader_id;
|
||||||
/*020*/ char ItemName[64];
|
/*020*/ char item_name[64];
|
||||||
/*084*/ uint32 Unknown076;
|
/*084*/ uint32 unknown_076;
|
||||||
/*088*/ uint32 ItemID;
|
/*088*/ uint32 item_id;
|
||||||
/*092*/ uint32 AlreadySold;
|
/*092*/ uint32 already_sold;
|
||||||
/*096*/ uint32 Quantity;
|
/*096*/ uint32 quantity;
|
||||||
/*100*/ uint32 Unknown092;
|
/*100*/ uint32 unknown_092;
|
||||||
/*104*/
|
/*104*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -2286,13 +2286,13 @@ namespace SoD
|
|||||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
|
||||||
OUT(Action);
|
OUT(action);
|
||||||
OUT(Price);
|
OUT(price);
|
||||||
OUT(TraderID);
|
OUT(trader_id);
|
||||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
OUT(ItemID);
|
OUT(item_id);
|
||||||
OUT(Quantity);
|
OUT(quantity);
|
||||||
OUT(AlreadySold);
|
OUT(already_sold);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -3517,12 +3517,12 @@ namespace SoD
|
|||||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
MEMSET_IN(TraderBuy_Struct);
|
MEMSET_IN(TraderBuy_Struct);
|
||||||
|
|
||||||
IN(Action);
|
IN(action);
|
||||||
IN(Price);
|
IN(price);
|
||||||
IN(TraderID);
|
IN(trader_id);
|
||||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||||
IN(ItemID);
|
IN(item_id);
|
||||||
IN(Quantity);
|
IN(quantity);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2879,20 +2879,21 @@ struct Trader_ShowItems_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Unknown004;
|
/*004*/ uint32 unknown_004;
|
||||||
/*008*/ uint32 Price;
|
/*008*/ uint32 price;
|
||||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
/*012*/ uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||||
/*016*/ uint32 TraderID;
|
/*016*/ uint32 trader_id;
|
||||||
/*020*/ char ItemName[64];
|
/*020*/ char item_name[64];
|
||||||
/*084*/ uint32 Unknown076;
|
/*084*/ uint32 unknown_076;
|
||||||
/*088*/ uint32 ItemID;
|
/*088*/ uint32 item_id;
|
||||||
/*092*/ uint32 AlreadySold;
|
/*092*/ uint32 already_sold;
|
||||||
/*096*/ uint32 Quantity;
|
/*096*/ uint32 quantity;
|
||||||
/*100*/ uint32 Unknown092;
|
/*100*/ uint32 unknown_092;
|
||||||
/*104*/
|
/*104*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct TraderItemUpdate_Struct{
|
struct TraderItemUpdate_Struct{
|
||||||
uint32 unknown0;
|
uint32 unknown0;
|
||||||
uint32 traderid;
|
uint32 traderid;
|
||||||
|
|||||||
+16
-16
@@ -270,8 +270,8 @@ namespace SoF
|
|||||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||||
|
|
||||||
OUT(ID);
|
OUT(trader_id);
|
||||||
OUT(Code);
|
OUT(action);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -1902,13 +1902,13 @@ namespace SoF
|
|||||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
|
||||||
OUT(Action);
|
OUT(action);
|
||||||
OUT(Price);
|
OUT(price);
|
||||||
OUT(TraderID);
|
OUT(trader_id);
|
||||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
OUT(ItemID);
|
OUT(item_id);
|
||||||
OUT(Quantity);
|
OUT(quantity);
|
||||||
OUT(AlreadySold);
|
OUT(already_sold);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -2349,7 +2349,7 @@ namespace SoF
|
|||||||
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||||
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||||
|
|
||||||
emu->category_id = EQ::bug::CategoryNameToCategoryID(eq->category_name);
|
emu->category_id = Bug::GetID(eq->category_name);
|
||||||
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
@@ -2908,12 +2908,12 @@ namespace SoF
|
|||||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
MEMSET_IN(TraderBuy_Struct);
|
MEMSET_IN(TraderBuy_Struct);
|
||||||
|
|
||||||
IN(Action);
|
IN(action);
|
||||||
IN(Price);
|
IN(price);
|
||||||
IN(TraderID);
|
IN(trader_id);
|
||||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||||
IN(ItemID);
|
IN(item_id);
|
||||||
IN(Quantity);
|
IN(quantity);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2771,8 +2771,8 @@ struct GetItems_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BecomeTrader_Struct{
|
struct BecomeTrader_Struct{
|
||||||
uint32 ID;
|
uint32 trader_id;
|
||||||
uint32 Code;
|
uint32 action;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_ShowItems_Struct{
|
struct Trader_ShowItems_Struct{
|
||||||
@@ -2782,15 +2782,15 @@ struct Trader_ShowItems_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Price;
|
/*004*/ uint32 price;
|
||||||
/*008*/ uint32 TraderID;
|
/*008*/ uint32 trader_id;
|
||||||
/*012*/ char ItemName[64];
|
/*012*/ char item_name[64];
|
||||||
/*076*/ uint32 Unknown076;
|
/*076*/ uint32 unknown_076;
|
||||||
/*080*/ uint32 ItemID;
|
/*080*/ uint32 item_id;
|
||||||
/*084*/ uint32 AlreadySold;
|
/*084*/ uint32 already_sold;
|
||||||
/*088*/ uint32 Quantity;
|
/*088*/ uint32 quantity;
|
||||||
/*092*/ uint32 Unknown092;
|
/*092*/ uint32 unknown_092;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderItemUpdate_Struct{
|
struct TraderItemUpdate_Struct{
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
|
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
|
||||||
|
|
||||||
#define ALLOC_LEN_ENCODE(len) \
|
#define ALLOC_LEN_ENCODE(len) \
|
||||||
__packet->pBuffer = new unsigned char[len]; \
|
__packet->pBuffer = new unsigned char[len] {}; \
|
||||||
__packet->size = len; \
|
__packet->size = len; \
|
||||||
memset(__packet->pBuffer, 0, len); \
|
memset(__packet->pBuffer, 0, len); \
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
#define SETUP_DIRECT_DECODE(emu_struct, eq_struct) \
|
#define SETUP_DIRECT_DECODE(emu_struct, eq_struct) \
|
||||||
unsigned char *__eq_buffer = __packet->pBuffer; \
|
unsigned char *__eq_buffer = __packet->pBuffer; \
|
||||||
__packet->size = sizeof(emu_struct); \
|
__packet->size = sizeof(emu_struct); \
|
||||||
__packet->pBuffer = new unsigned char[__packet->size]; \
|
__packet->pBuffer = new unsigned char[__packet->size] {}; \
|
||||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
||||||
auto size = strlen(in->var_field); \
|
auto size = strlen(in->var_field); \
|
||||||
__packet->size = sizeof(emu_struct) + size + 1; \
|
__packet->size = sizeof(emu_struct) + size + 1; \
|
||||||
__packet->pBuffer = new unsigned char[__packet->size]; \
|
__packet->pBuffer = new unsigned char[__packet->size] {}; \
|
||||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||||
|
|
||||||
|
|||||||
+388
-59
@@ -32,6 +32,7 @@
|
|||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "../item_instance.h"
|
#include "../item_instance.h"
|
||||||
#include "titanium_structs.h"
|
#include "titanium_structs.h"
|
||||||
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../raid.h"
|
#include "../raid.h"
|
||||||
#include "../guilds.h"
|
#include "../guilds.h"
|
||||||
@@ -197,64 +198,135 @@ namespace Titanium
|
|||||||
|
|
||||||
ENCODE(OP_BazaarSearch)
|
ENCODE(OP_BazaarSearch)
|
||||||
{
|
{
|
||||||
if (((*p)->size == sizeof(BazaarReturnDone_Struct)) || ((*p)->size == sizeof(BazaarWelcome_Struct))) {
|
|
||||||
|
|
||||||
EQApplicationPacket *in = *p;
|
|
||||||
*p = nullptr;
|
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//consume the packet
|
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
//store away the emu struct
|
uint32 action = *(uint32 *)in->pBuffer;
|
||||||
unsigned char *__emu_buffer = in->pBuffer;
|
|
||||||
BazaarSearchResults_Struct *emu = (BazaarSearchResults_Struct *)__emu_buffer;
|
|
||||||
|
|
||||||
//determine and verify length
|
switch (action) {
|
||||||
int entrycount = in->size / sizeof(BazaarSearchResults_Struct);
|
case BazaarSearch: {
|
||||||
if (entrycount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0) {
|
LogTrading(
|
||||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
|
"Encode OP_BazaarSearch(Ti) BazaarSearch action <green>[{}]",
|
||||||
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
action
|
||||||
delete in;
|
);
|
||||||
return;
|
std::vector<BazaarSearchResultsFromDB_Struct> results {};
|
||||||
|
auto bsms = (BazaarSearchMessaging_Struct *)in->pBuffer;
|
||||||
|
EQ::Util::MemoryStreamReader ss(
|
||||||
|
reinterpret_cast<char *>(bsms->payload),
|
||||||
|
in->size - sizeof(BazaarSearchMessaging_Struct)
|
||||||
|
);
|
||||||
|
cereal::BinaryInputArchive ar(ss);
|
||||||
|
ar(results);
|
||||||
|
|
||||||
|
auto size = results.size() * sizeof(structs::BazaarSearchResults_Struct);
|
||||||
|
auto buffer = new uchar[size];
|
||||||
|
uchar *bufptr = buffer;
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, structs::TiBazaarTraderBuyerActions::BazaarSearch);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->trader_entity_id);
|
||||||
|
bufptr += 4;
|
||||||
|
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->item_id);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->serial_number);
|
||||||
|
bufptr += 4;
|
||||||
|
if (row->stackable) {
|
||||||
|
strn0cpy(
|
||||||
|
reinterpret_cast<char *>(bufptr),
|
||||||
|
fmt::format("{}({})", row->item_name.c_str(), row->charges).c_str(),
|
||||||
|
64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strn0cpy(
|
||||||
|
reinterpret_cast<char *>(bufptr),
|
||||||
|
fmt::format("{}({})", row->item_name.c_str(), row->count).c_str(),
|
||||||
|
64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
bufptr += 64;
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->cost);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->item_stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
//make the EQ struct.
|
auto outapp = new EQApplicationPacket(OP_BazaarSearch, size);
|
||||||
in->size = sizeof(structs::BazaarSearchResults_Struct)*entrycount;
|
memcpy(outapp->pBuffer, buffer, size);
|
||||||
in->pBuffer = new unsigned char[in->size];
|
dest->FastQueuePacket(&outapp);
|
||||||
structs::BazaarSearchResults_Struct *eq = (structs::BazaarSearchResults_Struct *) in->pBuffer;
|
|
||||||
|
|
||||||
//zero out the packet. We could avoid this memset by setting all fields (including unknowns) in the loop.
|
safe_delete(outapp);
|
||||||
memset(in->pBuffer, 0, in->size);
|
safe_delete_array(buffer);
|
||||||
|
safe_delete(in);
|
||||||
for (int i = 0; i < entrycount; i++, eq++, emu++) {
|
break;
|
||||||
eq->Beginning.Action = emu->Beginning.Action;
|
|
||||||
eq->Beginning.Unknown001 = emu->Beginning.Unknown001;
|
|
||||||
eq->Beginning.Unknown002 = emu->Beginning.Unknown002;
|
|
||||||
eq->NumItems = emu->NumItems;
|
|
||||||
eq->SerialNumber = emu->SerialNumber;
|
|
||||||
eq->SellerID = emu->SellerID;
|
|
||||||
eq->Cost = emu->Cost;
|
|
||||||
eq->ItemStat = emu->ItemStat;
|
|
||||||
strcpy(eq->ItemName, emu->ItemName);
|
|
||||||
}
|
}
|
||||||
|
case BazaarInspect:
|
||||||
delete[] __emu_buffer;
|
case WelcomeMessage: {
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BazaarSearch(Ti) BazaarInspect/WelcomeMessage action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BazaarSearch(Ti) unhandled action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_BecomeTrader)
|
ENCODE(OP_BecomeTrader)
|
||||||
|
{
|
||||||
|
uint32 action = *(uint32 *)(*p)->pBuffer;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case TraderOff:
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||||
|
LogTrading(
|
||||||
OUT(ID);
|
"Encode OP_BecomeTrader(Ti) TraderOff action <green>[{}] entity_id <green>[{}] trader_name "
|
||||||
OUT(Code);
|
"<green>[{}]",
|
||||||
|
emu->action,
|
||||||
|
emu->entity_id,
|
||||||
|
emu->trader_name
|
||||||
|
);
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::Zero;
|
||||||
|
eq->entity_id = emu->entity_id;
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TraderOn:
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BecomeTrader(Ti) TraderOn action <green>[{}] entity_id <green>[{}] trader_name "
|
||||||
|
"<green>[{}]",
|
||||||
|
emu->action,
|
||||||
|
emu->entity_id,
|
||||||
|
emu->trader_name
|
||||||
|
);
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::BeginTraderMode;
|
||||||
|
eq->entity_id = emu->entity_id;
|
||||||
|
strn0cpy(eq->trader_name, emu->trader_name, sizeof(eq->trader_name));
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BecomeTrader(Ti) unhandled action <red>[{}] Sending packet as is.",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_Buff)
|
ENCODE(OP_Buff)
|
||||||
@@ -2010,32 +2082,170 @@ namespace Titanium
|
|||||||
|
|
||||||
ENCODE(OP_Trader)
|
ENCODE(OP_Trader)
|
||||||
{
|
{
|
||||||
if ((*p)->size != sizeof(TraderBuy_Struct)) {
|
auto action = *(uint32 *) (*p)->pBuffer;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case TraderOn: {
|
||||||
|
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader BeginTraderMode action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::BeginTraderMode;
|
||||||
|
OUT(entity_id);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TraderOff: {
|
||||||
|
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader EndTraderMode action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::EndTraderMode;
|
||||||
|
OUT(entity_id);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ListTraderItems: {
|
||||||
|
ENCODE_LENGTH_EXACT(Trader_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(Trader_Struct, structs::Trader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader ListTraderItems action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::ListTraderItems;
|
||||||
|
std::copy_n(emu->items, UF::invtype::BAZAAR_SIZE, eq->item_id);
|
||||||
|
std::copy_n(emu->item_cost, UF::invtype::BAZAAR_SIZE, eq->item_cost);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BuyTraderItem: {
|
||||||
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
eq->item_id,
|
||||||
|
eq->price,
|
||||||
|
eq->quantity,
|
||||||
|
eq->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::BuyTraderItem;
|
||||||
|
OUT(price);
|
||||||
|
OUT(trader_id);
|
||||||
|
OUT(item_id);
|
||||||
|
OUT(already_sold);
|
||||||
|
OUT(quantity);
|
||||||
|
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ItemMove: {
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader ItemMove action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
|
||||||
ENCODE_FORWARD(OP_TraderBuy);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
LogError("Unknown Encode OP_Trader action <red>{} received. Unhandled.", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_TraderBuy)
|
ENCODE(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_TraderBuy item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
emu->item_id,
|
||||||
|
emu->price,
|
||||||
|
emu->quantity,
|
||||||
|
emu->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
OUT(Action);
|
OUT(action);
|
||||||
OUT(Price);
|
OUT(price);
|
||||||
OUT(TraderID);
|
OUT(trader_id);
|
||||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
OUT(item_id);
|
||||||
OUT(ItemID);
|
OUT(already_sold);
|
||||||
OUT(Quantity);
|
OUT(quantity);
|
||||||
OUT(AlreadySold);
|
OUT_str(item_name);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_TraderShop)
|
||||||
|
{
|
||||||
|
auto action = *(uint32 *)(*p)->pBuffer;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case ClickTrader: {
|
||||||
|
ENCODE_LENGTH_EXACT(TraderClick_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"ClickTrader action <green>[{}] trader_id <green>[{}]",
|
||||||
|
action,
|
||||||
|
emu->TraderID
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = 0;
|
||||||
|
eq->trader_id = emu->TraderID;
|
||||||
|
eq->approval = emu->Approval;
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BuyTraderItem: {
|
||||||
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_TraderShop item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
eq->item_id,
|
||||||
|
eq->price,
|
||||||
|
eq->quantity,
|
||||||
|
eq->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::TiBazaarTraderBuyerActions::BuyTraderItem;
|
||||||
|
OUT(price);
|
||||||
|
OUT(trader_id);
|
||||||
|
OUT(item_id);
|
||||||
|
OUT(already_sold);
|
||||||
|
OUT(quantity);
|
||||||
|
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
LogError("Unknown Encode OP_TraderShop action <red>[{}] received. Unhandled.", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_TributeItem)
|
ENCODE(OP_TributeItem)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(TributeItem_Struct);
|
ENCODE_LENGTH_EXACT(TributeItem_Struct);
|
||||||
@@ -2286,6 +2496,53 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BazaarSearch)
|
||||||
|
{
|
||||||
|
uint32 action = *(uint32 *) __packet->pBuffer;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case structs::TiBazaarTraderBuyerActions::BazaarSearch: {
|
||||||
|
DECODE_LENGTH_EXACT(structs::BazaarSearch_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BazaarSearchCriteria_Struct, structs::BazaarSearch_Struct);
|
||||||
|
|
||||||
|
emu->action = eq->Beginning.Action;
|
||||||
|
emu->item_stat = eq->ItemStat;
|
||||||
|
emu->max_cost = eq->MaxPrice;
|
||||||
|
emu->min_cost = eq->MinPrice;
|
||||||
|
emu->max_level = eq->MaxLlevel;
|
||||||
|
emu->min_level = eq->Minlevel;
|
||||||
|
emu->race = eq->Race;
|
||||||
|
emu->slot = eq->Slot;
|
||||||
|
emu->type = eq->Type == UINT32_MAX ? UINT8_MAX : eq->Type;
|
||||||
|
emu->trader_entity_id = eq->TraderID;
|
||||||
|
emu->trader_id = 0;
|
||||||
|
emu->_class = eq->Class_;
|
||||||
|
emu->search_scope = eq->TraderID > 0 ? NonRoFBazaarSearchScope : Local_Scope;
|
||||||
|
emu->max_results = RuleI(Bazaar, MaxSearchResults);
|
||||||
|
strn0cpy(emu->item_name, eq->Name, sizeof(emu->item_name));
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::TiBazaarTraderBuyerActions::BazaarInspect: {
|
||||||
|
SETUP_DIRECT_DECODE(BazaarInspect_Struct, structs::BazaarInspect_Struct);
|
||||||
|
|
||||||
|
IN(action);
|
||||||
|
memcpy(emu->player_name, eq->player_name, sizeof(emu->player_name));
|
||||||
|
IN(serial_number);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::TiBazaarTraderBuyerActions::WelcomeMessage: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LogTrading("(Ti) Unhandled action <red>[{}]", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@@ -2310,7 +2567,7 @@ namespace Titanium
|
|||||||
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||||
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||||
|
|
||||||
emu->category_id = EQ::bug::CategoryNameToCategoryID(eq->category_name);
|
emu->category_id = Bug::GetID(eq->category_name);
|
||||||
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
@@ -2925,18 +3182,90 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_Trader)
|
||||||
|
{
|
||||||
|
auto action = (uint32) __packet->pBuffer[0];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case structs::TiBazaarTraderBuyerActions::BeginTraderMode: {
|
||||||
|
DECODE_LENGTH_EXACT(structs::BeginTrader_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::BeginTrader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Decode OP_Trader BeginTraderMode action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
emu->action = TraderOn;
|
||||||
|
emu->unknown_004 = 0;
|
||||||
|
std::copy_n(eq->serial_number, Titanium::invtype::BAZAAR_SIZE, emu->serial_number);
|
||||||
|
std::copy_n(eq->cost, Titanium::invtype::BAZAAR_SIZE, emu->item_cost);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::TiBazaarTraderBuyerActions::EndTraderMode: {
|
||||||
|
DECODE_LENGTH_EXACT(structs::Trader_ShowItems_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Decode OP_Trader(Ti) EndTraderMode action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
emu->action = TraderOff;
|
||||||
|
IN(entity_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::TiBazaarTraderBuyerActions::PriceUpdate:
|
||||||
|
case structs::TiBazaarTraderBuyerActions::ItemMove:
|
||||||
|
case structs::TiBazaarTraderBuyerActions::EndTransaction:
|
||||||
|
case structs::TiBazaarTraderBuyerActions::ListTraderItems: {
|
||||||
|
LogTrading(
|
||||||
|
"Decode OP_Trader(Ti) Price/ItemMove/EndTransaction/ListTraderItems action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::TiBazaarTraderBuyerActions::ReconcileItems: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LogError("Unhandled(Ti) action <red>[{}] received.", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_TraderBuy)
|
DECODE(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
MEMSET_IN(TraderBuy_Struct);
|
MEMSET_IN(TraderBuy_Struct);
|
||||||
|
|
||||||
IN(Action);
|
IN(action);
|
||||||
IN(Price);
|
IN(price);
|
||||||
IN(TraderID);
|
IN(trader_id);
|
||||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||||
IN(ItemID);
|
IN(item_id);
|
||||||
IN(Quantity);
|
IN(quantity);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECODE(OP_TraderShop)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::TraderClick_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"(Ti) action <green>[{}] trader_id <green>[{}] approval <green>[{}]",
|
||||||
|
eq->action,
|
||||||
|
eq->trader_id,
|
||||||
|
eq->approval
|
||||||
|
);
|
||||||
|
|
||||||
|
emu->Code = ClickTrader;
|
||||||
|
emu->TraderID = eq->trader_id;
|
||||||
|
emu->Approval = eq->approval;
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ E(OP_TaskDescription)
|
|||||||
E(OP_Track)
|
E(OP_Track)
|
||||||
E(OP_Trader)
|
E(OP_Trader)
|
||||||
E(OP_TraderBuy)
|
E(OP_TraderBuy)
|
||||||
|
E(OP_TraderShop)
|
||||||
E(OP_TributeItem)
|
E(OP_TributeItem)
|
||||||
E(OP_VetRewardsAvaliable)
|
E(OP_VetRewardsAvaliable)
|
||||||
E(OP_WearChange)
|
E(OP_WearChange)
|
||||||
@@ -92,6 +93,7 @@ E(OP_ZoneSpawns)
|
|||||||
D(OP_AdventureMerchantSell)
|
D(OP_AdventureMerchantSell)
|
||||||
D(OP_ApplyPoison)
|
D(OP_ApplyPoison)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
|
D(OP_BazaarSearch)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_Bug)
|
D(OP_Bug)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
@@ -123,7 +125,9 @@ D(OP_ReadBook)
|
|||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
D(OP_ShopRequest)
|
D(OP_ShopRequest)
|
||||||
|
D(OP_Trader)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
|
D(OP_TraderShop)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
D(OP_TributeItem)
|
D(OP_TributeItem)
|
||||||
D(OP_WearChange)
|
D(OP_WearChange)
|
||||||
|
|||||||
@@ -2273,24 +2273,29 @@ struct BazaarWelcome_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarSearch_Struct {
|
struct BazaarSearch_Struct {
|
||||||
BazaarWindowStart_Struct beginning;
|
BazaarWindowStart_Struct Beginning;
|
||||||
uint32 traderid;
|
uint32 TraderID;
|
||||||
uint32 class_;
|
uint32 Class_;
|
||||||
uint32 race;
|
uint32 Race;
|
||||||
uint32 stat;
|
uint32 ItemStat;
|
||||||
uint32 slot;
|
uint32 Slot;
|
||||||
uint32 type;
|
uint32 Type;
|
||||||
char name[64];
|
char Name[64];
|
||||||
uint32 minprice;
|
uint32 MinPrice;
|
||||||
uint32 maxprice;
|
uint32 MaxPrice;
|
||||||
uint32 minlevel;
|
uint32 Minlevel;
|
||||||
uint32 maxlevel;
|
uint32 MaxLlevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarInspect_Struct {
|
struct BazaarInspect_Struct {
|
||||||
|
uint32 action;
|
||||||
|
char player_name[64];
|
||||||
|
uint32 unknown_068;
|
||||||
|
uint32 serial_number;
|
||||||
|
uint32 unknown_076;
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
uint32 unknown;
|
|
||||||
char name[64];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarReturnDone_Struct{
|
struct BazaarReturnDone_Struct{
|
||||||
uint32 type;
|
uint32 type;
|
||||||
uint32 traderid;
|
uint32 traderid;
|
||||||
@@ -2298,16 +2303,17 @@ struct BazaarReturnDone_Struct{
|
|||||||
uint32 unknown12;
|
uint32 unknown12;
|
||||||
uint32 unknown16;
|
uint32 unknown16;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarSearchResults_Struct {
|
struct BazaarSearchResults_Struct {
|
||||||
BazaarWindowStart_Struct Beginning;
|
BazaarWindowStart_Struct Beginning;
|
||||||
uint32 SellerID;
|
uint32 entity_id;
|
||||||
uint32 NumItems; // Don't know. Don't know the significance of this field.
|
uint32 unknown_008;
|
||||||
uint32 SerialNumber;
|
uint32 item_id;
|
||||||
uint32 Unknown016;
|
uint32 serial_number;
|
||||||
uint32 Unknown020; // Something to do with stats as well
|
uint32 unknown_020;
|
||||||
char ItemName[64];
|
char item_name[64];
|
||||||
uint32 Cost;
|
uint32 item_cost;
|
||||||
uint32 ItemStat;
|
uint32 item_stat;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerSideFilters_Struct {
|
struct ServerSideFilters_Struct {
|
||||||
@@ -2454,44 +2460,52 @@ struct WhoAllReturnStruct {
|
|||||||
struct WhoAllPlayer player[0];
|
struct WhoAllPlayer player[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BeginTrader_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown04;
|
||||||
|
uint64 serial_number[EQ::invtype::BAZAAR_SIZE];
|
||||||
|
uint32 cost[EQ::invtype::BAZAAR_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
struct Trader_Struct {
|
struct Trader_Struct {
|
||||||
uint32 code;
|
uint32 action;
|
||||||
uint32 itemid[160];
|
uint32 unknown004;
|
||||||
uint32 unknown;
|
uint64 item_id[EQ::invtype::BAZAAR_SIZE];
|
||||||
uint32 itemcost[80];
|
uint32 item_cost[EQ::invtype::BAZAAR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClickTrader_Struct {
|
struct ClickTrader_Struct {
|
||||||
uint32 code;
|
uint32 code;
|
||||||
uint32 unknown[161];//damn soe this is totally pointless :/ but at least your finally using memset! Good job :) -LE
|
uint32 unknown[161];//damn soe this is totally pointless :/ but at least your finally using memset! Good job :) -LE
|
||||||
uint32 itemcost[80];
|
uint32 itemcost[EQ::invtype::BAZAAR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GetItems_Struct{
|
struct GetItems_Struct{
|
||||||
uint32 items[80];
|
uint32 items[EQ::invtype::BAZAAR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BecomeTrader_Struct {
|
struct BecomeTrader_Struct {
|
||||||
uint32 ID;
|
uint32 entity_id;
|
||||||
uint32 Code;
|
uint32 action;
|
||||||
|
char trader_name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_ShowItems_Struct{
|
struct Trader_ShowItems_Struct{
|
||||||
uint32 code;
|
uint32 action;
|
||||||
uint32 traderid;
|
uint32 entity_id;
|
||||||
uint32 unknown08[3];
|
uint32 unknown08[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
/*000*/ uint32 action;
|
||||||
/*004*/ uint32 Price;
|
/*004*/ uint32 price;
|
||||||
/*008*/ uint32 TraderID;
|
/*008*/ uint32 trader_id;
|
||||||
/*012*/ char ItemName[64];
|
/*012*/ char item_name[64];
|
||||||
/*076*/ uint32 Unknown076;
|
/*076*/ uint32 unknown_076;
|
||||||
/*080*/ uint32 ItemID;
|
/*080*/ uint32 item_id;
|
||||||
/*084*/ uint32 AlreadySold;
|
/*084*/ uint32 already_sold;
|
||||||
/*088*/ uint32 Quantity;
|
/*088*/ uint32 quantity;
|
||||||
/*092*/ uint32 Unknown092;
|
/*092*/ uint32 unknown_092;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -2517,8 +2531,9 @@ struct TraderDelItem_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderClick_Struct{
|
struct TraderClick_Struct{
|
||||||
uint32 traderid;
|
uint32 trader_id;
|
||||||
uint32 unknown4[2];
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
uint32 approval;
|
uint32 approval;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3744,6 +3759,21 @@ struct GuildMemberRank_Struct {
|
|||||||
/*076*/ uint32 alt_banker; //Banker/Alt bit 00 - none 10 - Alt 11 - Alt and Banker 01 - Banker. Banker not functional for RoF2+
|
/*076*/ uint32 alt_banker; //Banker/Alt bit 00 - none 10 - Alt 11 - Alt and Banker 01 - Banker. Banker not functional for RoF2+
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TiBazaarTraderBuyerActions {
|
||||||
|
Zero = 0,
|
||||||
|
BeginTraderMode = 1,
|
||||||
|
EndTraderMode = 2,
|
||||||
|
PriceUpdate = 3,
|
||||||
|
EndTransaction = 4,
|
||||||
|
BazaarSearch = 7,
|
||||||
|
WelcomeMessage = 9,
|
||||||
|
BuyTraderItem = 10,
|
||||||
|
ListTraderItems = 11,
|
||||||
|
BazaarInspect = 18,
|
||||||
|
ItemMove = 19,
|
||||||
|
ReconcileItems = 20
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*Titanium*/
|
}; /*Titanium*/
|
||||||
|
|||||||
+399
-67
@@ -37,6 +37,8 @@
|
|||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
#include "../raid.h"
|
#include "../raid.h"
|
||||||
#include "../guilds.h"
|
#include "../guilds.h"
|
||||||
|
//#include "../repositories/trader_repository.h"
|
||||||
|
#include "../cereal/include/cereal/types/vector.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -307,51 +309,135 @@ namespace UF
|
|||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
char *Buffer = (char *)in->pBuffer;
|
uint32 action = *(uint32 *)in->pBuffer;
|
||||||
|
|
||||||
uint8 SubAction = VARSTRUCT_DECODE_TYPE(uint8, Buffer);
|
switch (action) {
|
||||||
|
case BazaarSearch: {
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BazaarSearch(UF) BazaarSearch action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
std::vector<BazaarSearchResultsFromDB_Struct> results {};
|
||||||
|
auto bsms = (BazaarSearchMessaging_Struct *)in->pBuffer;
|
||||||
|
EQ::Util::MemoryStreamReader ss(
|
||||||
|
reinterpret_cast<char *>(bsms->payload),
|
||||||
|
in->size - sizeof(BazaarSearchMessaging_Struct)
|
||||||
|
);
|
||||||
|
cereal::BinaryInputArchive ar(ss);
|
||||||
|
ar(results);
|
||||||
|
|
||||||
if (SubAction != BazaarSearchResults)
|
auto size = results.size() * sizeof(BazaarSearchResults_Struct);
|
||||||
{
|
auto buffer = new uchar[size];
|
||||||
|
uchar *bufptr = buffer;
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, structs::UFBazaarTraderBuyerActions::BazaarSearch);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->trader_entity_id);
|
||||||
|
strn0cpy(reinterpret_cast<char *>(bufptr), row->trader_name.c_str(), 64);
|
||||||
|
bufptr += 64;
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, 1);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->item_id);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->serial_number);
|
||||||
|
bufptr += 4;
|
||||||
|
if (row->stackable) {
|
||||||
|
strn0cpy(
|
||||||
|
reinterpret_cast<char *>(bufptr),
|
||||||
|
fmt::format("{}({})", row->item_name.c_str(), row->charges).c_str(),
|
||||||
|
64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strn0cpy(
|
||||||
|
reinterpret_cast<char *>(bufptr),
|
||||||
|
fmt::format("{}({})", row->item_name.c_str(), row->count).c_str(),
|
||||||
|
64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
bufptr += 64;
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->cost);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->item_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_BazaarSearch, size);
|
||||||
|
memcpy(outapp->pBuffer, buffer, size);
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
|
safe_delete(outapp);
|
||||||
|
safe_delete_array(buffer);
|
||||||
|
safe_delete(in);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BazaarInspect:
|
||||||
|
case WelcomeMessage: {
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BazaarSearch(UF) BazaarInspect/WelcomeMessage action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
unsigned char *__emu_buffer = in->pBuffer;
|
LogTrading(
|
||||||
|
"Encode OP_BazaarSearch(UF) unhandled action <red>[{}]",
|
||||||
BazaarSearchResults_Struct *emu = (BazaarSearchResults_Struct *)__emu_buffer;
|
action
|
||||||
|
);
|
||||||
int EntryCount = in->size / sizeof(BazaarSearchResults_Struct);
|
|
||||||
|
|
||||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
|
||||||
{
|
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
|
||||||
delete in;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
in->size = EntryCount * sizeof(structs::BazaarSearchResults_Struct);
|
|
||||||
in->pBuffer = new unsigned char[in->size];
|
|
||||||
memset(in->pBuffer, 0, in->size);
|
|
||||||
|
|
||||||
structs::BazaarSearchResults_Struct *eq = (structs::BazaarSearchResults_Struct *)in->pBuffer;
|
|
||||||
|
|
||||||
for (int i = 0; i < EntryCount; ++i, ++emu, ++eq)
|
|
||||||
{
|
|
||||||
OUT(Beginning.Action);
|
|
||||||
OUT(SellerID);
|
|
||||||
memcpy(eq->SellerName, emu->SellerName, sizeof(eq->SellerName));
|
|
||||||
OUT(NumItems);
|
|
||||||
OUT(ItemID);
|
|
||||||
OUT(SerialNumber);
|
|
||||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
|
||||||
OUT(Cost);
|
|
||||||
OUT(ItemStat);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] __emu_buffer;
|
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_BecomeTrader)
|
||||||
|
{
|
||||||
|
uint32 action = *(uint32 *)(*p)->pBuffer;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case TraderOff:
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BecomeTrader(UF) TraderOff action <green>[{}] entity_id <green>[{}] trader_name "
|
||||||
|
"<green>[{}]",
|
||||||
|
emu->action,
|
||||||
|
emu->entity_id,
|
||||||
|
emu->trader_name
|
||||||
|
);
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::Zero;
|
||||||
|
eq->entity_id = emu->entity_id;
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TraderOn:
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BecomeTrader(UF) TraderOn action <green>[{}] entity_id <green>[{}] trader_name "
|
||||||
|
"<green>[{}]",
|
||||||
|
emu->action,
|
||||||
|
emu->entity_id,
|
||||||
|
emu->trader_name
|
||||||
|
);
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::BeginTraderMode;
|
||||||
|
eq->entity_id = emu->entity_id;
|
||||||
|
strn0cpy(eq->trader_name, emu->trader_name, sizeof(eq->trader_name));
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_BecomeTrader(UF) unhandled action <red>[{}] Sending packet as is.",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_Buff)
|
ENCODE(OP_Buff)
|
||||||
{
|
{
|
||||||
@@ -2743,32 +2829,170 @@ namespace UF
|
|||||||
|
|
||||||
ENCODE(OP_Trader)
|
ENCODE(OP_Trader)
|
||||||
{
|
{
|
||||||
if ((*p)->size != sizeof(TraderBuy_Struct)) {
|
auto action = *(uint32 *) (*p)->pBuffer;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case TraderOn: {
|
||||||
|
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader BeginTraderMode action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::BeginTraderMode;
|
||||||
|
OUT(entity_id);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TraderOff: {
|
||||||
|
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader EndTraderMode action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::EndTraderMode;
|
||||||
|
OUT(entity_id);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ListTraderItems: {
|
||||||
|
ENCODE_LENGTH_EXACT(Trader_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(Trader_Struct, structs::Trader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader ListTraderItems action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::ListTraderItems;
|
||||||
|
std::copy_n(emu->items, UF::invtype::BAZAAR_SIZE, eq->item_id);
|
||||||
|
std::copy_n(emu->item_cost, UF::invtype::BAZAAR_SIZE, eq->item_cost);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BuyTraderItem: {
|
||||||
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
eq->item_id,
|
||||||
|
eq->price,
|
||||||
|
eq->quantity,
|
||||||
|
eq->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::BuyTraderItem;
|
||||||
|
OUT(price);
|
||||||
|
OUT(trader_id);
|
||||||
|
OUT(item_id);
|
||||||
|
OUT(already_sold);
|
||||||
|
OUT(quantity);
|
||||||
|
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ItemMove: {
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_Trader ItemMove action <green>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
|
||||||
ENCODE_FORWARD(OP_TraderBuy);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
LogError("Unknown Encode OP_Trader action <red>{} received. Unhandled.", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_TraderBuy)
|
ENCODE(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_TraderBuy item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
emu->item_id,
|
||||||
|
emu->price,
|
||||||
|
emu->quantity,
|
||||||
|
emu->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
OUT(Action);
|
OUT(action);
|
||||||
OUT(Price);
|
OUT(price);
|
||||||
OUT(TraderID);
|
OUT(trader_id);
|
||||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
OUT(item_id);
|
||||||
OUT(ItemID);
|
OUT(already_sold);
|
||||||
OUT(Quantity);
|
OUT(quantity);
|
||||||
OUT(AlreadySold);
|
OUT_str(item_name);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_TraderShop)
|
||||||
|
{
|
||||||
|
auto action = *(uint32 *)(*p)->pBuffer;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case ClickTrader: {
|
||||||
|
ENCODE_LENGTH_EXACT(TraderClick_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"ClickTrader action <green>[{}] trader_id <green>[{}]",
|
||||||
|
action,
|
||||||
|
emu->TraderID
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = 0;
|
||||||
|
eq->trader_id = emu->TraderID;
|
||||||
|
eq->approval = emu->Approval;
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BuyTraderItem: {
|
||||||
|
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Encode OP_TraderShop item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
eq->item_id,
|
||||||
|
eq->price,
|
||||||
|
eq->quantity,
|
||||||
|
eq->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
|
eq->action = structs::UFBazaarTraderBuyerActions::BuyTraderItem;
|
||||||
|
OUT(price);
|
||||||
|
OUT(trader_id);
|
||||||
|
OUT(item_id);
|
||||||
|
OUT(already_sold);
|
||||||
|
OUT(quantity);
|
||||||
|
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
LogError("Unknown Encode OP_TraderShop action <red>[{}] received. Unhandled.", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_TributeItem)
|
ENCODE(OP_TributeItem)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(TributeItem_Struct);
|
ENCODE_LENGTH_EXACT(TributeItem_Struct);
|
||||||
@@ -3040,7 +3264,7 @@ namespace UF
|
|||||||
Bitfields->targetable = 1;
|
Bitfields->targetable = 1;
|
||||||
Bitfields->targetable_with_hotkey = emu->targetable_with_hotkey ? 1 : 0;
|
Bitfields->targetable_with_hotkey = emu->targetable_with_hotkey ? 1 : 0;
|
||||||
Bitfields->statue = 0;
|
Bitfields->statue = 0;
|
||||||
Bitfields->trader = 0;
|
Bitfields->trader = emu->trader ? 1 : 0;
|
||||||
Bitfields->buyer = 0;
|
Bitfields->buyer = 0;
|
||||||
|
|
||||||
Bitfields->showname = ShowName;
|
Bitfields->showname = ShowName;
|
||||||
@@ -3363,20 +3587,49 @@ namespace UF
|
|||||||
|
|
||||||
DECODE(OP_BazaarSearch)
|
DECODE(OP_BazaarSearch)
|
||||||
{
|
{
|
||||||
char *Buffer = (char *)__packet->pBuffer;
|
uint32 action = *(uint32 *) __packet->pBuffer;
|
||||||
|
|
||||||
uint8 SubAction = VARSTRUCT_DECODE_TYPE(uint8, Buffer);
|
switch (action) {
|
||||||
|
case structs::UFBazaarTraderBuyerActions::BazaarSearch: {
|
||||||
|
DECODE_LENGTH_EXACT(structs::BazaarSearch_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BazaarSearchCriteria_Struct, structs::BazaarSearch_Struct);
|
||||||
|
|
||||||
if ((SubAction != BazaarInspectItem) || (__packet->size != sizeof(structs::NewBazaarInspect_Struct)))
|
emu->action = eq->Beginning.Action;
|
||||||
return;
|
emu->item_stat = eq->ItemStat;
|
||||||
|
emu->max_cost = eq->MaxPrice;
|
||||||
SETUP_DIRECT_DECODE(NewBazaarInspect_Struct, structs::NewBazaarInspect_Struct);
|
emu->min_cost = eq->MinPrice;
|
||||||
MEMSET_IN(structs::NewBazaarInspect_Struct);
|
emu->max_level = eq->MaxLlevel;
|
||||||
IN(Beginning.Action);
|
emu->min_level = eq->Minlevel;
|
||||||
memcpy(emu->Name, eq->Name, sizeof(emu->Name));
|
emu->race = eq->Race;
|
||||||
IN(SerialNumber);
|
emu->slot = eq->Slot;
|
||||||
|
emu->type = eq->Type == UINT32_MAX ? UINT8_MAX : eq->Type;
|
||||||
|
emu->trader_entity_id = eq->TraderID;
|
||||||
|
emu->trader_id = 0;
|
||||||
|
emu->_class = eq->Class_;
|
||||||
|
emu->search_scope = eq->TraderID > 0 ? NonRoFBazaarSearchScope : Local_Scope;
|
||||||
|
emu->max_results = RuleI(Bazaar, MaxSearchResults);
|
||||||
|
strn0cpy(emu->item_name, eq->Name, sizeof(emu->item_name));
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::UFBazaarTraderBuyerActions::BazaarInspect: {
|
||||||
|
SETUP_DIRECT_DECODE(BazaarInspect_Struct, structs::BazaarInspect_Struct);
|
||||||
|
|
||||||
|
IN(action);
|
||||||
|
memcpy(emu->player_name, eq->player_name, sizeof(emu->player_name));
|
||||||
|
IN(serial_number);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::UFBazaarTraderBuyerActions::WelcomeMessage: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LogTrading("(UF) Unhandled action <red>[{}]", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODE(OP_BookButton)
|
DECODE(OP_BookButton)
|
||||||
@@ -4059,18 +4312,97 @@ namespace UF
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_Trader)
|
||||||
|
{
|
||||||
|
auto action = (uint32) __packet->pBuffer[0];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case structs::UFBazaarTraderBuyerActions::BeginTraderMode: {
|
||||||
|
DECODE_LENGTH_EXACT(structs::BeginTrader_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::BeginTrader_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Decode OP_Trader BeginTraderMode action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
emu->action = TraderOn;
|
||||||
|
emu->unknown_004 = 0;
|
||||||
|
std::copy_n(eq->serial_number, UF::invtype::BAZAAR_SIZE, emu->serial_number);
|
||||||
|
std::copy_n(eq->cost, UF::invtype::BAZAAR_SIZE, emu->item_cost);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::UFBazaarTraderBuyerActions::EndTraderMode: {
|
||||||
|
DECODE_LENGTH_EXACT(structs::Trader_ShowItems_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"Decode OP_Trader(UF) EndTraderMode action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
|
||||||
|
emu->action = TraderOff;
|
||||||
|
IN(entity_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::UFBazaarTraderBuyerActions::PriceUpdate:
|
||||||
|
case structs::UFBazaarTraderBuyerActions::ItemMove:
|
||||||
|
case structs::UFBazaarTraderBuyerActions::EndTransaction:
|
||||||
|
case structs::UFBazaarTraderBuyerActions::ListTraderItems: {
|
||||||
|
LogTrading(
|
||||||
|
"Decode OP_Trader(UF) Price/ItemMove/EndTransaction/ListTraderItems action <red>[{}]",
|
||||||
|
action
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case structs::UFBazaarTraderBuyerActions::ReconcileItems: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LogError("Unhandled(UF) action <red>[{}] received.", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_TraderBuy)
|
DECODE(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||||
MEMSET_IN(TraderBuy_Struct);
|
LogTrading(
|
||||||
|
"Decode OP_TraderBuy(UF) item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||||
|
eq->item_id,
|
||||||
|
eq->price,
|
||||||
|
eq->quantity,
|
||||||
|
eq->trader_id
|
||||||
|
);
|
||||||
|
|
||||||
IN(Action);
|
emu->action = BuyTraderItem;
|
||||||
IN(Price);
|
IN(price);
|
||||||
IN(TraderID);
|
IN(trader_id);
|
||||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
IN(item_id);
|
||||||
IN(ItemID);
|
IN(quantity);
|
||||||
IN(Quantity);
|
IN(already_sold);
|
||||||
|
strn0cpy(emu->item_name, eq->item_name, sizeof(eq->item_name));
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECODE(OP_TraderShop)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::TraderClick_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||||
|
LogTrading(
|
||||||
|
"(UF) action <green>[{}] trader_id <green>[{}] approval <green>[{}]",
|
||||||
|
eq->action,
|
||||||
|
eq->trader_id,
|
||||||
|
eq->approval
|
||||||
|
);
|
||||||
|
|
||||||
|
emu->Code = ClickTrader;
|
||||||
|
emu->TraderID = eq->trader_id;
|
||||||
|
emu->Approval = eq->approval;
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ E(OP_ApplyPoison)
|
|||||||
E(OP_AugmentInfo)
|
E(OP_AugmentInfo)
|
||||||
E(OP_Barter)
|
E(OP_Barter)
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_BecomeTrader)
|
||||||
E(OP_Buff)
|
E(OP_Buff)
|
||||||
E(OP_BuffCreate)
|
E(OP_BuffCreate)
|
||||||
E(OP_CancelTrade)
|
E(OP_CancelTrade)
|
||||||
@@ -100,6 +101,7 @@ E(OP_TaskDescription)
|
|||||||
E(OP_Track)
|
E(OP_Track)
|
||||||
E(OP_Trader)
|
E(OP_Trader)
|
||||||
E(OP_TraderBuy)
|
E(OP_TraderBuy)
|
||||||
|
E(OP_TraderShop)
|
||||||
E(OP_TributeItem)
|
E(OP_TributeItem)
|
||||||
E(OP_VetRewardsAvaliable)
|
E(OP_VetRewardsAvaliable)
|
||||||
E(OP_WearChange)
|
E(OP_WearChange)
|
||||||
@@ -160,7 +162,9 @@ D(OP_SetServerFilter)
|
|||||||
D(OP_ShopPlayerBuy)
|
D(OP_ShopPlayerBuy)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
D(OP_ShopRequest)
|
D(OP_ShopRequest)
|
||||||
|
D(OP_Trader)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
|
D(OP_TraderShop)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
D(OP_TributeItem)
|
D(OP_TributeItem)
|
||||||
D(OP_WearChange)
|
D(OP_WearChange)
|
||||||
|
|||||||
+61
-25
@@ -2687,10 +2687,14 @@ struct BazaarSearch_Struct {
|
|||||||
uint32 Minlevel;
|
uint32 Minlevel;
|
||||||
uint32 MaxLlevel;
|
uint32 MaxLlevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BazaarInspect_Struct {
|
struct BazaarInspect_Struct {
|
||||||
uint32 ItemID;
|
uint32 action;
|
||||||
uint32 Unknown004;
|
char player_name[64];
|
||||||
char Name[64];
|
uint32 unknown_068;
|
||||||
|
uint32 serial_number;
|
||||||
|
uint32 unknown_076;
|
||||||
|
uint32 item_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NewBazaarInspect_Struct {
|
struct NewBazaarInspect_Struct {
|
||||||
@@ -2929,10 +2933,17 @@ struct WhoAllPlayerPart4 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_Struct {
|
struct Trader_Struct {
|
||||||
uint32 code;
|
uint32 action;
|
||||||
uint32 itemid[160];
|
uint32 unknown004;
|
||||||
uint32 unknown;
|
uint64 item_id[80];
|
||||||
uint32 itemcost[80];
|
uint32 item_cost[80];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BeginTrader_Struct {
|
||||||
|
uint32 action;
|
||||||
|
uint32 unknown04;
|
||||||
|
uint64 serial_number[80];
|
||||||
|
uint32 cost[80];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClickTrader_Struct {
|
struct ClickTrader_Struct {
|
||||||
@@ -2946,29 +2957,29 @@ struct GetItems_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BecomeTrader_Struct {
|
struct BecomeTrader_Struct {
|
||||||
uint32 id;
|
uint32 entity_id;
|
||||||
uint32 code;
|
uint32 action;
|
||||||
|
char trader_name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trader_ShowItems_Struct{
|
struct Trader_ShowItems_Struct{
|
||||||
uint32 code;
|
uint32 action;
|
||||||
uint32 traderid;
|
uint32 entity_id;
|
||||||
uint32 unknown08[3];
|
uint32 unknown08[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderBuy_Struct {
|
struct TraderBuy_Struct {
|
||||||
/*000*/ uint32 Action;
|
uint32 action;
|
||||||
/*004*/ uint32 Unknown004;
|
uint32 unknown_004;
|
||||||
/*008*/ uint32 Price;
|
uint32 price;
|
||||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||||
/*016*/ uint32 TraderID;
|
uint32 trader_id;
|
||||||
/*020*/ char ItemName[64];
|
char item_name[64];
|
||||||
/*084*/ uint32 Unknown076;
|
uint32 unknown_076;
|
||||||
/*088*/ uint32 ItemID;
|
uint32 item_id;
|
||||||
/*092*/ uint32 AlreadySold;
|
uint32 already_sold;
|
||||||
/*096*/ uint32 Quantity;
|
uint32 quantity;
|
||||||
/*100*/ uint32 Unknown092;
|
uint32 unknown_092;
|
||||||
/*104*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraderItemUpdate_Struct{
|
struct TraderItemUpdate_Struct{
|
||||||
@@ -3002,8 +3013,9 @@ struct TraderDelItem_Struct{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TraderClick_Struct{
|
struct TraderClick_Struct{
|
||||||
uint32 traderid;
|
uint32 trader_id;
|
||||||
uint32 unknown4[2];
|
uint32 action;
|
||||||
|
uint32 unknown_004;
|
||||||
uint32 approval;
|
uint32 approval;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4674,6 +4686,30 @@ struct SayLinkBodyFrame_Struct {
|
|||||||
/*050*/
|
/*050*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TraderPriceUpdate_Struct {
|
||||||
|
/*000*/ uint32 action;
|
||||||
|
/*004*/ uint32 sub_action;
|
||||||
|
/*008*/ int32 serial_number;
|
||||||
|
/*012*/ uint32 unknown_012;
|
||||||
|
/*016*/ uint32 new_price;
|
||||||
|
/*020*/ uint32 unknown_016;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum UFBazaarTraderBuyerActions {
|
||||||
|
Zero = 0,
|
||||||
|
BeginTraderMode = 1,
|
||||||
|
EndTraderMode = 2,
|
||||||
|
PriceUpdate = 3,
|
||||||
|
EndTransaction = 4,
|
||||||
|
BazaarSearch = 7,
|
||||||
|
WelcomeMessage = 9,
|
||||||
|
BuyTraderItem = 10,
|
||||||
|
ListTraderItems = 11,
|
||||||
|
BazaarInspect = 18,
|
||||||
|
ItemMove = 19,
|
||||||
|
ReconcileItems = 20
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*UF*/
|
}; /*UF*/
|
||||||
|
|||||||
+54
-57
@@ -5,31 +5,19 @@
|
|||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
inline std::string striptrailingslash(const std::string &file_path)
|
|
||||||
{
|
|
||||||
if (file_path.back() == '/' || file_path.back() == '\\') {
|
|
||||||
return file_path.substr(0, file_path.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return file_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PathManager::LoadPaths()
|
void PathManager::LoadPaths()
|
||||||
{
|
{
|
||||||
m_server_path = File::FindEqemuConfigPath();
|
m_server_path = File::FindEqemuConfigPath();
|
||||||
|
|
||||||
if (!m_server_path.empty()) {
|
|
||||||
std::filesystem::current_path(m_server_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_server_path.empty()) {
|
if (m_server_path.empty()) {
|
||||||
LogInfo("Failed to load server path");
|
LogInfo("Failed to load server path");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("server [{}]", m_server_path);
|
std::filesystem::current_path(m_server_path);
|
||||||
|
|
||||||
if (!EQEmuConfig::LoadConfig()) {
|
if (!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Failed to load eqemu config");
|
LogError("Failed to load eqemu config");
|
||||||
@@ -38,60 +26,64 @@ void PathManager::LoadPaths()
|
|||||||
|
|
||||||
const auto c = EQEmuConfig::get();
|
const auto c = EQEmuConfig::get();
|
||||||
|
|
||||||
// maps
|
auto resolve_path = [&](const std::string& dir, const std::vector<std::string>& fallback_dirs = {}) -> std::string {
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->MapDir}.string())) {
|
// relative
|
||||||
m_maps_path = fs::relative(fs::path{m_server_path + "/" + c->MapDir}).string();
|
if (File::Exists((fs::path{m_server_path} / dir).string())) {
|
||||||
}
|
return fs::relative(fs::path{m_server_path} / dir).lexically_normal().string();
|
||||||
else if (File::Exists(fs::path{m_server_path + "/maps"}.string())) {
|
|
||||||
m_maps_path = fs::relative(fs::path{m_server_path + "/maps"}).string();
|
|
||||||
}
|
|
||||||
else if (File::Exists(fs::path{m_server_path + "/Maps"}.string())) {
|
|
||||||
m_maps_path = fs::relative(fs::path{m_server_path + "/Maps"}).string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// quests
|
// absolute
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->QuestDir}.string())) {
|
if (File::Exists(fs::path{dir}.string())) {
|
||||||
m_quests_path = fs::relative(fs::path{m_server_path + "/" + c->QuestDir}).string();
|
return fs::absolute(fs::path{dir}).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// plugins
|
// fallback search options if specified
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->PluginDir}.string())) {
|
for (const auto& fallback : fallback_dirs) {
|
||||||
m_plugins_path = fs::relative(fs::path{m_server_path + "/" + c->PluginDir}).string();
|
if (File::Exists((fs::path{m_server_path} / fallback).string())) {
|
||||||
|
return fs::relative(fs::path{m_server_path} / fallback).lexically_normal().string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lua_modules
|
// if all else fails, just set it to the config value
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->LuaModuleDir}.string())) {
|
return dir;
|
||||||
m_lua_modules_path = fs::relative(fs::path{m_server_path + "/" + c->LuaModuleDir}).string();
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// lua mods
|
m_maps_path = resolve_path(c->MapDir, {"maps", "Maps"});
|
||||||
if (File::Exists(fs::path{ m_server_path + "/mods" }.string())) {
|
m_quests_path = resolve_path(c->QuestDir);
|
||||||
m_lua_mods_path = fs::relative(fs::path{ m_server_path + "/mods" }).string();
|
m_plugins_path = resolve_path(c->PluginDir);
|
||||||
}
|
m_lua_modules_path = resolve_path(c->LuaModuleDir);
|
||||||
|
m_lua_mods_path = resolve_path("mods");
|
||||||
|
m_patch_path = resolve_path(c->PatchDir);
|
||||||
|
m_opcode_path = resolve_path(c->OpcodeDir);
|
||||||
|
m_shared_memory_path = resolve_path(c->SharedMemDir);
|
||||||
|
m_log_path = resolve_path(c->LogDir, {"logs"});
|
||||||
|
|
||||||
// patches
|
// Log all paths in a loop
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->PatchDir}.string())) {
|
std::vector<std::pair<std::string, std::string>> paths = {
|
||||||
m_patch_path = fs::relative(fs::path{m_server_path + "/" + c->PatchDir}).string();
|
{"server", m_server_path},
|
||||||
}
|
{"logs", m_log_path},
|
||||||
|
{"lua mods", m_lua_mods_path},
|
||||||
|
{"lua_modules", m_lua_modules_path},
|
||||||
|
{"maps", m_maps_path},
|
||||||
|
{"patches", m_patch_path},
|
||||||
|
{"opcode", m_opcode_path},
|
||||||
|
{"plugins", m_plugins_path},
|
||||||
|
{"quests", m_quests_path},
|
||||||
|
{"shared_memory", m_shared_memory_path}
|
||||||
|
};
|
||||||
|
|
||||||
// shared_memory_path
|
constexpr int name_width = 15;
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->SharedMemDir}.string())) {
|
constexpr int path_width = 0;
|
||||||
m_shared_memory_path = fs::relative(fs::path{ m_server_path + "/" + c->SharedMemDir }).string();
|
constexpr int break_length = 70;
|
||||||
}
|
|
||||||
|
|
||||||
// logging path
|
std::cout << std::endl;
|
||||||
if (File::Exists(fs::path{m_server_path + "/" + c->LogDir}.string())) {
|
LogInfo("{}", Strings::Repeat("-", break_length));
|
||||||
m_log_path = fs::relative(fs::path{m_server_path + "/" + c->LogDir}).string();
|
for (const auto& [name, in_path] : paths) {
|
||||||
|
if (!in_path.empty()) {
|
||||||
|
LogInfo("{:>{}} > [{:<{}}]", name, name_width, in_path, path_width);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
LogInfo("logs path [{}]", m_log_path);
|
LogInfo("{}", Strings::Repeat("-", break_length));
|
||||||
LogInfo("lua mods path [{}]", m_lua_mods_path);
|
|
||||||
LogInfo("lua_modules path [{}]", m_lua_modules_path);
|
|
||||||
LogInfo("maps path [{}]", m_maps_path);
|
|
||||||
LogInfo("patches path [{}]", m_patch_path);
|
|
||||||
LogInfo("plugins path [{}]", m_plugins_path);
|
|
||||||
LogInfo("quests path [{}]", m_quests_path);
|
|
||||||
LogInfo("shared_memory path [{}]", m_shared_memory_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &PathManager::GetServerPath() const
|
const std::string &PathManager::GetServerPath() const
|
||||||
@@ -129,6 +121,11 @@ const std::string &PathManager::GetPatchPath() const
|
|||||||
return m_patch_path;
|
return m_patch_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &PathManager::GetOpcodePath() const
|
||||||
|
{
|
||||||
|
return m_opcode_path;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string &PathManager::GetLuaModulesPath() const
|
const std::string &PathManager::GetLuaModulesPath() const
|
||||||
{
|
{
|
||||||
return m_lua_modules_path;
|
return m_lua_modules_path;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public:
|
|||||||
[[nodiscard]] const std::string &GetLuaModulesPath() const;
|
[[nodiscard]] const std::string &GetLuaModulesPath() const;
|
||||||
[[nodiscard]] const std::string &GetMapsPath() const;
|
[[nodiscard]] const std::string &GetMapsPath() const;
|
||||||
[[nodiscard]] const std::string &GetPatchPath() const;
|
[[nodiscard]] const std::string &GetPatchPath() const;
|
||||||
|
[[nodiscard]] const std::string &GetOpcodePath() const;
|
||||||
[[nodiscard]] const std::string &GetPluginsPath() const;
|
[[nodiscard]] const std::string &GetPluginsPath() const;
|
||||||
[[nodiscard]] const std::string &GetQuestsPath() const;
|
[[nodiscard]] const std::string &GetQuestsPath() const;
|
||||||
[[nodiscard]] const std::string &GetServerPath() const;
|
[[nodiscard]] const std::string &GetServerPath() const;
|
||||||
@@ -24,6 +25,7 @@ private:
|
|||||||
std::string m_lua_modules_path;
|
std::string m_lua_modules_path;
|
||||||
std::string m_maps_path;
|
std::string m_maps_path;
|
||||||
std::string m_patch_path;
|
std::string m_patch_path;
|
||||||
|
std::string m_opcode_path;
|
||||||
std::string m_plugins_path;
|
std::string m_plugins_path;
|
||||||
std::string m_quests_path;
|
std::string m_quests_path;
|
||||||
std::string m_server_path;
|
std::string m_server_path;
|
||||||
|
|||||||
@@ -49,23 +49,23 @@ public:
|
|||||||
std::string field;
|
std::string field;
|
||||||
|
|
||||||
switch (theme_id) {
|
switch (theme_id) {
|
||||||
case LDoNThemes::GUK: {
|
case LDoNTheme::GUK: {
|
||||||
field = "guk_";
|
field = "guk_";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LDoNThemes::MIR: {
|
case LDoNTheme::MIR: {
|
||||||
field = "mir_";
|
field = "mir_";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LDoNThemes::MMC: {
|
case LDoNTheme::MMC: {
|
||||||
field = "mmc_";
|
field = "mmc_";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LDoNThemes::RUJ: {
|
case LDoNTheme::RUJ: {
|
||||||
field = "ruj_";
|
field = "ruj_";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LDoNThemes::TAK: {
|
case LDoNTheme::TAK: {
|
||||||
field = "tak_";
|
field = "tak_";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,416 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_BOT_BLOCKED_BUFFS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_BOT_BLOCKED_BUFFS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseBotBlockedBuffsRepository {
|
||||||
|
public:
|
||||||
|
struct BotBlockedBuffs {
|
||||||
|
uint32_t bot_id;
|
||||||
|
uint32_t spell_id;
|
||||||
|
uint8_t blocked;
|
||||||
|
uint8_t blocked_pet;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("bot_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"bot_id",
|
||||||
|
"spell_id",
|
||||||
|
"blocked",
|
||||||
|
"blocked_pet",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"bot_id",
|
||||||
|
"spell_id",
|
||||||
|
"blocked",
|
||||||
|
"blocked_pet",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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_blocked_buffs");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotBlockedBuffs NewEntity()
|
||||||
|
{
|
||||||
|
BotBlockedBuffs e{};
|
||||||
|
|
||||||
|
e.bot_id = 0;
|
||||||
|
e.spell_id = 0;
|
||||||
|
e.blocked = 0;
|
||||||
|
e.blocked_pet = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotBlockedBuffs GetBotBlockedBuffs(
|
||||||
|
const std::vector<BotBlockedBuffs> &bot_blocked_buffss,
|
||||||
|
int bot_blocked_buffs_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &bot_blocked_buffs : bot_blocked_buffss) {
|
||||||
|
if (bot_blocked_buffs.bot_id == bot_blocked_buffs_id) {
|
||||||
|
return bot_blocked_buffs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotBlockedBuffs FindOne(
|
||||||
|
Database& db,
|
||||||
|
int bot_blocked_buffs_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_blocked_buffs_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
BotBlockedBuffs e{};
|
||||||
|
|
||||||
|
e.bot_id = row[0] ? static_cast<uint32_t>(atoi(row[0])) : 0;
|
||||||
|
e.spell_id = row[1] ? static_cast<uint32_t>(atoi(row[1])) : 0;
|
||||||
|
e.blocked = row[2] ? static_cast<uint8_t>(atoi(row[2])) : 0;
|
||||||
|
e.blocked_pet = row[3] ? static_cast<uint8_t>(atoi(row[3])) : 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int bot_blocked_buffs_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_blocked_buffs_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const BotBlockedBuffs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[0] + " = " + std::to_string(e.bot_id));
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.spell_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.blocked));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.blocked_pet));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.bot_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotBlockedBuffs InsertOne(
|
||||||
|
Database& db,
|
||||||
|
BotBlockedBuffs e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.blocked));
|
||||||
|
v.push_back(std::to_string(e.blocked_pet));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.bot_id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BotBlockedBuffs> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.blocked));
|
||||||
|
v.push_back(std::to_string(e.blocked_pet));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
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<BotBlockedBuffs> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<BotBlockedBuffs> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BotBlockedBuffs e{};
|
||||||
|
|
||||||
|
e.bot_id = row[0] ? static_cast<uint32_t>(atoi(row[0])) : 0;
|
||||||
|
e.spell_id = row[1] ? static_cast<uint32_t>(atoi(row[1])) : 0;
|
||||||
|
e.blocked = row[2] ? static_cast<uint8_t>(atoi(row[2])) : 0;
|
||||||
|
e.blocked_pet = row[3] ? static_cast<uint8_t>(atoi(row[3])) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BotBlockedBuffs> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<BotBlockedBuffs> 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) {
|
||||||
|
BotBlockedBuffs e{};
|
||||||
|
|
||||||
|
e.bot_id = row[0] ? static_cast<uint32_t>(atoi(row[0])) : 0;
|
||||||
|
e.spell_id = row[1] ? static_cast<uint32_t>(atoi(row[1])) : 0;
|
||||||
|
e.blocked = row[2] ? static_cast<uint8_t>(atoi(row[2])) : 0;
|
||||||
|
e.blocked_pet = row[3] ? static_cast<uint8_t>(atoi(row[3])) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const BotBlockedBuffs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.blocked));
|
||||||
|
v.push_back(std::to_string(e.blocked_pet));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BotBlockedBuffs> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.blocked));
|
||||||
|
v.push_back(std::to_string(e.blocked_pet));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_BOT_BLOCKED_BUFFS_REPOSITORY_H
|
||||||
@@ -64,13 +64,6 @@ public:
|
|||||||
int16_t poison;
|
int16_t poison;
|
||||||
int16_t disease;
|
int16_t disease;
|
||||||
int16_t corruption;
|
int16_t corruption;
|
||||||
uint32_t show_helm;
|
|
||||||
uint32_t follow_distance;
|
|
||||||
uint8_t stop_melee_level;
|
|
||||||
int32_t expansion_bitmask;
|
|
||||||
uint8_t enforce_spell_settings;
|
|
||||||
uint8_t archery_setting;
|
|
||||||
uint32_t caster_range;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -126,13 +119,6 @@ public:
|
|||||||
"poison",
|
"poison",
|
||||||
"disease",
|
"disease",
|
||||||
"corruption",
|
"corruption",
|
||||||
"show_helm",
|
|
||||||
"follow_distance",
|
|
||||||
"stop_melee_level",
|
|
||||||
"expansion_bitmask",
|
|
||||||
"enforce_spell_settings",
|
|
||||||
"archery_setting",
|
|
||||||
"caster_range",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,13 +170,6 @@ public:
|
|||||||
"poison",
|
"poison",
|
||||||
"disease",
|
"disease",
|
||||||
"corruption",
|
"corruption",
|
||||||
"show_helm",
|
|
||||||
"follow_distance",
|
|
||||||
"stop_melee_level",
|
|
||||||
"expansion_bitmask",
|
|
||||||
"enforce_spell_settings",
|
|
||||||
"archery_setting",
|
|
||||||
"caster_range",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,13 +255,7 @@ public:
|
|||||||
e.poison = 0;
|
e.poison = 0;
|
||||||
e.disease = 0;
|
e.disease = 0;
|
||||||
e.corruption = 0;
|
e.corruption = 0;
|
||||||
e.show_helm = 0;
|
|
||||||
e.follow_distance = 200;
|
|
||||||
e.stop_melee_level = 255;
|
|
||||||
e.expansion_bitmask = -1;
|
|
||||||
e.enforce_spell_settings = 0;
|
|
||||||
e.archery_setting = 0;
|
|
||||||
e.caster_range = 300;
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -364,13 +337,6 @@ public:
|
|||||||
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
|
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
|
||||||
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
|
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
|
||||||
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
|
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
|
||||||
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
|
|
||||||
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
|
|
||||||
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
|
|
||||||
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
|
|
||||||
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
|
|
||||||
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
|
||||||
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -383,14 +349,25 @@ public:
|
|||||||
int bot_data_id
|
int bot_data_id
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
std::string query;
|
||||||
fmt::format(
|
|
||||||
|
if (RuleB(Bots, BotSoftDeletes)) {
|
||||||
|
query = fmt::format(
|
||||||
|
"UPDATE {} SET name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64) WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_data_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
query = fmt::format(
|
||||||
"DELETE FROM {} WHERE {} = {}",
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
TableName(),
|
TableName(),
|
||||||
PrimaryKey(),
|
PrimaryKey(),
|
||||||
bot_data_id
|
bot_data_id
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
auto results = db.QueryDatabase(query);
|
||||||
|
|
||||||
return (results.Success() ? results.RowsAffected() : 0);
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
}
|
}
|
||||||
@@ -448,13 +425,6 @@ public:
|
|||||||
v.push_back(columns[42] + " = " + std::to_string(e.poison));
|
v.push_back(columns[42] + " = " + std::to_string(e.poison));
|
||||||
v.push_back(columns[43] + " = " + std::to_string(e.disease));
|
v.push_back(columns[43] + " = " + std::to_string(e.disease));
|
||||||
v.push_back(columns[44] + " = " + std::to_string(e.corruption));
|
v.push_back(columns[44] + " = " + std::to_string(e.corruption));
|
||||||
v.push_back(columns[45] + " = " + std::to_string(e.show_helm));
|
|
||||||
v.push_back(columns[46] + " = " + std::to_string(e.follow_distance));
|
|
||||||
v.push_back(columns[47] + " = " + std::to_string(e.stop_melee_level));
|
|
||||||
v.push_back(columns[48] + " = " + std::to_string(e.expansion_bitmask));
|
|
||||||
v.push_back(columns[49] + " = " + std::to_string(e.enforce_spell_settings));
|
|
||||||
v.push_back(columns[50] + " = " + std::to_string(e.archery_setting));
|
|
||||||
v.push_back(columns[51] + " = " + std::to_string(e.caster_range));
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -521,13 +491,6 @@ public:
|
|||||||
v.push_back(std::to_string(e.poison));
|
v.push_back(std::to_string(e.poison));
|
||||||
v.push_back(std::to_string(e.disease));
|
v.push_back(std::to_string(e.disease));
|
||||||
v.push_back(std::to_string(e.corruption));
|
v.push_back(std::to_string(e.corruption));
|
||||||
v.push_back(std::to_string(e.show_helm));
|
|
||||||
v.push_back(std::to_string(e.follow_distance));
|
|
||||||
v.push_back(std::to_string(e.stop_melee_level));
|
|
||||||
v.push_back(std::to_string(e.expansion_bitmask));
|
|
||||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
|
||||||
v.push_back(std::to_string(e.archery_setting));
|
|
||||||
v.push_back(std::to_string(e.caster_range));
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -602,13 +565,6 @@ public:
|
|||||||
v.push_back(std::to_string(e.poison));
|
v.push_back(std::to_string(e.poison));
|
||||||
v.push_back(std::to_string(e.disease));
|
v.push_back(std::to_string(e.disease));
|
||||||
v.push_back(std::to_string(e.corruption));
|
v.push_back(std::to_string(e.corruption));
|
||||||
v.push_back(std::to_string(e.show_helm));
|
|
||||||
v.push_back(std::to_string(e.follow_distance));
|
|
||||||
v.push_back(std::to_string(e.stop_melee_level));
|
|
||||||
v.push_back(std::to_string(e.expansion_bitmask));
|
|
||||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
|
||||||
v.push_back(std::to_string(e.archery_setting));
|
|
||||||
v.push_back(std::to_string(e.caster_range));
|
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -687,13 +643,6 @@ public:
|
|||||||
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
|
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
|
||||||
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
|
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
|
||||||
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
|
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
|
||||||
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
|
|
||||||
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
|
|
||||||
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
|
|
||||||
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
|
|
||||||
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
|
|
||||||
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
|
||||||
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -763,13 +712,6 @@ public:
|
|||||||
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
|
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
|
||||||
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
|
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
|
||||||
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
|
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
|
||||||
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
|
|
||||||
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
|
|
||||||
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
|
|
||||||
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
|
|
||||||
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
|
|
||||||
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
|
||||||
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -889,13 +831,6 @@ public:
|
|||||||
v.push_back(std::to_string(e.poison));
|
v.push_back(std::to_string(e.poison));
|
||||||
v.push_back(std::to_string(e.disease));
|
v.push_back(std::to_string(e.disease));
|
||||||
v.push_back(std::to_string(e.corruption));
|
v.push_back(std::to_string(e.corruption));
|
||||||
v.push_back(std::to_string(e.show_helm));
|
|
||||||
v.push_back(std::to_string(e.follow_distance));
|
|
||||||
v.push_back(std::to_string(e.stop_melee_level));
|
|
||||||
v.push_back(std::to_string(e.expansion_bitmask));
|
|
||||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
|
||||||
v.push_back(std::to_string(e.archery_setting));
|
|
||||||
v.push_back(std::to_string(e.caster_range));
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -963,13 +898,6 @@ public:
|
|||||||
v.push_back(std::to_string(e.poison));
|
v.push_back(std::to_string(e.poison));
|
||||||
v.push_back(std::to_string(e.disease));
|
v.push_back(std::to_string(e.disease));
|
||||||
v.push_back(std::to_string(e.corruption));
|
v.push_back(std::to_string(e.corruption));
|
||||||
v.push_back(std::to_string(e.show_helm));
|
|
||||||
v.push_back(std::to_string(e.follow_distance));
|
|
||||||
v.push_back(std::to_string(e.stop_melee_level));
|
|
||||||
v.push_back(std::to_string(e.expansion_bitmask));
|
|
||||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
|
||||||
v.push_back(std::to_string(e.archery_setting));
|
|
||||||
v.push_back(std::to_string(e.caster_range));
|
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,464 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_BOT_SETTINGS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_BOT_SETTINGS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseBotSettingsRepository {
|
||||||
|
public:
|
||||||
|
struct BotSettings {
|
||||||
|
uint32_t character_id;
|
||||||
|
uint32_t bot_id;
|
||||||
|
uint8_t stance;
|
||||||
|
uint16_t setting_id;
|
||||||
|
uint8_t setting_type;
|
||||||
|
int32_t value;
|
||||||
|
std::string category_name;
|
||||||
|
std::string setting_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("character_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"character_id",
|
||||||
|
"bot_id",
|
||||||
|
"stance",
|
||||||
|
"setting_id",
|
||||||
|
"setting_type",
|
||||||
|
"value",
|
||||||
|
"category_name",
|
||||||
|
"setting_name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"character_id",
|
||||||
|
"bot_id",
|
||||||
|
"stance",
|
||||||
|
"setting_id",
|
||||||
|
"setting_type",
|
||||||
|
"value",
|
||||||
|
"category_name",
|
||||||
|
"setting_name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("bot_settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotSettings NewEntity()
|
||||||
|
{
|
||||||
|
BotSettings e{};
|
||||||
|
|
||||||
|
e.character_id = 0;
|
||||||
|
e.bot_id = 0;
|
||||||
|
e.stance = 0;
|
||||||
|
e.setting_id = 0;
|
||||||
|
e.setting_type = 0;
|
||||||
|
e.value = 0;
|
||||||
|
e.category_name = "";
|
||||||
|
e.setting_name = "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotSettings GetBotSettings(
|
||||||
|
const std::vector<BotSettings> &bot_settingss,
|
||||||
|
int bot_settings_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &bot_settings : bot_settingss) {
|
||||||
|
if (bot_settings.character_id == bot_settings_id) {
|
||||||
|
return bot_settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotSettings FindOne(
|
||||||
|
Database& db,
|
||||||
|
int bot_settings_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_settings_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
BotSettings e{};
|
||||||
|
|
||||||
|
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.bot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.stance = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.setting_id = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.setting_type = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.value = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
||||||
|
e.category_name = row[6] ? row[6] : "";
|
||||||
|
e.setting_name = row[7] ? row[7] : "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int bot_settings_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_settings_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const BotSettings &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[0] + " = " + std::to_string(e.character_id));
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.bot_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.stance));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.setting_id));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.setting_type));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.value));
|
||||||
|
v.push_back(columns[6] + " = '" + Strings::Escape(e.category_name) + "'");
|
||||||
|
v.push_back(columns[7] + " = '" + Strings::Escape(e.setting_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.character_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotSettings InsertOne(
|
||||||
|
Database& db,
|
||||||
|
BotSettings e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.stance));
|
||||||
|
v.push_back(std::to_string(e.setting_id));
|
||||||
|
v.push_back(std::to_string(e.setting_type));
|
||||||
|
v.push_back(std::to_string(e.value));
|
||||||
|
v.push_back("'" + Strings::Escape(e.category_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.character_id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BotSettings> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.stance));
|
||||||
|
v.push_back(std::to_string(e.setting_id));
|
||||||
|
v.push_back(std::to_string(e.setting_type));
|
||||||
|
v.push_back(std::to_string(e.value));
|
||||||
|
v.push_back("'" + Strings::Escape(e.category_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BotSettings> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<BotSettings> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BotSettings e{};
|
||||||
|
|
||||||
|
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.bot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.stance = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.setting_id = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.setting_type = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.value = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
||||||
|
e.category_name = row[6] ? row[6] : "";
|
||||||
|
e.setting_name = row[7] ? row[7] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BotSettings> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<BotSettings> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {}",
|
||||||
|
BaseSelect(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BotSettings e{};
|
||||||
|
|
||||||
|
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.bot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.stance = row[2] ? static_cast<uint8_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.setting_id = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.setting_type = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.value = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
||||||
|
e.category_name = row[6] ? row[6] : "";
|
||||||
|
e.setting_name = row[7] ? row[7] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const BotSettings &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.stance));
|
||||||
|
v.push_back(std::to_string(e.setting_id));
|
||||||
|
v.push_back(std::to_string(e.setting_type));
|
||||||
|
v.push_back(std::to_string(e.value));
|
||||||
|
v.push_back("'" + Strings::Escape(e.category_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BotSettings> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
v.push_back(std::to_string(e.stance));
|
||||||
|
v.push_back(std::to_string(e.setting_id));
|
||||||
|
v.push_back(std::to_string(e.setting_type));
|
||||||
|
v.push_back(std::to_string(e.value));
|
||||||
|
v.push_back("'" + Strings::Escape(e.category_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.setting_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_BOT_SETTINGS_REPOSITORY_H
|
||||||
@@ -21,7 +21,7 @@ public:
|
|||||||
struct BotSpellsEntries {
|
struct BotSpellsEntries {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
int32_t npc_spells_id;
|
int32_t npc_spells_id;
|
||||||
int16_t spellid;
|
uint16_t spell_id;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint8_t minlevel;
|
uint8_t minlevel;
|
||||||
uint8_t maxlevel;
|
uint8_t maxlevel;
|
||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
return {
|
return {
|
||||||
"id",
|
"id",
|
||||||
"npc_spells_id",
|
"npc_spells_id",
|
||||||
"spellid",
|
"spell_id",
|
||||||
"type",
|
"type",
|
||||||
"minlevel",
|
"minlevel",
|
||||||
"maxlevel",
|
"maxlevel",
|
||||||
@@ -67,7 +67,7 @@ public:
|
|||||||
return {
|
return {
|
||||||
"id",
|
"id",
|
||||||
"npc_spells_id",
|
"npc_spells_id",
|
||||||
"spellid",
|
"spell_id",
|
||||||
"type",
|
"type",
|
||||||
"minlevel",
|
"minlevel",
|
||||||
"maxlevel",
|
"maxlevel",
|
||||||
@@ -122,7 +122,7 @@ public:
|
|||||||
|
|
||||||
e.id = 0;
|
e.id = 0;
|
||||||
e.npc_spells_id = 0;
|
e.npc_spells_id = 0;
|
||||||
e.spellid = 0;
|
e.spell_id = 0;
|
||||||
e.type = 0;
|
e.type = 0;
|
||||||
e.minlevel = 0;
|
e.minlevel = 0;
|
||||||
e.maxlevel = 255;
|
e.maxlevel = 255;
|
||||||
@@ -173,7 +173,7 @@ public:
|
|||||||
|
|
||||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
||||||
e.spellid = row[2] ? static_cast<int16_t>(atoi(row[2])) : 0;
|
e.spell_id = row[2] ? static_cast<uint16_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
|
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
|
||||||
@@ -220,7 +220,7 @@ public:
|
|||||||
auto columns = Columns();
|
auto columns = Columns();
|
||||||
|
|
||||||
v.push_back(columns[1] + " = " + std::to_string(e.npc_spells_id));
|
v.push_back(columns[1] + " = " + std::to_string(e.npc_spells_id));
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.spellid));
|
v.push_back(columns[2] + " = " + std::to_string(e.spell_id));
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.type));
|
v.push_back(columns[3] + " = " + std::to_string(e.type));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.minlevel));
|
v.push_back(columns[4] + " = " + std::to_string(e.minlevel));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.maxlevel));
|
v.push_back(columns[5] + " = " + std::to_string(e.maxlevel));
|
||||||
@@ -256,7 +256,7 @@ public:
|
|||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.npc_spells_id));
|
v.push_back(std::to_string(e.npc_spells_id));
|
||||||
v.push_back(std::to_string(e.spellid));
|
v.push_back(std::to_string(e.spell_id));
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.minlevel));
|
v.push_back(std::to_string(e.minlevel));
|
||||||
v.push_back(std::to_string(e.maxlevel));
|
v.push_back(std::to_string(e.maxlevel));
|
||||||
@@ -300,7 +300,7 @@ public:
|
|||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.npc_spells_id));
|
v.push_back(std::to_string(e.npc_spells_id));
|
||||||
v.push_back(std::to_string(e.spellid));
|
v.push_back(std::to_string(e.spell_id));
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.minlevel));
|
v.push_back(std::to_string(e.minlevel));
|
||||||
v.push_back(std::to_string(e.maxlevel));
|
v.push_back(std::to_string(e.maxlevel));
|
||||||
@@ -348,7 +348,7 @@ public:
|
|||||||
|
|
||||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
||||||
e.spellid = row[2] ? static_cast<int16_t>(atoi(row[2])) : 0;
|
e.spell_id = row[2] ? static_cast<uint16_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
|
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
|
||||||
@@ -387,7 +387,7 @@ public:
|
|||||||
|
|
||||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
||||||
e.spellid = row[2] ? static_cast<int16_t>(atoi(row[2])) : 0;
|
e.spell_id = row[2] ? static_cast<uint16_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
|
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
|
||||||
@@ -476,7 +476,7 @@ public:
|
|||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.npc_spells_id));
|
v.push_back(std::to_string(e.npc_spells_id));
|
||||||
v.push_back(std::to_string(e.spellid));
|
v.push_back(std::to_string(e.spell_id));
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.minlevel));
|
v.push_back(std::to_string(e.minlevel));
|
||||||
v.push_back(std::to_string(e.maxlevel));
|
v.push_back(std::to_string(e.maxlevel));
|
||||||
@@ -513,7 +513,7 @@ public:
|
|||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.npc_spells_id));
|
v.push_back(std::to_string(e.npc_spells_id));
|
||||||
v.push_back(std::to_string(e.spellid));
|
v.push_back(std::to_string(e.spell_id));
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.minlevel));
|
v.push_back(std::to_string(e.minlevel));
|
||||||
v.push_back(std::to_string(e.maxlevel));
|
v.push_back(std::to_string(e.maxlevel));
|
||||||
|
|||||||
@@ -0,0 +1,475 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_BUYER_BUY_LINES_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_BUYER_BUY_LINES_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseBuyerBuyLinesRepository {
|
||||||
|
public:
|
||||||
|
struct BuyerBuyLines {
|
||||||
|
uint64_t id;
|
||||||
|
uint64_t buyer_id;
|
||||||
|
uint32_t char_id;
|
||||||
|
int32_t buy_slot_id;
|
||||||
|
int32_t item_id;
|
||||||
|
int32_t item_qty;
|
||||||
|
int32_t item_price;
|
||||||
|
uint32_t item_icon;
|
||||||
|
std::string item_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"buyer_id",
|
||||||
|
"char_id",
|
||||||
|
"buy_slot_id",
|
||||||
|
"item_id",
|
||||||
|
"item_qty",
|
||||||
|
"item_price",
|
||||||
|
"item_icon",
|
||||||
|
"item_name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"buyer_id",
|
||||||
|
"char_id",
|
||||||
|
"buy_slot_id",
|
||||||
|
"item_id",
|
||||||
|
"item_qty",
|
||||||
|
"item_price",
|
||||||
|
"item_icon",
|
||||||
|
"item_name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("buyer_buy_lines");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerBuyLines NewEntity()
|
||||||
|
{
|
||||||
|
BuyerBuyLines e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.buyer_id = 0;
|
||||||
|
e.char_id = 0;
|
||||||
|
e.buy_slot_id = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
e.item_qty = 0;
|
||||||
|
e.item_price = 0;
|
||||||
|
e.item_icon = 0;
|
||||||
|
e.item_name = "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerBuyLines GetBuyerBuyLines(
|
||||||
|
const std::vector<BuyerBuyLines> &buyer_buy_liness,
|
||||||
|
int buyer_buy_lines_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &buyer_buy_lines : buyer_buy_liness) {
|
||||||
|
if (buyer_buy_lines.id == buyer_buy_lines_id) {
|
||||||
|
return buyer_buy_lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerBuyLines FindOne(
|
||||||
|
Database& db,
|
||||||
|
int buyer_buy_lines_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
buyer_buy_lines_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
BuyerBuyLines e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.buyer_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
|
||||||
|
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.buy_slot_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
|
||||||
|
e.item_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
||||||
|
e.item_qty = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
||||||
|
e.item_price = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
|
||||||
|
e.item_icon = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.item_name = row[8] ? row[8] : "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int buyer_buy_lines_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
buyer_buy_lines_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const BuyerBuyLines &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.buyer_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.char_id));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.buy_slot_id));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.item_id));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.item_qty));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.item_price));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.item_icon));
|
||||||
|
v.push_back(columns[8] + " = '" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerBuyLines InsertOne(
|
||||||
|
Database& db,
|
||||||
|
BuyerBuyLines e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.buyer_id));
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.buy_slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_price));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
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<BuyerBuyLines> &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.buyer_id));
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.buy_slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_price));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BuyerBuyLines> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<BuyerBuyLines> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BuyerBuyLines e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.buyer_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
|
||||||
|
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.buy_slot_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
|
||||||
|
e.item_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
||||||
|
e.item_qty = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
||||||
|
e.item_price = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
|
||||||
|
e.item_icon = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.item_name = row[8] ? row[8] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BuyerBuyLines> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<BuyerBuyLines> 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) {
|
||||||
|
BuyerBuyLines e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.buyer_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
|
||||||
|
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.buy_slot_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
|
||||||
|
e.item_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
||||||
|
e.item_qty = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
||||||
|
e.item_price = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
|
||||||
|
e.item_icon = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.item_name = row[8] ? row[8] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const BuyerBuyLines &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.buyer_id));
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.buy_slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_price));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BuyerBuyLines> &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.buyer_id));
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.buy_slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_price));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_BUYER_BUY_LINES_REPOSITORY_H
|
||||||
@@ -19,40 +19,46 @@
|
|||||||
class BaseBuyerRepository {
|
class BaseBuyerRepository {
|
||||||
public:
|
public:
|
||||||
struct Buyer {
|
struct Buyer {
|
||||||
int32_t charid;
|
uint64_t id;
|
||||||
int32_t buyslot;
|
uint32_t char_id;
|
||||||
int32_t itemid;
|
uint32_t char_entity_id;
|
||||||
std::string itemname;
|
std::string char_name;
|
||||||
int32_t quantity;
|
uint32_t char_zone_id;
|
||||||
int32_t price;
|
uint32_t char_zone_instance_id;
|
||||||
|
time_t transaction_date;
|
||||||
|
std::string welcome_message;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
{
|
{
|
||||||
return std::string("charid");
|
return std::string("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::string> Columns()
|
static std::vector<std::string> Columns()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"charid",
|
"id",
|
||||||
"buyslot",
|
"char_id",
|
||||||
"itemid",
|
"char_entity_id",
|
||||||
"itemname",
|
"char_name",
|
||||||
"quantity",
|
"char_zone_id",
|
||||||
"price",
|
"char_zone_instance_id",
|
||||||
|
"transaction_date",
|
||||||
|
"welcome_message",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::string> SelectColumns()
|
static std::vector<std::string> SelectColumns()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"charid",
|
"id",
|
||||||
"buyslot",
|
"char_id",
|
||||||
"itemid",
|
"char_entity_id",
|
||||||
"itemname",
|
"char_name",
|
||||||
"quantity",
|
"char_zone_id",
|
||||||
"price",
|
"char_zone_instance_id",
|
||||||
|
"UNIX_TIMESTAMP(transaction_date)",
|
||||||
|
"welcome_message",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,12 +99,14 @@ public:
|
|||||||
{
|
{
|
||||||
Buyer e{};
|
Buyer e{};
|
||||||
|
|
||||||
e.charid = 0;
|
e.id = 0;
|
||||||
e.buyslot = 0;
|
e.char_id = 0;
|
||||||
e.itemid = 0;
|
e.char_entity_id = 0;
|
||||||
e.itemname = "";
|
e.char_name = "";
|
||||||
e.quantity = 0;
|
e.char_zone_id = 0;
|
||||||
e.price = 0;
|
e.char_zone_instance_id = 0;
|
||||||
|
e.transaction_date = 0;
|
||||||
|
e.welcome_message = "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -109,7 +117,7 @@ public:
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (auto &buyer : buyers) {
|
for (auto &buyer : buyers) {
|
||||||
if (buyer.charid == buyer_id) {
|
if (buyer.id == buyer_id) {
|
||||||
return buyer;
|
return buyer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,12 +143,14 @@ public:
|
|||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
Buyer e{};
|
Buyer e{};
|
||||||
|
|
||||||
e.charid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
e.buyslot = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.itemid = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
e.char_entity_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.itemname = row[3] ? row[3] : "";
|
e.char_name = row[3] ? row[3] : "";
|
||||||
e.quantity = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
e.char_zone_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.price = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
e.char_zone_instance_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.transaction_date = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
|
||||||
|
e.welcome_message = row[7] ? row[7] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -174,12 +184,13 @@ public:
|
|||||||
|
|
||||||
auto columns = Columns();
|
auto columns = Columns();
|
||||||
|
|
||||||
v.push_back(columns[0] + " = " + std::to_string(e.charid));
|
v.push_back(columns[1] + " = " + std::to_string(e.char_id));
|
||||||
v.push_back(columns[1] + " = " + std::to_string(e.buyslot));
|
v.push_back(columns[2] + " = " + std::to_string(e.char_entity_id));
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.itemid));
|
v.push_back(columns[3] + " = '" + Strings::Escape(e.char_name) + "'");
|
||||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.itemname) + "'");
|
v.push_back(columns[4] + " = " + std::to_string(e.char_zone_id));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.quantity));
|
v.push_back(columns[5] + " = " + std::to_string(e.char_zone_instance_id));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.price));
|
v.push_back(columns[6] + " = FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
|
||||||
|
v.push_back(columns[7] + " = '" + Strings::Escape(e.welcome_message) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -187,7 +198,7 @@ public:
|
|||||||
TableName(),
|
TableName(),
|
||||||
Strings::Implode(", ", v),
|
Strings::Implode(", ", v),
|
||||||
PrimaryKey(),
|
PrimaryKey(),
|
||||||
e.charid
|
e.id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -201,12 +212,14 @@ public:
|
|||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.buyslot));
|
v.push_back(std::to_string(e.char_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.char_entity_id));
|
||||||
v.push_back("'" + Strings::Escape(e.itemname) + "'");
|
v.push_back("'" + Strings::Escape(e.char_name) + "'");
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.char_zone_id));
|
||||||
v.push_back(std::to_string(e.price));
|
v.push_back(std::to_string(e.char_zone_instance_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
|
||||||
|
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -217,7 +230,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (results.Success()) {
|
if (results.Success()) {
|
||||||
e.charid = results.LastInsertedID();
|
e.id = results.LastInsertedID();
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,12 +249,14 @@ public:
|
|||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.buyslot));
|
v.push_back(std::to_string(e.char_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.char_entity_id));
|
||||||
v.push_back("'" + Strings::Escape(e.itemname) + "'");
|
v.push_back("'" + Strings::Escape(e.char_name) + "'");
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.char_zone_id));
|
||||||
v.push_back(std::to_string(e.price));
|
v.push_back(std::to_string(e.char_zone_instance_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
|
||||||
|
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -275,12 +290,14 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Buyer e{};
|
Buyer e{};
|
||||||
|
|
||||||
e.charid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
e.buyslot = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.itemid = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
e.char_entity_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.itemname = row[3] ? row[3] : "";
|
e.char_name = row[3] ? row[3] : "";
|
||||||
e.quantity = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
e.char_zone_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.price = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
e.char_zone_instance_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.transaction_date = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
|
||||||
|
e.welcome_message = row[7] ? row[7] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -305,12 +322,14 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Buyer e{};
|
Buyer e{};
|
||||||
|
|
||||||
e.charid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
e.buyslot = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
|
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.itemid = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
e.char_entity_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.itemname = row[3] ? row[3] : "";
|
e.char_name = row[3] ? row[3] : "";
|
||||||
e.quantity = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
e.char_zone_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.price = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
|
e.char_zone_instance_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.transaction_date = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
|
||||||
|
e.welcome_message = row[7] ? row[7] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -385,12 +404,14 @@ public:
|
|||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.buyslot));
|
v.push_back(std::to_string(e.char_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.char_entity_id));
|
||||||
v.push_back("'" + Strings::Escape(e.itemname) + "'");
|
v.push_back("'" + Strings::Escape(e.char_name) + "'");
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.char_zone_id));
|
||||||
v.push_back(std::to_string(e.price));
|
v.push_back(std::to_string(e.char_zone_instance_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
|
||||||
|
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -413,12 +434,14 @@ public:
|
|||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.buyslot));
|
v.push_back(std::to_string(e.char_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.char_entity_id));
|
||||||
v.push_back("'" + Strings::Escape(e.itemname) + "'");
|
v.push_back("'" + Strings::Escape(e.char_name) + "'");
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.char_zone_id));
|
||||||
v.push_back(std::to_string(e.price));
|
v.push_back(std::to_string(e.char_zone_instance_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
|
||||||
|
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,439 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_BUYER_TRADE_ITEMS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_BUYER_TRADE_ITEMS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseBuyerTradeItemsRepository {
|
||||||
|
public:
|
||||||
|
struct BuyerTradeItems {
|
||||||
|
uint64_t id;
|
||||||
|
uint64_t buyer_buy_lines_id;
|
||||||
|
int32_t item_id;
|
||||||
|
int32_t item_qty;
|
||||||
|
int32_t item_icon;
|
||||||
|
std::string item_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"buyer_buy_lines_id",
|
||||||
|
"item_id",
|
||||||
|
"item_qty",
|
||||||
|
"item_icon",
|
||||||
|
"item_name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"buyer_buy_lines_id",
|
||||||
|
"item_id",
|
||||||
|
"item_qty",
|
||||||
|
"item_icon",
|
||||||
|
"item_name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("buyer_trade_items");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerTradeItems NewEntity()
|
||||||
|
{
|
||||||
|
BuyerTradeItems e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.buyer_buy_lines_id = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
e.item_qty = 0;
|
||||||
|
e.item_icon = 0;
|
||||||
|
e.item_name = "0";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerTradeItems GetBuyerTradeItems(
|
||||||
|
const std::vector<BuyerTradeItems> &buyer_trade_itemss,
|
||||||
|
int buyer_trade_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &buyer_trade_items : buyer_trade_itemss) {
|
||||||
|
if (buyer_trade_items.id == buyer_trade_items_id) {
|
||||||
|
return buyer_trade_items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerTradeItems FindOne(
|
||||||
|
Database& db,
|
||||||
|
int buyer_trade_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
buyer_trade_items_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
BuyerTradeItems e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.buyer_buy_lines_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
|
||||||
|
e.item_id = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
||||||
|
e.item_qty = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
|
||||||
|
e.item_icon = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
||||||
|
e.item_name = row[5] ? row[5] : "0";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int buyer_trade_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
buyer_trade_items_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const BuyerTradeItems &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.buyer_buy_lines_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.item_qty));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.item_icon));
|
||||||
|
v.push_back(columns[5] + " = '" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuyerTradeItems InsertOne(
|
||||||
|
Database& db,
|
||||||
|
BuyerTradeItems e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.buyer_buy_lines_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
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<BuyerTradeItems> &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.buyer_buy_lines_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BuyerTradeItems> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<BuyerTradeItems> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BuyerTradeItems e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.buyer_buy_lines_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
|
||||||
|
e.item_id = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
||||||
|
e.item_qty = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
|
||||||
|
e.item_icon = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
||||||
|
e.item_name = row[5] ? row[5] : "0";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BuyerTradeItems> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<BuyerTradeItems> 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) {
|
||||||
|
BuyerTradeItems e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.buyer_buy_lines_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
|
||||||
|
e.item_id = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
||||||
|
e.item_qty = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
|
||||||
|
e.item_icon = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
|
||||||
|
e.item_name = row[5] ? row[5] : "0";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const BuyerTradeItems &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.buyer_buy_lines_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BuyerTradeItems> &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.buyer_buy_lines_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_qty));
|
||||||
|
v.push_back(std::to_string(e.item_icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.item_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_BUYER_TRADE_ITEMS_REPOSITORY_H
|
||||||
@@ -123,6 +123,7 @@ public:
|
|||||||
uint32_t aa_points_old;
|
uint32_t aa_points_old;
|
||||||
uint32_t e_last_invsnapshot;
|
uint32_t e_last_invsnapshot;
|
||||||
time_t deleted_at;
|
time_t deleted_at;
|
||||||
|
uint8_t illusion_block;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -237,6 +238,7 @@ public:
|
|||||||
"aa_points_old",
|
"aa_points_old",
|
||||||
"e_last_invsnapshot",
|
"e_last_invsnapshot",
|
||||||
"deleted_at",
|
"deleted_at",
|
||||||
|
"illusion_block",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +349,7 @@ public:
|
|||||||
"aa_points_old",
|
"aa_points_old",
|
||||||
"e_last_invsnapshot",
|
"e_last_invsnapshot",
|
||||||
"UNIX_TIMESTAMP(deleted_at)",
|
"UNIX_TIMESTAMP(deleted_at)",
|
||||||
|
"illusion_block",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,6 +494,7 @@ public:
|
|||||||
e.aa_points_old = 0;
|
e.aa_points_old = 0;
|
||||||
e.e_last_invsnapshot = 0;
|
e.e_last_invsnapshot = 0;
|
||||||
e.deleted_at = 0;
|
e.deleted_at = 0;
|
||||||
|
e.illusion_block = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -631,6 +635,7 @@ public:
|
|||||||
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
|
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
|
||||||
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
|
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
|
||||||
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
|
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
|
||||||
|
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -767,6 +772,7 @@ public:
|
|||||||
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
|
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
|
||||||
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
|
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
|
||||||
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
v.push_back(columns[104] + " = " + std::to_string(e.illusion_block));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -892,6 +898,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aa_points_old));
|
v.push_back(std::to_string(e.aa_points_old));
|
||||||
v.push_back(std::to_string(e.e_last_invsnapshot));
|
v.push_back(std::to_string(e.e_last_invsnapshot));
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
v.push_back(std::to_string(e.illusion_block));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -1025,6 +1032,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aa_points_old));
|
v.push_back(std::to_string(e.aa_points_old));
|
||||||
v.push_back(std::to_string(e.e_last_invsnapshot));
|
v.push_back(std::to_string(e.e_last_invsnapshot));
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
v.push_back(std::to_string(e.illusion_block));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -1162,6 +1170,7 @@ public:
|
|||||||
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
|
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
|
||||||
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
|
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
|
||||||
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
|
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
|
||||||
|
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -1290,6 +1299,7 @@ public:
|
|||||||
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
|
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
|
||||||
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
|
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
|
||||||
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
|
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
|
||||||
|
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -1468,6 +1478,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aa_points_old));
|
v.push_back(std::to_string(e.aa_points_old));
|
||||||
v.push_back(std::to_string(e.e_last_invsnapshot));
|
v.push_back(std::to_string(e.e_last_invsnapshot));
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
v.push_back(std::to_string(e.illusion_block));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -1594,6 +1605,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aa_points_old));
|
v.push_back(std::to_string(e.aa_points_old));
|
||||||
v.push_back(std::to_string(e.e_last_invsnapshot));
|
v.push_back(std::to_string(e.e_last_invsnapshot));
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
v.push_back(std::to_string(e.illusion_block));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,475 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_CHARACTER_EVOLVING_ITEMS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_CHARACTER_EVOLVING_ITEMS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseCharacterEvolvingItemsRepository {
|
||||||
|
public:
|
||||||
|
struct CharacterEvolvingItems {
|
||||||
|
uint64_t id;
|
||||||
|
uint32_t character_id;
|
||||||
|
uint32_t item_id;
|
||||||
|
uint8_t activated;
|
||||||
|
uint8_t equipped;
|
||||||
|
int64_t current_amount;
|
||||||
|
double progression;
|
||||||
|
uint32_t final_item_id;
|
||||||
|
time_t deleted_at;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"character_id",
|
||||||
|
"item_id",
|
||||||
|
"activated",
|
||||||
|
"equipped",
|
||||||
|
"current_amount",
|
||||||
|
"progression",
|
||||||
|
"final_item_id",
|
||||||
|
"deleted_at",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"character_id",
|
||||||
|
"item_id",
|
||||||
|
"activated",
|
||||||
|
"equipped",
|
||||||
|
"current_amount",
|
||||||
|
"progression",
|
||||||
|
"final_item_id",
|
||||||
|
"UNIX_TIMESTAMP(deleted_at)",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("character_evolving_items");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterEvolvingItems NewEntity()
|
||||||
|
{
|
||||||
|
CharacterEvolvingItems e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.character_id = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
e.activated = 0;
|
||||||
|
e.equipped = 0;
|
||||||
|
e.current_amount = 0;
|
||||||
|
e.progression = 0;
|
||||||
|
e.final_item_id = 0;
|
||||||
|
e.deleted_at = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterEvolvingItems GetCharacterEvolvingItems(
|
||||||
|
const std::vector<CharacterEvolvingItems> &character_evolving_itemss,
|
||||||
|
int character_evolving_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &character_evolving_items : character_evolving_itemss) {
|
||||||
|
if (character_evolving_items.id == character_evolving_items_id) {
|
||||||
|
return character_evolving_items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterEvolvingItems FindOne(
|
||||||
|
Database& db,
|
||||||
|
int character_evolving_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
character_evolving_items_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
CharacterEvolvingItems e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.character_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.activated = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.equipped = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.current_amount = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
||||||
|
e.progression = row[6] ? strtod(row[6], nullptr) : 0;
|
||||||
|
e.final_item_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.deleted_at = strtoll(row[8] ? row[8] : "-1", nullptr, 10);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int character_evolving_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
character_evolving_items_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterEvolvingItems &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.item_id));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.activated));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.equipped));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.current_amount));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.progression));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.final_item_id));
|
||||||
|
v.push_back(columns[8] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterEvolvingItems InsertOne(
|
||||||
|
Database& db,
|
||||||
|
CharacterEvolvingItems 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.item_id));
|
||||||
|
v.push_back(std::to_string(e.activated));
|
||||||
|
v.push_back(std::to_string(e.equipped));
|
||||||
|
v.push_back(std::to_string(e.current_amount));
|
||||||
|
v.push_back(std::to_string(e.progression));
|
||||||
|
v.push_back(std::to_string(e.final_item_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterEvolvingItems> &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.item_id));
|
||||||
|
v.push_back(std::to_string(e.activated));
|
||||||
|
v.push_back(std::to_string(e.equipped));
|
||||||
|
v.push_back(std::to_string(e.current_amount));
|
||||||
|
v.push_back(std::to_string(e.progression));
|
||||||
|
v.push_back(std::to_string(e.final_item_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<CharacterEvolvingItems> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<CharacterEvolvingItems> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
CharacterEvolvingItems e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.character_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.activated = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.equipped = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.current_amount = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
||||||
|
e.progression = row[6] ? strtod(row[6], nullptr) : 0;
|
||||||
|
e.final_item_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.deleted_at = strtoll(row[8] ? row[8] : "-1", nullptr, 10);
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<CharacterEvolvingItems> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<CharacterEvolvingItems> 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) {
|
||||||
|
CharacterEvolvingItems e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
|
||||||
|
e.character_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.activated = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.equipped = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.current_amount = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
||||||
|
e.progression = row[6] ? strtod(row[6], nullptr) : 0;
|
||||||
|
e.final_item_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.deleted_at = strtoll(row[8] ? row[8] : "-1", nullptr, 10);
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterEvolvingItems &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.item_id));
|
||||||
|
v.push_back(std::to_string(e.activated));
|
||||||
|
v.push_back(std::to_string(e.equipped));
|
||||||
|
v.push_back(std::to_string(e.current_amount));
|
||||||
|
v.push_back(std::to_string(e.progression));
|
||||||
|
v.push_back(std::to_string(e.final_item_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterEvolvingItems> &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.item_id));
|
||||||
|
v.push_back(std::to_string(e.activated));
|
||||||
|
v.push_back(std::to_string(e.equipped));
|
||||||
|
v.push_back(std::to_string(e.current_amount));
|
||||||
|
v.push_back(std::to_string(e.progression));
|
||||||
|
v.push_back(std::to_string(e.final_item_id));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_CHARACTER_EVOLVING_ITEMS_REPOSITORY_H
|
||||||
@@ -0,0 +1,499 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_CHARACTER_PARCELS_CONTAINERS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_CHARACTER_PARCELS_CONTAINERS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseCharacterParcelsContainersRepository {
|
||||||
|
public:
|
||||||
|
struct CharacterParcelsContainers {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t parcels_id;
|
||||||
|
uint32_t slot_id;
|
||||||
|
uint32_t item_id;
|
||||||
|
uint32_t aug_slot_1;
|
||||||
|
uint32_t aug_slot_2;
|
||||||
|
uint32_t aug_slot_3;
|
||||||
|
uint32_t aug_slot_4;
|
||||||
|
uint32_t aug_slot_5;
|
||||||
|
uint32_t aug_slot_6;
|
||||||
|
uint32_t quantity;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"parcels_id",
|
||||||
|
"slot_id",
|
||||||
|
"item_id",
|
||||||
|
"aug_slot_1",
|
||||||
|
"aug_slot_2",
|
||||||
|
"aug_slot_3",
|
||||||
|
"aug_slot_4",
|
||||||
|
"aug_slot_5",
|
||||||
|
"aug_slot_6",
|
||||||
|
"quantity",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"parcels_id",
|
||||||
|
"slot_id",
|
||||||
|
"item_id",
|
||||||
|
"aug_slot_1",
|
||||||
|
"aug_slot_2",
|
||||||
|
"aug_slot_3",
|
||||||
|
"aug_slot_4",
|
||||||
|
"aug_slot_5",
|
||||||
|
"aug_slot_6",
|
||||||
|
"quantity",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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_parcels_containers");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterParcelsContainers NewEntity()
|
||||||
|
{
|
||||||
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.parcels_id = 0;
|
||||||
|
e.slot_id = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
e.aug_slot_1 = 0;
|
||||||
|
e.aug_slot_2 = 0;
|
||||||
|
e.aug_slot_3 = 0;
|
||||||
|
e.aug_slot_4 = 0;
|
||||||
|
e.aug_slot_5 = 0;
|
||||||
|
e.aug_slot_6 = 0;
|
||||||
|
e.quantity = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterParcelsContainers GetCharacterParcelsContainers(
|
||||||
|
const std::vector<CharacterParcelsContainers> &character_parcels_containerss,
|
||||||
|
int character_parcels_containers_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &character_parcels_containers : character_parcels_containerss) {
|
||||||
|
if (character_parcels_containers.id == character_parcels_containers_id) {
|
||||||
|
return character_parcels_containers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterParcelsContainers FindOne(
|
||||||
|
Database& db,
|
||||||
|
int character_parcels_containers_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
character_parcels_containers_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int character_parcels_containers_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
character_parcels_containers_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterParcelsContainers &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.parcels_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.slot_id));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.aug_slot_1));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.aug_slot_2));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.aug_slot_3));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.aug_slot_4));
|
||||||
|
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
|
||||||
|
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
|
||||||
|
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterParcelsContainers InsertOne(
|
||||||
|
Database& db,
|
||||||
|
CharacterParcelsContainers e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.parcels_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_1));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_2));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_3));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_4));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
|
||||||
|
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<CharacterParcelsContainers> &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.parcels_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_1));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_2));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_3));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_4));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
|
||||||
|
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<CharacterParcelsContainers> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<CharacterParcelsContainers> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<CharacterParcelsContainers> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<CharacterParcelsContainers> 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) {
|
||||||
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterParcelsContainers &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.parcels_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_1));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_2));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_3));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_4));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterParcelsContainers> &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.parcels_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_1));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_2));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_3));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_4));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_CHARACTER_PARCELS_CONTAINERS_REPOSITORY_H
|
||||||
@@ -0,0 +1,392 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_CHARACTER_PET_NAME_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_CHARACTER_PET_NAME_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseCharacterPetNameRepository {
|
||||||
|
public:
|
||||||
|
struct CharacterPetName {
|
||||||
|
int32_t character_id;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("character_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"character_id",
|
||||||
|
"name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"character_id",
|
||||||
|
"name",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("character_pet_name");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterPetName NewEntity()
|
||||||
|
{
|
||||||
|
CharacterPetName e{};
|
||||||
|
|
||||||
|
e.character_id = 0;
|
||||||
|
e.name = "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterPetName GetCharacterPetName(
|
||||||
|
const std::vector<CharacterPetName> &character_pet_names,
|
||||||
|
int character_pet_name_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &character_pet_name : character_pet_names) {
|
||||||
|
if (character_pet_name.character_id == character_pet_name_id) {
|
||||||
|
return character_pet_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterPetName FindOne(
|
||||||
|
Database& db,
|
||||||
|
int character_pet_name_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
character_pet_name_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
CharacterPetName e{};
|
||||||
|
|
||||||
|
e.character_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||||
|
e.name = row[1] ? row[1] : "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int character_pet_name_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
character_pet_name_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterPetName &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[0] + " = " + std::to_string(e.character_id));
|
||||||
|
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.character_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharacterPetName InsertOne(
|
||||||
|
Database& db,
|
||||||
|
CharacterPetName e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.character_id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterPetName> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<CharacterPetName> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<CharacterPetName> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
CharacterPetName e{};
|
||||||
|
|
||||||
|
e.character_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||||
|
e.name = row[1] ? row[1] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<CharacterPetName> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<CharacterPetName> 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) {
|
||||||
|
CharacterPetName e{};
|
||||||
|
|
||||||
|
e.character_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||||
|
e.name = row[1] ? row[1] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterPetName &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterPetName> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_CHARACTER_PET_NAME_REPOSITORY_H
|
||||||
@@ -23,6 +23,7 @@ public:
|
|||||||
std::string key_;
|
std::string key_;
|
||||||
std::string value;
|
std::string value;
|
||||||
uint32_t expires;
|
uint32_t expires;
|
||||||
|
int64_t account_id;
|
||||||
int64_t character_id;
|
int64_t character_id;
|
||||||
int64_t npc_id;
|
int64_t npc_id;
|
||||||
int64_t bot_id;
|
int64_t bot_id;
|
||||||
@@ -36,6 +37,7 @@ public:
|
|||||||
CEREAL_NVP(key_),
|
CEREAL_NVP(key_),
|
||||||
CEREAL_NVP(value),
|
CEREAL_NVP(value),
|
||||||
CEREAL_NVP(expires),
|
CEREAL_NVP(expires),
|
||||||
|
CEREAL_NVP(account_id),
|
||||||
CEREAL_NVP(character_id),
|
CEREAL_NVP(character_id),
|
||||||
CEREAL_NVP(npc_id),
|
CEREAL_NVP(npc_id),
|
||||||
CEREAL_NVP(bot_id)
|
CEREAL_NVP(bot_id)
|
||||||
@@ -55,6 +57,7 @@ public:
|
|||||||
"`key`",
|
"`key`",
|
||||||
"value",
|
"value",
|
||||||
"expires",
|
"expires",
|
||||||
|
"account_id",
|
||||||
"character_id",
|
"character_id",
|
||||||
"npc_id",
|
"npc_id",
|
||||||
"bot_id",
|
"bot_id",
|
||||||
@@ -68,6 +71,7 @@ public:
|
|||||||
"`key`",
|
"`key`",
|
||||||
"value",
|
"value",
|
||||||
"expires",
|
"expires",
|
||||||
|
"account_id",
|
||||||
"character_id",
|
"character_id",
|
||||||
"npc_id",
|
"npc_id",
|
||||||
"bot_id",
|
"bot_id",
|
||||||
@@ -115,6 +119,7 @@ public:
|
|||||||
e.key_ = "";
|
e.key_ = "";
|
||||||
e.value = "";
|
e.value = "";
|
||||||
e.expires = 0;
|
e.expires = 0;
|
||||||
|
e.account_id = 0;
|
||||||
e.character_id = 0;
|
e.character_id = 0;
|
||||||
e.npc_id = 0;
|
e.npc_id = 0;
|
||||||
e.bot_id = 0;
|
e.bot_id = 0;
|
||||||
@@ -158,9 +163,10 @@ public:
|
|||||||
e.key_ = row[1] ? row[1] : "";
|
e.key_ = row[1] ? row[1] : "";
|
||||||
e.value = row[2] ? row[2] : "";
|
e.value = row[2] ? row[2] : "";
|
||||||
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.character_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
|
e.account_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
|
||||||
e.npc_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
e.character_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
||||||
e.bot_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
e.npc_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||||
|
e.bot_id = row[7] ? strtoll(row[7], nullptr, 10) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -197,9 +203,10 @@ public:
|
|||||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'");
|
v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'");
|
||||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
|
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.expires));
|
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[4] + " = " + std::to_string(e.account_id));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.npc_id));
|
v.push_back(columns[5] + " = " + std::to_string(e.character_id));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.bot_id));
|
v.push_back(columns[6] + " = " + std::to_string(e.npc_id));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.bot_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -225,6 +232,7 @@ public:
|
|||||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||||
v.push_back(std::to_string(e.expires));
|
v.push_back(std::to_string(e.expires));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
v.push_back(std::to_string(e.character_id));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.npc_id));
|
v.push_back(std::to_string(e.npc_id));
|
||||||
v.push_back(std::to_string(e.bot_id));
|
v.push_back(std::to_string(e.bot_id));
|
||||||
@@ -261,6 +269,7 @@ public:
|
|||||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||||
v.push_back(std::to_string(e.expires));
|
v.push_back(std::to_string(e.expires));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
v.push_back(std::to_string(e.character_id));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.npc_id));
|
v.push_back(std::to_string(e.npc_id));
|
||||||
v.push_back(std::to_string(e.bot_id));
|
v.push_back(std::to_string(e.bot_id));
|
||||||
@@ -301,9 +310,10 @@ public:
|
|||||||
e.key_ = row[1] ? row[1] : "";
|
e.key_ = row[1] ? row[1] : "";
|
||||||
e.value = row[2] ? row[2] : "";
|
e.value = row[2] ? row[2] : "";
|
||||||
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.character_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
|
e.account_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
|
||||||
e.npc_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
e.character_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
||||||
e.bot_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
e.npc_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||||
|
e.bot_id = row[7] ? strtoll(row[7], nullptr, 10) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -332,9 +342,10 @@ public:
|
|||||||
e.key_ = row[1] ? row[1] : "";
|
e.key_ = row[1] ? row[1] : "";
|
||||||
e.value = row[2] ? row[2] : "";
|
e.value = row[2] ? row[2] : "";
|
||||||
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.expires = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.character_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
|
e.account_id = row[4] ? strtoll(row[4], nullptr, 10) : 0;
|
||||||
e.npc_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
e.character_id = row[5] ? strtoll(row[5], nullptr, 10) : 0;
|
||||||
e.bot_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
e.npc_id = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||||
|
e.bot_id = row[7] ? strtoll(row[7], nullptr, 10) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -413,6 +424,7 @@ public:
|
|||||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||||
v.push_back(std::to_string(e.expires));
|
v.push_back(std::to_string(e.expires));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
v.push_back(std::to_string(e.character_id));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.npc_id));
|
v.push_back(std::to_string(e.npc_id));
|
||||||
v.push_back(std::to_string(e.bot_id));
|
v.push_back(std::to_string(e.bot_id));
|
||||||
@@ -442,6 +454,7 @@ public:
|
|||||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||||
v.push_back(std::to_string(e.expires));
|
v.push_back(std::to_string(e.expires));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
v.push_back(std::to_string(e.character_id));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.npc_id));
|
v.push_back(std::to_string(e.npc_id));
|
||||||
v.push_back(std::to_string(e.bot_id));
|
v.push_back(std::to_string(e.bot_id));
|
||||||
|
|||||||
@@ -0,0 +1,511 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_FIND_LOCATION_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_FIND_LOCATION_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseFindLocationRepository {
|
||||||
|
public:
|
||||||
|
struct FindLocation {
|
||||||
|
uint32_t id;
|
||||||
|
std::string zone;
|
||||||
|
int32_t version;
|
||||||
|
int8_t min_expansion;
|
||||||
|
int8_t max_expansion;
|
||||||
|
std::string content_flags;
|
||||||
|
std::string content_flags_disabled;
|
||||||
|
int32_t type;
|
||||||
|
int32_t zone_id;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"zone",
|
||||||
|
"version",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
|
"type",
|
||||||
|
"zone_id",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"zone",
|
||||||
|
"version",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
|
"type",
|
||||||
|
"zone_id",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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("find_location");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FindLocation NewEntity()
|
||||||
|
{
|
||||||
|
FindLocation e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.zone = "";
|
||||||
|
e.version = 0;
|
||||||
|
e.min_expansion = -1;
|
||||||
|
e.max_expansion = -1;
|
||||||
|
e.content_flags = "";
|
||||||
|
e.content_flags_disabled = "";
|
||||||
|
e.type = 0;
|
||||||
|
e.zone_id = 0;
|
||||||
|
e.x = 0;
|
||||||
|
e.y = 0;
|
||||||
|
e.z = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FindLocation GetFindLocation(
|
||||||
|
const std::vector<FindLocation> &find_locations,
|
||||||
|
int find_location_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &find_location : find_locations) {
|
||||||
|
if (find_location.id == find_location_id) {
|
||||||
|
return find_location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static FindLocation FindOne(
|
||||||
|
Database& db,
|
||||||
|
int find_location_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
find_location_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
FindLocation e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.zone = row[1] ? row[1] : "";
|
||||||
|
e.version = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
||||||
|
e.min_expansion = row[3] ? static_cast<int8_t>(atoi(row[3])) : -1;
|
||||||
|
e.max_expansion = row[4] ? static_cast<int8_t>(atoi(row[4])) : -1;
|
||||||
|
e.content_flags = row[5] ? row[5] : "";
|
||||||
|
e.content_flags_disabled = row[6] ? row[6] : "";
|
||||||
|
e.type = row[7] ? static_cast<int32_t>(atoi(row[7])) : 0;
|
||||||
|
e.zone_id = row[8] ? static_cast<int32_t>(atoi(row[8])) : 0;
|
||||||
|
e.x = row[9] ? strtof(row[9], nullptr) : 0;
|
||||||
|
e.y = row[10] ? strtof(row[10], nullptr) : 0;
|
||||||
|
e.z = row[11] ? strtof(row[11], nullptr) : 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int find_location_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
find_location_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const FindLocation &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = '" + Strings::Escape(e.zone) + "'");
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.version));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.min_expansion));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[5] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[6] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.type));
|
||||||
|
v.push_back(columns[8] + " = " + std::to_string(e.zone_id));
|
||||||
|
v.push_back(columns[9] + " = " + std::to_string(e.x));
|
||||||
|
v.push_back(columns[10] + " = " + std::to_string(e.y));
|
||||||
|
v.push_back(columns[11] + " = " + std::to_string(e.z));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FindLocation InsertOne(
|
||||||
|
Database& db,
|
||||||
|
FindLocation e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.zone) + "'");
|
||||||
|
v.push_back(std::to_string(e.version));
|
||||||
|
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) + "'");
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
|
||||||
|
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<FindLocation> &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.zone) + "'");
|
||||||
|
v.push_back(std::to_string(e.version));
|
||||||
|
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) + "'");
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
|
||||||
|
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<FindLocation> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<FindLocation> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
FindLocation e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.zone = row[1] ? row[1] : "";
|
||||||
|
e.version = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
||||||
|
e.min_expansion = row[3] ? static_cast<int8_t>(atoi(row[3])) : -1;
|
||||||
|
e.max_expansion = row[4] ? static_cast<int8_t>(atoi(row[4])) : -1;
|
||||||
|
e.content_flags = row[5] ? row[5] : "";
|
||||||
|
e.content_flags_disabled = row[6] ? row[6] : "";
|
||||||
|
e.type = row[7] ? static_cast<int32_t>(atoi(row[7])) : 0;
|
||||||
|
e.zone_id = row[8] ? static_cast<int32_t>(atoi(row[8])) : 0;
|
||||||
|
e.x = row[9] ? strtof(row[9], nullptr) : 0;
|
||||||
|
e.y = row[10] ? strtof(row[10], nullptr) : 0;
|
||||||
|
e.z = row[11] ? strtof(row[11], nullptr) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<FindLocation> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<FindLocation> 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) {
|
||||||
|
FindLocation e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.zone = row[1] ? row[1] : "";
|
||||||
|
e.version = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
|
||||||
|
e.min_expansion = row[3] ? static_cast<int8_t>(atoi(row[3])) : -1;
|
||||||
|
e.max_expansion = row[4] ? static_cast<int8_t>(atoi(row[4])) : -1;
|
||||||
|
e.content_flags = row[5] ? row[5] : "";
|
||||||
|
e.content_flags_disabled = row[6] ? row[6] : "";
|
||||||
|
e.type = row[7] ? static_cast<int32_t>(atoi(row[7])) : 0;
|
||||||
|
e.zone_id = row[8] ? static_cast<int32_t>(atoi(row[8])) : 0;
|
||||||
|
e.x = row[9] ? strtof(row[9], nullptr) : 0;
|
||||||
|
e.y = row[10] ? strtof(row[10], nullptr) : 0;
|
||||||
|
e.z = row[11] ? strtof(row[11], nullptr) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const FindLocation &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.zone) + "'");
|
||||||
|
v.push_back(std::to_string(e.version));
|
||||||
|
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) + "'");
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<FindLocation> &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.zone) + "'");
|
||||||
|
v.push_back(std::to_string(e.version));
|
||||||
|
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) + "'");
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_FIND_LOCATION_REPOSITORY_H
|
||||||
@@ -19,70 +19,73 @@
|
|||||||
class BaseInventoryRepository {
|
class BaseInventoryRepository {
|
||||||
public:
|
public:
|
||||||
struct Inventory {
|
struct Inventory {
|
||||||
uint32_t charid;
|
uint32_t character_id;
|
||||||
uint32_t slotid;
|
uint32_t slot_id;
|
||||||
uint32_t itemid;
|
uint32_t item_id;
|
||||||
uint16_t charges;
|
uint16_t charges;
|
||||||
uint32_t color;
|
uint32_t color;
|
||||||
uint32_t augslot1;
|
uint32_t augment_one;
|
||||||
uint32_t augslot2;
|
uint32_t augment_two;
|
||||||
uint32_t augslot3;
|
uint32_t augment_three;
|
||||||
uint32_t augslot4;
|
uint32_t augment_four;
|
||||||
uint32_t augslot5;
|
uint32_t augment_five;
|
||||||
int32_t augslot6;
|
uint32_t augment_six;
|
||||||
uint8_t instnodrop;
|
uint8_t instnodrop;
|
||||||
std::string custom_data;
|
std::string custom_data;
|
||||||
uint32_t ornamenticon;
|
uint32_t ornament_icon;
|
||||||
uint32_t ornamentidfile;
|
uint32_t ornament_idfile;
|
||||||
int32_t ornament_hero_model;
|
int32_t ornament_hero_model;
|
||||||
|
uint64_t guid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
{
|
{
|
||||||
return std::string("charid");
|
return std::string("character_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::string> Columns()
|
static std::vector<std::string> Columns()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"charid",
|
"character_id",
|
||||||
"slotid",
|
"slot_id",
|
||||||
"itemid",
|
"item_id",
|
||||||
"charges",
|
"charges",
|
||||||
"color",
|
"color",
|
||||||
"augslot1",
|
"augment_one",
|
||||||
"augslot2",
|
"augment_two",
|
||||||
"augslot3",
|
"augment_three",
|
||||||
"augslot4",
|
"augment_four",
|
||||||
"augslot5",
|
"augment_five",
|
||||||
"augslot6",
|
"augment_six",
|
||||||
"instnodrop",
|
"instnodrop",
|
||||||
"custom_data",
|
"custom_data",
|
||||||
"ornamenticon",
|
"ornament_icon",
|
||||||
"ornamentidfile",
|
"ornament_idfile",
|
||||||
"ornament_hero_model",
|
"ornament_hero_model",
|
||||||
|
"guid",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::string> SelectColumns()
|
static std::vector<std::string> SelectColumns()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"charid",
|
"character_id",
|
||||||
"slotid",
|
"slot_id",
|
||||||
"itemid",
|
"item_id",
|
||||||
"charges",
|
"charges",
|
||||||
"color",
|
"color",
|
||||||
"augslot1",
|
"augment_one",
|
||||||
"augslot2",
|
"augment_two",
|
||||||
"augslot3",
|
"augment_three",
|
||||||
"augslot4",
|
"augment_four",
|
||||||
"augslot5",
|
"augment_five",
|
||||||
"augslot6",
|
"augment_six",
|
||||||
"instnodrop",
|
"instnodrop",
|
||||||
"custom_data",
|
"custom_data",
|
||||||
"ornamenticon",
|
"ornament_icon",
|
||||||
"ornamentidfile",
|
"ornament_idfile",
|
||||||
"ornament_hero_model",
|
"ornament_hero_model",
|
||||||
|
"guid",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,22 +126,23 @@ public:
|
|||||||
{
|
{
|
||||||
Inventory e{};
|
Inventory e{};
|
||||||
|
|
||||||
e.charid = 0;
|
e.character_id = 0;
|
||||||
e.slotid = 0;
|
e.slot_id = 0;
|
||||||
e.itemid = 0;
|
e.item_id = 0;
|
||||||
e.charges = 0;
|
e.charges = 0;
|
||||||
e.color = 0;
|
e.color = 0;
|
||||||
e.augslot1 = 0;
|
e.augment_one = 0;
|
||||||
e.augslot2 = 0;
|
e.augment_two = 0;
|
||||||
e.augslot3 = 0;
|
e.augment_three = 0;
|
||||||
e.augslot4 = 0;
|
e.augment_four = 0;
|
||||||
e.augslot5 = 0;
|
e.augment_five = 0;
|
||||||
e.augslot6 = 0;
|
e.augment_six = 0;
|
||||||
e.instnodrop = 0;
|
e.instnodrop = 0;
|
||||||
e.custom_data = "";
|
e.custom_data = "";
|
||||||
e.ornamenticon = 0;
|
e.ornament_icon = 0;
|
||||||
e.ornamentidfile = 0;
|
e.ornament_idfile = 0;
|
||||||
e.ornament_hero_model = 0;
|
e.ornament_hero_model = 0;
|
||||||
|
e.guid = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -149,7 +153,7 @@ public:
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (auto &inventory : inventorys) {
|
for (auto &inventory : inventorys) {
|
||||||
if (inventory.charid == inventory_id) {
|
if (inventory.character_id == inventory_id) {
|
||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,22 +179,23 @@ public:
|
|||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
Inventory e{};
|
Inventory e{};
|
||||||
|
|
||||||
e.charid = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.slotid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.itemid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.augslot1 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.augslot2 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
e.augslot3 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
e.augslot4 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.augslot5 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.augslot6 = row[10] ? static_cast<int32_t>(atoi(row[10])) : 0;
|
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
|
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
e.custom_data = row[12] ? row[12] : "";
|
e.custom_data = row[12] ? row[12] : "";
|
||||||
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
|
e.ornament_icon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
|
||||||
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
e.ornament_idfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||||
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
|
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
|
||||||
|
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -224,22 +229,23 @@ public:
|
|||||||
|
|
||||||
auto columns = Columns();
|
auto columns = Columns();
|
||||||
|
|
||||||
v.push_back(columns[0] + " = " + std::to_string(e.charid));
|
v.push_back(columns[0] + " = " + std::to_string(e.character_id));
|
||||||
v.push_back(columns[1] + " = " + std::to_string(e.slotid));
|
v.push_back(columns[1] + " = " + std::to_string(e.slot_id));
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.itemid));
|
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.charges));
|
v.push_back(columns[3] + " = " + std::to_string(e.charges));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.color));
|
v.push_back(columns[4] + " = " + std::to_string(e.color));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.augslot1));
|
v.push_back(columns[5] + " = " + std::to_string(e.augment_one));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.augslot2));
|
v.push_back(columns[6] + " = " + std::to_string(e.augment_two));
|
||||||
v.push_back(columns[7] + " = " + std::to_string(e.augslot3));
|
v.push_back(columns[7] + " = " + std::to_string(e.augment_three));
|
||||||
v.push_back(columns[8] + " = " + std::to_string(e.augslot4));
|
v.push_back(columns[8] + " = " + std::to_string(e.augment_four));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.augslot5));
|
v.push_back(columns[9] + " = " + std::to_string(e.augment_five));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.augslot6));
|
v.push_back(columns[10] + " = " + std::to_string(e.augment_six));
|
||||||
v.push_back(columns[11] + " = " + std::to_string(e.instnodrop));
|
v.push_back(columns[11] + " = " + std::to_string(e.instnodrop));
|
||||||
v.push_back(columns[12] + " = '" + Strings::Escape(e.custom_data) + "'");
|
v.push_back(columns[12] + " = '" + Strings::Escape(e.custom_data) + "'");
|
||||||
v.push_back(columns[13] + " = " + std::to_string(e.ornamenticon));
|
v.push_back(columns[13] + " = " + std::to_string(e.ornament_icon));
|
||||||
v.push_back(columns[14] + " = " + std::to_string(e.ornamentidfile));
|
v.push_back(columns[14] + " = " + std::to_string(e.ornament_idfile));
|
||||||
v.push_back(columns[15] + " = " + std::to_string(e.ornament_hero_model));
|
v.push_back(columns[15] + " = " + std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(columns[16] + " = " + std::to_string(e.guid));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -247,7 +253,7 @@ public:
|
|||||||
TableName(),
|
TableName(),
|
||||||
Strings::Implode(", ", v),
|
Strings::Implode(", ", v),
|
||||||
PrimaryKey(),
|
PrimaryKey(),
|
||||||
e.charid
|
e.character_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -261,22 +267,23 @@ public:
|
|||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.slotid));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.item_id));
|
||||||
v.push_back(std::to_string(e.charges));
|
v.push_back(std::to_string(e.charges));
|
||||||
v.push_back(std::to_string(e.color));
|
v.push_back(std::to_string(e.color));
|
||||||
v.push_back(std::to_string(e.augslot1));
|
v.push_back(std::to_string(e.augment_one));
|
||||||
v.push_back(std::to_string(e.augslot2));
|
v.push_back(std::to_string(e.augment_two));
|
||||||
v.push_back(std::to_string(e.augslot3));
|
v.push_back(std::to_string(e.augment_three));
|
||||||
v.push_back(std::to_string(e.augslot4));
|
v.push_back(std::to_string(e.augment_four));
|
||||||
v.push_back(std::to_string(e.augslot5));
|
v.push_back(std::to_string(e.augment_five));
|
||||||
v.push_back(std::to_string(e.augslot6));
|
v.push_back(std::to_string(e.augment_six));
|
||||||
v.push_back(std::to_string(e.instnodrop));
|
v.push_back(std::to_string(e.instnodrop));
|
||||||
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornament_icon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornament_idfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -287,7 +294,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (results.Success()) {
|
if (results.Success()) {
|
||||||
e.charid = results.LastInsertedID();
|
e.character_id = results.LastInsertedID();
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,22 +313,23 @@ public:
|
|||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.slotid));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.item_id));
|
||||||
v.push_back(std::to_string(e.charges));
|
v.push_back(std::to_string(e.charges));
|
||||||
v.push_back(std::to_string(e.color));
|
v.push_back(std::to_string(e.color));
|
||||||
v.push_back(std::to_string(e.augslot1));
|
v.push_back(std::to_string(e.augment_one));
|
||||||
v.push_back(std::to_string(e.augslot2));
|
v.push_back(std::to_string(e.augment_two));
|
||||||
v.push_back(std::to_string(e.augslot3));
|
v.push_back(std::to_string(e.augment_three));
|
||||||
v.push_back(std::to_string(e.augslot4));
|
v.push_back(std::to_string(e.augment_four));
|
||||||
v.push_back(std::to_string(e.augslot5));
|
v.push_back(std::to_string(e.augment_five));
|
||||||
v.push_back(std::to_string(e.augslot6));
|
v.push_back(std::to_string(e.augment_six));
|
||||||
v.push_back(std::to_string(e.instnodrop));
|
v.push_back(std::to_string(e.instnodrop));
|
||||||
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornament_icon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornament_idfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -355,22 +363,23 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Inventory e{};
|
Inventory e{};
|
||||||
|
|
||||||
e.charid = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.slotid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.itemid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.augslot1 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.augslot2 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
e.augslot3 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
e.augslot4 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.augslot5 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.augslot6 = row[10] ? static_cast<int32_t>(atoi(row[10])) : 0;
|
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
|
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
e.custom_data = row[12] ? row[12] : "";
|
e.custom_data = row[12] ? row[12] : "";
|
||||||
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
|
e.ornament_icon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
|
||||||
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
e.ornament_idfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||||
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
|
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
|
||||||
|
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -395,22 +404,23 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Inventory e{};
|
Inventory e{};
|
||||||
|
|
||||||
e.charid = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.character_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.slotid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
e.slot_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.itemid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.charges = row[3] ? static_cast<uint16_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.color = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.augslot1 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.augment_one = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.augslot2 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.augment_two = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
e.augslot3 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
e.augment_three = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
e.augslot4 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.augment_four = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.augslot5 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.augment_five = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.augslot6 = row[10] ? static_cast<int32_t>(atoi(row[10])) : 0;
|
e.augment_six = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
|
e.instnodrop = row[11] ? static_cast<uint8_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
e.custom_data = row[12] ? row[12] : "";
|
e.custom_data = row[12] ? row[12] : "";
|
||||||
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
|
e.ornament_icon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
|
||||||
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
e.ornament_idfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||||
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
|
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
|
||||||
|
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -485,22 +495,23 @@ public:
|
|||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.slotid));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.item_id));
|
||||||
v.push_back(std::to_string(e.charges));
|
v.push_back(std::to_string(e.charges));
|
||||||
v.push_back(std::to_string(e.color));
|
v.push_back(std::to_string(e.color));
|
||||||
v.push_back(std::to_string(e.augslot1));
|
v.push_back(std::to_string(e.augment_one));
|
||||||
v.push_back(std::to_string(e.augslot2));
|
v.push_back(std::to_string(e.augment_two));
|
||||||
v.push_back(std::to_string(e.augslot3));
|
v.push_back(std::to_string(e.augment_three));
|
||||||
v.push_back(std::to_string(e.augslot4));
|
v.push_back(std::to_string(e.augment_four));
|
||||||
v.push_back(std::to_string(e.augslot5));
|
v.push_back(std::to_string(e.augment_five));
|
||||||
v.push_back(std::to_string(e.augslot6));
|
v.push_back(std::to_string(e.augment_six));
|
||||||
v.push_back(std::to_string(e.instnodrop));
|
v.push_back(std::to_string(e.instnodrop));
|
||||||
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornament_icon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornament_idfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -523,22 +534,23 @@ public:
|
|||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.charid));
|
v.push_back(std::to_string(e.character_id));
|
||||||
v.push_back(std::to_string(e.slotid));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.item_id));
|
||||||
v.push_back(std::to_string(e.charges));
|
v.push_back(std::to_string(e.charges));
|
||||||
v.push_back(std::to_string(e.color));
|
v.push_back(std::to_string(e.color));
|
||||||
v.push_back(std::to_string(e.augslot1));
|
v.push_back(std::to_string(e.augment_one));
|
||||||
v.push_back(std::to_string(e.augslot2));
|
v.push_back(std::to_string(e.augment_two));
|
||||||
v.push_back(std::to_string(e.augslot3));
|
v.push_back(std::to_string(e.augment_three));
|
||||||
v.push_back(std::to_string(e.augslot4));
|
v.push_back(std::to_string(e.augment_four));
|
||||||
v.push_back(std::to_string(e.augslot5));
|
v.push_back(std::to_string(e.augment_five));
|
||||||
v.push_back(std::to_string(e.augslot6));
|
v.push_back(std::to_string(e.augment_six));
|
||||||
v.push_back(std::to_string(e.instnodrop));
|
v.push_back(std::to_string(e.instnodrop));
|
||||||
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
v.push_back("'" + Strings::Escape(e.custom_data) + "'");
|
||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornament_icon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornament_idfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
uint32_t ornamenticon;
|
uint32_t ornamenticon;
|
||||||
uint32_t ornamentidfile;
|
uint32_t ornamentidfile;
|
||||||
int32_t ornament_hero_model;
|
int32_t ornament_hero_model;
|
||||||
|
uint64_t guid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -63,6 +64,7 @@ public:
|
|||||||
"ornamenticon",
|
"ornamenticon",
|
||||||
"ornamentidfile",
|
"ornamentidfile",
|
||||||
"ornament_hero_model",
|
"ornament_hero_model",
|
||||||
|
"guid",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +88,7 @@ public:
|
|||||||
"ornamenticon",
|
"ornamenticon",
|
||||||
"ornamentidfile",
|
"ornamentidfile",
|
||||||
"ornament_hero_model",
|
"ornament_hero_model",
|
||||||
|
"guid",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,6 +146,7 @@ public:
|
|||||||
e.ornamenticon = 0;
|
e.ornamenticon = 0;
|
||||||
e.ornamentidfile = 0;
|
e.ornamentidfile = 0;
|
||||||
e.ornament_hero_model = 0;
|
e.ornament_hero_model = 0;
|
||||||
|
e.guid = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -196,6 +200,7 @@ public:
|
|||||||
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||||
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||||
e.ornament_hero_model = row[16] ? static_cast<int32_t>(atoi(row[16])) : 0;
|
e.ornament_hero_model = row[16] ? static_cast<int32_t>(atoi(row[16])) : 0;
|
||||||
|
e.guid = row[17] ? strtoull(row[17], nullptr, 10) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -246,6 +251,7 @@ public:
|
|||||||
v.push_back(columns[14] + " = " + std::to_string(e.ornamenticon));
|
v.push_back(columns[14] + " = " + std::to_string(e.ornamenticon));
|
||||||
v.push_back(columns[15] + " = " + std::to_string(e.ornamentidfile));
|
v.push_back(columns[15] + " = " + std::to_string(e.ornamentidfile));
|
||||||
v.push_back(columns[16] + " = " + std::to_string(e.ornament_hero_model));
|
v.push_back(columns[16] + " = " + std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(columns[17] + " = " + std::to_string(e.guid));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -284,6 +290,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornamenticon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornamentidfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -330,6 +337,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornamenticon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornamentidfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -380,6 +388,7 @@ public:
|
|||||||
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||||
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||||
e.ornament_hero_model = row[16] ? static_cast<int32_t>(atoi(row[16])) : 0;
|
e.ornament_hero_model = row[16] ? static_cast<int32_t>(atoi(row[16])) : 0;
|
||||||
|
e.guid = row[17] ? strtoull(row[17], nullptr, 10) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -421,6 +430,7 @@ public:
|
|||||||
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||||
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||||
e.ornament_hero_model = row[16] ? static_cast<int32_t>(atoi(row[16])) : 0;
|
e.ornament_hero_model = row[16] ? static_cast<int32_t>(atoi(row[16])) : 0;
|
||||||
|
e.guid = row[17] ? strtoull(row[17], nullptr, 10) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -512,6 +522,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornamenticon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornamentidfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -551,6 +562,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.ornamenticon));
|
v.push_back(std::to_string(e.ornamenticon));
|
||||||
v.push_back(std::to_string(e.ornamentidfile));
|
v.push_back(std::to_string(e.ornamentidfile));
|
||||||
v.push_back(std::to_string(e.ornament_hero_model));
|
v.push_back(std::to_string(e.ornament_hero_model));
|
||||||
|
v.push_back(std::to_string(e.guid));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,451 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_ITEMS_EVOLVING_DETAILS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_ITEMS_EVOLVING_DETAILS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
class BaseItemsEvolvingDetailsRepository {
|
||||||
|
public:
|
||||||
|
struct ItemsEvolvingDetails {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t item_evo_id;
|
||||||
|
uint32_t item_evolve_level;
|
||||||
|
uint32_t item_id;
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t sub_type;
|
||||||
|
int64_t required_amount;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"item_evo_id",
|
||||||
|
"item_evolve_level",
|
||||||
|
"item_id",
|
||||||
|
"type",
|
||||||
|
"sub_type",
|
||||||
|
"required_amount",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"item_evo_id",
|
||||||
|
"item_evolve_level",
|
||||||
|
"item_id",
|
||||||
|
"type",
|
||||||
|
"sub_type",
|
||||||
|
"required_amount",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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("items_evolving_details");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemsEvolvingDetails NewEntity()
|
||||||
|
{
|
||||||
|
ItemsEvolvingDetails e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.item_evo_id = 0;
|
||||||
|
e.item_evolve_level = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
e.type = 0;
|
||||||
|
e.sub_type = 0;
|
||||||
|
e.required_amount = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemsEvolvingDetails GetItemsEvolvingDetails(
|
||||||
|
const std::vector<ItemsEvolvingDetails> &items_evolving_detailss,
|
||||||
|
int items_evolving_details_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &items_evolving_details : items_evolving_detailss) {
|
||||||
|
if (items_evolving_details.id == items_evolving_details_id) {
|
||||||
|
return items_evolving_details;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemsEvolvingDetails FindOne(
|
||||||
|
Database& db,
|
||||||
|
int items_evolving_details_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
items_evolving_details_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
ItemsEvolvingDetails e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.item_evo_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int items_evolving_details_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
items_evolving_details_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const ItemsEvolvingDetails &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.item_evo_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.item_evolve_level));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.type));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.sub_type));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.required_amount));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemsEvolvingDetails InsertOne(
|
||||||
|
Database& db,
|
||||||
|
ItemsEvolvingDetails e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.item_evo_id));
|
||||||
|
v.push_back(std::to_string(e.item_evolve_level));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.sub_type));
|
||||||
|
v.push_back(std::to_string(e.required_amount));
|
||||||
|
|
||||||
|
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<ItemsEvolvingDetails> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.item_evo_id));
|
||||||
|
v.push_back(std::to_string(e.item_evolve_level));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.sub_type));
|
||||||
|
v.push_back(std::to_string(e.required_amount));
|
||||||
|
|
||||||
|
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<ItemsEvolvingDetails> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<ItemsEvolvingDetails> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
ItemsEvolvingDetails e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.item_evo_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<ItemsEvolvingDetails> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<ItemsEvolvingDetails> 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) {
|
||||||
|
ItemsEvolvingDetails e{};
|
||||||
|
|
||||||
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
|
e.item_evo_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
|
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
|
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
|
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
|
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const ItemsEvolvingDetails &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.item_evo_id));
|
||||||
|
v.push_back(std::to_string(e.item_evolve_level));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.sub_type));
|
||||||
|
v.push_back(std::to_string(e.required_amount));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<ItemsEvolvingDetails> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.item_evo_id));
|
||||||
|
v.push_back(std::to_string(e.item_evolve_level));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.sub_type));
|
||||||
|
v.push_back(std::to_string(e.required_amount));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_ITEMS_EVOLVING_DETAILS_REPOSITORY_H
|
||||||
@@ -31,6 +31,10 @@ public:
|
|||||||
int32_t resist_adjust;
|
int32_t resist_adjust;
|
||||||
int16_t min_hp;
|
int16_t min_hp;
|
||||||
int16_t max_hp;
|
int16_t max_hp;
|
||||||
|
int8_t min_expansion;
|
||||||
|
int8_t max_expansion;
|
||||||
|
std::string content_flags;
|
||||||
|
std::string content_flags_disabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -53,6 +57,10 @@ public:
|
|||||||
"resist_adjust",
|
"resist_adjust",
|
||||||
"min_hp",
|
"min_hp",
|
||||||
"max_hp",
|
"max_hp",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +79,10 @@ public:
|
|||||||
"resist_adjust",
|
"resist_adjust",
|
||||||
"min_hp",
|
"min_hp",
|
||||||
"max_hp",
|
"max_hp",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +135,10 @@ public:
|
|||||||
e.resist_adjust = 0;
|
e.resist_adjust = 0;
|
||||||
e.min_hp = 0;
|
e.min_hp = 0;
|
||||||
e.max_hp = 0;
|
e.max_hp = 0;
|
||||||
|
e.min_expansion = -1;
|
||||||
|
e.max_expansion = -1;
|
||||||
|
e.content_flags = "";
|
||||||
|
e.content_flags_disabled = "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -171,6 +187,10 @@ public:
|
|||||||
e.resist_adjust = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
|
e.resist_adjust = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
|
||||||
e.min_hp = row[10] ? static_cast<int16_t>(atoi(row[10])) : 0;
|
e.min_hp = row[10] ? static_cast<int16_t>(atoi(row[10])) : 0;
|
||||||
e.max_hp = row[11] ? static_cast<int16_t>(atoi(row[11])) : 0;
|
e.max_hp = row[11] ? static_cast<int16_t>(atoi(row[11])) : 0;
|
||||||
|
e.min_expansion = row[12] ? static_cast<int8_t>(atoi(row[12])) : -1;
|
||||||
|
e.max_expansion = row[13] ? static_cast<int8_t>(atoi(row[13])) : -1;
|
||||||
|
e.content_flags = row[14] ? row[14] : "";
|
||||||
|
e.content_flags_disabled = row[15] ? row[15] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -215,6 +235,10 @@ public:
|
|||||||
v.push_back(columns[9] + " = " + std::to_string(e.resist_adjust));
|
v.push_back(columns[9] + " = " + std::to_string(e.resist_adjust));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.min_hp));
|
v.push_back(columns[10] + " = " + std::to_string(e.min_hp));
|
||||||
v.push_back(columns[11] + " = " + std::to_string(e.max_hp));
|
v.push_back(columns[11] + " = " + std::to_string(e.max_hp));
|
||||||
|
v.push_back(columns[12] + " = " + std::to_string(e.min_expansion));
|
||||||
|
v.push_back(columns[13] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[14] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[15] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -248,6 +272,10 @@ public:
|
|||||||
v.push_back(std::to_string(e.resist_adjust));
|
v.push_back(std::to_string(e.resist_adjust));
|
||||||
v.push_back(std::to_string(e.min_hp));
|
v.push_back(std::to_string(e.min_hp));
|
||||||
v.push_back(std::to_string(e.max_hp));
|
v.push_back(std::to_string(e.max_hp));
|
||||||
|
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(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -289,6 +317,10 @@ public:
|
|||||||
v.push_back(std::to_string(e.resist_adjust));
|
v.push_back(std::to_string(e.resist_adjust));
|
||||||
v.push_back(std::to_string(e.min_hp));
|
v.push_back(std::to_string(e.min_hp));
|
||||||
v.push_back(std::to_string(e.max_hp));
|
v.push_back(std::to_string(e.max_hp));
|
||||||
|
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) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -334,6 +366,10 @@ public:
|
|||||||
e.resist_adjust = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
|
e.resist_adjust = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
|
||||||
e.min_hp = row[10] ? static_cast<int16_t>(atoi(row[10])) : 0;
|
e.min_hp = row[10] ? static_cast<int16_t>(atoi(row[10])) : 0;
|
||||||
e.max_hp = row[11] ? static_cast<int16_t>(atoi(row[11])) : 0;
|
e.max_hp = row[11] ? static_cast<int16_t>(atoi(row[11])) : 0;
|
||||||
|
e.min_expansion = row[12] ? static_cast<int8_t>(atoi(row[12])) : -1;
|
||||||
|
e.max_expansion = row[13] ? static_cast<int8_t>(atoi(row[13])) : -1;
|
||||||
|
e.content_flags = row[14] ? row[14] : "";
|
||||||
|
e.content_flags_disabled = row[15] ? row[15] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -370,6 +406,10 @@ public:
|
|||||||
e.resist_adjust = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
|
e.resist_adjust = row[9] ? static_cast<int32_t>(atoi(row[9])) : 0;
|
||||||
e.min_hp = row[10] ? static_cast<int16_t>(atoi(row[10])) : 0;
|
e.min_hp = row[10] ? static_cast<int16_t>(atoi(row[10])) : 0;
|
||||||
e.max_hp = row[11] ? static_cast<int16_t>(atoi(row[11])) : 0;
|
e.max_hp = row[11] ? static_cast<int16_t>(atoi(row[11])) : 0;
|
||||||
|
e.min_expansion = row[12] ? static_cast<int8_t>(atoi(row[12])) : -1;
|
||||||
|
e.max_expansion = row[13] ? static_cast<int8_t>(atoi(row[13])) : -1;
|
||||||
|
e.content_flags = row[14] ? row[14] : "";
|
||||||
|
e.content_flags_disabled = row[15] ? row[15] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -456,6 +496,10 @@ public:
|
|||||||
v.push_back(std::to_string(e.resist_adjust));
|
v.push_back(std::to_string(e.resist_adjust));
|
||||||
v.push_back(std::to_string(e.min_hp));
|
v.push_back(std::to_string(e.min_hp));
|
||||||
v.push_back(std::to_string(e.max_hp));
|
v.push_back(std::to_string(e.max_hp));
|
||||||
|
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(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -490,6 +534,10 @@ public:
|
|||||||
v.push_back(std::to_string(e.resist_adjust));
|
v.push_back(std::to_string(e.resist_adjust));
|
||||||
v.push_back(std::to_string(e.min_hp));
|
v.push_back(std::to_string(e.min_hp));
|
||||||
v.push_back(std::to_string(e.max_hp));
|
v.push_back(std::to_string(e.max_hp));
|
||||||
|
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) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user