mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 16:28:28 +00:00
Compare commits
815 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8bd1d51674 | |||
| 0504426dca | |||
| 62c742a7e9 | |||
| ea5cbdd0d0 | |||
| df746dd07d | |||
| cd158aabca | |||
| 95687b57e9 | |||
| 77de74a089 | |||
| 1da7901029 | |||
| 738a31df51 | |||
| 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 | |||
| 1be86edf20 | |||
| b49b564940 | |||
| d302b9c02e | |||
| d36bc3915d | |||
| d6f1bba96c | |||
| d1c7e45437 | |||
| 257935d33a | |||
| fe136e58e4 | |||
| fddb91794b | |||
| ad3a675222 | |||
| fa733eee50 | |||
| f07c5901f4 | |||
| 6dd061cba2 | |||
| 405d963005 | |||
| 7ad97ce168 | |||
| a71ad416b4 | |||
| 758859eea6 | |||
| aa0e53f5fc | |||
| 34c27ebb2a | |||
| 943274b443 | |||
| c4cda66c3b | |||
| 46f3e50b5c | |||
| f77eec83e5 | |||
| dfd1bfbd49 | |||
| b3538021cc | |||
| 7b19225e48 | |||
| ac8cf326b2 | |||
| 39bb7e1723 | |||
| e268ab18f5 | |||
| 37e21d7757 | |||
| 1529c0f670 | |||
| 1b8922fc14 | |||
| 1e0373a3e3 | |||
| 99612ba7b3 | |||
| 1891c9b6de | |||
| 6b698b5f51 | |||
| 703d2cd1d8 | |||
| 4215a3b9d6 | |||
| fcffc6b3d4 | |||
| 64fefaebe4 | |||
| 7b44745c67 | |||
| c3295d129d | |||
| a565e5f824 | |||
| 5a6e0c9e3d | |||
| 8fa6eab2c2 | |||
| 3f49a656c4 | |||
| ff3e955804 | |||
| 2538ee7976 | |||
| a7bfc5ec92 | |||
| d7d99152ac | |||
| 0d09edf9aa | |||
| 0a3f1d3c41 | |||
| ac12ba153e | |||
| 989d199908 | |||
| 1bc1f71254 | |||
| 41c5369c18 | |||
| d6b5a9d343 | |||
| a5e8a4c2cd | |||
| 9a09d820a5 | |||
| b1d873d1fc | |||
| 043eeced6f | |||
| e9a0c79301 | |||
| dc48c45421 | |||
| d7a8fb8691 | |||
| 3a5381d38a | |||
| e64f03fcc0 | |||
| d77966797e | |||
| 048aad437b | |||
| b2d9de8d96 | |||
| 42bfa4bb2e | |||
| 72ce7c8e91 | |||
| e306c86875 | |||
| 3ae7979a67 | |||
| b638795f9b | |||
| 9e3bf91374 | |||
| cd89926435 | |||
| e19f72f021 | |||
| df1dc5d1e4 | |||
| e11286164f | |||
| b946b800fb | |||
| ab8ac81df6 | |||
| 109940fc0c | |||
| a87496b0cf | |||
| f905ee70e4 | |||
| 52417023f8 | |||
| 20d9417628 | |||
| 4692799677 | |||
| cf7f0f4321 | |||
| 823a5956de | |||
| 6a8bd3c5d6 | |||
| 523ba30d81 | |||
| d7ea290b6b | |||
| 036309ebec | |||
| b400700d81 | |||
| 21cec87ac4 | |||
| abdec39cdd | |||
| d2372de982 | |||
| ea9b7841d4 | |||
| 8826d7b927 | |||
| e4157f0221 | |||
| 66cc947b2a | |||
| 5bfd8f5da2 | |||
| 96830b4a19 | |||
| 4bf60a6522 | |||
| 16cb7364e8 | |||
| f5050ab5dc | |||
| e32cbf19ee | |||
| ee12a7ad2e | |||
| e5bdbc4f1e | |||
| f829a99e6d | |||
| 82aa6a1587 | |||
| 161c13f457 | |||
| b29c26becb | |||
| e48dae2392 | |||
| 4b83a96f64 | |||
| 95cc22ffbb | |||
| 6ca11256c6 | |||
| d94493468c | |||
| 957b4f8821 | |||
| 5013459824 | |||
| 94af2843e3 | |||
| 3bfb148bdc | |||
| 96370e0298 | |||
| fef5108b0d | |||
| 6f883566f6 | |||
| 45b1501c8a | |||
| 7e94f0ac72 | |||
| 2aa19f4cae | |||
| 805829f15d | |||
| 2c2a8cdb63 | |||
| ee3d02bac6 | |||
| b90139bd9a | |||
| e6a3d5e1c5 | |||
| 74f1eac401 | |||
| 1be9b2cdfd | |||
| add0a8dddf | |||
| 8c226054e7 | |||
| b4605f77e3 | |||
| 74a63daf7e | |||
| 8ee7910569 | |||
| b766a79c11 | |||
| 5e3b6d363a | |||
| b2fc59878a | |||
| 4896688ac5 | |||
| 0385ed8526 | |||
| 9974aaff57 | |||
| b6c3e549da | |||
| 70ee95efc0 | |||
| 1d38e473d7 | |||
| 1aa3a4b11a | |||
| 398ecbc8cf | |||
| c4613e1b0f | |||
| 3003a59955 | |||
| 0c582cc4f9 | |||
| 69c42510ca | |||
| 79c8858ec8 | |||
| c3d8d423fe | |||
| 1cbda61891 | |||
| 8d12a5b1b1 | |||
| 182327b385 | |||
| aa0ca88d9d | |||
| 103a37e762 | |||
| 34f19489d0 | |||
| c001060429 | |||
| 89be55254e | |||
| 2da6190950 | |||
| d5e024cc02 | |||
| 35fe38cd09 | |||
| eb3664a444 | |||
| a244509d63 | |||
| 873c128f46 | |||
| 8314f2348c | |||
| 29720f95ed | |||
| a478fd2600 | |||
| f57c37e9c5 | |||
| b9fb4babba | |||
| c2e4082045 | |||
| e1dee55ecd | |||
| 1632ff04b0 | |||
| 873209dbc0 | |||
| a00b2eb382 | |||
| 67d8250b1c | |||
| f505c2cfd2 | |||
| a221e50cc2 | |||
| 32c5d4d9f6 | |||
| ce4716e9a5 | |||
| a99ce4fbdb | |||
| dcfc54d408 | |||
| c13ec5a06d | |||
| d182fc3613 | |||
| 5a89fcfb78 | |||
| db3601c25c | |||
| 137a9f835a | |||
| 4ad46b54df | |||
| 3f46210639 | |||
| 6ec63969bb | |||
| 767846f7e5 | |||
| 04bb9bf39c | |||
| e6df5be1ed | |||
| 6bb2f97b74 | |||
| 86f39743fc | |||
| 447fc026a8 | |||
| 7408df933c | |||
| 2f59e70c6b | |||
| eb8514eea8 | |||
| f498bac574 | |||
| 9a0b3a4c36 | |||
| 34ea870717 | |||
| d68c1a7a6c | |||
| c50100fcdb | |||
| 20cdc1e63d | |||
| 43c7523ee1 | |||
| e060d97798 | |||
| 435b6142b8 | |||
| 508b37dc93 | |||
| 0adca46a73 | |||
| e920e35a5c | |||
| 20c01ef343 | |||
| 1567141c19 | |||
| 6bc9bcf15a | |||
| 86a2a86ba8 | |||
| 3e6924d10e | |||
| a27a8adf1e | |||
| 13994fb3e4 | |||
| 78aa527bc7 | |||
| 58287b6539 | |||
| 718a157c06 | |||
| 801025c166 | |||
| 91f5932c6d | |||
| dacebca9dd | |||
| 75539b4f89 | |||
| 804b798068 | |||
| b280f50c99 | |||
| 14d4a2610f | |||
| 26693992b6 | |||
| 772fed5e30 | |||
| 331e04fbf8 | |||
| 9e2afd5571 | |||
| 8edf7a07e3 | |||
| b6b779723e | |||
| c654c1d674 | |||
| fcbf5cae47 | |||
| 0ffea36905 | |||
| 3f9a604c5c | |||
| 297e358c02 | |||
| 029581772d | |||
| 175f2b16f5 | |||
| 71f47dbcef | |||
| 6297c56db2 | |||
| 6efd7c5177 | |||
| 24578f6c1e | |||
| 490ed50c9f | |||
| 7c982df0e3 | |||
| fa783c3c6b | |||
| 5377bb3f49 | |||
| f98c79fdba | |||
| ae79022e06 | |||
| bc59882a65 | |||
| 2e0ed82986 | |||
| 8e3218aaf7 | |||
| 9276966418 | |||
| b89772ca91 | |||
| a1f2a21c99 | |||
| 1cb72642ac | |||
| a38fd8f986 | |||
| 337b6f38e0 | |||
| b4414d3052 | |||
| bfeeb0ce05 | |||
| e640e3cad3 | |||
| c09a3a5bba | |||
| ce907c9519 | |||
| 7a770e0e08 | |||
| 97c3205657 | |||
| ff2e56abc7 | |||
| 9ee16f8bf7 | |||
| 5b43bf4a5e | |||
| 4c769c46b3 | |||
| 8a87e00b66 | |||
| 0ebc7f9bb6 | |||
| 9ac25338bb | |||
| e9285fd2ca | |||
| 5b85f89c21 | |||
| 7fed8fc8c8 | |||
| 26769f40d9 | |||
| f6148b9b8d | |||
| ca1299bf1d | |||
| 3fb24dc0a3 | |||
| dcd7bffa54 | |||
| 5298abe6bc | |||
| fbc2b7c152 | |||
| 86705000b0 | |||
| 748e37dbdf | |||
| 27256215b8 | |||
| 59cbe1a152 | |||
| 3e50427bb7 | |||
| 883b3b5826 | |||
| 135ee6b2b7 | |||
| 906879ce2e | |||
| 8b7aba2769 | |||
| 9303255caa | |||
| 14509fcc4e | |||
| e40267b9b8 | |||
| f3073b463f | |||
| 5ad4129312 | |||
| 4b5b29b165 | |||
| 3b7a138de4 | |||
| 742b437f2c | |||
| d41bd8f963 | |||
| 73a099c5ea | |||
| 77c0eb3998 | |||
| 5d1c59c95f | |||
| 1d7f39c13b | |||
| 1bb8678abe | |||
| 47968774d9 | |||
| d7dc717249 | |||
| 32659426ba | |||
| 238c9fe667 | |||
| b9f997015a | |||
| 11e2a252e5 | |||
| fc627ed52d | |||
| 4c028b85f0 | |||
| f1d5e3eedf | |||
| d59531b16f | |||
| e182d685d3 | |||
| 6968a70310 | |||
| 06e8d258e4 | |||
| 8cb15f9357 | |||
| eb33e5a064 | |||
| 71f78b757e | |||
| 818f833d04 | |||
| 1238a6ca68 | |||
| 4afc1efb38 | |||
| 24eb40d231 | |||
| 2475092ed9 | |||
| 53d6e449c2 | |||
| b61649a2a0 | |||
| ef635cb257 | |||
| 62b5f8a488 | |||
| d0e069f4f8 | |||
| 1b5b22eeca | |||
| 66d9371714 | |||
| 0418dc4aa3 | |||
| f12c87a04a | |||
| 97dbf85a4c | |||
| 46a0cf6b02 | |||
| 8f34bd998f | |||
| 98928aee74 | |||
| e6dc980315 | |||
| ec465616b4 | |||
| 23de0119ff | |||
| f59b4feb94 | |||
| e035660150 | |||
| 472dd71d7f | |||
| 409b6bf424 | |||
| 9da713a830 | |||
| 7d194083aa | |||
| dd41fc5fcd | |||
| 6bf36f3e77 | |||
| dfb06db17b | |||
| 3e958c575b | |||
| e5db19965f | |||
| ce73f6bfe1 | |||
| 700f4645e2 | |||
| 5a7d544c5b | |||
| 0f7f71334a | |||
| c731f3f560 | |||
| b30fbc70a3 | |||
| 195cb80d56 | |||
| b2d5007466 | |||
| 47e2eb0acf | |||
| c36b3f030b | |||
| 2b821e50ff | |||
| 0aa07e9529 | |||
| 7ddafd9ed8 | |||
| 5488e9bf22 | |||
| 6db6d7dca9 | |||
| 066b762e73 | |||
| cd85a8524a | |||
| 4490a53ba0 | |||
| 00eb462d47 | |||
| 2df7d19f97 | |||
| 48c6db3a9c | |||
| cce368d94c | |||
| 84b8bdd2b4 | |||
| fc8ace91cb | |||
| 2d6c9f881a | |||
| 9b72c07a54 | |||
| 9d5d13fbd0 | |||
| bc3e9e8fba | |||
| d9cfc3a858 | |||
| 51dc62dfb1 | |||
| e52e4d5b3f | |||
| 0c3149a6e5 | |||
| 611122833d | |||
| b83373491e | |||
| dfa349492c | |||
| c08200188f | |||
| 41d9a15c74 | |||
| 2ed4effbe3 | |||
| 6ec09f300a | |||
| 079f612730 | |||
| 2c971fb2de | |||
| 20e9a8b2d2 | |||
| 8fa6a0b496 | |||
| d6e1c3f187 | |||
| 70a4b6a2b1 | |||
| 7923d7bc6c | |||
| 6007ba454c | |||
| d4a78f4799 | |||
| 0ada53aa96 | |||
| 7803170d6b | |||
| 20778ad7d9 | |||
| 44d63c47d9 | |||
| b288202c96 | |||
| a724e92638 | |||
| 0ea825e9a4 | |||
| 2ca50b339d | |||
| 164fe31fa8 | |||
| f3de3e8c31 | |||
| 1227f35382 | |||
| c0769a9c29 | |||
| 2dd0e51936 | |||
| fd787af53a | |||
| aa39ac8023 | |||
| 397096996c | |||
| f8de9b9167 | |||
| 9d48cbcd29 | |||
| eb5eb0ca30 | |||
| bc4bebb4a9 | |||
| 05f09b56e6 | |||
| 411fe3d95d | |||
| c1e984dfc1 | |||
| a5d9a8596a | |||
| 7e23d798d5 | |||
| 47ab8910a3 | |||
| 259add68f5 | |||
| d2f5dc43a6 | |||
| 99d2e3a8b1 | |||
| 122fe398b4 | |||
| 43c4b13978 | |||
| a3a707adae | |||
| c4da9766a4 | |||
| a8eb2832ce | |||
| 076aab50e8 | |||
| 1e8889a9fc | |||
| 7c3481daf9 | |||
| b93dec357f | |||
| 2f4af4f0c2 | |||
| a0f2a8a743 | |||
| 4c7016bd7b | |||
| 6c18cd0bee | |||
| 87e63e1e36 | |||
| a771882cff | |||
| b3f6a8c55f | |||
| 605502cd9d | |||
| 4712ca471b | |||
| 836c3d6596 | |||
| 53169ae217 | |||
| fd31915fae | |||
| 52763b6dd2 | |||
| 51cd43b4ea | |||
| 2db84f5a4f | |||
| 79cc2d5351 | |||
| d31cb09214 | |||
| 8bedcd8751 | |||
| 473c5096f6 | |||
| 0b181d5048 | |||
| a7e9af2d27 | |||
| 7a72d5d67e | |||
| 25872203ff | |||
| 6396a6fbef | |||
| 6db0a5c3f0 | |||
| 4fa9e1d66f | |||
| 556af8c5e9 | |||
| f3ef8a0993 | |||
| 267c280db8 | |||
| e06c7d7735 | |||
| 028ebc3a0c | |||
| b3bd44cd76 | |||
| 75a627a3a2 | |||
| 0194aedc92 | |||
| 5cc87cbda7 | |||
| 703862d977 | |||
| 6e325c1ee3 | |||
| 933b83add6 | |||
| b3cd4e63f1 | |||
| 3c894cb533 | |||
| b19ad64800 | |||
| 2cd3d27c67 | |||
| d3b46becd0 | |||
| 286479198f | |||
| 21ec832ca6 | |||
| bdf5f8b4a3 | |||
| 4ca6485398 | |||
| 0c9c2e25c1 | |||
| 7e651877c7 | |||
| 9739c1c8ef | |||
| 8aae59eebe | |||
| c1b07afae9 | |||
| 9c238cd08d | |||
| 33adb9bcc1 | |||
| 2e8bf82861 | |||
| 4d118ab978 | |||
| fcb40daaf1 | |||
| 553bafdbe1 | |||
| d0443db199 | |||
| 9206163190 | |||
| e504482b94 | |||
| 77b88e3dec | |||
| aeeb350068 | |||
| df83113cea | |||
| 940abfaf7a | |||
| a46443b95e | |||
| 871f320311 | |||
| a222128599 | |||
| 45b249e33d | |||
| c24834de5d | |||
| 841d7f2700 | |||
| 56c29154f0 | |||
| 6466c2ff21 | |||
| 16dc210cd8 | |||
| 77045f558e | |||
| e1fa2d5bc5 | |||
| b03f52de18 | |||
| 226cc3d6cb | |||
| 7f54e26dec | |||
| 11a81d8e8a | |||
| e719aa43cf | |||
| 22994e3264 | |||
| cfbdecad19 | |||
| 2427f7e034 | |||
| 9a6403b196 | |||
| d8953c5156 | |||
| 33b40e83b7 | |||
| e75c31d524 | |||
| cf1f8d5460 | |||
| 690cacdaab | |||
| f9f45eedcd | |||
| 93ddffa57f | |||
| c9993fb698 | |||
| aa0fbb8b45 | |||
| 62532c6bdd | |||
| f8c3c03185 | |||
| 692a90f3f0 | |||
| 3a49d851ca | |||
| fdc5c27061 | |||
| 56be69ddb1 | |||
| 9477ff72ac | |||
| 6d8e80b1e5 | |||
| ebeaef598b | |||
| 60b65da7f2 | |||
| 100e6698ea | |||
| 2bd94ab7a2 | |||
| 4c8d68c24b | |||
| 1755678b1f | |||
| 39e2763968 | |||
| f7780b0247 | |||
| c0fe0f11f7 | |||
| a1f1f11940 | |||
| 4c5013e09e | |||
| 838ffbd8c7 | |||
| 42b41d973c | |||
| e7761133a9 | |||
| 93f2bea96e | |||
| ded82ac6d6 | |||
| 6ef182edfd | |||
| e466ca1c6d | |||
| fa5a3155fe | |||
| a20d333f9d | |||
| 853739b538 | |||
| 6094ec9c7b | |||
| 9da1d6b397 | |||
| 8ea7299a57 | |||
| 0811a899d1 | |||
| fad9599642 | |||
| 62711b13d8 | |||
| 2702485206 | |||
| 0aadb891a1 | |||
| d812310c5b | |||
| 1420983700 | |||
| d25cc35f1b | |||
| ed7f395612 | |||
| 8dceb20dd8 | |||
| 6929d180ca | |||
| 011a66a75e | |||
| 07120563a2 | |||
| cc985cbcd5 | |||
| 97caa79472 | |||
| cfa575c756 | |||
| 85063249b4 | |||
| 04d6f8feea | |||
| dfc1bf0381 | |||
| 2237c3a056 | |||
| 4af191c593 |
@@ -0,0 +1,6 @@
|
||||
!Makefile
|
||||
base/*.sql
|
||||
base/*.zip
|
||||
base/db/
|
||||
base/maps/
|
||||
!base/expansion/Makefile
|
||||
@@ -0,0 +1,9 @@
|
||||
# This is a "dev" image for running eqemu in development, also for dev containers
|
||||
ARG USERNAME=user-name-goes-here
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
FROM --platform=linux/arm64 mcr.microsoft.com/devcontainers/base:debian
|
||||
RUN sudo apt update && sudo apt install -y --no-install-recommends build-essential libtool cmake curl debconf-utils git libluabind-dev libsodium-dev liblua5.2-0 liblua5.2-dev libmariadb-dev libssl-dev minizip make mariadb-client locales nano open-vm-tools unzip uuid-dev iputils-ping wget libcurl4-openssl-dev gdb libyaml-cpp-dev ccache ninja-build pv mariadb-server libperl-dev libjson-perl libio-stringy-perl liblua5.1-dev libluabind-dev libboost-dev mariadb-server valgrind telnet libgoogle-perftools-dev google-perftools
|
||||
|
||||
USER $USERNAME
|
||||
@@ -0,0 +1,9 @@
|
||||
# This is a "dev" image for running eqemu in development, also for dev containers
|
||||
ARG USERNAME=user-name-goes-here
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
FROM mcr.microsoft.com/devcontainers/base:debian
|
||||
RUN sudo apt update && sudo apt install -y --no-install-recommends build-essential libtool cmake curl debconf-utils git libluabind-dev libsodium-dev liblua5.2-0 liblua5.2-dev libmariadb-dev libssl-dev minizip make mariadb-client locales nano open-vm-tools unzip uuid-dev iputils-ping wget libcurl4-openssl-dev gdb libyaml-cpp-dev ccache ninja-build pv mariadb-server libperl-dev libjson-perl libio-stringy-perl liblua5.1-dev libluabind-dev libboost-dev mariadb-server valgrind telnet libgoogle-perftools-dev google-perftools
|
||||
|
||||
USER $USERNAME
|
||||
@@ -0,0 +1,284 @@
|
||||
NAME := eqemu-server
|
||||
.ONESHELL:
|
||||
|
||||
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
|
||||
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
|
||||
|
||||
.PHONY: cmake
|
||||
cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
mkdir -p build$$BUILD_SUFFIX
|
||||
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_TESTS=ON \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
|
||||
|
||||
clean:
|
||||
ifneq (,$(findstring .devcontainer,$$PWD))
|
||||
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
|
||||
endif
|
||||
rm -rf build
|
||||
|
||||
docker-cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARGS} make cmake
|
||||
|
||||
docker-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARGS} make build
|
||||
|
||||
# Build image if it doesn't exist
|
||||
docker-image-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.dev -t ${NAME} .
|
||||
endif
|
||||
|
||||
docker-arm-cmake: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-build: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-image-build:
|
||||
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
|
||||
endif
|
||||
|
||||
docker-clean: clean
|
||||
|
||||
.PHONY: prep
|
||||
prep:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "Preparing build/bin for usage..."
|
||||
mkdir -p build/bin/assets/patches
|
||||
cp -R -u -p .devcontainer/base/eqemu_config.json build/bin/eqemu_config.json
|
||||
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
|
||||
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
|
||||
mkdir -p build/bin/assets
|
||||
cp -R -u -p utils/patches build/bin/assets/
|
||||
-unlink build/bin/lua_modules
|
||||
cd build/bin && ln -s quests/lua_modules lua_modules
|
||||
-unlink build/bin/mods
|
||||
cd build/bin && ln -s quests/mods mods
|
||||
-unlink build/bin/maps
|
||||
cd build/bin && ln -s ../../base/maps maps
|
||||
mkdir -p build/bin/logs
|
||||
mkdir -p build/bin/shared
|
||||
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
|
||||
|
||||
maps:
|
||||
@echo "Downloading maps..."
|
||||
@mkdir -p base/maps
|
||||
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
|
||||
@cd base/maps && unzip -o master.zip
|
||||
@cd base/maps && mv eqemu-maps-master/* .
|
||||
@cd base/maps && rm -rf eqemu-maps-master
|
||||
@echo "Maps downloaded."
|
||||
|
||||
quests:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
|
||||
|
||||
# Runs tests
|
||||
.PHONY: test
|
||||
test:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && ./tests
|
||||
|
||||
# Runs login binary
|
||||
.PHONY: login
|
||||
login:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && ./loginserver
|
||||
|
||||
# Runs shared_memory binary
|
||||
.PHONY: shared
|
||||
shared:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && ./shared_memory
|
||||
|
||||
# Runs zone binary
|
||||
.PHONY: zone
|
||||
zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/zone/zone*.log
|
||||
cd build/bin && ./zone
|
||||
|
||||
# Runs world binary
|
||||
.PHONY: world
|
||||
world:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/world*.log
|
||||
cd build/bin && ./world
|
||||
|
||||
# Runs ucs binary
|
||||
.PHONY: ucs
|
||||
ucs:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/ucs*.log
|
||||
cd build/bin && ./ucs
|
||||
|
||||
# Runs queryserv binary
|
||||
.PHONY: queryserv
|
||||
queryserv:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/query_server*.log
|
||||
cd build/bin && ./queryserv
|
||||
|
||||
valgrind-%:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
|
||||
|
||||
# Start mariaDB standalone
|
||||
.PHONY: mariadb
|
||||
mariadb:
|
||||
@sudo service mariadb start
|
||||
|
||||
.PHONY: inject-mariadb
|
||||
inject-mariadb:
|
||||
-sudo service mariadb start
|
||||
-mkdir -p base/db/
|
||||
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
|
||||
-sudo mariadb -e 'CREATE DATABASE peq;'
|
||||
-sudo mariadb -e "CREATE USER 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
||||
-sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
|
||||
ifeq (,$(wildcard base/db/db.sql.zip))
|
||||
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
|
||||
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
|
||||
-cd base/db && unzip db.sql.zip
|
||||
endif
|
||||
@echo "Sourcing db may take a while, please wait..."
|
||||
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
|
||||
@echo "MariaDB is now injected."
|
||||
|
||||
.PHONY: gm-%
|
||||
gm-%:
|
||||
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
|
||||
@echo "Account $* is now a GM. /camp to have it go into effect."
|
||||
|
||||
depends:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
|
||||
exit
|
||||
endif
|
||||
sudo apt install graphviz pip time
|
||||
pip3 install graphviz
|
||||
mkdir -p build/depends
|
||||
@if [ ! -f "build/depends/dependency_graph.py" ]; then \
|
||||
wget https://raw.githubusercontent.com/pvigier/dependency-graph/master/dependency_graph.py -O build/depends/dependency_graph.py; \
|
||||
fi
|
||||
@echo "Generating dependency graphs (This may take a while)..."
|
||||
@echo "Login..."
|
||||
time python3 build/depends/dependency_graph.py -f png login build/depends/login.dot
|
||||
@echo "World..."
|
||||
time python3 build/depends/dependency_graph.py -f png world build/depends/world.dot
|
||||
@echo "Zone..."
|
||||
time python3 build/depends/dependency_graph.py -f png zone build/depends/zone.dot
|
||||
@echo "Common..."
|
||||
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
|
||||
|
||||
backup:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@mkdir -p build/bin/backup
|
||||
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
|
||||
|
||||
cpu-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && CPUPROFILE=prof.out ./zone
|
||||
|
||||
pprof-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
|
||||
pprof-web-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-web-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --web zone prof.out
|
||||
pprof-gv-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-gv-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --gv zone prof.out > prof.gv
|
||||
heap-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile heap-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && HEAPPROFILE=prof.out ./zone
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"server": {
|
||||
"zones": {
|
||||
"defaultstatus": "0",
|
||||
"ports": {
|
||||
"low": "7000",
|
||||
"high": "7400"
|
||||
}
|
||||
},
|
||||
"qsdatabase": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"username": "peq",
|
||||
"password": "peqpass",
|
||||
"db": "peq"
|
||||
},
|
||||
"chatserver": {
|
||||
"port": "7778",
|
||||
"host": ""
|
||||
},
|
||||
"mailserver": {
|
||||
"host": "",
|
||||
"port": "7778"
|
||||
},
|
||||
"webinterface": {
|
||||
"port": "9081"
|
||||
},
|
||||
"world": {
|
||||
"longname": "New Devbox",
|
||||
"address": "192.168.1.100",
|
||||
"localaddress": "192.168.1.100",
|
||||
"loginserver1": {
|
||||
"account": "",
|
||||
"password": "",
|
||||
"legacy": 0,
|
||||
"host": "login.projecteq.net",
|
||||
"port": "5998"
|
||||
},
|
||||
"tcp": {
|
||||
"ip": "127.0.0.1",
|
||||
"port": "9001"
|
||||
},
|
||||
"telnet": {
|
||||
"ip": "0.0.0.0",
|
||||
"port": "9000",
|
||||
"enabled": "true"
|
||||
},
|
||||
"key": "random-generate-here",
|
||||
"http": {
|
||||
"port": "9080",
|
||||
"enabled": "true",
|
||||
"mimefile": "mime.types"
|
||||
},
|
||||
"shortname": "dev"
|
||||
},
|
||||
"database": {
|
||||
"db": "peq",
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"username": "peq",
|
||||
"password": "peqpass"
|
||||
},
|
||||
"files": {
|
||||
"opcodes": "assets/patches/opcodes.conf",
|
||||
"mail_opcodes": "assets/patches/mail_opcodes.conf"
|
||||
},
|
||||
"directories": {
|
||||
"patches": "assets/patches/",
|
||||
"opcodes": "assets/patches/",
|
||||
"plugins": "quests/plugins/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"database": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"db": "peq",
|
||||
"user": "peq",
|
||||
"password": "peqpass"
|
||||
},
|
||||
"account": {
|
||||
"auto_create_accounts": true
|
||||
},
|
||||
"worldservers": {
|
||||
"unregistered_allowed": true,
|
||||
"reject_duplicate_servers": false
|
||||
},
|
||||
"web_api": {
|
||||
"enabled": true,
|
||||
"port": 6000
|
||||
},
|
||||
"security": {
|
||||
"mode": 14,
|
||||
"allow_password_login": true,
|
||||
"allow_token_login": true
|
||||
},
|
||||
"logging": {
|
||||
"trace": false,
|
||||
"world_trace": false,
|
||||
"dump_packets_in": false,
|
||||
"dump_packets_out": false
|
||||
},
|
||||
"client_configuration": {
|
||||
"titanium_port": 5998,
|
||||
"titanium_opcodes": "assets/patches/login_opcodes.conf",
|
||||
"sod_port": 5999,
|
||||
"sod_opcodes": "assets/patches/login_opcodes_sod.conf"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
|
||||
{
|
||||
"name": "eqemu",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile.debian.dev"
|
||||
},
|
||||
"appPort": [
|
||||
"5998:5998/udp",
|
||||
"7000:7000/udp",
|
||||
"7001:7001/udp",
|
||||
"7002:7002/udp",
|
||||
"7003:7003/udp",
|
||||
"7004:7004/udp",
|
||||
"7005:7005/udp",
|
||||
"9000:9000/udp",
|
||||
"9001:9001/udp"
|
||||
],
|
||||
"forwardPorts": [
|
||||
3306
|
||||
],
|
||||
"remoteEnv": {
|
||||
"LOCALWSF": "${localWorkspaceFolder}",
|
||||
"CONTAINERWSF": "${containerWorkspaceFolder}"
|
||||
},
|
||||
"containerUser": "vscode",
|
||||
// add ptrace
|
||||
"runArgs": [
|
||||
"--cap-add=SYS_PTRACE",
|
||||
"--security-opt",
|
||||
"seccomp=unconfined"
|
||||
],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools-extension-pack",
|
||||
"vilicvane.sensitive-replace",
|
||||
"maattdd.gitless",
|
||||
"bibhasdn.unique-lines",
|
||||
"GitHub.copilot",
|
||||
"xackery.make-magic",
|
||||
"Gruntfuggly.todo-tree",
|
||||
"ms-vscode.cmake-tools"
|
||||
]
|
||||
}
|
||||
},
|
||||
"workspaceFolder": "/src",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@ volumes:
|
||||
|
||||
steps:
|
||||
- name: Build Linux X64
|
||||
image: akkadius/eqemu-server:v13
|
||||
image: akkadius/eqemu-server:v14
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
|
||||
@@ -61,9 +61,6 @@ bin/
|
||||
compile_flags.txt
|
||||
.cache/
|
||||
|
||||
# vscode generated settings
|
||||
.vscode/
|
||||
|
||||
# Build pipeline
|
||||
!utils/scripts/build/
|
||||
!utils/scripts/build/should-release/should-release
|
||||
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${default}",
|
||||
"${workspaceFolder}/submodules/fmt/include",
|
||||
"${workspaceFolder}/submodules/cereal/include",
|
||||
"${workspaceFolder}/submodules/glm",
|
||||
"${workspaceFolder}/submodules/libuv/include"
|
||||
],
|
||||
"defines": [
|
||||
"LUA_EQEMU=1"
|
||||
],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
+173
@@ -0,0 +1,173 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "${workspaceFolder}/build/bin/world",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) shared_memory",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/shared_memory",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) world",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/world",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) zone",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/zone",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"args": [
|
||||
"",
|
||||
],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) zone neriakb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/zone",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"args": [
|
||||
"neriakb",
|
||||
],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) login",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/loginserver",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) ucs",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/ucs",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) queryserv",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/queryserv",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+136
@@ -0,0 +1,136 @@
|
||||
{
|
||||
"editor.detectIndentation": false,
|
||||
"editor.insertSpaces": false,
|
||||
"editor.tabSize": 4,
|
||||
"editor.autoIndent": "full",
|
||||
"editor.trimAutoWhitespace": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
//"editor.formatOnSave": true,
|
||||
"search.exclude": {
|
||||
"dependencies": false,
|
||||
},
|
||||
"C_Cpp.default.includePath": [
|
||||
"/usr/include/x86_64-linux-gnu",
|
||||
"/usr/include/lua5.2",
|
||||
"/usr/include/mariadb",
|
||||
"${workspaceFolder}/dependencies/curl_x64/include",
|
||||
"${workspaceFolder}/dependencies/fmt/include",
|
||||
"${workspaceFolder}/dependencies/glm",
|
||||
"${workspaceFolder}/dependencies/libuv/include",
|
||||
"${workspaceFolder}/dependencies/sol2",
|
||||
"${workspaceFolder}/dependencies/zlibng"
|
||||
],
|
||||
"telemetry.enableTelemetry": false,
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"cmake.configureArgs": [
|
||||
"-DEQEMU_BUILD_LOGIN=ON",
|
||||
"-DEQEMU_BUILD_TESTS=ON",
|
||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
|
||||
"-DEQEMU_ADD_PROFILER=ON",
|
||||
"Ninja"
|
||||
],
|
||||
"cmake.skipConfigureIfCachePresent": true,
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
"*.ipp": "cpp",
|
||||
"functional": "cpp",
|
||||
"string": "cpp",
|
||||
"iostream": "cpp",
|
||||
"map": "cpp",
|
||||
"fstream": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"cstring": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"strstream": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"source_location": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"charconv": "cpp",
|
||||
"format": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp"
|
||||
},
|
||||
"cmake.statusbar.advanced": {
|
||||
"kit": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"debug": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"buildTarget": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"launch": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"ctest": {
|
||||
"visibility": "icon",
|
||||
}
|
||||
}
|
||||
}
|
||||
+1864
-12
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@ SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
||||
OPTION(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON)
|
||||
|
||||
IF (EQEMU_BUILD_STATIC)
|
||||
SET(BUILD_SHARED_LIBS OFF)
|
||||
@@ -30,6 +31,13 @@ IF (EQEMU_BUILD_STATIC)
|
||||
ENDIF ()
|
||||
ENDIF (EQEMU_BUILD_STATIC)
|
||||
|
||||
|
||||
# Requires libgoogle-perftools-dev google-perftools packages for linux (debian)
|
||||
IF(EQEMU_ADD_PROFILER)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-as-needed,-lprofiler,--as-needed")
|
||||
ENDIF(EQEMU_ADD_PROFILER)
|
||||
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
|
||||
add_subdirectory(import)
|
||||
add_subdirectory(export)
|
||||
|
||||
+51
-153
@@ -29,11 +29,19 @@
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.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/spells_new_repository.h"
|
||||
#include "../../common/file.h"
|
||||
#include "../../common/events/player_event_logs.h"
|
||||
#include "../../common/skill_caps.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
PlayerEventLogs player_event_logs;
|
||||
|
||||
void ExportSpells(SharedDatabase *db);
|
||||
void ExportSkillCaps(SharedDatabase *db);
|
||||
@@ -94,25 +102,22 @@ int main(int argc, char **argv)
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
std::string arg_1;
|
||||
std::string export_type;
|
||||
|
||||
if (argv[1]) {
|
||||
arg_1 = argv[1];
|
||||
export_type = argv[1];
|
||||
}
|
||||
|
||||
if (arg_1 == "spells") {
|
||||
if (Strings::EqualFold(export_type, "spells")) {
|
||||
ExportSpells(&content_db);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "skills") {
|
||||
} else if (Strings::EqualFold(export_type, "skills")) {
|
||||
ExportSkillCaps(&content_db);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "basedata") {
|
||||
} else if (Strings::EqualFold(export_type, "basedata") || Strings::EqualFold(export_type, "base_data")) {
|
||||
ExportBaseData(&content_db);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "dbstring") {
|
||||
} else if (Strings::EqualFold(export_type, "dbstr") || Strings::EqualFold(export_type, "dbstring")) {
|
||||
ExportDBStrings(&database);
|
||||
return 0;
|
||||
}
|
||||
@@ -127,186 +132,79 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExportSpells(SharedDatabase *db)
|
||||
void ExportSpells(SharedDatabase* db)
|
||||
{
|
||||
LogInfo("Exporting Spells");
|
||||
|
||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string query = "SELECT * FROM spells_new ORDER BY id";
|
||||
auto results = db->QueryDatabase(query);
|
||||
const auto& lines = SpellsNewRepository::GetSpellFileLines(*db);
|
||||
|
||||
if (results.Success()) {
|
||||
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('^');
|
||||
}
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
|
||||
if (row[i] != nullptr) {
|
||||
line += row[i];
|
||||
}
|
||||
}
|
||||
file << file_string;
|
||||
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
file.close();
|
||||
|
||||
fclose(f);
|
||||
LogInfo("Exported [{}] Spell{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
||||
void ExportSkillCaps(SharedDatabase* db)
|
||||
{
|
||||
|
||||
bool res = false;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
|
||||
class_id, skill_id
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
||||
{
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
|
||||
class_id, skill_id, level
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return Strings::ToInt(row[0]);
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Skill Caps");
|
||||
|
||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int cl = 1; cl <= 16; ++cl) {
|
||||
for (int skill = 0; skill <= 77; ++skill) {
|
||||
if (SkillUsable(db, skill, cl)) {
|
||||
int previous_cap = 0;
|
||||
for (int level = 1; level <= 100; ++level) {
|
||||
int cap = GetSkill(db, skill, cl, level);
|
||||
if (cap < previous_cap) {
|
||||
cap = previous_cap;
|
||||
}
|
||||
const auto& lines = SkillCapsRepository::GetSkillCapFileLines(*db);
|
||||
|
||||
fprintf(f, "%d^%d^%d^%d^0\n", cl, skill, level, cap);
|
||||
previous_cap = cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
|
||||
fclose(f);
|
||||
file << file_string;
|
||||
|
||||
file.close();
|
||||
|
||||
LogInfo("Exported [{}] Skill Cap{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
void ExportBaseData(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Base Data");
|
||||
|
||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
std::ofstream file(fmt::format("{}/export/BaseData.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string query = "SELECT * FROM base_data ORDER BY level, class";
|
||||
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('^');
|
||||
}
|
||||
const auto& lines = BaseDataRepository::GetBaseDataFileLines(*db);
|
||||
|
||||
if (row[rowIndex] != nullptr) {
|
||||
line += row[rowIndex];
|
||||
}
|
||||
}
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
|
||||
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)
|
||||
{
|
||||
LogInfo("Exporting DB Strings");
|
||||
|
||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(f, "Major^Minor^String(New)\n");
|
||||
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
|
||||
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('^');
|
||||
}
|
||||
const auto& lines = DbStrRepository::GetDBStrFileLines(*db);
|
||||
|
||||
if (row[rowIndex] != nullptr) {
|
||||
line += row[rowIndex];
|
||||
}
|
||||
}
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
file << file_string;
|
||||
|
||||
fclose(f);
|
||||
file.close();
|
||||
|
||||
LogInfo("Exported [{}] Database String{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,15 @@
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
#include "../../common/repositories/base_data_repository.h"
|
||||
#include "../../common/file.h"
|
||||
#include "../../common/events/player_event_logs.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
PlayerEventLogs player_event_logs;
|
||||
|
||||
void ImportSpells(SharedDatabase *db);
|
||||
void ImportSkillCaps(SharedDatabase *db);
|
||||
@@ -255,50 +259,45 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ImportBaseData(SharedDatabase *db) {
|
||||
void ImportBaseData(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Importing Base Data");
|
||||
|
||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
return;
|
||||
const std::string& file_name = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
||||
|
||||
const auto& file_contents = File::GetContents(file_name);
|
||||
if (!file_contents.error.empty()) {
|
||||
LogError("{}", file_contents.error);
|
||||
}
|
||||
|
||||
std::string delete_sql = "DELETE FROM base_data";
|
||||
db->QueryDatabase(delete_sql);
|
||||
db->QueryDatabase("DELETE FROM base_data");
|
||||
|
||||
char buffer[2048];
|
||||
while(fgets(buffer, 2048, f)) {
|
||||
auto split = Strings::Split(buffer, '^');
|
||||
std::vector<BaseDataRepository::BaseData> v;
|
||||
|
||||
if(split.size() < 10) {
|
||||
auto e = BaseDataRepository::NewEntity();
|
||||
|
||||
for (const auto& line: Strings::Split(file_contents.contents, "\n")) {
|
||||
const auto& line_data = Strings::Split(line, '^');
|
||||
|
||||
if (line_data.size() < 10) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string sql;
|
||||
int level, class_id;
|
||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
||||
e.level = static_cast<uint8_t>(Strings::ToUnsignedInt(line_data[0]));
|
||||
e.class_ = static_cast<uint8_t>(Strings::ToUnsignedInt(line_data[1]));
|
||||
e.hp = Strings::ToFloat(line_data[2]);
|
||||
e.mana = Strings::ToFloat(line_data[3]);
|
||||
e.end = Strings::ToFloat(line_data[4]);
|
||||
e.hp_regen = Strings::ToFloat(line_data[5]);
|
||||
e.end_regen = Strings::ToFloat(line_data[6]);
|
||||
e.hp_fac = Strings::ToFloat(line_data[7]);
|
||||
e.mana_fac = Strings::ToFloat(line_data[8]);
|
||||
e.end_fac = Strings::ToFloat(line_data[9]);
|
||||
|
||||
level = Strings::ToInt(split[0].c_str());
|
||||
class_id = Strings::ToInt(split[1].c_str());
|
||||
hp = Strings::ToFloat(split[2].c_str());
|
||||
mana = Strings::ToFloat(split[3].c_str());
|
||||
end = Strings::ToFloat(split[4].c_str());
|
||||
unk1 = Strings::ToFloat(split[5].c_str());
|
||||
unk2 = Strings::ToFloat(split[6].c_str());
|
||||
hp_fac = Strings::ToFloat(split[7].c_str());
|
||||
mana_fac = Strings::ToFloat(split[8].c_str());
|
||||
end_fac = Strings::ToFloat(split[9].c_str());
|
||||
|
||||
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
||||
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
|
||||
level, class_id, hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac);
|
||||
|
||||
db->QueryDatabase(sql);
|
||||
v.emplace_back(e);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
BaseDataRepository::InsertMany(*db, v);
|
||||
}
|
||||
|
||||
void ImportDBStrings(SharedDatabase *db) {
|
||||
|
||||
+32
-16
@@ -2,6 +2,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
|
||||
SET(common_sources
|
||||
base_packet.cpp
|
||||
bazaar.cpp
|
||||
bodytypes.cpp
|
||||
classes.cpp
|
||||
cli/eqemu_command_handler.cpp
|
||||
compression.cpp
|
||||
@@ -13,7 +15,6 @@ SET(common_sources
|
||||
crc32.cpp
|
||||
database/database_dump_service.cpp
|
||||
database.cpp
|
||||
database_conversions.cpp
|
||||
database_instances.cpp
|
||||
database/database_update_manifest.cpp
|
||||
database/database_update_manifest_bots.cpp
|
||||
@@ -61,6 +62,7 @@ SET(common_sources
|
||||
mutex.cpp
|
||||
mysql_request_result.cpp
|
||||
mysql_request_row.cpp
|
||||
mysql_stmt.cpp
|
||||
opcode_map.cpp
|
||||
opcodemgr.cpp
|
||||
packet_dump.cpp
|
||||
@@ -84,6 +86,7 @@ SET(common_sources
|
||||
shared_tasks.cpp
|
||||
shareddb.cpp
|
||||
skills.cpp
|
||||
skill_caps.cpp
|
||||
spdat.cpp
|
||||
strings.cpp
|
||||
struct_strategy.cpp
|
||||
@@ -156,6 +159,7 @@ SET(repositories
|
||||
repositories/base/base_bugs_repository.h
|
||||
repositories/base/base_bug_reports_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_alternate_abilities_repository.h
|
||||
repositories/base/base_character_alt_currency_repository.h
|
||||
@@ -177,6 +181,8 @@ SET(repositories
|
||||
repositories/base/base_character_leadership_abilities_repository.h
|
||||
repositories/base/base_character_material_repository.h
|
||||
repositories/base/base_character_memmed_spells_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_pet_buffs_repository.h
|
||||
repositories/base/base_character_pet_info_repository.h
|
||||
@@ -223,6 +229,9 @@ SET(repositories
|
||||
repositories/base/base_group_leaders_repository.h
|
||||
repositories/base/base_guilds_repository.h
|
||||
repositories/base/base_guild_ranks_repository.h
|
||||
repositories/base/base_guild_permissions_repository.h
|
||||
repositories/base/base_guild_members_repository.h
|
||||
repositories/base/base_guild_bank_repository.h
|
||||
repositories/base/base_guild_relations_repository.h
|
||||
repositories/base/base_horses_repository.h
|
||||
repositories/base/base_instance_list_repository.h
|
||||
@@ -231,7 +240,6 @@ SET(repositories
|
||||
repositories/base/base_inventory_snapshots_repository.h
|
||||
repositories/base/base_ip_exemptions_repository.h
|
||||
repositories/base/base_items_repository.h
|
||||
repositories/base/base_item_tick_repository.h
|
||||
repositories/base/base_ldon_trap_entries_repository.h
|
||||
repositories/base/base_ldon_trap_templates_repository.h
|
||||
repositories/base/base_level_exp_mods_repository.h
|
||||
@@ -333,7 +341,8 @@ SET(repositories
|
||||
repositories/books_repository.h
|
||||
repositories/bugs_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_alternate_abilities_repository.h
|
||||
repositories/character_alt_currency_repository.h
|
||||
@@ -355,6 +364,8 @@ SET(repositories
|
||||
repositories/character_leadership_abilities_repository.h
|
||||
repositories/character_material_repository.h
|
||||
repositories/character_memmed_spells_repository.h
|
||||
repositories/character_parcels_repository.h
|
||||
repositories/character_parcels_containers_repository.h
|
||||
repositories/character_peqzone_flags_repository.h
|
||||
repositories/character_pet_buffs_repository.h
|
||||
repositories/character_pet_info_repository.h
|
||||
@@ -401,6 +412,9 @@ SET(repositories
|
||||
repositories/group_leaders_repository.h
|
||||
repositories/guilds_repository.h
|
||||
repositories/guild_ranks_repository.h
|
||||
repositories/guild_permissions_repository.h
|
||||
repositories/guild_members_repository.h
|
||||
repositories/guild_bank_repository.h
|
||||
repositories/guild_relations_repository.h
|
||||
repositories/horses_repository.h
|
||||
repositories/instance_list_repository.h
|
||||
@@ -409,7 +423,6 @@ SET(repositories
|
||||
repositories/inventory_snapshots_repository.h
|
||||
repositories/ip_exemptions_repository.h
|
||||
repositories/items_repository.h
|
||||
repositories/item_tick_repository.h
|
||||
repositories/ldon_trap_entries_repository.h
|
||||
repositories/ldon_trap_templates_repository.h
|
||||
repositories/level_exp_mods_repository.h
|
||||
@@ -489,12 +502,12 @@ SET(repositories
|
||||
repositories/zone_repository.h
|
||||
repositories/zone_points_repository.h
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
SET(common_headers
|
||||
additive_lagged_fibonacci_engine.h
|
||||
bazaar.h
|
||||
base_packet.h
|
||||
base_data.h
|
||||
bodytypes.h
|
||||
classes.h
|
||||
compression.h
|
||||
@@ -541,7 +554,6 @@ SET(common_headers
|
||||
events/player_event_logs.h
|
||||
events/player_event_discord_formatter.h
|
||||
events/player_events.h
|
||||
errmsg.h
|
||||
event_sub.h
|
||||
expedition_lockout_timer.h
|
||||
extprofile.h
|
||||
@@ -563,10 +575,9 @@ SET(common_headers
|
||||
item_fieldlist.h
|
||||
item_instance.h
|
||||
json_config.h
|
||||
languages.h
|
||||
light_source.h
|
||||
linked_list.h
|
||||
loottable.h
|
||||
loot.h
|
||||
mail_oplist.h
|
||||
md5.h
|
||||
memory_buffer.h
|
||||
@@ -576,6 +587,7 @@ SET(common_headers
|
||||
mutex.h
|
||||
mysql_request_result.h
|
||||
mysql_request_row.h
|
||||
mysql_stmt.h
|
||||
op_codes.h
|
||||
opcode_dispatch.h
|
||||
opcodemgr.h
|
||||
@@ -592,7 +604,7 @@ SET(common_headers
|
||||
ptimer.h
|
||||
queue.h
|
||||
races.h
|
||||
raid.h
|
||||
raid.h
|
||||
random.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
@@ -606,6 +618,7 @@ SET(common_headers
|
||||
shared_tasks.h
|
||||
shareddb.h
|
||||
skills.h
|
||||
skill_caps.h
|
||||
spdat.h
|
||||
strings.h
|
||||
struct_strategy.h
|
||||
@@ -681,13 +694,13 @@ SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
event/timer.h
|
||||
event/task.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Json FILES
|
||||
json/json.h
|
||||
json/jsoncpp.cpp
|
||||
json/json-forwards.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Net FILES
|
||||
net/console_server.cpp
|
||||
@@ -724,7 +737,7 @@ SOURCE_GROUP(Net FILES
|
||||
net/websocket_server.h
|
||||
net/websocket_server_connection.cpp
|
||||
net/websocket_server_connection.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patches FILES
|
||||
patches/patches.h
|
||||
@@ -768,12 +781,12 @@ SOURCE_GROUP(Patches FILES
|
||||
patches/titanium_limits.cpp
|
||||
patches/uf.cpp
|
||||
patches/uf_limits.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(StackWalker FILES
|
||||
StackWalker/StackWalker.h
|
||||
StackWalker/StackWalker.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Util FILES
|
||||
util/memory_stream.h
|
||||
@@ -781,7 +794,7 @@ SOURCE_GROUP(Util FILES
|
||||
util/directory.h
|
||||
util/uuid.cpp
|
||||
util/uuid.h
|
||||
)
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||
|
||||
@@ -792,5 +805,8 @@ IF (UNIX)
|
||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||
ENDIF (UNIX)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_COMMON_BASE_DATA_H
|
||||
#define __EQEMU_COMMON_BASE_DATA_H
|
||||
|
||||
struct BaseDataStruct
|
||||
{
|
||||
double base_hp;
|
||||
double base_mana;
|
||||
double base_end;
|
||||
double hp_regen;
|
||||
double end_regen;
|
||||
double hp_factor;
|
||||
double mana_factor;
|
||||
double endurance_factor;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,360 @@
|
||||
#include "bazaar.h"
|
||||
|
||||
#include "../../common/item_instance.h"
|
||||
#include "repositories/trader_repository.h"
|
||||
#include <memory>
|
||||
|
||||
std::vector<BazaarSearchResultsFromDB_Struct>
|
||||
Bazaar::GetSearchResults(
|
||||
SharedDatabase &db,
|
||||
BazaarSearchCriteria_Struct search,
|
||||
uint32 char_zone_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 [{}]",
|
||||
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
|
||||
);
|
||||
|
||||
std::string search_criteria_trader("TRUE ");
|
||||
|
||||
if (search.search_scope == NonRoFBazaarSearchScope) {
|
||||
search_criteria_trader.append(
|
||||
fmt::format(
|
||||
" AND trader.char_entity_id = {} AND trader.char_zone_id = {}",
|
||||
search.trader_entity_id,
|
||||
Zones::BAZAAR
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (search.search_scope == Local_Scope) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.char_zone_id = {}", char_zone_id));
|
||||
}
|
||||
else if (search.trader_id > 0) {
|
||||
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));
|
||||
}
|
||||
|
||||
// not yet implemented
|
||||
// if (search.prestige != 0) {
|
||||
// 0xffffffff prestige only, 0xfffffffe non-prestige, 0 all
|
||||
// search_criteria.append(fmt::format(" AND items.type = {} ", search.prestige));
|
||||
// }
|
||||
|
||||
std::string query = fmt::format(
|
||||
"SELECT COUNT(item_id), trader.char_id, trader.item_id, trader.item_sn, trader.item_charges, trader.item_cost, "
|
||||
"trader.slot_id, SUM(trader.item_charges), trader.char_zone_id, trader.char_entity_id, character_data.name, "
|
||||
"aug_slot_1, aug_slot_2, aug_slot_3, aug_slot_4, aug_slot_5, aug_slot_6 "
|
||||
"FROM trader, character_data "
|
||||
"WHERE {} AND trader.char_id = character_data.id "
|
||||
"GROUP BY trader.item_sn, trader.item_charges, trader.char_id",
|
||||
search_criteria_trader.c_str()
|
||||
);
|
||||
|
||||
std::vector<BazaarSearchResultsFromDB_Struct> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
struct ItemSearchType {
|
||||
EQ::item::ItemType type;
|
||||
bool condition;
|
||||
};
|
||||
|
||||
struct AddititiveSearchCriteria {
|
||||
bool should_check;
|
||||
bool condition;
|
||||
};
|
||||
|
||||
for (auto row: results) {
|
||||
BazaarSearchResultsFromDB_Struct r{};
|
||||
|
||||
r.item_id = Strings::ToInt(row[2]);
|
||||
r.charges = Strings::ToInt(row[4]);
|
||||
|
||||
auto item = db.GetItem(r.item_id);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 aug_slot_1 = Strings::ToUnsignedInt(row[11]);
|
||||
uint32 aug_slot_2 = Strings::ToUnsignedInt(row[12]);
|
||||
uint32 aug_slot_3 = Strings::ToUnsignedInt(row[13]);
|
||||
uint32 aug_slot_4 = Strings::ToUnsignedInt(row[14]);
|
||||
uint32 aug_slot_5 = Strings::ToUnsignedInt(row[15]);
|
||||
uint32 aug_slot_6 = Strings::ToUnsignedInt(row[16]);
|
||||
|
||||
std::unique_ptr<EQ::ItemInstance> inst(
|
||||
db.CreateItem(
|
||||
item,
|
||||
r.charges,
|
||||
aug_slot_1,
|
||||
aug_slot_2,
|
||||
aug_slot_3,
|
||||
aug_slot_4,
|
||||
aug_slot_5,
|
||||
aug_slot_6
|
||||
)
|
||||
);
|
||||
|
||||
if (!inst->GetItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
r.count = Strings::ToInt(row[0]);
|
||||
r.trader_id = Strings::ToInt(row[1]);
|
||||
r.serial_number = Strings::ToInt(row[3]);
|
||||
r.cost = Strings::ToInt(row[5]);
|
||||
r.slot_id = Strings::ToInt(row[6]);
|
||||
r.sum_charges = Strings::ToInt(row[7]);
|
||||
r.stackable = item->Stackable;
|
||||
r.icon_id = item->Icon;
|
||||
r.trader_zone_id = Strings::ToInt(row[8]);
|
||||
r.trader_entity_id = Strings::ToInt(row[9]);
|
||||
r.serial_number_RoF = fmt::format("{:016}\0", Strings::ToInt(row[3]));
|
||||
r.item_name = fmt::format("{:.63}\0", item->Name);
|
||||
r.trader_name = fmt::format("{:.63}\0", std::string(row[10]).c_str());
|
||||
|
||||
LogTradingDetail(
|
||||
"Searching against item [{}] ({}) for trader [{}]",
|
||||
item->Name,
|
||||
item->ID,
|
||||
r.trader_name
|
||||
);
|
||||
|
||||
// item stat searches
|
||||
std::map<uint32, uint32> item_stat_searches = {
|
||||
|
||||
{STAT_AC, inst->GetItemArmorClass(true)},
|
||||
{STAT_AGI, static_cast<uint32>(inst->GetItemAgi(true))},
|
||||
{STAT_CHA, static_cast<uint32>(inst->GetItemCha(true))},
|
||||
{STAT_DEX, static_cast<uint32>(inst->GetItemDex(true))},
|
||||
{STAT_INT, static_cast<uint32>(inst->GetItemInt(true))},
|
||||
{STAT_STA, static_cast<uint32>(inst->GetItemSta(true))},
|
||||
{STAT_STR, static_cast<uint32>(inst->GetItemStr(true))},
|
||||
{STAT_WIS, static_cast<uint32>(inst->GetItemWis(true))},
|
||||
{STAT_COLD, static_cast<uint32>(inst->GetItemCR(true))},
|
||||
{STAT_DISEASE, static_cast<uint32>(inst->GetItemDR(true))},
|
||||
{STAT_FIRE, static_cast<uint32>(inst->GetItemFR(true))},
|
||||
{STAT_MAGIC, static_cast<uint32>(inst->GetItemMR(true))},
|
||||
{STAT_POISON, static_cast<uint32>(inst->GetItemPR(true))},
|
||||
{STAT_HP, static_cast<uint32>(inst->GetItemHP(true))},
|
||||
{STAT_MANA, static_cast<uint32>(inst->GetItemMana(true))},
|
||||
{STAT_ENDURANCE, static_cast<uint32>(inst->GetItemEndur(true))},
|
||||
{STAT_ATTACK, static_cast<uint32>(inst->GetItemAttack(true))},
|
||||
{STAT_HP_REGEN, static_cast<uint32>(inst->GetItemRegen(true))},
|
||||
{STAT_MANA_REGEN, static_cast<uint32>(inst->GetItemManaRegen(true))},
|
||||
{STAT_HASTE, static_cast<uint32>(inst->GetItemHaste(true))},
|
||||
{STAT_DAMAGE_SHIELD, static_cast<uint32>(inst->GetItemDamageShield(true))},
|
||||
{STAT_DS_MITIGATION, static_cast<uint32>(inst->GetItemDSMitigation(true))},
|
||||
{STAT_HEAL_AMOUNT, static_cast<uint32>(inst->GetItemHealAmt(true))},
|
||||
{STAT_SPELL_DAMAGE, static_cast<uint32>(inst->GetItemSpellDamage(true))},
|
||||
{STAT_CLAIRVOYANCE, static_cast<uint32>(inst->GetItemClairvoyance(true))},
|
||||
{STAT_HEROIC_AGILITY, static_cast<uint32>(inst->GetItemHeroicAgi(true))},
|
||||
{STAT_HEROIC_CHARISMA, static_cast<uint32>(inst->GetItemHeroicCha(true))},
|
||||
{STAT_HEROIC_DEXTERITY, static_cast<uint32>(inst->GetItemHeroicDex(true))},
|
||||
{STAT_HEROIC_INTELLIGENCE, static_cast<uint32>(inst->GetItemHeroicInt(true))},
|
||||
{STAT_HEROIC_STAMINA, static_cast<uint32>(inst->GetItemHeroicSta(true))},
|
||||
{STAT_HEROIC_STRENGTH, static_cast<uint32>(inst->GetItemHeroicStr(true))},
|
||||
{STAT_HEROIC_WISDOM, static_cast<uint32>(inst->GetItemHeroicWis(true))},
|
||||
{STAT_BASH, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillBash, true))},
|
||||
{STAT_BACKSTAB, static_cast<uint32>(inst->GetItemBackstabDamage(true))},
|
||||
{STAT_DRAGON_PUNCH, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillDragonPunch, true))},
|
||||
{STAT_EAGLE_STRIKE, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillEagleStrike, true))},
|
||||
{STAT_FLYING_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillFlyingKick, true))},
|
||||
{STAT_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillKick, true))},
|
||||
{STAT_ROUND_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillRoundKick, true))},
|
||||
{STAT_TIGER_CLAW, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillTigerClaw, true))},
|
||||
{STAT_FRENZY, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillFrenzy, true))},
|
||||
};
|
||||
|
||||
r.item_stat = item_stat_searches.contains(search.item_stat) ? item_stat_searches[search.item_stat] : 0;
|
||||
if (item_stat_searches.contains(search.item_stat) && item_stat_searches[search.item_stat] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
static std::map<uint8, uint32> item_slot_searches = {
|
||||
{EQ::invslot::slotCharm, 1},
|
||||
{EQ::invslot::slotEar1, 2},
|
||||
{EQ::invslot::slotHead, 4},
|
||||
{EQ::invslot::slotFace, 8},
|
||||
{EQ::invslot::slotEar2, 16},
|
||||
{EQ::invslot::slotNeck, 32},
|
||||
{EQ::invslot::slotShoulders, 64},
|
||||
{EQ::invslot::slotArms, 128},
|
||||
{EQ::invslot::slotBack, 256},
|
||||
{EQ::invslot::slotWrist1, 512},
|
||||
{EQ::invslot::slotWrist2, 1024},
|
||||
{EQ::invslot::slotRange, 2048},
|
||||
{EQ::invslot::slotHands, 4096},
|
||||
{EQ::invslot::slotPrimary, 8192},
|
||||
{EQ::invslot::slotSecondary, 16384},
|
||||
{EQ::invslot::slotFinger1, 32768},
|
||||
{EQ::invslot::slotFinger2, 65536},
|
||||
{EQ::invslot::slotChest, 131072},
|
||||
{EQ::invslot::slotLegs, 262144},
|
||||
{EQ::invslot::slotFeet, 524288},
|
||||
{EQ::invslot::slotWaist, 1048576},
|
||||
{EQ::invslot::slotPowerSource, 2097152},
|
||||
{EQ::invslot::slotAmmo, 4194304},
|
||||
};
|
||||
|
||||
auto GetEquipmentSlotBit = [&](uint32 slot) -> uint32 {
|
||||
return item_slot_searches.contains(slot) ? item_slot_searches[slot] : 0;
|
||||
};
|
||||
|
||||
auto FindItemAugSlot = [&]() -> bool {
|
||||
for (auto const &s: inst->GetItem()->AugSlotType) {
|
||||
return s == search.augment;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// item type searches
|
||||
std::vector<ItemSearchType> item_search_types = {
|
||||
{EQ::item::ItemType::ItemTypeAll, true},
|
||||
{EQ::item::ItemType::ItemTypeBook, item->ItemClass == EQ::item::ItemType::ItemTypeBook},
|
||||
{EQ::item::ItemType::ItemTypeContainer, item->ItemClass == EQ::item::ItemType::ItemTypeContainer ||
|
||||
item->IsClassBag()},
|
||||
{EQ::item::ItemType::ItemTypeAllEffects, item->Scroll.Effect > 0 && item->Scroll.Effect < 65000},
|
||||
{EQ::item::ItemType::ItemTypeUnknown9, item->Worn.Effect == 998},
|
||||
{EQ::item::ItemType::ItemTypeUnknown10, item->Worn.Effect >= 1298 && item->Worn.Effect <= 1307},
|
||||
{EQ::item::ItemType::ItemTypeFocusEffect, item->Focus.Effect > 0},
|
||||
{EQ::item::ItemType::ItemTypeArmor, item->ItemType == EQ::item::ItemType::ItemTypeArmor},
|
||||
{EQ::item::ItemType::ItemType1HBlunt, item->ItemType == EQ::item::ItemType::ItemType1HBlunt},
|
||||
{EQ::item::ItemType::ItemType1HPiercing, item->ItemType == EQ::item::ItemType::ItemType1HPiercing},
|
||||
{EQ::item::ItemType::ItemType1HSlash, item->ItemType == EQ::item::ItemType::ItemType1HSlash},
|
||||
{EQ::item::ItemType::ItemType2HBlunt, item->ItemType == EQ::item::ItemType::ItemType2HBlunt},
|
||||
{EQ::item::ItemType::ItemType2HSlash, item->ItemType == EQ::item::ItemType::ItemType2HSlash},
|
||||
{EQ::item::ItemType::ItemTypeBow, item->ItemType == EQ::item::ItemType::ItemTypeBow},
|
||||
{EQ::item::ItemType::ItemTypeShield, item->ItemType == EQ::item::ItemType::ItemTypeShield},
|
||||
{EQ::item::ItemType::ItemTypeMisc, item->ItemType == EQ::item::ItemType::ItemTypeMisc},
|
||||
{EQ::item::ItemType::ItemTypeFood, item->ItemType == EQ::item::ItemType::ItemTypeFood},
|
||||
{EQ::item::ItemType::ItemTypeDrink, item->ItemType == EQ::item::ItemType::ItemTypeDrink},
|
||||
{EQ::item::ItemType::ItemTypeLight, item->ItemType == EQ::item::ItemType::ItemTypeLight},
|
||||
{EQ::item::ItemType::ItemTypeCombinable, item->ItemType == EQ::item::ItemType::ItemTypeCombinable},
|
||||
{EQ::item::ItemType::ItemTypeBandage, item->ItemType == EQ::item::ItemType::ItemTypeBandage},
|
||||
{EQ::item::ItemType::ItemTypeSmallThrowing, item->ItemType == EQ::item::ItemType::ItemTypeSmallThrowing ||
|
||||
item->ItemType == EQ::item::ItemType::ItemTypeLargeThrowing},
|
||||
{EQ::item::ItemType::ItemTypeSpell, item->ItemType == EQ::item::ItemType::ItemTypeSpell},
|
||||
{EQ::item::ItemType::ItemTypePotion, item->ItemType == EQ::item::ItemType::ItemTypePotion},
|
||||
{EQ::item::ItemType::ItemTypeBrassInstrument, item->ItemType == EQ::item::ItemType::ItemTypeBrassInstrument},
|
||||
{EQ::item::ItemType::ItemTypeWindInstrument, item->ItemType == EQ::item::ItemType::ItemTypeWindInstrument},
|
||||
{EQ::item::ItemType::ItemTypeStringedInstrument, item->ItemType == EQ::item::ItemType::ItemTypeStringedInstrument},
|
||||
{EQ::item::ItemType::ItemTypePercussionInstrument, item->ItemType == EQ::item::ItemType::ItemTypePercussionInstrument},
|
||||
{EQ::item::ItemType::ItemTypeArrow, item->ItemType == EQ::item::ItemType::ItemTypeArrow},
|
||||
{EQ::item::ItemType::ItemTypeJewelry, item->ItemType == EQ::item::ItemType::ItemTypeJewelry},
|
||||
{EQ::item::ItemType::ItemTypeNote, item->ItemType == EQ::item::ItemType::ItemTypeNote},
|
||||
{EQ::item::ItemType::ItemTypeKey, item->ItemType == EQ::item::ItemType::ItemTypeKey},
|
||||
{EQ::item::ItemType::ItemType2HPiercing, item->ItemType == EQ::item::ItemType::ItemType2HPiercing},
|
||||
{EQ::item::ItemType::ItemTypeAlcohol, item->ItemType == EQ::item::ItemType::ItemTypeAlcohol},
|
||||
{EQ::item::ItemType::ItemTypeMartial, item->ItemType == EQ::item::ItemType::ItemTypeMartial},
|
||||
{EQ::item::ItemType::ItemTypeAugmentation, item->ItemType == EQ::item::ItemType::ItemTypeAugmentation},
|
||||
{EQ::item::ItemType::ItemTypeAlternateAbility, item->ItemType == EQ::item::ItemType::ItemTypeAlternateAbility},
|
||||
{EQ::item::ItemType::ItemTypeCount, item->ItemType == EQ::item::ItemType::ItemTypeCount},
|
||||
{EQ::item::ItemType::ItemTypeCollectible, item->ItemType == EQ::item::ItemType::ItemTypeCollectible}
|
||||
};
|
||||
|
||||
bool met_filter = false;
|
||||
bool has_filter = false;
|
||||
|
||||
for (auto &i: item_search_types) {
|
||||
if (i.type == search.type) {
|
||||
has_filter = true;
|
||||
if (i.condition) {
|
||||
LogTradingDetail("Item [{}] met search criteria for type [{}]", item->Name, uint8(i.type));
|
||||
met_filter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has_filter && !met_filter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Add catch-all item type filter for specific item types
|
||||
|
||||
// item additive searches
|
||||
std::vector<AddititiveSearchCriteria> item_additive_searches = {
|
||||
{
|
||||
.should_check = search.min_level != 1 && inst->GetItemRequiredLevel(true) > 0,
|
||||
.condition = inst->GetItemRequiredLevel(true) >= search.min_level
|
||||
},
|
||||
{
|
||||
.should_check = search.max_level != 1 && inst->GetItemRequiredLevel(true) > 0,
|
||||
.condition = inst->GetItemRequiredLevel(true) <= search.max_level
|
||||
},
|
||||
{
|
||||
.should_check = !std::string(search.item_name).empty(),
|
||||
.condition = Strings::ContainsLower(item->Name, search.item_name)
|
||||
},
|
||||
{
|
||||
.should_check = search._class != 0xFFFFFFFF,
|
||||
.condition = static_cast<bool>(item->Classes & GetPlayerClassBit(search._class))
|
||||
},
|
||||
{
|
||||
.should_check = search.race != 0xFFFFFFFF,
|
||||
.condition = static_cast<bool>(item->Races & GetPlayerRaceBit(GetRaceIDFromPlayerRaceValue(search.race)))
|
||||
},
|
||||
{
|
||||
.should_check = search.augment != 0,
|
||||
.condition = FindItemAugSlot()
|
||||
},
|
||||
{
|
||||
.should_check = search.slot != 0xFFFFFFFF,
|
||||
.condition = static_cast<bool>(item->Slots & GetEquipmentSlotBit(search.slot))
|
||||
},
|
||||
};
|
||||
|
||||
bool should_add = true;
|
||||
|
||||
for (auto &i: item_additive_searches) {
|
||||
LogTradingDetail(
|
||||
"Checking item [{}] for search criteria - should_check [{}] condition [{}]",
|
||||
item->Name,
|
||||
i.should_check,
|
||||
i.condition
|
||||
);
|
||||
if (i.should_check && !i.condition) {
|
||||
should_add = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!should_add) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LogTradingDetail("Found item [{}] meeting search criteria.", r.item_name);
|
||||
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,14 @@
|
||||
#ifndef EQEMU_BAZAAR_H
|
||||
#define EQEMU_BAZAAR_H
|
||||
|
||||
#include <vector>
|
||||
#include "shareddb.h"
|
||||
|
||||
class Bazaar {
|
||||
public:
|
||||
static std::vector<BazaarSearchResultsFromDB_Struct>
|
||||
GetSearchResults(SharedDatabase &db, BazaarSearchCriteria_Struct search, unsigned int char_zone_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();
|
||||
}
|
||||
+91
-45
@@ -18,50 +18,96 @@
|
||||
#ifndef BODYTYPES_H
|
||||
#define BODYTYPES_H
|
||||
|
||||
typedef enum {
|
||||
BT_Humanoid = 1,
|
||||
BT_Lycanthrope = 2,
|
||||
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 */
|
||||
#include "types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// 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
|
||||
|
||||
+296
-473
File diff suppressed because it is too large
Load Diff
+96
-93
@@ -19,99 +19,106 @@
|
||||
#define CLASSES_CH
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#define NO_CLASS 0
|
||||
#define WARRIOR 1
|
||||
#define CLERIC 2
|
||||
#define PALADIN 3
|
||||
#define RANGER 4
|
||||
#define SHADOWKNIGHT 5
|
||||
#define DRUID 6
|
||||
#define MONK 7
|
||||
#define BARD 8
|
||||
#define ROGUE 9
|
||||
#define SHAMAN 10
|
||||
#define NECROMANCER 11
|
||||
#define WIZARD 12
|
||||
#define MAGICIAN 13
|
||||
#define ENCHANTER 14
|
||||
#define BEASTLORD 15
|
||||
#define BERSERKER 16
|
||||
#define WARRIORGM 20
|
||||
#define CLERICGM 21
|
||||
#define PALADINGM 22
|
||||
#define RANGERGM 23
|
||||
#define SHADOWKNIGHTGM 24
|
||||
#define DRUIDGM 25
|
||||
#define MONKGM 26
|
||||
#define BARDGM 27
|
||||
#define ROGUEGM 28
|
||||
#define SHAMANGM 29
|
||||
#define NECROMANCERGM 30
|
||||
#define WIZARDGM 31
|
||||
#define MAGICIANGM 32
|
||||
#define ENCHANTERGM 33
|
||||
#define BEASTLORDGM 34
|
||||
#define BERSERKERGM 35
|
||||
#define BANKER 40
|
||||
#define MERCHANT 41
|
||||
#define DISCORD_MERCHANT 59
|
||||
#define ADVENTURE_RECRUITER 60
|
||||
#define ADVENTURE_MERCHANT 61
|
||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
|
||||
#define TRIBUTE_MASTER 63
|
||||
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
||||
#define GUILD_BANKER 66
|
||||
#define NORRATHS_KEEPERS_MERCHANT 67
|
||||
#define DARK_REIGN_MERCHANT 68
|
||||
#define FELLOWSHIP_MASTER 69
|
||||
#define ALT_CURRENCY_MERCHANT 70
|
||||
#define MERCENARY_MASTER 71
|
||||
namespace Class {
|
||||
constexpr uint8 None = 0;
|
||||
constexpr uint8 Warrior = 1;
|
||||
constexpr uint8 Cleric = 2;
|
||||
constexpr uint8 Paladin = 3;
|
||||
constexpr uint8 Ranger = 4;
|
||||
constexpr uint8 ShadowKnight = 5;
|
||||
constexpr uint8 Druid = 6;
|
||||
constexpr uint8 Monk = 7;
|
||||
constexpr uint8 Bard = 8;
|
||||
constexpr uint8 Rogue = 9;
|
||||
constexpr uint8 Shaman = 10;
|
||||
constexpr uint8 Necromancer = 11;
|
||||
constexpr uint8 Wizard = 12;
|
||||
constexpr uint8 Magician = 13;
|
||||
constexpr uint8 Enchanter = 14;
|
||||
constexpr uint8 Beastlord = 15;
|
||||
constexpr uint8 Berserker = 16;
|
||||
constexpr uint8 WarriorGM = 20;
|
||||
constexpr uint8 ClericGM = 21;
|
||||
constexpr uint8 PaladinGM = 22;
|
||||
constexpr uint8 RangerGM = 23;
|
||||
constexpr uint8 ShadowKnightGM = 24;
|
||||
constexpr uint8 DruidGM = 25;
|
||||
constexpr uint8 MonkGM = 26;
|
||||
constexpr uint8 BardGM = 27;
|
||||
constexpr uint8 RogueGM = 28;
|
||||
constexpr uint8 ShamanGM = 29;
|
||||
constexpr uint8 NecromancerGM = 30;
|
||||
constexpr uint8 WizardGM = 31;
|
||||
constexpr uint8 MagicianGM = 32;
|
||||
constexpr uint8 EnchanterGM = 33;
|
||||
constexpr uint8 BeastlordGM = 34;
|
||||
constexpr uint8 BerserkerGM = 35;
|
||||
constexpr uint8 Banker = 40;
|
||||
constexpr uint8 Merchant = 41;
|
||||
constexpr uint8 DiscordMerchant = 59;
|
||||
constexpr uint8 AdventureRecruiter = 60;
|
||||
constexpr uint8 AdventureMerchant = 61;
|
||||
constexpr uint8 LDoNTreasure = 62;
|
||||
constexpr uint8 TributeMaster = 63;
|
||||
constexpr uint8 GuildTributeMaster = 64;
|
||||
constexpr uint8 GuildBanker = 66;
|
||||
constexpr uint8 NorrathsKeepersMerchant = 67;
|
||||
constexpr uint8 DarkReignMerchant = 68;
|
||||
constexpr uint8 FellowshipMaster = 69;
|
||||
constexpr uint8 AlternateCurrencyMerchant = 70;
|
||||
constexpr uint8 MercenaryLiaison = 71;
|
||||
|
||||
constexpr uint8 PLAYER_CLASS_COUNT = 16;
|
||||
constexpr uint16 ALL_CLASSES_BITMASK = 65535;
|
||||
};
|
||||
|
||||
// player class values
|
||||
#define PLAYER_CLASS_UNKNOWN 0
|
||||
#define PLAYER_CLASS_WARRIOR 1
|
||||
#define PLAYER_CLASS_CLERIC 2
|
||||
#define PLAYER_CLASS_PALADIN 3
|
||||
#define PLAYER_CLASS_RANGER 4
|
||||
#define PLAYER_CLASS_SHADOWKNIGHT 5
|
||||
#define PLAYER_CLASS_DRUID 6
|
||||
#define PLAYER_CLASS_MONK 7
|
||||
#define PLAYER_CLASS_BARD 8
|
||||
#define PLAYER_CLASS_ROGUE 9
|
||||
#define PLAYER_CLASS_SHAMAN 10
|
||||
#define PLAYER_CLASS_NECROMANCER 11
|
||||
#define PLAYER_CLASS_WIZARD 12
|
||||
#define PLAYER_CLASS_MAGICIAN 13
|
||||
#define PLAYER_CLASS_ENCHANTER 14
|
||||
#define PLAYER_CLASS_BEASTLORD 15
|
||||
#define PLAYER_CLASS_BERSERKER 16
|
||||
static std::map<uint8, uint16> player_class_bitmasks = {
|
||||
{Class::Warrior, 1},
|
||||
{Class::Cleric, 2},
|
||||
{Class::Paladin, 4},
|
||||
{Class::Ranger, 8},
|
||||
{Class::ShadowKnight, 16},
|
||||
{Class::Druid, 32},
|
||||
{Class::Monk, 64},
|
||||
{Class::Bard, 128},
|
||||
{Class::Rogue, 256},
|
||||
{Class::Shaman, 512},
|
||||
{Class::Necromancer, 1024},
|
||||
{Class::Wizard, 2048},
|
||||
{Class::Magician, 4096},
|
||||
{Class::Enchanter, 8192},
|
||||
{Class::Beastlord, 16384},
|
||||
{Class::Berserker, 32768},
|
||||
};
|
||||
|
||||
#define PLAYER_CLASS_COUNT 16
|
||||
static std::string shadow_knight_class_name = (
|
||||
RuleB(World, UseOldShadowKnightClassExport) ?
|
||||
"Shadowknight" :
|
||||
"Shadow Knight"
|
||||
);
|
||||
|
||||
|
||||
// player class bits
|
||||
#define PLAYER_CLASS_UNKNOWN_BIT 0
|
||||
#define PLAYER_CLASS_WARRIOR_BIT 1
|
||||
#define PLAYER_CLASS_CLERIC_BIT 2
|
||||
#define PLAYER_CLASS_PALADIN_BIT 4
|
||||
#define PLAYER_CLASS_RANGER_BIT 8
|
||||
#define PLAYER_CLASS_SHADOWKNIGHT_BIT 16
|
||||
#define PLAYER_CLASS_DRUID_BIT 32
|
||||
#define PLAYER_CLASS_MONK_BIT 64
|
||||
#define PLAYER_CLASS_BARD_BIT 128
|
||||
#define PLAYER_CLASS_ROGUE_BIT 256
|
||||
#define PLAYER_CLASS_SHAMAN_BIT 512
|
||||
#define PLAYER_CLASS_NECROMANCER_BIT 1024
|
||||
#define PLAYER_CLASS_WIZARD_BIT 2048
|
||||
#define PLAYER_CLASS_MAGICIAN_BIT 4096
|
||||
#define PLAYER_CLASS_ENCHANTER_BIT 8192
|
||||
#define PLAYER_CLASS_BEASTLORD_BIT 16384
|
||||
#define PLAYER_CLASS_BERSERKER_BIT 32768
|
||||
|
||||
#define PLAYER_CLASS_ALL_MASK 65535 // was 65536
|
||||
static std::map<uint8, std::string> class_names = {
|
||||
{Class::Warrior, "Warrior"},
|
||||
{Class::Cleric, "Cleric"},
|
||||
{Class::Paladin, "Paladin"},
|
||||
{Class::Ranger, "Ranger"},
|
||||
{Class::ShadowKnight, shadow_knight_class_name},
|
||||
{Class::Druid, "Druid"},
|
||||
{Class::Monk, "Monk"},
|
||||
{Class::Bard, "Bard"},
|
||||
{Class::Rogue, "Rogue"},
|
||||
{Class::Shaman, "Shaman"},
|
||||
{Class::Necromancer, "Necromancer"},
|
||||
{Class::Wizard, "Wizard"},
|
||||
{Class::Magician, "Magician"},
|
||||
{Class::Enchanter, "Enchanter"},
|
||||
{Class::Beastlord, "Beastlord"},
|
||||
{Class::Berserker, "Berserker"},
|
||||
};
|
||||
|
||||
|
||||
#define ARMOR_TYPE_UNKNOWN 0
|
||||
@@ -126,16 +133,12 @@
|
||||
|
||||
|
||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
||||
|
||||
bool IsPlayerClass(uint8 class_id);
|
||||
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
||||
|
||||
uint32 GetPlayerClassValue(uint8 class_id);
|
||||
uint32 GetPlayerClassBit(uint8 class_id);
|
||||
|
||||
uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value);
|
||||
uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
||||
uint8 GetPlayerClassValue(uint8 class_id);
|
||||
uint16 GetPlayerClassBit(uint8 class_id);
|
||||
|
||||
bool IsFighterClass(uint8 class_id);
|
||||
bool IsSpellFighterClass(uint8 class_id);
|
||||
|
||||
@@ -1,29 +1,12 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "world_content_service.h"
|
||||
|
||||
#include <utility>
|
||||
#include <glm/vec3.hpp>
|
||||
#include "../database.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../loottable.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
#include "../zone_store.h"
|
||||
|
||||
|
||||
WorldContentService::WorldContentService()
|
||||
@@ -120,7 +103,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
||||
/**
|
||||
* @param content_flags
|
||||
*/
|
||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags)
|
||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags> &content_flags)
|
||||
{
|
||||
WorldContentService::content_flags = content_flags;
|
||||
}
|
||||
@@ -168,14 +151,14 @@ bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
|
||||
}
|
||||
|
||||
// if we don't have any enabled flag in enabled flags, we fail
|
||||
for (const auto& flag: Strings::Split(f.content_flags)) {
|
||||
for (const auto &flag: Strings::Split(f.content_flags)) {
|
||||
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have any disabled flag in disabled flags, we fail
|
||||
for (const auto& flag: Strings::Split(f.content_flags_disabled)) {
|
||||
for (const auto &flag: Strings::Split(f.content_flags_disabled)) {
|
||||
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
@@ -196,11 +179,13 @@ void WorldContentService::ReloadContentFlags()
|
||||
LogInfo(
|
||||
"Loaded content flag [{}] [{}]",
|
||||
f.flag_name,
|
||||
(f.enabled ? "Enabled" : "Disabled")
|
||||
(f.enabled ? "enabled" : "disabled")
|
||||
);
|
||||
}
|
||||
|
||||
SetContentFlags(set_content_flags);
|
||||
LoadStaticGlobalZoneInstances();
|
||||
zone_store.LoadZones(*m_content_database);
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetDatabase() const
|
||||
@@ -215,6 +200,18 @@ WorldContentService *WorldContentService::SetDatabase(Database *database)
|
||||
return this;
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetContentDatabase() const
|
||||
{
|
||||
return m_content_database;
|
||||
}
|
||||
|
||||
WorldContentService *WorldContentService::SetContentDatabase(Database *database)
|
||||
{
|
||||
WorldContentService::m_content_database = database;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
|
||||
{
|
||||
auto flags = ContentFlagsRepository::GetWhere(
|
||||
@@ -239,3 +236,114 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
||||
|
||||
ReloadContentFlags();
|
||||
}
|
||||
|
||||
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
||||
{
|
||||
auto r = FindZone(zc->zoneID, zc->instanceID);
|
||||
if (r.zone_id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
zc->instanceID = r.instance.id;
|
||||
}
|
||||
|
||||
// LoadStaticGlobalZoneInstances loads all static global zone instances
|
||||
// these are zones that are never set to expire and are global
|
||||
// these are used commonly in v1/v2/v3 versions of the same zone for expansion routing
|
||||
WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
|
||||
{
|
||||
m_zone_static_instances = InstanceListRepository::GetWhere(
|
||||
*GetDatabase(),
|
||||
fmt::format("never_expires = 1 AND is_global = 1")
|
||||
);
|
||||
|
||||
LogInfo("Loaded [{}] zone_instances", m_zone_static_instances.size());
|
||||
|
||||
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(
|
||||
"Routed player to public static instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
||||
i.id,
|
||||
z.short_name,
|
||||
z.zoneidnumber,
|
||||
z.version,
|
||||
z.long_name,
|
||||
i.notes
|
||||
);
|
||||
|
||||
return WorldContentService::FindZoneResult{
|
||||
.zone_id = static_cast<uint32>(z.zoneidnumber),
|
||||
.instance = i,
|
||||
.zone = z
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WorldContentService::FindZoneResult{.zone_id = 0};
|
||||
}
|
||||
|
||||
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
|
||||
{
|
||||
for (auto &i: m_zone_static_instances) {
|
||||
if (i.id == instance_id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,33 +1,21 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../loottable.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
#include "../repositories/zone_repository.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
|
||||
class Database;
|
||||
|
||||
struct ContentFlags {
|
||||
int16 min_expansion;
|
||||
int16 max_expansion;
|
||||
std::string content_flags;
|
||||
std::string content_flags_disabled;
|
||||
};
|
||||
|
||||
namespace Expansion {
|
||||
static const int EXPANSION_ALL = -1;
|
||||
static const int EXPANSION_FILTER_MAX = 99;
|
||||
@@ -172,18 +160,38 @@ public:
|
||||
WorldContentService * SetExpansionContext();
|
||||
|
||||
bool DoesPassContentFiltering(const ContentFlags& f);
|
||||
bool DoesZonePassContentFiltering(const ZoneRepository::Zone& z);
|
||||
|
||||
WorldContentService * SetDatabase(Database *database);
|
||||
Database *GetDatabase() const;
|
||||
|
||||
WorldContentService * SetContentDatabase(Database *database);
|
||||
Database *GetContentDatabase() const;
|
||||
|
||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
||||
|
||||
void HandleZoneRoutingMiddleware(ZoneChange_Struct *zc);
|
||||
|
||||
struct FindZoneResult {
|
||||
uint32 zone_id = 0;
|
||||
InstanceListRepository::InstanceList instance;
|
||||
ZoneRepository::Zone zone;
|
||||
};
|
||||
|
||||
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
|
||||
bool IsInPublicStaticInstance(uint32 instance_id);
|
||||
|
||||
private:
|
||||
int current_expansion{};
|
||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||
|
||||
// reference to database
|
||||
Database *m_database;
|
||||
Database *m_content_database;
|
||||
|
||||
// holds a record of the zone table from the database
|
||||
WorldContentService *LoadStaticGlobalZoneInstances();
|
||||
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
|
||||
};
|
||||
|
||||
extern WorldContentService content_service;
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#if WINDOWS
|
||||
#ifdef _WINDOWS
|
||||
#define popen _popen
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@ void SendCrashReport(const std::string &crash_report)
|
||||
{
|
||||
// can configure multiple endpoints if need be
|
||||
std::vector<std::string> endpoints = {
|
||||
"http://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
"https://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||
};
|
||||
|
||||
|
||||
+1339
-1652
File diff suppressed because it is too large
Load Diff
+152
-144
@@ -18,8 +18,8 @@
|
||||
#ifndef EQEMU_DATABASE_H
|
||||
#define EQEMU_DATABASE_H
|
||||
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
|
||||
#include "global_define.h"
|
||||
#include "eqemu_logsys.h"
|
||||
@@ -38,8 +38,7 @@
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace EQ {
|
||||
class InventoryProfile;
|
||||
}
|
||||
|
||||
@@ -52,10 +51,11 @@ struct npcDecayTimes_Struct {
|
||||
|
||||
struct VarCache_Struct {
|
||||
std::map<std::string, std::string> m_cache;
|
||||
uint32 last_update;
|
||||
uint32 last_update;
|
||||
VarCache_Struct() : last_update(0) { }
|
||||
void Add(const std::string &key, const std::string &value) { m_cache[key] = value; }
|
||||
const std::string *Get(const std::string &key) {
|
||||
void Add(const std::string& key, const std::string& value) { m_cache[key] = value; }
|
||||
const std::string* Get(const std::string& key)
|
||||
{
|
||||
auto it = m_cache.find(key);
|
||||
return (it != m_cache.end() ? &it->second : nullptr);
|
||||
}
|
||||
@@ -76,37 +76,33 @@ class PTimerList;
|
||||
|
||||
#define SQL(...) #__VA_ARGS__
|
||||
|
||||
class LogSettings;
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port, std::string connection_label = "default");
|
||||
Database(
|
||||
const std::string& host,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
const std::string& database,
|
||||
uint32 port
|
||||
);
|
||||
bool Connect(
|
||||
const std::string& host,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
const std::string& database,
|
||||
uint32 port,
|
||||
std::string connection_label = "default"
|
||||
);
|
||||
~Database();
|
||||
|
||||
/* Character Creation */
|
||||
|
||||
bool CreateCharacter(
|
||||
uint32 account_id,
|
||||
char *name,
|
||||
uint16 gender,
|
||||
uint16 race,
|
||||
uint16 class_,
|
||||
uint8 str,
|
||||
uint8 sta,
|
||||
uint8 cha,
|
||||
uint8 dex,
|
||||
uint8 int_,
|
||||
uint8 agi,
|
||||
uint8 wis,
|
||||
uint8 face
|
||||
);
|
||||
bool DeleteCharacter(char *character_name);
|
||||
bool MoveCharacterToZone(const char *charname, uint32 zone_id);
|
||||
bool DeleteCharacter(const std::string& name);
|
||||
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
|
||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||
bool ReserveName(uint32 account_id, char *name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||
bool UpdateName(const char *oldname, const char *newname);
|
||||
bool ReserveName(uint32 account_id, const std::string& name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
bool UpdateName(const std::string& old_name, const std::string& new_name);
|
||||
bool CopyCharacter(
|
||||
const std::string& source_character_name,
|
||||
const std::string& destination_character_name,
|
||||
@@ -114,165 +110,177 @@ public:
|
||||
);
|
||||
|
||||
/* General Information Queries */
|
||||
bool AddBannedIP(const std::string& banned_ip, const std::string& notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(const std::string& name);
|
||||
bool CheckBannedIPs(const std::string& login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(const std::string& login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(const std::string& name, bool surname = false);
|
||||
bool IsNameUsed(const std::string& name);
|
||||
|
||||
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(std::string name);
|
||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(std::string name, bool surname = false);
|
||||
bool CheckUsedName(std::string name);
|
||||
uint32 GetAccountIDByChar(const std::string& name, uint32* character_id = 0);
|
||||
uint32 GetAccountIDByChar(uint32 character_id);
|
||||
uint32 GetAccountIDByName(const std::string& account_name, const std::string& loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const std::string& name);
|
||||
uint32 GetGuildIDByCharID(uint32 character_id);
|
||||
uint32 GetGroupIDByCharID(uint32 character_id);
|
||||
uint32 GetRaidIDByCharID(uint32 character_id);
|
||||
|
||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||
uint32 GetAccountIDByChar(uint32 char_id);
|
||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const char *name);
|
||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
std::string GetCharNameByID(uint32 char_id);
|
||||
std::string GetNPCNameByID(uint32 npc_id);
|
||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, std::string login_ip);
|
||||
const std::string GetAccountName(uint32 account_id, uint32* lsaccount_id = 0);
|
||||
const std::string GetCharName(uint32 character_id);
|
||||
const std::string GetCharNameByID(uint32 character_id);
|
||||
const std::string GetNPCNameByID(uint32 npc_id);
|
||||
const std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, const std::string& login_ip);
|
||||
|
||||
/* Instancing */
|
||||
|
||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceExists(uint16 instance_id);
|
||||
bool CheckInstanceExpired(uint16 instance_id);
|
||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
||||
bool GetUnusedInstanceID(uint16 &instance_id);
|
||||
bool GetUnusedInstanceID(uint16& instance_id);
|
||||
bool IsGlobalInstance(uint16 instance_id);
|
||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||
bool RemoveClientsFromInstance(uint16 instance_id);
|
||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
||||
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||
|
||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||
uint16 GetInstanceID(uint32 zone, uint32 character_id, int16 version);
|
||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
||||
uint8_t GetInstanceVersion(uint16 instance_id);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool& is_perma);
|
||||
uint32 GetInstanceZoneID(uint16 instance_id);
|
||||
|
||||
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
||||
void AssignGroupToInstance(uint32 group_id, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 raid_id, uint32 instance_id);
|
||||
void DeleteInstance(uint16 instance_id);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32>& character_ids);
|
||||
void PurgeExpiredInstances();
|
||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||
void CleanupInstanceCorpses();
|
||||
|
||||
/* Adventure related. */
|
||||
|
||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win = false, bool remove = false);
|
||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
||||
void UpdateAdventureStatsEntry(uint32 character_id, uint8 theme_id, bool is_win = false, bool is_remove = false);
|
||||
bool GetAdventureStats(uint32 character_id, AdventureStats_Struct* as);
|
||||
|
||||
/* Account Related */
|
||||
const std::string GetLiveChar(uint32 account_id);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 account_id, const std::string& password);
|
||||
bool UpdateLiveChar(const std::string& name, uint32 account_id);
|
||||
int16 GetAccountStatus(uint32 account_id);
|
||||
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 CreateAccount(
|
||||
const std::string& name,
|
||||
const std::string& password,
|
||||
int16 status,
|
||||
const std::string& loginserver,
|
||||
uint32 lsaccount_id
|
||||
);
|
||||
uint32 GetAccountIDFromLSID(
|
||||
const std::string& in_loginserver_id,
|
||||
uint32 in_loginserver_account_id,
|
||||
char* in_account_name = 0,
|
||||
int16* in_status = 0
|
||||
);
|
||||
|
||||
bool DeleteAccount(const char *name, const char* loginserver);
|
||||
bool GetLiveChar(uint32 account_id, char* cname);
|
||||
bool SetAccountStatus(const char* name, int16 status);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 accid, const char* password);
|
||||
bool UpdateLiveChar(char* charname, uint32 account_id);
|
||||
uint8 GetAgreementFlag(uint32 account_id);
|
||||
void SetAgreementFlag(uint32 account_id);
|
||||
|
||||
int16 CheckStatus(uint32 account_id);
|
||||
int GetIPExemption(const std::string& account_ip);
|
||||
void SetIPExemption(const std::string& account_ip, int exemption_amount);
|
||||
|
||||
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
|
||||
|
||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||
uint8 GetAgreementFlag(uint32 acctid);
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 acctid);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
int GetInstanceID(uint32 character_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
|
||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
uint32 GetGroupID(const char* name);
|
||||
|
||||
void ClearGroup(uint32 gid = 0);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
||||
void SetGroupLeaderName(uint32 gid, const char* name);
|
||||
std::string GetGroupLeaderForLogin(const std::string& character_name);
|
||||
char* GetGroupLeadershipInfo(
|
||||
uint32 group_id,
|
||||
char* leaderbuf,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
char* mentoree = nullptr,
|
||||
int* mentor_percent = nullptr,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr
|
||||
);
|
||||
std::string GetGroupLeaderName(uint32 group_id);
|
||||
uint32 GetGroupID(const std::string& name);
|
||||
void ClearGroup(uint32 group_id = 0);
|
||||
void ClearGroupLeader(uint32 group_id = 0);
|
||||
void SetGroupLeaderName(uint32 group_id, const std::string& name);
|
||||
|
||||
/* Raids */
|
||||
const std::string GetRaidLeaderName(uint32 raid_id);
|
||||
uint32 GetRaidID(const std::string& name);
|
||||
void ClearRaid(uint32 raid_id = 0);
|
||||
void ClearRaidDetails(uint32 raid_id = 0);
|
||||
void ClearRaidLeader(uint32 group_id = std::numeric_limits<uint32>::max(), uint32 raid_id = 0);
|
||||
void GetGroupLeadershipInfo(
|
||||
uint32 group_id,
|
||||
uint32 raid_id,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
char* mentoree = nullptr,
|
||||
int* mentor_percent = nullptr,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr
|
||||
);
|
||||
void GetRaidLeadershipInfo(
|
||||
uint32 raid_id,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
RaidLeadershipAA_Struct* RLAA = nullptr
|
||||
);
|
||||
void SetRaidGroupLeaderInfo(uint32 group_id, uint32 raid_id);
|
||||
|
||||
const char *GetRaidLeaderName(uint32 rid);
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
void ClearGuildOnlineStatus();
|
||||
void ClearTraderDetails();
|
||||
void ClearBuyerDetails();
|
||||
|
||||
uint32 GetRaidID(const char* name);
|
||||
|
||||
void ClearRaid(uint32 rid = 0);
|
||||
void ClearRaidDetails(uint32 rid = 0);
|
||||
void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0);
|
||||
void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
|
||||
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
|
||||
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
|
||||
/* Database Conversions 'database_conversions.cpp' */
|
||||
|
||||
bool CheckDatabaseConversions();
|
||||
bool CheckDatabaseConvertCorpseDeblob();
|
||||
bool CheckDatabaseConvertPPDeblob();
|
||||
|
||||
/* Database Variables */
|
||||
bool GetVariable(const std::string& name, std::string& value);
|
||||
bool SetVariable(const std::string& name, const std::string& value);
|
||||
bool LoadVariables();
|
||||
|
||||
bool GetVariable(std::string varname, std::string &varvalue);
|
||||
bool SetVariable(const std::string& varname, const std::string &varvalue);
|
||||
bool LoadVariables();
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint32 GetServerType();
|
||||
void AddReport(const std::string& who, const std::string& against, const std::string& lines);
|
||||
struct TimeOfDay_Struct LoadTime(time_t& realtime);
|
||||
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||
void ClearMerchantTemp();
|
||||
void ClearPTimers(uint32 character_id);
|
||||
void SetFirstLogon(uint32 character_id, uint8 first_logon);
|
||||
void SetLFG(uint32 character_id, bool is_lfg);
|
||||
void SetLFP(uint32 character_id, bool is_lfp);
|
||||
void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon);
|
||||
|
||||
/* General Queries */
|
||||
int64 CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
|
||||
bool LoadPTimers(uint32 charid, PTimerList &into);
|
||||
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
|
||||
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
||||
uint8 GetServerType();
|
||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||
|
||||
void AddReport(std::string who, std::string against, std::string lines);
|
||||
struct TimeOfDay_Struct LoadTime(time_t &realtime);
|
||||
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||
void ClearMerchantTemp();
|
||||
void ClearPTimers(uint32 charid);
|
||||
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
|
||||
void SetLFG(uint32 CharID, bool LFG);
|
||||
void SetLFP(uint32 CharID, bool LFP);
|
||||
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
|
||||
|
||||
int CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
void SourceSqlFromUrl(std::string url);
|
||||
void SourceDatabaseTableFromUrl(const std::string& table_name, const std::string& url);
|
||||
void SourceSqlFromUrl(const std::string& url);
|
||||
void PurgeCharacterParcels();
|
||||
void Encode(std::string &in);
|
||||
void Decode(std::string &in);
|
||||
|
||||
private:
|
||||
|
||||
Mutex Mvarcache;
|
||||
Mutex Mvarcache;
|
||||
VarCache_Struct varcache;
|
||||
|
||||
/* Groups, utility methods. */
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
|
||||
/* Raid, utility methods. */
|
||||
void ClearAllRaids();
|
||||
|
||||
@@ -322,6 +322,10 @@ void DatabaseDumpService::DatabaseDump()
|
||||
pipe_file
|
||||
);
|
||||
|
||||
LogInfo("Backing up database [{}]", execute_command);
|
||||
LogInfo("This can take a few minutes depending on the size of your database");
|
||||
LogInfo("LOADING... PLEASE WAIT...");
|
||||
|
||||
BuildCredentialsFile();
|
||||
std::string execution_result = Process::execute(execute_command);
|
||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||
@@ -571,7 +575,12 @@ void DatabaseDumpService::RemoveSqlBackup()
|
||||
{
|
||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||
if (File::Exists(file)) {
|
||||
std::filesystem::remove(file);
|
||||
try {
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
LogError("std::filesystem::remove err [{}]", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
|
||||
@@ -76,9 +76,9 @@ void DatabaseUpdate::CheckDbUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
std::string DatabaseUpdate::GetQueryResult(std::string query)
|
||||
std::string DatabaseUpdate::GetQueryResult(const ManifestEntry& e)
|
||||
{
|
||||
auto results = m_database->QueryDatabase(query);
|
||||
auto results = (e.content_schema_update ? m_content_database : m_database)->QueryDatabase(e.check);
|
||||
|
||||
std::vector<std::string> result_lines = {};
|
||||
|
||||
@@ -121,6 +121,16 @@ bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_resu
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if we are running in a terminal
|
||||
bool is_atty()
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
return ::_isatty(_fileno(stdin));
|
||||
#else
|
||||
return isatty(fileno(stdin));
|
||||
#endif
|
||||
}
|
||||
|
||||
// return true if we ran updates
|
||||
bool DatabaseUpdate::UpdateManifest(
|
||||
std::vector<ManifestEntry> entries,
|
||||
@@ -136,7 +146,7 @@ bool DatabaseUpdate::UpdateManifest(
|
||||
for (auto &e: entries) {
|
||||
if (e.version == version) {
|
||||
bool has_migration = true;
|
||||
std::string r = GetQueryResult(e.check);
|
||||
std::string r = GetQueryResult(e);
|
||||
if (ShouldRunMigration(e, r)) {
|
||||
has_migration = false;
|
||||
missing_migrations.emplace_back(e.version);
|
||||
@@ -179,7 +189,7 @@ bool DatabaseUpdate::UpdateManifest(
|
||||
if (e.version == m) {
|
||||
bool errored_migration = false;
|
||||
|
||||
auto r = m_database->QueryDatabaseMulti(e.sql);
|
||||
auto r = (e.content_schema_update ? m_content_database : m_database)->QueryDatabaseMulti(e.sql);
|
||||
|
||||
// ignore empty query result "errors"
|
||||
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
||||
@@ -187,31 +197,38 @@ bool DatabaseUpdate::UpdateManifest(
|
||||
errored_migration = true;
|
||||
|
||||
LogInfo("Required database update failed. This could be a problem");
|
||||
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
||||
|
||||
// user input
|
||||
std::string input;
|
||||
bool gave_input = false;
|
||||
time_t start_time = time(nullptr);
|
||||
time_t wait_time_seconds = 60;
|
||||
// if terminal attached then prompt for skip
|
||||
if (is_atty()) {
|
||||
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
||||
|
||||
// spawn a concurrent thread that waits for input from std::cin
|
||||
std::thread t1(
|
||||
[&]() {
|
||||
std::cin >> input;
|
||||
gave_input = true;
|
||||
// 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));
|
||||
}
|
||||
);
|
||||
t1.detach();
|
||||
|
||||
// check the inputReceived flag once every 50ms for 10 seconds
|
||||
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
|
||||
// prompt for user skip
|
||||
if (Strings::Trim(input) == "y") {
|
||||
errored_migration = false;
|
||||
// prompt for user skip
|
||||
if (Strings::Trim(input) == "y") {
|
||||
errored_migration = false;
|
||||
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||
}
|
||||
} else {
|
||||
errored_migration = true;
|
||||
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||
}
|
||||
}
|
||||
@@ -247,6 +264,13 @@ DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
|
||||
return this;
|
||||
}
|
||||
|
||||
DatabaseUpdate *DatabaseUpdate::SetContentDatabase(Database *db)
|
||||
{
|
||||
m_content_database = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||
{
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
@@ -274,9 +298,9 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
// server database version is required
|
||||
bool server_up_to_date = v.server_database_version == b.server_database_version;
|
||||
bool server_up_to_date = v.server_database_version >= b.server_database_version;
|
||||
// bots database version is optional, if not enabled then it is always up-to-date
|
||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
|
||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version >= b.bots_database_version : true;
|
||||
|
||||
return server_up_to_date && bots_up_to_date;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct ManifestEntry {
|
||||
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
|
||||
};
|
||||
|
||||
struct DatabaseVersion {
|
||||
@@ -22,14 +23,16 @@ public:
|
||||
DatabaseVersion GetDatabaseVersions();
|
||||
DatabaseVersion GetBinaryDatabaseVersions();
|
||||
void CheckDbUpdates();
|
||||
std::string GetQueryResult(std::string query);
|
||||
std::string GetQueryResult(const ManifestEntry& e);
|
||||
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
|
||||
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
|
||||
|
||||
DatabaseUpdate *SetDatabase(Database *db);
|
||||
DatabaseUpdate *SetContentDatabase(Database *db);
|
||||
bool HasPendingUpdates();
|
||||
private:
|
||||
Database *m_database;
|
||||
Database *m_content_database;
|
||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
||||
void InjectBotsVersionColumn();
|
||||
};
|
||||
|
||||
@@ -4844,7 +4844,7 @@ UPDATE data_buckets SET bot_id = SUBSTRING_INDEX(SUBSTRING_INDEX( `key`, '-', 2
|
||||
ADD COLUMN `marked_npc_3_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_3_entity_id`,
|
||||
ADD COLUMN `marked_npc_3_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_3_zone_id`;
|
||||
)"
|
||||
},
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9235,
|
||||
.description = "2023_07_31_character_stats_record.sql",
|
||||
@@ -4947,7 +4947,7 @@ UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `cha
|
||||
.version = 9237,
|
||||
.description = "2023_10_15_import_13th_floor.sql",
|
||||
.check = "SHOW COLUMNS FROM `items` LIKE 'bardeffect';",
|
||||
.condition = "contains",
|
||||
.condition = "missing",
|
||||
.match = "mediumint",
|
||||
.sql = R"(
|
||||
ALTER TABLE `items`
|
||||
@@ -4997,7 +4997,879 @@ ADD PRIMARY KEY (`id`) USING BTREE,
|
||||
ADD UNIQUE INDEX(`varname`);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9241,
|
||||
.description = "2023_10_29_split_spawn2_enabled.sql",
|
||||
.check = "SHOW TABLES LIKE 'spawn2_disabled'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `spawn2_backup_2023_10_29` LIKE `spawn2`;
|
||||
INSERT INTO `spawn2_backup_2023_10_29` SELECT * FROM `spawn2`;
|
||||
CREATE TABLE `spawn2_disabled` (
|
||||
`id` bigint(11) NOT NULL AUTO_INCREMENT,
|
||||
`spawn2_id` int(11) DEFAULT NULL,
|
||||
`instance_id` int(11) DEFAULT 0,
|
||||
`disabled` smallint(11) DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `spawn2_id` (`spawn2_id`,`instance_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||
INSERT INTO spawn2_disabled (spawn2_id, disabled) SELECT id, 1 FROM spawn2 WHERE enabled = 0;
|
||||
ALTER TABLE `spawn2` DROP COLUMN `enabled`;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9242,
|
||||
.description = "2023_11_7_mintime_maxtime_spawnentry.sql",
|
||||
.check = "SHOW COLUMNS FROM `spawnentry` LIKE 'min_time'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `spawnentry`
|
||||
ADD COLUMN `min_time` smallint(4) NOT NULL DEFAULT 0 AFTER `condition_value_filter`,
|
||||
ADD COLUMN `max_time` smallint(4) NOT NULL DEFAULT 0 AFTER `min_time`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9243,
|
||||
.description = "2023_11_27_starting_items_revamp.sql",
|
||||
.check = "SHOW COLUMNS FROM `starting_items` LIKE 'race_list'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `starting_items_backup_9243` LIKE `starting_items`;
|
||||
INSERT INTO `starting_items_backup_9243` SELECT * FROM `starting_items`;
|
||||
|
||||
CREATE TABLE `starting_items_new` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`race_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
`class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
`deity_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
`zone_id_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`gm` mediumint(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`slot` mediumint(9) NOT NULL DEFAULT -1,
|
||||
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||
`content_flags` varchar(100) NULL,
|
||||
`content_flags_disabled` varchar(100) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
INSERT INTO
|
||||
`starting_items_new`
|
||||
(
|
||||
SELECT
|
||||
0 AS `id`,
|
||||
GROUP_CONCAT(DISTINCT `class` ORDER BY class ASC SEPARATOR '|') AS `class_list`,
|
||||
GROUP_CONCAT(DISTINCT `race` ORDER BY race ASC SEPARATOR '|') AS `race_list`,
|
||||
GROUP_CONCAT(DISTINCT `deityid` ORDER BY deityid ASC SEPARATOR '|') AS `deity_list`,
|
||||
GROUP_CONCAT(DISTINCT `zoneid` ORDER BY zoneid ASC SEPARATOR '|') AS `zone_list`,
|
||||
`itemid`,
|
||||
`item_charges`,
|
||||
`gm`,
|
||||
`slot`,
|
||||
`min_expansion`,
|
||||
`max_expansion`,
|
||||
`content_flags`,
|
||||
`content_flags_disabled`
|
||||
FROM
|
||||
`starting_items`
|
||||
GROUP BY
|
||||
`itemid`
|
||||
);
|
||||
|
||||
DROP TABLE `starting_items`;
|
||||
RENAME TABLE `starting_items_new` TO `starting_items`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9244,
|
||||
.description = "2023_11_30_items_table_schema.sql",
|
||||
.check = "SHOW COLUMNS FROM `items` LIKE 'updated'",
|
||||
.condition = "contains",
|
||||
.match = "0000-00-00 00:00:00",
|
||||
.sql = R"(
|
||||
ALTER TABLE `items` MODIFY COLUMN `updated` datetime NULL DEFAULT NULL;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9245,
|
||||
.description = "2023_12_03_object_incline.sql",
|
||||
.check = "SHOW COLUMNS FROM `object` LIKE 'incline'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `object` CHANGE COLUMN `unknown08` `size_percentage` float NOT NULL DEFAULT 0 AFTER `icon`;
|
||||
ALTER TABLE `object` CHANGE COLUMN `unknown10` `solid_type` mediumint(5) NOT NULL DEFAULT 0 AFTER `size`;
|
||||
ALTER TABLE `object` CHANGE COLUMN `unknown20` `incline` int(11) NOT NULL DEFAULT 0 AFTER `solid_type`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9246,
|
||||
.description = "2023_12_07_keyring_id.sql",
|
||||
.check = "SHOW COLUMNS FROM `keyring` LIKE 'id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `keyring`
|
||||
ADD COLUMN `id` int UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
ADD PRIMARY KEY (`id`);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9247,
|
||||
.description = "2023_12_14_starting_items_fix.sql",
|
||||
.check = "SHOW COLUMNS FROM `starting_items` LIKE 'inventory_slot'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `starting_items`
|
||||
CHANGE COLUMN `race_list` `temporary` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `id`,
|
||||
CHANGE COLUMN `class_list` `race_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `temporary`,
|
||||
CHANGE COLUMN `gm` `status` mediumint(3) NOT NULL DEFAULT 0 AFTER `item_charges`,
|
||||
CHANGE COLUMN `slot` `inventory_slot` mediumint(9) NOT NULL DEFAULT -1 AFTER `status`;
|
||||
|
||||
ALTER TABLE `starting_items`
|
||||
CHANGE COLUMN `temporary` `class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `id`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9248,
|
||||
.description = "2023_12_22_drop_npc_emotes_index.sql",
|
||||
.check = "show index from npc_emotes where key_name = 'emoteid'",
|
||||
.condition = "not_empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_emotes` DROP INDEX `emoteid`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9249,
|
||||
.description = "2023_12_26_add_tasks_enabled_column.sql",
|
||||
.check = "SHOW COLUMNS FROM `tasks` LIKE 'enabled'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `tasks`
|
||||
ADD COLUMN `enabled` smallint NULL DEFAULT 1 AFTER `faction_amount`
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9250,
|
||||
.description = "2023_01_06_task_activities_list_group.sql",
|
||||
.check = "SHOW COLUMNS FROM `task_activities` LIKE 'list_group'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `task_activities`
|
||||
ADD COLUMN `list_group` TINYINT UNSIGNED NOT NULL DEFAULT '0' AFTER `optional`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9251,
|
||||
.description = "2023_01_12_instance_list_notes.sql",
|
||||
.check = "SHOW COLUMNS FROM `instance_list` LIKE 'notes'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `instance_list`
|
||||
ADD COLUMN `notes` varchar(50) NOT NULL DEFAULT '' AFTER `never_expires`;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9252,
|
||||
.description = "2024_01_07_zone_idle_when_empty.sql",
|
||||
.check = "SHOW COLUMNS FROM `zone` LIKE 'idle_when_empty'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `zone`
|
||||
ADD COLUMN `idle_when_empty` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 AFTER `min_lava_damage`,
|
||||
ADD COLUMN `seconds_before_idle` int(11) UNSIGNED NOT NULL DEFAULT 60 AFTER `idle_when_empty`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9253,
|
||||
.description = "2024_01_13_merchantlist_slot.sql",
|
||||
.check = "SHOW COLUMNS FROM `merchantlist` LIKE 'slot'",
|
||||
.condition = "missing",
|
||||
.match = "unsigned",
|
||||
.sql = R"(
|
||||
ALTER TABLE `merchantlist`
|
||||
MODIFY COLUMN `slot` int(11) UNSIGNED NOT NULL DEFAULT 0
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9254,
|
||||
.description = "2024_01_13_merchantlist_temp_slot.sql",
|
||||
.check = "SHOW COLUMNS FROM `merchantlist_temp` LIKE 'slot'",
|
||||
.condition = "contains",
|
||||
.match = "tinyint",
|
||||
.sql = R"(
|
||||
ALTER TABLE `merchantlist_temp`
|
||||
MODIFY COLUMN `slot` int(11) UNSIGNED NOT NULL DEFAULT 0
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9255,
|
||||
.description = "2024_01_13_drop_item_tick_deprecated.sql",
|
||||
.check = "show tables like 'item_tick'",
|
||||
.condition = "not_empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
DROP TABLE IF EXISTS item_tick
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9256,
|
||||
.description = "2024_01_16_increase_spawngroup_size.sql",
|
||||
.check = "SHOW COLUMNS FROM `spawngroup` LIKE 'name'",
|
||||
.condition = "contains",
|
||||
.match = "varchar(50)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `spawngroup`
|
||||
MODIFY COLUMN `name` varchar(200) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `id`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9257,
|
||||
.description = "2024_01_16_ground_spawns_fix_z.sql",
|
||||
.check = "SHOW COLUMNS FROM `ground_spawns` LIKE 'fix_z'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `ground_spawns`
|
||||
ADD COLUMN `fix_z` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 AFTER `respawn_timer`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9258,
|
||||
.description = "2024_02_04_base_data.sql",
|
||||
.check = "SHOW COLUMNS FROM `base_data` LIKE 'hp_regen'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `base_data`
|
||||
CHANGE COLUMN `unk1` `hp_regen` double NOT NULL AFTER `end`,
|
||||
CHANGE COLUMN `unk2` `end_regen` double NOT NULL AFTER `hp_regen`,
|
||||
MODIFY COLUMN `level` tinyint(3) UNSIGNED NOT NULL FIRST,
|
||||
MODIFY COLUMN `class` tinyint(2) UNSIGNED NOT NULL AFTER `level`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9259,
|
||||
.description = "2024_01_13_corpse_rez_overhaul.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_corpses` LIKE 'rez_time'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_corpses`
|
||||
ADD COLUMN `rez_time` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `wc_9`,
|
||||
ADD COLUMN `gm_exp` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `rez_time`,
|
||||
ADD COLUMN `killed_by` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `gm_exp`,
|
||||
ADD COLUMN `rezzable` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `killed_by`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9260,
|
||||
.description = "2023_11_11_guild_features.sql",
|
||||
.check = "SHOW TABLES LIKE 'guild_permissions'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `guild_permissions` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`perm_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`guild_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`permission` INT(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `perm_id_guild_id` (`perm_id`, `guild_id`) USING BTREE
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
|
||||
UPDATE guild_ranks SET title = 'Leader' WHERE `rank` = '1';
|
||||
UPDATE guild_ranks SET title = 'Senior Officer' WHERE `rank` = '2';
|
||||
UPDATE guild_ranks SET title = 'Officer' WHERE `rank` = '3';
|
||||
UPDATE guild_ranks SET title = 'Senior Member' WHERE `rank` = '4';
|
||||
UPDATE guild_ranks SET title = 'Member' WHERE `rank` = '5';
|
||||
UPDATE guild_ranks SET title = 'Junior Member' WHERE `rank` = '6';
|
||||
UPDATE guild_ranks SET title = 'Initiate' WHERE `rank` = '7';
|
||||
UPDATE guild_ranks SET title = 'Recruit' WHERE `rank` = '8';
|
||||
|
||||
DELETE FROM guild_ranks WHERE `rank` = 0;
|
||||
|
||||
ALTER TABLE `guild_ranks`
|
||||
DROP COLUMN `can_hear`,
|
||||
DROP COLUMN `can_speak`,
|
||||
DROP COLUMN `can_invite`,
|
||||
DROP COLUMN `can_remove`,
|
||||
DROP COLUMN `can_promote`,
|
||||
DROP COLUMN `can_demote`,
|
||||
DROP COLUMN `can_motd`,
|
||||
DROP COLUMN `can_warpeace`;
|
||||
|
||||
UPDATE guild_members SET `rank` = '5' WHERE `rank` = '0';
|
||||
UPDATE guild_members SET `rank` = '3' WHERE `rank` = '1';
|
||||
UPDATE guild_members SET `rank` = '1' WHERE `rank` = '2';
|
||||
|
||||
ALTER TABLE `guild_members`
|
||||
ADD COLUMN `online` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `alt`;
|
||||
|
||||
ALTER TABLE `guilds`
|
||||
ADD COLUMN `favor` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `url`;
|
||||
|
||||
CREATE TABLE guild_tributes (
|
||||
guild_id int(11) unsigned NOT NULL DEFAULT 0,
|
||||
tribute_id_1 int(11) unsigned NOT NULL DEFAULT 0,
|
||||
tribute_id_1_tier int(11) unsigned NOT NULL DEFAULT 0,
|
||||
tribute_id_2 int(11) unsigned NOT NULL DEFAULT 0,
|
||||
tribute_id_2_tier int(11) unsigned NOT NULL DEFAULT 0,
|
||||
time_remaining int(11) unsigned NOT NULL DEFAULT 0,
|
||||
enabled int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (guild_id) USING BTREE
|
||||
) ENGINE=InnoDB;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9261,
|
||||
.description = "2024_02_11_character_corpses.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_corpses` LIKE 'time_of_death'",
|
||||
.condition = "contains",
|
||||
.match = "0000-00-00 00:00:00",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_corpses` MODIFY COLUMN `time_of_death` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9262,
|
||||
.description = "2024_02_11_object_contents.sql",
|
||||
.check = "SHOW COLUMNS FROM `object_contents` LIKE 'droptime'",
|
||||
.condition = "contains",
|
||||
.match = "0000-00-00 00:00:00",
|
||||
.sql = R"(
|
||||
ALTER TABLE `object_contents` MODIFY COLUMN `droptime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9263,
|
||||
.description = "2024_02_16_rearrange_zone_columns.sql",
|
||||
.check = "show columns from zone like 'note'",
|
||||
.condition = "missing",
|
||||
.match = "varchar(200)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `zone`
|
||||
MODIFY COLUMN `id` int(10) NOT NULL AUTO_INCREMENT FIRST,
|
||||
MODIFY COLUMN `zoneidnumber` int(4) NOT NULL DEFAULT 0 AFTER `id`,
|
||||
MODIFY COLUMN `version` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `zoneidnumber`,
|
||||
MODIFY COLUMN `short_name` varchar(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `version`,
|
||||
MODIFY COLUMN `long_name` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL AFTER `short_name`,
|
||||
MODIFY COLUMN `min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `long_name`,
|
||||
MODIFY COLUMN `note` varchar(200) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `map_file_name`,
|
||||
MODIFY COLUMN `min_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `note`,
|
||||
MODIFY COLUMN `max_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `min_expansion`,
|
||||
MODIFY COLUMN `content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `max_expansion`,
|
||||
MODIFY COLUMN `content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `content_flags`,
|
||||
MODIFY COLUMN `expansion` tinyint(3) NOT NULL DEFAULT 0 AFTER `content_flags_disabled`,
|
||||
MODIFY COLUMN `file_name` varchar(16) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `expansion`,
|
||||
MODIFY COLUMN `safe_x` float NOT NULL DEFAULT 0 AFTER `file_name`,
|
||||
MODIFY COLUMN `safe_y` float NOT NULL DEFAULT 0 AFTER `safe_x`,
|
||||
MODIFY COLUMN `safe_z` float NOT NULL DEFAULT 0 AFTER `safe_y`,
|
||||
MODIFY COLUMN `safe_heading` float NOT NULL DEFAULT 0 AFTER `safe_z`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9264,
|
||||
.description = "2024_02_18_starting_items_augments.sql",
|
||||
.check = "SHOW COLUMNS FROM `starting_items` LIKE 'augment_one'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `starting_items`
|
||||
ADD COLUMN `augment_one` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `item_charges`,
|
||||
ADD COLUMN `augment_two` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_one`,
|
||||
ADD COLUMN `augment_three` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_two`,
|
||||
ADD COLUMN `augment_four` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
|
||||
ADD COLUMN `augment_five` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
|
||||
ADD COLUMN `augment_six` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9265,
|
||||
.description = "2024_03_03_add_id_to_guild_bank.sql",
|
||||
.check = "SHOW COLUMNS FROM `guild_bank` LIKE 'id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `guild_bank`
|
||||
ADD COLUMN `id` INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
ADD PRIMARY KEY (`id`);
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9266,
|
||||
.description = "2024_03_02_rule_values_rule_value_length.sql",
|
||||
.check = "SHOW COLUMNS FROM `rule_values` LIKE 'rule_value'",
|
||||
.condition = "contains",
|
||||
.match = "varchar(30)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `rule_values`
|
||||
MODIFY COLUMN `rule_value` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `rule_name`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9267,
|
||||
.description = "2024_02_18_group_id_bot_id.sql",
|
||||
.check = "SHOW COLUMNS FROM `group_id` LIKE 'bot_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `group_id`
|
||||
CHANGE COLUMN `groupid` `group_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `charid` `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `group_id`,
|
||||
CHANGE COLUMN `ismerc` `merc_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `name`,
|
||||
ADD COLUMN `bot_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `character_id`,
|
||||
MODIFY COLUMN `name` varchar(64) NOT NULL DEFAULT '' AFTER `character_id`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`group_id`, `character_id`, `bot_id`, `merc_id`) USING BTREE;
|
||||
ALTER TABLE `group_id`
|
||||
MODIFY COLUMN `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `name`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9268,
|
||||
.description = "2024_03_23_skill_caps.sql",
|
||||
.check = "SHOW COLUMNS FROM `skill_caps` LIKE 'skill_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `skill_caps`
|
||||
CHANGE COLUMN `skillID` `skill_id` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `class` `class_id` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `skill_id`,
|
||||
ADD COLUMN `id` int(3) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||
ADD INDEX `level_skill_cap`(`skill_id`, `class_id`, `level`, `cap`);
|
||||
)",
|
||||
.content_schema_update = true,
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9269,
|
||||
.description = "2024_03_27_account_auto_login_charname.sql",
|
||||
.check = "SHOW COLUMNS FROM `account` LIKE 'auto_login_charname'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `account`
|
||||
ADD COLUMN `auto_login_charname` varchar(64) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `charname`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9270,
|
||||
.description = "2024_04_31_content_flagging_lootdrop_entries.sql",
|
||||
.check = "SHOW COLUMNS FROM `lootdrop_entries` LIKE 'content_flags'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `lootdrop_entries` ADD `min_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `lootdrop_entries` ADD `max_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `lootdrop_entries` ADD `content_flags` varchar(100) NULL;
|
||||
ALTER TABLE `lootdrop_entries` ADD `content_flags_disabled` varchar(100) NULL;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9271,
|
||||
.description = "2024_03_10_parcel_implementation.sql",
|
||||
.check = "SHOW TABLES LIKE 'character_parcels'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(CREATE TABLE `character_parcels` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`char_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`slot_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`from_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
|
||||
`note` VARCHAR(1024) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
|
||||
`sent_date` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `data_constraint` (`slot_id`, `char_id`) USING BTREE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9272,
|
||||
.description = "2024_04_23_add_parcel_support_for_augmented_items.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'aug_slot_1'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_parcels`
|
||||
ADD COLUMN `aug_slot_1` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `item_id`,
|
||||
ADD COLUMN `aug_slot_2` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_1`,
|
||||
ADD COLUMN `aug_slot_3` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_2`,
|
||||
ADD COLUMN `aug_slot_4` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_3`,
|
||||
ADD COLUMN `aug_slot_5` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_4`,
|
||||
ADD COLUMN `aug_slot_6` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_5`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9273,
|
||||
.description = "2024_04_24_door_close_timer.sql",
|
||||
.check = "SHOW COLUMNS FROM `doors` LIKE 'close_timer_ms'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `doors`
|
||||
ADD COLUMN `close_timer_ms` smallint(8) UNSIGNED NOT NULL DEFAULT 5000 AFTER `is_ldon_door`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9274,
|
||||
.description = "2024_05_02_parcel_npc_content.sql",
|
||||
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'is_parcel_merchant'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_types`
|
||||
ADD COLUMN `is_parcel_merchant` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `keeps_sold_items`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9275,
|
||||
.description = "2024_04_28_character_extra_haste.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_data` LIKE 'extra_haste'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_data`
|
||||
ADD COLUMN `extra_haste` int(11) NOT NULL DEFAULT 0 AFTER `wis`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9276,
|
||||
.description = "2024_05_12_fix_guild_bank_dup_issue.sql",
|
||||
.check = "SHOW COLUMNS FROM `guild_bank` WHERE FIELD = 'qty' AND Type LIKE '%unsigned';",
|
||||
.condition = "not_empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `guild_bank`
|
||||
CHANGE COLUMN `qty` `qty` INT(10) NOT NULL DEFAULT '0' AFTER `itemid`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9277,
|
||||
.description = "2024_05_09_parcel_enable_containers.sql",
|
||||
.check = "SHOW TABLES LIKE 'character_parcels_containers'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `character_parcels_containers` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`parcels_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`slot_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_1` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_2` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_3` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_4` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_5` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_6` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `fk_character_parcels_id` (`parcels_id`) USING BTREE,
|
||||
CONSTRAINT `fk_character_parcels_id` FOREIGN KEY (`parcels_id`) REFERENCES `character_parcels` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1
|
||||
;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9278,
|
||||
.description = "2024_05_06_npc_greed.sql",
|
||||
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'greed'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_types`
|
||||
ADD COLUMN `greed` tinyint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `merchant_id`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9279,
|
||||
.description = "2024_05_13_content_flagging_npc_spells_entries.sql",
|
||||
.check = "SHOW COLUMNS FROM `npc_spells_entries` LIKE 'content_flags'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_spells_entries` ADD `min_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `npc_spells_entries` ADD `max_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `npc_spells_entries` ADD `content_flags` varchar(100) NULL;
|
||||
ALTER TABLE `npc_spells_entries` ADD `content_flags_disabled` varchar(100) NULL;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9280,
|
||||
.description = "2024_05_11_update_trader_support.sql",
|
||||
.check = "SHOW COLUMNS FROM `trader` LIKE 'aug_slot_1'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `trader`
|
||||
ADD COLUMN `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
CHANGE COLUMN `char_id` `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`,
|
||||
CHANGE COLUMN `item_id` `item_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_id`,
|
||||
ADD COLUMN `aug_slot_1` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `item_id`,
|
||||
ADD COLUMN `aug_slot_2` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_1`,
|
||||
ADD COLUMN `aug_slot_3` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_2`,
|
||||
ADD COLUMN `aug_slot_4` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_3`,
|
||||
ADD COLUMN `aug_slot_5` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_4`,
|
||||
ADD COLUMN `aug_slot_6` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_5`,
|
||||
CHANGE COLUMN `serialnumber` `item_sn` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_6`,
|
||||
CHANGE COLUMN `charges` `item_charges` INT(11) NOT NULL DEFAULT '0' AFTER `item_sn`,
|
||||
ADD COLUMN `char_entity_id` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `slot_id`,
|
||||
ADD COLUMN `char_zone_id` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `char_entity_id`,
|
||||
ADD COLUMN `active_transaction` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `char_zone_id`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD INDEX `charid_slotid` (`char_id`, `slot_id`);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9281,
|
||||
.description = "2024_06_24_update_buyer_support.sql",
|
||||
.check = "SHOW COLUMNS FROM `buyer` LIKE 'id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `buyer`
|
||||
ADD COLUMN `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
CHANGE COLUMN `charid` `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`,
|
||||
ADD COLUMN `char_entity_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_id`,
|
||||
ADD COLUMN `char_name` VARCHAR(64) NULL DEFAULT NULL AFTER `char_entity_id`,
|
||||
ADD COLUMN `char_zone_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_name`,
|
||||
ADD COLUMN `char_zone_instance_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_zone_id`,
|
||||
ADD COLUMN `transaction_date` DATETIME NULL DEFAULT NULL AFTER `char_zone_instance_id`,
|
||||
ADD COLUMN `welcome_message` VARCHAR(256) NULL DEFAULT NULL AFTER `transaction_date`,
|
||||
DROP COLUMN `buyslot`,
|
||||
DROP COLUMN `itemid`,
|
||||
DROP COLUMN `itemname`,
|
||||
DROP COLUMN `quantity`,
|
||||
DROP COLUMN `price`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||
ADD INDEX `charid` (`char_id`);
|
||||
|
||||
CREATE TABLE `buyer_buy_lines` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`buyer_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`buy_slot_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_qty` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_price` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_icon` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_name` VARCHAR(64) NOT NULL DEFAULT '' COLLATE 'latin1_swedish_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `buyerid_charid_buyslotid` (`buyer_id`, `char_id`, `buy_slot_id`) USING BTREE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
|
||||
CREATE TABLE `buyer_trade_items` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`buyer_buy_lines_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_qty` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_icon` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_name` VARCHAR(64) NOT NULL DEFAULT '0' COLLATE 'latin1_swedish_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `buyerbuylinesid` (`buyer_buy_lines_id`) USING BTREE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9282,
|
||||
.description = "2024_08_02_spell_buckets_comparison.sql",
|
||||
.check = "SHOW COLUMNS FROM `spell_buckets` LIKE 'bucket_comparison'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `spell_buckets`
|
||||
CHANGE COLUMN `spellid` `spell_id` int UNSIGNED NOT NULL FIRST,
|
||||
CHANGE COLUMN `key` `bucket_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `spell_id`,
|
||||
CHANGE COLUMN `value` `bucket_value` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `bucket_name`,
|
||||
ADD COLUMN `bucket_comparison` tinyint UNSIGNED NOT NULL DEFAULT 0 AFTER `bucket_value`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`spell_id`) USING BTREE;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9283,
|
||||
.description = "2024_08_05_fix_client_hotbar",
|
||||
.check = "SHOW COLUMNS FROM `inventory` LIKE 'guid'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `inventory`
|
||||
ADD COLUMN `guid` BIGINT UNSIGNED NULL DEFAULT '0' AFTER `ornament_hero_model`;
|
||||
ALTER TABLE `inventory_snapshots`
|
||||
ADD COLUMN `guid` BIGINT UNSIGNED NULL DEFAULT '0' AFTER `ornament_hero_model`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9284,
|
||||
.description = "2024_10_08_character_exp_modifiers_default.sql",
|
||||
.check = "SHOW CREATE TABLE `character_exp_modifiers`",
|
||||
.condition = "contains",
|
||||
.match = "`exp_modifier` float NOT NULL,",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_exp_modifiers`
|
||||
MODIFY COLUMN `aa_modifier` float NOT NULL DEFAULT 1.0 AFTER `instance_version`,
|
||||
MODIFY COLUMN `exp_modifier` float NOT NULL DEFAULT 1.0 AFTER `aa_modifier`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9285,
|
||||
.description = "2024_11_08_data_buckets_indexes.sql",
|
||||
.check = "SHOW CREATE TABLE `data_buckets`",
|
||||
.condition = "missing",
|
||||
.match = "idx_character_expires",
|
||||
.sql = R"(
|
||||
CREATE INDEX idx_character_expires ON data_buckets (character_id, expires);
|
||||
CREATE INDEX idx_npc_expires ON data_buckets (npc_id, expires);
|
||||
CREATE INDEX idx_bot_expires ON data_buckets (bot_id, expires);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9286,
|
||||
.description = "2024_10_24_sharedbank_guid_primary_key.sql",
|
||||
.check = "SHOW COLUMN FROM `sharedbank` LIKE 'guid'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `sharedbank`
|
||||
CHANGE COLUMN `acctid` `account_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `slotid` `slot_id` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `account_id`,
|
||||
CHANGE COLUMN `itemid` `item_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `slot_id`,
|
||||
CHANGE COLUMN `augslot1` `augment_one` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `charges`,
|
||||
CHANGE COLUMN `augslot2` `augment_two` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_one`,
|
||||
CHANGE COLUMN `augslot3` `augment_three` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_two`,
|
||||
CHANGE COLUMN `augslot4` `augment_four` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
|
||||
CHANGE COLUMN `augslot5` `augment_five` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
|
||||
CHANGE COLUMN `augslot6` `augment_six` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`,
|
||||
MODIFY COLUMN `charges` smallint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `item_id`,
|
||||
ADD COLUMN `color` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `charges`,
|
||||
ADD COLUMN `ornament_icon` int(11) UNSIGNED NOT NULL AFTER `custom_data`,
|
||||
ADD COLUMN `ornament_idfile` int(11) UNSIGNED NOT NULL AFTER `ornament_icon`,
|
||||
ADD COLUMN `ornament_hero_model` int(11) NOT NULL AFTER `ornament_idfile`,
|
||||
ADD COLUMN `guid` bigint(20) UNSIGNED NOT NULL DEFAULT 0 AFTER `ornament_hero_model`,
|
||||
ADD PRIMARY KEY (`account_id`, `slot_id`);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9287,
|
||||
.description = "2024_10_24_inventory_changes.sql",
|
||||
.check = "SHOW COLUMN FROM `inventory` LIKE 'charid'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `inventory`
|
||||
CHANGE COLUMN `charid` `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `slotid` `slot_id` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `character_id`,
|
||||
CHANGE COLUMN `itemid` `item_id` int(11) UNSIGNED NULL DEFAULT 0 AFTER `slot_id`,
|
||||
CHANGE COLUMN `augslot1` `augment_one` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `color`,
|
||||
CHANGE COLUMN `augslot2` `augment_two` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_one`,
|
||||
CHANGE COLUMN `augslot3` `augment_three` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_two`,
|
||||
CHANGE COLUMN `augslot4` `augment_four` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
|
||||
CHANGE COLUMN `augslot5` `augment_five` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
|
||||
CHANGE COLUMN `augslot6` `augment_six` mediumint(7) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`,
|
||||
CHANGE COLUMN `ornamenticon` `ornament_icon` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `custom_data`,
|
||||
CHANGE COLUMN `ornamentidfile` `ornament_idfile` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `ornament_icon`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`character_id`, `slot_id`) USING BTREE;
|
||||
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 251) + 4010) WHERE `slot_id` BETWEEN 251 AND 260; -- Bag 1
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 261) + 4210) WHERE `slot_id` BETWEEN 261 AND 270; -- Bag 2
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 271) + 4410) WHERE `slot_id` BETWEEN 271 AND 280; -- Bag 3
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 281) + 4610) WHERE `slot_id` BETWEEN 281 AND 290; -- Bag 4
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 291) + 4810) WHERE `slot_id` BETWEEN 291 AND 300; -- Bag 5
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 301) + 5010) WHERE `slot_id` BETWEEN 301 AND 310; -- Bag 6
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 311) + 5210) WHERE `slot_id` BETWEEN 311 AND 320; -- Bag 7
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 321) + 5410) WHERE `slot_id` BETWEEN 321 AND 330; -- Bag 8
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 331) + 5610) WHERE `slot_id` BETWEEN 331 AND 340; -- Bag 9
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 341) + 5810) WHERE `slot_id` BETWEEN 341 AND 350; -- Bag 10
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 351) + 6010) WHERE `slot_id` BETWEEN 351 AND 360; -- Cursor Bag
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2031) + 6210) WHERE `slot_id` BETWEEN 2031 AND 2040; -- Bank Bag 1
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2041) + 6410) WHERE `slot_id` BETWEEN 2041 AND 2050; -- Bank Bag 2
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2051) + 6610) WHERE `slot_id` BETWEEN 2051 AND 2060; -- Bank Bag 3
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2061) + 6810) WHERE `slot_id` BETWEEN 2061 AND 2070; -- Bank Bag 4
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2071) + 7010) WHERE `slot_id` BETWEEN 2071 AND 2080; -- Bank Bag 5
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2081) + 7210) WHERE `slot_id` BETWEEN 2081 AND 2090; -- Bank Bag 6
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2091) + 7410) WHERE `slot_id` BETWEEN 2091 AND 2100; -- Bank Bag 7
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2101) + 7610) WHERE `slot_id` BETWEEN 2101 AND 2110; -- Bank Bag 8
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2111) + 7810) WHERE `slot_id` BETWEEN 2111 AND 2120; -- Bank Bag 9
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2121) + 8010) WHERE `slot_id` BETWEEN 2121 AND 2130; -- Bank Bag 10
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2131) + 8210) WHERE `slot_id` BETWEEN 2131 AND 2140; -- Bank Bag 11
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2141) + 8410) WHERE `slot_id` BETWEEN 2141 AND 2150; -- Bank Bag 12
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2151) + 8610) WHERE `slot_id` BETWEEN 2151 AND 2160; -- Bank Bag 13
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2161) + 8810) WHERE `slot_id` BETWEEN 2161 AND 2170; -- Bank Bag 14
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2171) + 9010) WHERE `slot_id` BETWEEN 2171 AND 2180; -- Bank Bag 15
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2181) + 9210) WHERE `slot_id` BETWEEN 2181 AND 2190; -- Bank Bag 16
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2191) + 9410) WHERE `slot_id` BETWEEN 2191 AND 2200; -- Bank Bag 17
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2201) + 9610) WHERE `slot_id` BETWEEN 2201 AND 2210; -- Bank Bag 18
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2211) + 9810) WHERE `slot_id` BETWEEN 2211 AND 2220; -- Bank Bag 19
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2221) + 10010) WHERE `slot_id` BETWEEN 2221 AND 2230; -- Bank Bag 20
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2231) + 10210) WHERE `slot_id` BETWEEN 2231 AND 2240; -- Bank Bag 21
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2241) + 10410) WHERE `slot_id` BETWEEN 2241 AND 2250; -- Bank Bag 22
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2251) + 10610) WHERE `slot_id` BETWEEN 2251 AND 2260; -- Bank Bag 23
|
||||
UPDATE `inventory` SET `slot_id` = ((`slot_id` - 2261) + 10810) WHERE `slot_id` BETWEEN 2261 AND 2270; -- Bank Bag 24
|
||||
UPDATE `sharedbank` SET `slot_id` = ((`slot_id` - 2531) + 11010) WHERE `slot_id` BETWEEN 2531 AND 2540; -- Shared Bank Bag 1
|
||||
UPDATE `sharedbank` SET `slot_id` = ((`slot_id` - 2541) + 11210) WHERE `slot_id` BETWEEN 2541 AND 2550; -- Shared Bank Bag 2
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9288,
|
||||
.description = "2024_10_24_merchantlist_temp_uncap.sql",
|
||||
.check = "SHOW CREATE TABLE `merchantlist_temp`",
|
||||
.condition = "contains",
|
||||
.match = "`slot` tinyint(3)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `merchantlist_temp`
|
||||
MODIFY COLUMN `slot` int UNSIGNED NOT NULL DEFAULT 0 AFTER `npcid`;
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
// .version = 9228,
|
||||
|
||||
@@ -82,6 +82,85 @@ CREATE TABLE `bot_starting_items` (
|
||||
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9041,
|
||||
.description = "2023_12_04_bot_timers.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_timers` LIKE 'recast_time'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_timers`
|
||||
ADD COLUMN `recast_time` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `timer_value`,
|
||||
ADD COLUMN `is_spell` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `recast_time`,
|
||||
ADD COLUMN `is_disc` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `is_spell`,
|
||||
ADD COLUMN `spell_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `is_disc`,
|
||||
ADD COLUMN `is_item` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `spell_id`,
|
||||
ADD COLUMN `item_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `is_item`;
|
||||
ALTER TABLE `bot_timers`
|
||||
DROP FOREIGN KEY `FK_bot_timers_1`;
|
||||
ALTER TABLE `bot_timers`
|
||||
DROP PRIMARY KEY;
|
||||
ALTER TABLE `bot_timers`
|
||||
ADD PRIMARY KEY (`bot_id`, `timer_id`, `spell_id`, `item_id`);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9042,
|
||||
.description = "2024_01_27_delete_bot_foreign_keys.sql",
|
||||
.check = "SHOW CREATE TABLE `bot_stances`",
|
||||
.condition = "contains",
|
||||
.match = "FOREIGN",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_buffs` DROP FOREIGN KEY `FK_bot_buffs_1`;
|
||||
ALTER TABLE `bot_heal_rotations` DROP FOREIGN KEY `FK_bot_heal_rotations`;
|
||||
ALTER TABLE `bot_heal_rotation_members` DROP FOREIGN KEY `FK_bot_heal_rotation_members_1`;
|
||||
ALTER TABLE `bot_heal_rotation_members` DROP FOREIGN KEY `FK_bot_heal_rotation_members_2`;
|
||||
ALTER TABLE `bot_heal_rotation_targets` DROP FOREIGN KEY `FK_bot_heal_rotation_targets`;
|
||||
ALTER TABLE `bot_inventories` DROP FOREIGN KEY `FK_bot_inventories_1`;
|
||||
ALTER TABLE `bot_pets` DROP FOREIGN KEY `FK_bot_pets_1`;
|
||||
ALTER TABLE `bot_pet_buffs` DROP FOREIGN KEY `FK_bot_pet_buffs_1`;
|
||||
ALTER TABLE `bot_pet_inventories` DROP FOREIGN KEY `FK_bot_pet_inventories_1`;
|
||||
ALTER TABLE `bot_stances` DROP FOREIGN KEY `FK_bot_stances_1`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9043,
|
||||
.description = "2024_02_18_bot_starting_items_augments.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_starting_items` LIKE 'augment_one'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_starting_items`
|
||||
ADD COLUMN `augment_one` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `item_charges`,
|
||||
ADD COLUMN `augment_two` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_one`,
|
||||
ADD COLUMN `augment_three` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_two`,
|
||||
ADD COLUMN `augment_four` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
|
||||
ADD COLUMN `augment_five` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
|
||||
ADD COLUMN `augment_six` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9044,
|
||||
.description = "2024_04_23_bot_extra_haste.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'extra_haste'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `extra_haste` mediumint(8) NOT NULL DEFAULT 0 AFTER `wis`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9045,
|
||||
.description = "2024_08_05_bot_spells_entries_unsigned_spell_id.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_spells_entries` LIKE 'spell_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_spells_entries`
|
||||
CHANGE COLUMN `spellid` `spell_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `npc_spells_id`;
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/strings.h"
|
||||
|
||||
#include "database.h"
|
||||
#include "database/database_update.h"
|
||||
|
||||
|
||||
// Disgrace: for windows compile
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
|
||||
#include "unix.h"
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#endif
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
DatabaseUpdate database_update;
|
||||
|
||||
bool Database::CheckDatabaseConversions()
|
||||
{
|
||||
auto *r = RuleManager::Instance();
|
||||
r->LoadRules(this, "default", false);
|
||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
||||
r->SetRule("Bots:Enabled", "true", this, true, true);
|
||||
}
|
||||
|
||||
database_update.SetDatabase(this)->CheckDbUpdates();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/repositories/raid_members_repository.h"
|
||||
#include "../common/repositories/respawn_times_repository.h"
|
||||
#include "../common/repositories/spawn_condition_values_repository.h"
|
||||
#include "repositories/spawn2_disabled_repository.h"
|
||||
|
||||
|
||||
#include "database.h"
|
||||
@@ -49,6 +50,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
||||
{
|
||||
auto e = InstanceListPlayerRepository::NewEntity();
|
||||
@@ -419,20 +421,25 @@ void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
||||
auto zone_id = GetInstanceZoneID(instance_id);
|
||||
auto version = GetInstanceVersion(instance_id);
|
||||
|
||||
auto l = GroupIdRepository::GetWhere(
|
||||
const auto& l = GroupIdRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"groupid = {}",
|
||||
"`group_id` = {}",
|
||||
group_id
|
||||
)
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
||||
AddClientToInstance(instance_id, e.charid);
|
||||
if (!e.character_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GetInstanceID(zone_id, e.character_id, version)) {
|
||||
AddClientToInstance(instance_id, e.character_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -502,7 +509,7 @@ void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 ch
|
||||
return;
|
||||
}
|
||||
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id).c_str());
|
||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
||||
|
||||
if (!raid_leader_instance_id) {
|
||||
@@ -553,6 +560,7 @@ void Database::PurgeExpiredInstances()
|
||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
Spawn2DisabledRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
@@ -567,3 +575,23 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
|
||||
InstanceListRepository::UpdateOne(*this, i);
|
||||
}
|
||||
|
||||
void Database::CleanupInstanceCorpses() {
|
||||
auto l = InstanceListRepository::GetWhere(
|
||||
*this,
|
||||
"never_expires = 0"
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> instance_ids;
|
||||
for (const auto& e : l) {
|
||||
instance_ids.emplace_back(std::to_string(e.id));
|
||||
}
|
||||
|
||||
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
|
||||
|
||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ namespace DatabaseSchema {
|
||||
{
|
||||
return {
|
||||
{"adventure_stats", "player_id"},
|
||||
{"buyer", "charid"},
|
||||
{"char_recipe_list", "char_id"},
|
||||
{"character_activities", "charid"},
|
||||
{"character_alt_currency", "char_id"},
|
||||
@@ -59,6 +58,8 @@ namespace DatabaseSchema {
|
||||
{"character_leadership_abilities", "id"},
|
||||
{"character_material", "id"},
|
||||
{"character_memmed_spells", "id"},
|
||||
{"character_parcels", "char_id"},
|
||||
{"character_parcels_containers", "id"},
|
||||
{"character_pet_buffs", "char_id"},
|
||||
{"character_pet_info", "char_id"},
|
||||
{"character_pet_inventory", "char_id"},
|
||||
@@ -71,7 +72,7 @@ namespace DatabaseSchema {
|
||||
{"character_tasks", "charid"},
|
||||
{"character_tribute", "character_id"},
|
||||
{"completed_tasks", "charid"},
|
||||
{"data_buckets", "id"},
|
||||
{"data_buckets", "character_id"},
|
||||
{"faction_values", "char_id"},
|
||||
{"friends", "charid"},
|
||||
{"guild_members", "char_id"},
|
||||
@@ -105,6 +106,8 @@ namespace DatabaseSchema {
|
||||
"adventure_details",
|
||||
"adventure_stats",
|
||||
"buyer",
|
||||
"buyer_buy_lines",
|
||||
"buyer_trade_items",
|
||||
"char_recipe_list",
|
||||
"character_activities",
|
||||
"character_alt_currency",
|
||||
@@ -128,6 +131,8 @@ namespace DatabaseSchema {
|
||||
"character_leadership_abilities",
|
||||
"character_material",
|
||||
"character_memmed_spells",
|
||||
"character_parcels",
|
||||
"character_parcels_containers",
|
||||
"character_pet_buffs",
|
||||
"character_pet_info",
|
||||
"character_pet_inventory",
|
||||
@@ -146,8 +151,10 @@ namespace DatabaseSchema {
|
||||
"friends",
|
||||
"guild_bank",
|
||||
"guild_members",
|
||||
"guild_permissions",
|
||||
"guild_ranks",
|
||||
"guild_relations",
|
||||
"guild_tributes",
|
||||
"guilds",
|
||||
"instance_list_player",
|
||||
"inventory",
|
||||
@@ -319,6 +326,9 @@ namespace DatabaseSchema {
|
||||
"banned_ips",
|
||||
"bug_reports",
|
||||
"bugs",
|
||||
"buyer",
|
||||
"buyer_buy_lines",
|
||||
"buyer_trade_items",
|
||||
"completed_shared_task_activity_state",
|
||||
"completed_shared_task_members",
|
||||
"completed_shared_tasks",
|
||||
@@ -332,7 +342,6 @@ namespace DatabaseSchema {
|
||||
"group_leaders",
|
||||
"instance_list",
|
||||
"ip_exemptions",
|
||||
"item_tick",
|
||||
"lfguild",
|
||||
"merc_buffs",
|
||||
"merchantlist_temp",
|
||||
@@ -345,6 +354,7 @@ namespace DatabaseSchema {
|
||||
"respawn_times",
|
||||
"saylink",
|
||||
"server_scheduled_events",
|
||||
"spawn2_disabled",
|
||||
"player_event_log_settings",
|
||||
"player_event_logs",
|
||||
"shared_task_activity_state",
|
||||
|
||||
+7
-2
@@ -7,8 +7,8 @@
|
||||
#include "timer.h"
|
||||
|
||||
#include "dbcore.h"
|
||||
#include "mysql_stmt.h"
|
||||
|
||||
#include <errmsg.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <mysqld_error.h>
|
||||
@@ -138,7 +138,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
* Error logging
|
||||
*/
|
||||
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
||||
LogMySQLError("MySQL Error ({}) [{}] Query [{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
||||
}
|
||||
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
||||
@@ -437,3 +437,8 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
||||
{
|
||||
return mysql::PreparedStmt(*mysql, std::move(query), m_mutex);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#include <string.h>
|
||||
#include <mutex>
|
||||
|
||||
#define CR_SERVER_GONE_ERROR 2006
|
||||
#define CR_SERVER_LOST 2013
|
||||
|
||||
namespace mysql { class PreparedStmt; }
|
||||
|
||||
class DBcore {
|
||||
public:
|
||||
enum eStatus {
|
||||
@@ -45,6 +50,11 @@ public:
|
||||
}
|
||||
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:
|
||||
bool Open(
|
||||
const char *iHost,
|
||||
|
||||
+6
-70
@@ -19,81 +19,17 @@
|
||||
|
||||
#include "deity.h"
|
||||
|
||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
||||
uint32 Deity::GetBitmask(uint32 deity_id)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
return bit_DeityBertoxxulous;
|
||||
case DeityBrellSirilis:
|
||||
return bit_DeityBrellSirilis;
|
||||
case DeityCazicThule:
|
||||
return bit_DeityCazicThule;
|
||||
case DeityErollisiMarr:
|
||||
return bit_DeityErollisiMarr;
|
||||
case DeityBristlebane:
|
||||
return bit_DeityBristlebane;
|
||||
case DeityInnoruuk:
|
||||
return bit_DeityInnoruuk;
|
||||
case DeityKarana:
|
||||
return bit_DeityKarana;
|
||||
case DeityMithanielMarr:
|
||||
return bit_DeityMithanielMarr;
|
||||
case DeityPrexus:
|
||||
return bit_DeityPrexus;
|
||||
case DeityQuellious:
|
||||
return bit_DeityQuellious;
|
||||
case DeityRallosZek:
|
||||
return bit_DeityRallosZek;
|
||||
case DeityRodcetNife:
|
||||
return bit_DeityRodcetNife;
|
||||
case DeitySolusekRo:
|
||||
return bit_DeitySolusekRo;
|
||||
case DeityTheTribunal:
|
||||
return bit_DeityTheTribunal;
|
||||
case DeityTunare:
|
||||
return bit_DeityTunare;
|
||||
case DeityVeeshan:
|
||||
return bit_DeityVeeshan;
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return bit_DeityAgnostic;
|
||||
default:
|
||||
return bit_DeityAll;
|
||||
}
|
||||
return IsValid(deity_id) ? deity_bitmasks[deity_id] : Deity::Bitmask::All;
|
||||
}
|
||||
|
||||
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 = {
|
||||
{ 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;
|
||||
return IsValid(deity_id) ? deity_names[deity_id] : "UNKNOWN DEITY";
|
||||
}
|
||||
|
||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
||||
bool Deity::IsValid(uint32 deity_id)
|
||||
{
|
||||
|
||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
return deity_names.find(deity_id) != deity_names.end();
|
||||
}
|
||||
|
||||
+85
-50
@@ -23,60 +23,95 @@
|
||||
#include "types.h"
|
||||
#include <map>
|
||||
#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 deity {
|
||||
enum DeityType {
|
||||
DeityUnknown = 0,
|
||||
DeityAgnostic_LB = 140,
|
||||
DeityBertoxxulous = 201,
|
||||
DeityBrellSirilis,
|
||||
DeityCazicThule,
|
||||
DeityErollisiMarr,
|
||||
DeityBristlebane,
|
||||
DeityInnoruuk,
|
||||
DeityKarana,
|
||||
DeityMithanielMarr,
|
||||
DeityPrexus,
|
||||
DeityQuellious,
|
||||
DeityRallosZek,
|
||||
DeityRodcetNife,
|
||||
DeitySolusekRo,
|
||||
DeityTheTribunal,
|
||||
DeityTunare,
|
||||
DeityVeeshan,
|
||||
DeityAgnostic = 396
|
||||
};
|
||||
namespace Bitmask {
|
||||
constexpr uint32 Agnostic = 1;
|
||||
constexpr uint32 Bertoxxulous = 2;
|
||||
constexpr uint32 BrellSirilis = 4;
|
||||
constexpr uint32 CazicThule = 8;
|
||||
constexpr uint32 ErollisiMarr = 16;
|
||||
constexpr uint32 Bristlebane = 32;
|
||||
constexpr uint32 Innoruuk = 64;
|
||||
constexpr uint32 Karana = 128;
|
||||
constexpr uint32 MithanielMarr = 256;
|
||||
constexpr uint32 Prexus = 512;
|
||||
constexpr uint32 Quellious = 1024;
|
||||
constexpr uint32 RallosZek = 2048;
|
||||
constexpr uint32 RodcetNife = 4096;
|
||||
constexpr uint32 SolusekRo = 8192;
|
||||
constexpr uint32 TheTribunal = 16384;
|
||||
constexpr uint32 Tunare = 32768;
|
||||
constexpr uint32 Veeshan = 65536;
|
||||
constexpr uint32 All = std::numeric_limits<uint32>::max();
|
||||
}
|
||||
|
||||
enum DeityTypeBit : uint32 {
|
||||
bit_DeityAgnostic = 0x00000001,
|
||||
bit_DeityBertoxxulous = 0x00000002,
|
||||
bit_DeityBrellSirilis = 0x00000004,
|
||||
bit_DeityCazicThule = 0x00000008,
|
||||
bit_DeityErollisiMarr = 0x00000010,
|
||||
bit_DeityBristlebane = 0x00000020,
|
||||
bit_DeityInnoruuk = 0x00000040,
|
||||
bit_DeityKarana = 0x00000080,
|
||||
bit_DeityMithanielMarr = 0x00000100,
|
||||
bit_DeityPrexus = 0x00000200,
|
||||
bit_DeityQuellious = 0x00000400,
|
||||
bit_DeityRallosZek = 0x00000800,
|
||||
bit_DeityRodcetNife = 0x00001000,
|
||||
bit_DeitySolusekRo = 0x00002000,
|
||||
bit_DeityTheTribunal = 0x00004000,
|
||||
bit_DeityTunare = 0x00008000,
|
||||
bit_DeityVeeshan = 0x00010000,
|
||||
bit_DeityAll = UINT32_MAX
|
||||
};
|
||||
uint32 GetBitmask(uint32 deity_id);
|
||||
std::string GetName(uint32 deity_id);
|
||||
bool IsValid(uint32 deity_id);
|
||||
}
|
||||
|
||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
||||
extern std::string GetDeityName(DeityType deity_type);
|
||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
||||
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" }
|
||||
};
|
||||
|
||||
} /*deity*/
|
||||
|
||||
} /*EQEmu*/
|
||||
static std::map<uint32, uint32> deity_bitmasks = {
|
||||
{ Deity::Agnostic1, Deity::Bitmask::Agnostic },
|
||||
{ Deity::Agnostic2, Deity::Bitmask::Agnostic },
|
||||
{ Deity::Bertoxxulous, Deity::Bitmask::Bertoxxulous },
|
||||
{ Deity::BrellSirilis, Deity::Bitmask::BrellSirilis },
|
||||
{ Deity::CazicThule, Deity::Bitmask::CazicThule },
|
||||
{ Deity::ErollisiMarr, Deity::Bitmask::ErollisiMarr },
|
||||
{ Deity::Bristlebane, Deity::Bitmask::Bristlebane },
|
||||
{ Deity::Innoruuk, Deity::Bitmask::Innoruuk },
|
||||
{ Deity::Karana, Deity::Bitmask::Karana },
|
||||
{ Deity::MithanielMarr, Deity::Bitmask::MithanielMarr },
|
||||
{ Deity::Prexus, Deity::Bitmask::Prexus },
|
||||
{ Deity::Quellious, Deity::Bitmask::Quellious },
|
||||
{ Deity::RallosZek, Deity::Bitmask::RallosZek },
|
||||
{ Deity::RodcetNife, Deity::Bitmask::RodcetNife },
|
||||
{ Deity::SolusekRo, Deity::Bitmask::SolusekRo },
|
||||
{ Deity::TheTribunal, Deity::Bitmask::TheTribunal },
|
||||
{ Deity::Tunare, Deity::Bitmask::Tunare },
|
||||
{ Deity::Veeshan, Deity::Bitmask::Veeshan }
|
||||
};
|
||||
|
||||
#endif /* COMMON_DEITY_H */
|
||||
|
||||
+187
-308
@@ -22,7 +22,6 @@
|
||||
#include "data_verification.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
#include "languages.h"
|
||||
#include "rulesys.h"
|
||||
|
||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
@@ -60,144 +59,81 @@ int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
return local_array[inv_type];
|
||||
}
|
||||
|
||||
const char* EQ::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||
switch (category_id) {
|
||||
case catVideo:
|
||||
return "Video";
|
||||
case catAudio:
|
||||
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) {
|
||||
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) {
|
||||
switch (stance_type) {
|
||||
case stanceUnknown:
|
||||
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) {
|
||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
||||
return (stance_type - EQ::constants::stancePassive);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
||||
uint32 Bug::GetID(const std::string& category_name)
|
||||
{
|
||||
static const std::map<int, std::string> language_map = {
|
||||
{ LANG_COMMON_TONGUE, "Common Tongue" },
|
||||
{ LANG_BARBARIAN, "Barbarian" },
|
||||
{ LANG_ERUDIAN, "Erudian" },
|
||||
{ LANG_ELVISH, "Elvish" },
|
||||
{ LANG_DARK_ELVISH, "Dark Elvish" },
|
||||
{ LANG_DWARVISH, "Dwarvish" },
|
||||
{ LANG_TROLL, "Troll" },
|
||||
{ LANG_OGRE, "Ogre" },
|
||||
{ LANG_GNOMISH, "Gnomish" },
|
||||
{ LANG_HALFLING, "Halfling" },
|
||||
{ LANG_THIEVES_CANT, "Thieves Cant" },
|
||||
{ LANG_OLD_ERUDIAN, "Old Erudian" },
|
||||
{ LANG_ELDER_ELVISH, "Elder Elvish" },
|
||||
{ LANG_FROGLOK, "Froglok" },
|
||||
{ LANG_GOBLIN, "Goblin" },
|
||||
{ LANG_GNOLL, "Gnoll" },
|
||||
{ LANG_COMBINE_TONGUE, "Combine Tongue" },
|
||||
{ LANG_ELDER_TEIRDAL, "Elder Teirdal" },
|
||||
{ LANG_LIZARDMAN, "Lizardman" },
|
||||
{ LANG_ORCISH, "Orcish" },
|
||||
{ LANG_FAERIE, "Faerie" },
|
||||
{ LANG_DRAGON, "Dragon" },
|
||||
{ LANG_ELDER_DRAGON, "Elder Dragon" },
|
||||
{ LANG_DARK_SPEECH, "Dark Speech" },
|
||||
{ LANG_VAH_SHIR, "Vah Shir" },
|
||||
{ LANG_ALARAN, "Alaran" },
|
||||
{ LANG_HADAL, "Hadal" },
|
||||
{ LANG_UNKNOWN, "Unknown" }
|
||||
for (const auto& e : bug_category_names) {
|
||||
if (e.second == category_name) {
|
||||
return e.first;
|
||||
}
|
||||
}
|
||||
|
||||
return Bug::Category::Other;
|
||||
}
|
||||
|
||||
std::string Bug::GetName(uint32 category_id)
|
||||
{
|
||||
return IsValid(category_id) ? bug_category_names[category_id] : "UNKNOWN BUG CATEGORY";
|
||||
}
|
||||
|
||||
bool Bug::IsValid(uint32 category_id)
|
||||
{
|
||||
return bug_category_names.find(category_id) != bug_category_names.end();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
static const std::map<uint8, std::string> language_map = {
|
||||
{ Language::CommonTongue, "Common Tongue" },
|
||||
{ Language::Barbarian, "Barbarian" },
|
||||
{ Language::Erudian, "Erudian" },
|
||||
{ Language::Elvish, "Elvish" },
|
||||
{ Language::DarkElvish, "Dark Elvish" },
|
||||
{ Language::Dwarvish, "Dwarvish" },
|
||||
{ Language::Troll, "Troll" },
|
||||
{ Language::Ogre, "Ogre" },
|
||||
{ Language::Gnomish, "Gnomish" },
|
||||
{ Language::Halfling, "Halfling" },
|
||||
{ Language::ThievesCant, "Thieves Cant" },
|
||||
{ Language::OldErudian, "Old Erudian" },
|
||||
{ Language::ElderElvish, "Elder Elvish" },
|
||||
{ Language::Froglok, "Froglok" },
|
||||
{ Language::Goblin, "Goblin" },
|
||||
{ Language::Gnoll, "Gnoll" },
|
||||
{ Language::CombineTongue, "Combine Tongue" },
|
||||
{ Language::ElderTeirDal, "Elder Teir'Dal" },
|
||||
{ Language::Lizardman, "Lizardman" },
|
||||
{ Language::Orcish, "Orcish" },
|
||||
{ Language::Faerie, "Faerie" },
|
||||
{ Language::Dragon, "Dragon" },
|
||||
{ Language::ElderDragon, "Elder Dragon" },
|
||||
{ Language::DarkSpeech, "Dark Speech" },
|
||||
{ Language::VahShir, "Vah Shir" },
|
||||
{ Language::Alaran, "Alaran" },
|
||||
{ Language::Hadal, "Hadal" },
|
||||
{ Language::Unknown27, "Unknown" }
|
||||
};
|
||||
|
||||
return language_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetLanguageName(int language_id)
|
||||
std::string EQ::constants::GetLanguageName(uint8 language_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
||||
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
@@ -250,102 +186,6 @@ std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
||||
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()
|
||||
{
|
||||
static const std::map<uint8, std::string> consider_level_map = {
|
||||
@@ -436,85 +276,6 @@ std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
||||
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()
|
||||
{
|
||||
static const std::map<uint8, std::string> weather_type_map = {
|
||||
@@ -564,6 +325,7 @@ std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> emote_type_map = {
|
||||
{ EmoteTypes::Say, "Say" },
|
||||
{ EmoteTypes::Emote, "Emote" },
|
||||
{ EmoteTypes::Shout, "Shout" },
|
||||
{ EmoteTypes::Proximity, "Proximity" }
|
||||
@@ -574,9 +336,126 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||
|
||||
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
||||
{
|
||||
if (!EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
||||
if (!EQ::ValueWithin(emote_type, EmoteTypes::Say, EmoteTypes::Proximity)) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetAppearanceTypeMap()
|
||||
{
|
||||
static const std::map<uint32, std::string> appearance_type_map = {
|
||||
{ AppearanceType::Die, "Die" },
|
||||
{ AppearanceType::WhoLevel, "Who Level" },
|
||||
{ AppearanceType::MaxHealth, "Max Health" },
|
||||
{ AppearanceType::Invisibility, "Invisibility" },
|
||||
{ AppearanceType::PVP, "PVP" },
|
||||
{ AppearanceType::Light, "Light" },
|
||||
{ AppearanceType::Animation, "Animation" },
|
||||
{ AppearanceType::Sneak, "Sneak" },
|
||||
{ AppearanceType::SpawnID, "Spawn ID" },
|
||||
{ AppearanceType::Health, "Health" },
|
||||
{ AppearanceType::Linkdead, "Linkdead" },
|
||||
{ AppearanceType::FlyMode, "Fly Mode" },
|
||||
{ AppearanceType::GM, "GM" },
|
||||
{ AppearanceType::Anonymous, "Anonymous" },
|
||||
{ AppearanceType::GuildID, "Guild ID" },
|
||||
{ AppearanceType::GuildRank, "Guild Rank" },
|
||||
{ AppearanceType::AFK, "AFK" },
|
||||
{ AppearanceType::Pet, "Pet" },
|
||||
{ AppearanceType::Summoned, "Summoned" },
|
||||
{ AppearanceType::Split, "Split" },
|
||||
{ AppearanceType::Size, "Size" },
|
||||
{ AppearanceType::SetType, "Set Type" },
|
||||
{ AppearanceType::NPCName, "NPCName" },
|
||||
{ AppearanceType::AARank, "AARank" },
|
||||
{ AppearanceType::CancelSneakHide, "Cancel Sneak Hide" },
|
||||
{ AppearanceType::AreaHealthRegen, "Area Health Regeneration" },
|
||||
{ AppearanceType::AreaManaRegen, "Area Mana Regeneration" },
|
||||
{ AppearanceType::AreaEnduranceRegen, "Area Endurance Regeneration" },
|
||||
{ AppearanceType::FreezeBeneficialBuffs, "Freeze Beneficial Buffs" },
|
||||
{ AppearanceType::NPCTintIndex, "NPC Tint Index" },
|
||||
{ AppearanceType::GroupAutoConsent, "Group Auto Consent" },
|
||||
{ AppearanceType::RaidAutoConsent, "Raid Auto Consent" },
|
||||
{ AppearanceType::GuildAutoConsent, "Guild Auto Consent" },
|
||||
{ AppearanceType::ShowHelm, "Show Helm" },
|
||||
{ AppearanceType::DamageState, "Damage State" },
|
||||
{ AppearanceType::EQPlayers, "EQ Players" },
|
||||
{ AppearanceType::FindBits, "Find Bits" },
|
||||
{ AppearanceType::TextureType, "Texture Type" },
|
||||
{ AppearanceType::FacePick, "Face Pick" },
|
||||
{ AppearanceType::AntiCheat, "Anti Cheat" },
|
||||
{ AppearanceType::GuildShow, "Guild Show" },
|
||||
{ AppearanceType::OfflineMode, "Offline Mode" }
|
||||
};
|
||||
|
||||
return appearance_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetAppearanceTypeName(uint32 appearance_type)
|
||||
{
|
||||
const auto& a = EQ::constants::GetAppearanceTypeMap().find(appearance_type);
|
||||
if (a != EQ::constants::GetAppearanceTypeMap().end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string SpecialAbility::GetName(int ability_id)
|
||||
{
|
||||
return IsValid(ability_id) ? special_ability_names[ability_id] : "UNKNOWN SPECIAL ABILITY";
|
||||
}
|
||||
|
||||
bool SpecialAbility::IsValid(int ability_id)
|
||||
{
|
||||
return special_ability_names.find(ability_id) != special_ability_names.end();
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetConsiderColorMap()
|
||||
{
|
||||
static const std::map<uint32, std::string> consider_color_map = {
|
||||
{ ConsiderColor::Green, "Green" },
|
||||
{ ConsiderColor::DarkBlue, "Dark Blue" },
|
||||
{ ConsiderColor::Gray, "Gray" },
|
||||
{ ConsiderColor::White, "White" },
|
||||
{ ConsiderColor::Red, "Red" },
|
||||
{ ConsiderColor::Yellow, "Yellow" },
|
||||
{ ConsiderColor::LightBlue, "Light Blue" },
|
||||
{ ConsiderColor::WhiteTitanium, "White" },
|
||||
};
|
||||
|
||||
return consider_color_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetConsiderColorName(uint32 consider_color)
|
||||
{
|
||||
const auto& c = EQ::constants::GetConsiderColorMap().find(consider_color);
|
||||
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();
|
||||
}
|
||||
|
||||
+338
-192
@@ -26,6 +26,76 @@
|
||||
|
||||
#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
|
||||
namespace EQ
|
||||
@@ -62,7 +132,7 @@ namespace EQ
|
||||
using RoF2::invtype::KRONO_SIZE;
|
||||
using RoF2::invtype::OTHER_SIZE;
|
||||
|
||||
using Titanium::invtype::TRADE_NPC_SIZE;
|
||||
using RoF2::invtype::TRADE_NPC_SIZE;
|
||||
|
||||
using RoF2::invtype::TYPE_INVALID;
|
||||
using RoF2::invtype::TYPE_BEGIN;
|
||||
@@ -89,7 +159,7 @@ namespace EQ
|
||||
using RoF2::invslot::SLOT_INVALID;
|
||||
using RoF2::invslot::SLOT_BEGIN;
|
||||
|
||||
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
|
||||
using RoF2::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
|
||||
|
||||
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
|
||||
|
||||
@@ -109,28 +179,28 @@ namespace EQ
|
||||
using RoF2::invslot::BONUS_STAT_END;
|
||||
using RoF2::invslot::BONUS_SKILL_END;
|
||||
|
||||
using Titanium::invslot::BANK_BEGIN;
|
||||
using SoF::invslot::BANK_END;
|
||||
using RoF2::invslot::BANK_BEGIN;
|
||||
using RoF2::invslot::BANK_END;
|
||||
|
||||
using Titanium::invslot::SHARED_BANK_BEGIN;
|
||||
using Titanium::invslot::SHARED_BANK_END;
|
||||
using RoF2::invslot::SHARED_BANK_BEGIN;
|
||||
using RoF2::invslot::SHARED_BANK_END;
|
||||
|
||||
using Titanium::invslot::TRADE_BEGIN;
|
||||
using Titanium::invslot::TRADE_END;
|
||||
using RoF2::invslot::TRADE_BEGIN;
|
||||
using RoF2::invslot::TRADE_END;
|
||||
|
||||
using Titanium::invslot::TRADE_NPC_END;
|
||||
using RoF2::invslot::TRADE_NPC_END;
|
||||
|
||||
using Titanium::invslot::WORLD_BEGIN;
|
||||
using Titanium::invslot::WORLD_END;
|
||||
using RoF2::invslot::WORLD_BEGIN;
|
||||
using RoF2::invslot::WORLD_END;
|
||||
|
||||
using Titanium::invslot::TRIBUTE_BEGIN;
|
||||
using Titanium::invslot::TRIBUTE_END;
|
||||
using RoF2::invslot::TRIBUTE_BEGIN;
|
||||
using RoF2::invslot::TRIBUTE_END;
|
||||
|
||||
using Titanium::invslot::GUILD_TRIBUTE_BEGIN;
|
||||
using Titanium::invslot::GUILD_TRIBUTE_END;
|
||||
using RoF2::invslot::GUILD_TRIBUTE_BEGIN;
|
||||
using RoF2::invslot::GUILD_TRIBUTE_END;
|
||||
|
||||
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
|
||||
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
|
||||
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
|
||||
|
||||
using RoF2::invslot::EQUIPMENT_BITMASK;
|
||||
using RoF2::invslot::GENERAL_BITMASK;
|
||||
@@ -144,38 +214,40 @@ namespace EQ
|
||||
} // namespace invslot
|
||||
|
||||
namespace invbag {
|
||||
using Titanium::invbag::SLOT_INVALID;
|
||||
using Titanium::invbag::SLOT_BEGIN;
|
||||
using Titanium::invbag::SLOT_END;
|
||||
using Titanium::invbag::SLOT_COUNT;
|
||||
using RoF2::invbag::SLOT_INVALID;
|
||||
using RoF2::invbag::SLOT_BEGIN;
|
||||
using RoF2::invbag::SLOT_END;
|
||||
using RoF2::invbag::SLOT_COUNT;
|
||||
|
||||
using Titanium::invbag::GENERAL_BAGS_BEGIN;
|
||||
using RoF2::invslot::WORLD_END;
|
||||
|
||||
const int16 GENERAL_BAGS_BEGIN = WORLD_END + 1;
|
||||
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
|
||||
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
|
||||
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
|
||||
|
||||
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
|
||||
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
|
||||
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
|
||||
|
||||
const int16 CURSOR_BAG_BEGIN = 351;
|
||||
const int16 CURSOR_BAG_BEGIN = GENERAL_BAGS_END + 1;
|
||||
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
|
||||
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
|
||||
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::BANK_BAGS_BEGIN;
|
||||
const int16 BANK_BAGS_BEGIN = CURSOR_BAG_END + 1;
|
||||
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
|
||||
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
|
||||
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
|
||||
|
||||
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
|
||||
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
|
||||
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::SHARED_BANK_BAGS_BEGIN;
|
||||
const int16 SHARED_BANK_BAGS_BEGIN = BANK_BAGS_END + 1;
|
||||
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
|
||||
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
|
||||
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::TRADE_BAGS_BEGIN;
|
||||
const int16 TRADE_BAGS_BEGIN = SHARED_BANK_BAGS_END + 1;
|
||||
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
|
||||
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
|
||||
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::GetInvBagIndexName;
|
||||
using RoF2::invbag::GetInvBagIndexName;
|
||||
|
||||
} // namespace invbag
|
||||
|
||||
@@ -204,19 +276,6 @@ namespace EQ
|
||||
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);
|
||||
|
||||
enum StanceType : int {
|
||||
stanceUnknown = 0,
|
||||
stancePassive,
|
||||
stanceBalanced,
|
||||
stanceEfficient,
|
||||
stanceReactive,
|
||||
stanceAggressive,
|
||||
stanceAssist,
|
||||
stanceBurn,
|
||||
stanceEfficient2,
|
||||
stanceBurnAE
|
||||
};
|
||||
|
||||
enum BotSpellIDs : int {
|
||||
Warrior = 3001,
|
||||
Cleric,
|
||||
@@ -267,70 +326,6 @@ namespace EQ
|
||||
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 {
|
||||
None,
|
||||
Raining,
|
||||
@@ -350,16 +345,14 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum EmoteTypes : uint8 {
|
||||
Say,
|
||||
Emote,
|
||||
Shout,
|
||||
Proximity
|
||||
};
|
||||
|
||||
const char *GetStanceName(StanceType stance_type);
|
||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||
|
||||
extern const std::map<int, std::string>& GetLanguageMap();
|
||||
std::string GetLanguageName(int language_id);
|
||||
extern const std::map<uint8, std::string>& GetLanguageMap();
|
||||
std::string GetLanguageName(uint8 language_id);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
||||
std::string GetLDoNThemeName(uint32 theme_id);
|
||||
@@ -367,12 +360,6 @@ namespace EQ
|
||||
extern const std::map<int8, std::string>& GetFlyModeMap();
|
||||
std::string GetFlyModeName(int8 flymode_id);
|
||||
|
||||
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
|
||||
std::string GetBodyTypeName(bodyType bodytype_id);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetAccountStatusMap();
|
||||
std::string GetAccountStatusName(uint8 account_status);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
||||
std::string GetConsiderLevelName(uint8 consider_level);
|
||||
|
||||
@@ -385,9 +372,6 @@ namespace EQ
|
||||
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
|
||||
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();
|
||||
std::string GetWeatherTypeName(uint8 weather_type);
|
||||
|
||||
@@ -397,9 +381,11 @@ namespace EQ
|
||||
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
||||
std::string GetEmoteTypeName(uint8 emote_type);
|
||||
|
||||
const int STANCE_TYPE_FIRST = stancePassive;
|
||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
||||
std::string GetAppearanceTypeName(uint32 animation_type);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetConsiderColorMap();
|
||||
std::string GetConsiderColorName(uint32 consider_color);
|
||||
|
||||
} /*constants*/
|
||||
|
||||
@@ -454,37 +440,6 @@ namespace EQ
|
||||
|
||||
} // 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 {
|
||||
RoamBoxPauseInProgress = -3,
|
||||
QuestControlNoGrid = -2,
|
||||
@@ -498,7 +453,7 @@ namespace EQ
|
||||
Raid,
|
||||
Guild
|
||||
};
|
||||
}; // namespace consent
|
||||
};
|
||||
} /*EQEmu*/
|
||||
|
||||
enum ServerLockType : int {
|
||||
@@ -507,26 +462,6 @@ enum ServerLockType : int {
|
||||
Unlock
|
||||
};
|
||||
|
||||
enum AccountStatus : uint8 {
|
||||
Player = 0,
|
||||
Steward = 10,
|
||||
ApprenticeGuide = 20,
|
||||
Guide = 50,
|
||||
QuestTroupe = 80,
|
||||
SeniorGuide = 81,
|
||||
GMTester = 85,
|
||||
EQSupport = 90,
|
||||
GMStaff = 95,
|
||||
GMAdmin = 100,
|
||||
GMLeadAdmin = 150,
|
||||
QuestMaster = 160,
|
||||
GMAreas = 170,
|
||||
GMCoder = 180,
|
||||
GMMgmt = 200,
|
||||
GMImpossible = 250,
|
||||
Max = 255
|
||||
};
|
||||
|
||||
enum Invisibility : uint8 {
|
||||
Visible,
|
||||
Invisible,
|
||||
@@ -552,6 +487,17 @@ enum ConsiderLevel : uint8 {
|
||||
Scowls
|
||||
};
|
||||
|
||||
namespace ConsiderColor {
|
||||
constexpr uint32 Green = 2;
|
||||
constexpr uint32 DarkBlue = 4;
|
||||
constexpr uint32 Gray = 6;
|
||||
constexpr uint32 White = 10;
|
||||
constexpr uint32 Red = 13;
|
||||
constexpr uint32 Yellow = 15;
|
||||
constexpr uint32 LightBlue = 18;
|
||||
constexpr uint32 WhiteTitanium = 20;
|
||||
};
|
||||
|
||||
enum TargetDescriptionType : uint8 {
|
||||
LCSelf,
|
||||
UCSelf,
|
||||
@@ -567,19 +513,6 @@ enum ReloadWorld : uint8 {
|
||||
ForceRepop
|
||||
};
|
||||
|
||||
enum BucketComparison : uint8 {
|
||||
BucketEqualTo = 0,
|
||||
BucketNotEqualTo,
|
||||
BucketGreaterThanOrEqualTo,
|
||||
BucketLesserThanOrEqualTo,
|
||||
BucketGreaterThan,
|
||||
BucketLesserThan,
|
||||
BucketIsAny,
|
||||
BucketIsNotAny,
|
||||
BucketIsBetween,
|
||||
BucketIsNotBetween
|
||||
};
|
||||
|
||||
enum class EntityFilterType {
|
||||
All,
|
||||
Bots,
|
||||
@@ -593,6 +526,131 @@ enum class ApplySpellType {
|
||||
Raid
|
||||
};
|
||||
|
||||
namespace SpecialAbility {
|
||||
constexpr int Summon = 1;
|
||||
constexpr int Enrage = 2;
|
||||
constexpr int Rampage = 3;
|
||||
constexpr int AreaRampage = 4;
|
||||
constexpr int Flurry = 5;
|
||||
constexpr int TripleAttack = 6;
|
||||
constexpr int QuadrupleAttack = 7;
|
||||
constexpr int DualWield = 8;
|
||||
constexpr int BaneAttack = 9;
|
||||
constexpr int MagicalAttack = 10;
|
||||
constexpr int RangedAttack = 11;
|
||||
constexpr int SlowImmunity = 12;
|
||||
constexpr int MesmerizeImmunity = 13;
|
||||
constexpr int CharmImmunity = 14;
|
||||
constexpr int StunImmunity = 15;
|
||||
constexpr int SnareImmunity = 16;
|
||||
constexpr int FearImmunity = 17;
|
||||
constexpr int DispellImmunity = 18;
|
||||
constexpr int MeleeImmunity = 19;
|
||||
constexpr int MagicImmunity = 20;
|
||||
constexpr int FleeingImmunity = 21;
|
||||
constexpr int MeleeImmunityExceptBane = 22;
|
||||
constexpr int MeleeImmunityExceptMagical = 23;
|
||||
constexpr int AggroImmunity = 24;
|
||||
constexpr int BeingAggroImmunity = 25;
|
||||
constexpr int CastingFromRangeImmunity = 26;
|
||||
constexpr int FeignDeathImmunity = 27;
|
||||
constexpr int TauntImmunity = 28;
|
||||
constexpr int TunnelVision = 29;
|
||||
constexpr int NoBuffHealFriends = 30;
|
||||
constexpr int PacifyImmunity = 31;
|
||||
constexpr int Leash = 32;
|
||||
constexpr int Tether = 33;
|
||||
constexpr int DestructibleObject = 34;
|
||||
constexpr int HarmFromClientImmunity = 35;
|
||||
constexpr int AlwaysFlee = 36;
|
||||
constexpr int FleePercent = 37;
|
||||
constexpr int AllowBeneficial = 38;
|
||||
constexpr int DisableMelee = 39;
|
||||
constexpr int NPCChaseDistance = 40;
|
||||
constexpr int AllowedToTank = 41;
|
||||
constexpr int IgnoreRootAggroRules = 42;
|
||||
constexpr int CastingResistDifficulty = 43;
|
||||
constexpr int CounterAvoidDamage = 44;
|
||||
constexpr int ProximityAggro = 45;
|
||||
constexpr int RangedAttackImmunity = 46;
|
||||
constexpr int ClientDamageImmunity = 47;
|
||||
constexpr int NPCDamageImmunity = 48;
|
||||
constexpr int ClientAggroImmunity = 49;
|
||||
constexpr int NPCAggroImmunity = 50;
|
||||
constexpr int ModifyAvoidDamage = 51;
|
||||
constexpr int MemoryFadeImmunity = 52;
|
||||
constexpr int OpenImmunity = 53;
|
||||
constexpr int AssassinateImmunity = 54;
|
||||
constexpr int HeadshotImmunity = 55;
|
||||
constexpr int BotAggroImmunity = 56;
|
||||
constexpr int BotDamageImmunity = 57;
|
||||
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
|
||||
{
|
||||
@@ -618,4 +676,92 @@ namespace HeroicBonusBucket
|
||||
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 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*/
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef enum { //EQEmu internal opcodes list
|
||||
_maxEmuOpcode
|
||||
} EmuOpcode;
|
||||
|
||||
constexpr int format_as(EmuOpcode opcode) { return static_cast<int>(opcode); }
|
||||
extern const char *OpcodeNames[_maxEmuOpcode+1];
|
||||
|
||||
#endif
|
||||
|
||||
+29
-1
@@ -67,6 +67,7 @@ N(OP_Buff),
|
||||
N(OP_BuffCreate),
|
||||
N(OP_BuffRemoveRequest),
|
||||
N(OP_Bug),
|
||||
N(OP_BuyerItems),
|
||||
N(OP_CameraEffect),
|
||||
N(OP_Camp),
|
||||
N(OP_CancelSneakHide),
|
||||
@@ -228,6 +229,7 @@ N(OP_GuildBank),
|
||||
N(OP_GuildBankItemList),
|
||||
N(OP_GuildCreate),
|
||||
N(OP_GuildDelete),
|
||||
N(OP_GuildDeleteGuild),
|
||||
N(OP_GuildDemote),
|
||||
N(OP_GuildInvite),
|
||||
N(OP_GuildInviteAccept),
|
||||
@@ -239,15 +241,33 @@ N(OP_GuildManageStatus),
|
||||
N(OP_GuildMemberLevelUpdate),
|
||||
N(OP_GuildMemberList),
|
||||
N(OP_GuildMemberUpdate),
|
||||
N(OP_GuildMemberLevel),
|
||||
N(OP_GuildMemberRankAltBanker),
|
||||
N(OP_GuildMemberPublicNote),
|
||||
N(OP_GuildMemberAdd),
|
||||
N(OP_GuildMemberRename),
|
||||
N(OP_GuildMemberDelete),
|
||||
N(OP_GuildMemberDetails),
|
||||
N(OP_GuildRenameGuild),
|
||||
N(OP_GuildMOTD),
|
||||
N(OP_GuildPeace),
|
||||
N(OP_GuildPromote),
|
||||
N(OP_GuildPublicNote),
|
||||
N(OP_GuildRemove),
|
||||
N(OP_GuildSelectTribute),
|
||||
N(OP_GuildModifyBenefits),
|
||||
N(OP_GuildTributeToggleReq),
|
||||
N(OP_GuildTributeToggleReply),
|
||||
N(OP_GuildOptInOut),
|
||||
N(OP_GuildSaveActiveTributes),
|
||||
N(OP_GuildSendActiveTributes),
|
||||
N(OP_GuildTributeFavorAndTimer),
|
||||
N(OP_GuildsList),
|
||||
N(OP_GuildStatus),
|
||||
N(OP_GuildTributeInfo),
|
||||
N(OP_GuildUpdateURLAndChannel),
|
||||
N(OP_GuildUpdate),
|
||||
N(OP_GuildTributeDonateItem),
|
||||
N(OP_GuildTributeDonatePlat),
|
||||
N(OP_GuildWar),
|
||||
N(OP_Heartbeat),
|
||||
N(OP_Hide),
|
||||
@@ -425,6 +445,7 @@ N(OP_ReqClientSpawn),
|
||||
N(OP_ReqNewZone),
|
||||
N(OP_RequestClientZoneChange),
|
||||
N(OP_RequestDuel),
|
||||
N(OP_RequestGuildTributes),
|
||||
N(OP_RequestKnowledgeBase),
|
||||
N(OP_RequestTitles),
|
||||
N(OP_RespawnWindow),
|
||||
@@ -490,6 +511,11 @@ N(OP_ShopEndConfirm),
|
||||
N(OP_ShopItem),
|
||||
N(OP_ShopPlayerBuy),
|
||||
N(OP_ShopPlayerSell),
|
||||
N(OP_ShopSendParcel),
|
||||
N(OP_ShopDeleteParcel),
|
||||
N(OP_ShopRespondParcel),
|
||||
N(OP_ShopRetrieveParcel),
|
||||
N(OP_ShopParcelIcon),
|
||||
N(OP_ShopRequest),
|
||||
N(OP_SimpleMessage),
|
||||
N(OP_SkillUpdate),
|
||||
@@ -508,6 +534,7 @@ N(OP_Stamina),
|
||||
N(OP_Stun),
|
||||
N(OP_Surname),
|
||||
N(OP_SwapSpell),
|
||||
N(OP_SystemFingerprint),
|
||||
N(OP_TargetBuffs),
|
||||
N(OP_TargetCommand),
|
||||
N(OP_TargetHoTT),
|
||||
@@ -532,6 +559,7 @@ N(OP_TradeBusy),
|
||||
N(OP_TradeCoins),
|
||||
N(OP_TradeMoneyUpdate),
|
||||
N(OP_Trader),
|
||||
N(OP_TraderBulkSend),
|
||||
N(OP_TraderBuy),
|
||||
N(OP_TraderDelItem),
|
||||
N(OP_TradeRequest),
|
||||
|
||||
+199
-119
@@ -23,61 +23,59 @@
|
||||
#include "skills.h"
|
||||
#include "types.h"
|
||||
|
||||
namespace AppearanceType {
|
||||
constexpr uint32 Die = 0; // Causes the client to keel over and zone to bind point (default action)
|
||||
constexpr uint32 WhoLevel = 1; // Level that shows up on /who
|
||||
constexpr uint32 MaxHealth = 2;
|
||||
constexpr uint32 Invisibility = 3; // 0 = Visible, 1 = Invisible
|
||||
constexpr uint32 PVP = 4; // 0 = Non-PVP, 1 = PVP
|
||||
constexpr uint32 Light = 5; // Light type emitted by player (lightstone, shiny shield)
|
||||
constexpr uint32 Animation = 14; // 100 = Standing, 102 = Freeze, 105 = Looting, 110 = Sitting, 111 = Crouching, 115 = Lying
|
||||
constexpr uint32 Sneak = 15; // 0 = Normal, 1 = Sneaking
|
||||
constexpr uint32 SpawnID = 16; // Server -> Client, sets player spawn ID
|
||||
constexpr uint32 Health = 17; // Client->Server, my HP has changed (like regen tic)
|
||||
constexpr uint32 Linkdead = 18; // 0 = Normal, 1 = Linkdead
|
||||
constexpr uint32 FlyMode = 19; // 0 = Off, 1 = Flying, 2 = Levitating, 3 = Water, 4 = Floating, 5 = Levitating while Running
|
||||
constexpr uint32 GM = 20; // 0 = Non-GM, 1 = GM
|
||||
constexpr uint32 Anonymous = 21; // 0 = Non-Anonymous, 1 = Anonymous, 2 = Roleplaying
|
||||
constexpr uint32 GuildID = 22;
|
||||
constexpr uint32 GuildRank = 23;
|
||||
constexpr uint32 AFK = 24; // 0 = Non-AFK, 1 = AFK
|
||||
constexpr uint32 Pet = 25; // Parameter is Entity ID of owner, or 0 for when charm breaks
|
||||
constexpr uint32 Summoned = 27;
|
||||
constexpr uint32 Split = 28; // 0 = No Split, 1 = Auto Split
|
||||
constexpr uint32 Size = 29; // Spawn's Size
|
||||
constexpr uint32 SetType = 30; // 0 = PC, 1 = NPC, 2 = Corpse
|
||||
constexpr uint32 NPCName = 31; // Change PC name color to NPC name color
|
||||
constexpr uint32 AARank = 32; // AA Rank Title ID, title in /who?
|
||||
constexpr uint32 CancelSneakHide = 33; // Turns off Hide and Sneak
|
||||
constexpr uint32 AreaHealthRegen = 35; // Guild Hall Regeneration Pool sets to value * 0.001
|
||||
constexpr uint32 AreaManaRegen = 36; // Guild Hall Regeneration Pool sets to value * 0.001
|
||||
constexpr uint32 AreaEnduranceRegen = 37; // Guild Hall Regeneration Pool sets to value * 0.001
|
||||
constexpr uint32 FreezeBeneficialBuffs = 38; // Freezes beneficial buff timers for PCs
|
||||
constexpr uint32 NPCTintIndex = 39;
|
||||
constexpr uint32 GroupAutoConsent = 40; // Auto Consent Group
|
||||
constexpr uint32 RaidAutoConsent = 41; // Auto Consent Raid
|
||||
constexpr uint32 GuildAutoConsent = 42; // Auto Consent Guild
|
||||
constexpr uint32 ShowHelm = 43; // 0 = Hide, 1 = Show
|
||||
constexpr uint32 DamageState = 44; // The damage state of a destructible object (0 through 10) plays sound IDs, most only have 2 or 4 states though
|
||||
constexpr uint32 EQPlayers = 45; // EQ Players Update
|
||||
constexpr uint32 FindBits = 46; // Set Find Bits?
|
||||
constexpr uint32 TextureType = 48; // Texture Type?
|
||||
constexpr uint32 FacePick = 49; // Turns off face pick window?
|
||||
constexpr uint32 AntiCheat = 51; // Sent by the client randomly telling the server how long since last action has occurred
|
||||
constexpr uint32 GuildShow = 52;
|
||||
constexpr uint32 OfflineMode = 53; // Offline Mode
|
||||
}
|
||||
|
||||
//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2)
|
||||
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
|
||||
#define AT_WhoLevel 1 // the level that shows up on /who
|
||||
#define AT_HPMax 2 // idk
|
||||
#define AT_Invis 3 // 0 = visible, 1 = invisible
|
||||
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
|
||||
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
|
||||
#define AT_Anim 14 // 100=standing, 110=sitting, 111=ducking, 115=feigned, 105=looting
|
||||
#define AT_Sneak 15 // 0 = normal, 1 = sneaking
|
||||
#define AT_SpawnID 16 // server to client, sets player spawn id
|
||||
#define AT_HP 17 // Client->Server, my HP has changed (like regen tic)
|
||||
#define AT_Linkdead 18 // 0 = normal, 1 = linkdead
|
||||
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate max 5, see GravityBehavior enum
|
||||
#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM
|
||||
#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay
|
||||
#define AT_GuildID 22
|
||||
#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader
|
||||
#define AT_AFK 24 // 0 = normal, 1 = afk
|
||||
#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks
|
||||
#define AT_Summoned 27 // Unsure
|
||||
#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only)
|
||||
#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2)
|
||||
#define AT_SetType 30 // 0 = PC, 1 = NPC, 2 <= = corpse
|
||||
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name, Trader on RoF2?
|
||||
#define AT_AARank 32 // AA Rank Title ID thingy, does is this the title in /who?
|
||||
#define AT_CancelSneakHide 33 // Turns off Hide and Sneak
|
||||
//#define AT_34 34 // unknown (present: SoF, absent: RoF2)
|
||||
#define AT_AreaHPRegen 35 // guild hall regen pool sets to value * 0.001
|
||||
#define AT_AreaManaRegen 36 // guild hall regen pool sets to value * 0.001
|
||||
#define AT_AreaEndRegen 37 // guild hall regen pool sets to value * 0.001
|
||||
#define AT_FreezeBuffs 38 // Freezes beneficial buff timers
|
||||
#define AT_NpcTintIndex 39 // not 100% sure
|
||||
#define AT_GroupConsent 40 // auto consent group
|
||||
#define AT_RaidConsent 41 // auto consent raid
|
||||
#define AT_GuildConsent 42 // auto consent guild
|
||||
#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic
|
||||
#define AT_DamageState 44 // The damage state of a destructible object (0 through 10) plays soundids most only have 2 or 4 states though
|
||||
#define AT_EQPlayers 45 // /eqplayersupdate
|
||||
#define AT_FindBits 46 // set FindBits, whatever those are!
|
||||
#define AT_TextureType 48 // TextureType
|
||||
#define AT_FacePick 49 // Turns off face pick window? maybe ...
|
||||
#define AT_AntiCheat 51 // sent by the client randomly telling the server how long since last action has occured
|
||||
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
|
||||
#define AT_Offline 53 // Offline mode
|
||||
|
||||
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
||||
|
||||
// animations for AT_Anim
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_STAND 0x64
|
||||
#define ANIM_SIT 0x6e
|
||||
#define ANIM_CROUCH 0x6f
|
||||
#define ANIM_DEATH 0x73
|
||||
#define ANIM_LOOT 0x69
|
||||
namespace Animation {
|
||||
constexpr uint32 Standing = 100;
|
||||
constexpr uint32 Freeze = 102;
|
||||
constexpr uint32 Looting = 105;
|
||||
constexpr uint32 Sitting = 110;
|
||||
constexpr uint32 Crouching = 111;
|
||||
constexpr uint32 Lying = 115;
|
||||
}
|
||||
|
||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||
|
||||
@@ -686,6 +684,53 @@ namespace Zones {
|
||||
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
||||
}
|
||||
|
||||
namespace Language {
|
||||
constexpr uint8 CommonTongue = 0;
|
||||
constexpr uint8 Barbarian = 1;
|
||||
constexpr uint8 Erudian = 2;
|
||||
constexpr uint8 Elvish = 3;
|
||||
constexpr uint8 DarkElvish = 4;
|
||||
constexpr uint8 Dwarvish = 5;
|
||||
constexpr uint8 Troll = 6;
|
||||
constexpr uint8 Ogre = 7;
|
||||
constexpr uint8 Gnomish = 8;
|
||||
constexpr uint8 Halfling = 9;
|
||||
constexpr uint8 ThievesCant = 10;
|
||||
constexpr uint8 OldErudian = 11;
|
||||
constexpr uint8 ElderElvish = 12;
|
||||
constexpr uint8 Froglok = 13;
|
||||
constexpr uint8 Goblin = 14;
|
||||
constexpr uint8 Gnoll = 15;
|
||||
constexpr uint8 CombineTongue = 16;
|
||||
constexpr uint8 ElderTeirDal = 17;
|
||||
constexpr uint8 Lizardman = 18;
|
||||
constexpr uint8 Orcish = 19;
|
||||
constexpr uint8 Faerie = 20;
|
||||
constexpr uint8 Dragon = 21;
|
||||
constexpr uint8 ElderDragon = 22;
|
||||
constexpr uint8 DarkSpeech = 23;
|
||||
constexpr uint8 VahShir = 24;
|
||||
constexpr uint8 Alaran = 25;
|
||||
constexpr uint8 Hadal = 26;
|
||||
constexpr uint8 Unknown27 = 27;
|
||||
|
||||
constexpr uint8 MaxValue = 100;
|
||||
}
|
||||
namespace PetInfoType {
|
||||
constexpr int Current = 0;
|
||||
constexpr int Suspended = 1;
|
||||
}
|
||||
|
||||
namespace BuffEffectType {
|
||||
constexpr uint8 None = 0;
|
||||
constexpr uint8 Buff = 2;
|
||||
constexpr uint8 InverseBuff = 4;
|
||||
}
|
||||
|
||||
namespace AlternateCurrencyMode {
|
||||
constexpr uint32 Update = 7;
|
||||
constexpr uint32 Populate = 8;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
FilterNone = 0,
|
||||
@@ -713,10 +758,10 @@ typedef enum {
|
||||
FilterFocusEffects = 22, //0=show, 1=hide
|
||||
FilterPetSpells = 23, //0=show, 1=hide
|
||||
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
||||
FilterUnknown25 = 25,
|
||||
FilterUnknown26 = 26,
|
||||
FilterUnknown27 = 27,
|
||||
FilterUnknown28 = 28,
|
||||
FilterItemSpeech = 25, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed
|
||||
_FilterCount
|
||||
} eqFilterType;
|
||||
|
||||
@@ -727,67 +772,47 @@ typedef enum {
|
||||
FilterShowSelfOnly
|
||||
} eqFilterMode;
|
||||
|
||||
#define STAT_STR 0
|
||||
#define STAT_STA 1
|
||||
#define STAT_AGI 2
|
||||
#define STAT_DEX 3
|
||||
#define STAT_INT 4
|
||||
#define STAT_WIS 5
|
||||
#define STAT_CHA 6
|
||||
#define STAT_MAGIC 7
|
||||
#define STAT_COLD 8
|
||||
#define STAT_FIRE 9
|
||||
#define STAT_POISON 10
|
||||
#define STAT_DISEASE 11
|
||||
#define STAT_MANA 12
|
||||
#define STAT_HP 13
|
||||
#define STAT_AC 14
|
||||
#define STAT_ENDURANCE 15
|
||||
#define STAT_ATTACK 16
|
||||
#define STAT_HP_REGEN 17
|
||||
#define STAT_MANA_REGEN 18
|
||||
#define STAT_HASTE 19
|
||||
#define STAT_DAMAGE_SHIELD 20
|
||||
|
||||
/*
|
||||
** Recast timer types. Used as an off set to charProfileStruct timers.
|
||||
**
|
||||
** (Another orphaned enumeration...)
|
||||
*/
|
||||
enum RecastTimerTypes
|
||||
{
|
||||
RecTimer_0 = 0,
|
||||
RecTimer_1,
|
||||
RecTimer_WeaponHealClick, // 2
|
||||
RecTimer_MuramiteBaneNukeClick, // 3
|
||||
RecTimer_4,
|
||||
RecTimer_DispellClick, // 5 (also click heal orbs?)
|
||||
RecTimer_Epic, // 6
|
||||
RecTimer_OoWBPClick, // 7
|
||||
RecTimer_VishQuestClassItem, // 8
|
||||
RecTimer_HealPotion, // 9
|
||||
RecTimer_10,
|
||||
RecTimer_11,
|
||||
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
|
||||
};
|
||||
#define STAT_STR 0
|
||||
#define STAT_STA 1
|
||||
#define STAT_AGI 2
|
||||
#define STAT_DEX 3
|
||||
#define STAT_INT 4
|
||||
#define STAT_WIS 5
|
||||
#define STAT_CHA 6
|
||||
#define STAT_MAGIC 7
|
||||
#define STAT_COLD 8
|
||||
#define STAT_FIRE 9
|
||||
#define STAT_POISON 10
|
||||
#define STAT_DISEASE 11
|
||||
#define STAT_MANA 12
|
||||
#define STAT_HP 13
|
||||
#define STAT_AC 14
|
||||
#define STAT_ENDURANCE 15
|
||||
#define STAT_ATTACK 16
|
||||
#define STAT_HP_REGEN 17
|
||||
#define STAT_MANA_REGEN 18
|
||||
#define STAT_HASTE 19
|
||||
#define STAT_DAMAGE_SHIELD 20
|
||||
#define STAT_DS_MITIGATION 22
|
||||
#define STAT_HEAL_AMOUNT 23
|
||||
#define STAT_SPELL_DAMAGE 24
|
||||
#define STAT_CLAIRVOYANCE 25
|
||||
#define STAT_HEROIC_AGILITY 26
|
||||
#define STAT_HEROIC_CHARISMA 27
|
||||
#define STAT_HEROIC_DEXTERITY 28
|
||||
#define STAT_HEROIC_INTELLIGENCE 29
|
||||
#define STAT_HEROIC_STAMINA 30
|
||||
#define STAT_HEROIC_STRENGTH 31
|
||||
#define STAT_HEROIC_WISDOM 32
|
||||
#define STAT_BASH 33
|
||||
#define STAT_BACKSTAB 34
|
||||
#define STAT_DRAGON_PUNCH 35
|
||||
#define STAT_EAGLE_STRIKE 36
|
||||
#define STAT_FLYING_KICK 37
|
||||
#define STAT_KICK 38
|
||||
#define STAT_ROUND_KICK 39
|
||||
#define STAT_TIGER_CLAW 40
|
||||
#define STAT_FRENZY 41
|
||||
|
||||
static const uint8 DamageTypeSomething = 0x1C; //0x1c is something...
|
||||
static const uint8 DamageTypeFalling = 0xFC;
|
||||
@@ -1052,4 +1077,59 @@ enum ScribeSpellActions
|
||||
Unmemorize
|
||||
};
|
||||
|
||||
enum SpellTimeRestrictions
|
||||
{
|
||||
NoRestriction,
|
||||
Day,
|
||||
Night
|
||||
};
|
||||
|
||||
enum MoneyTypes
|
||||
{
|
||||
Copper,
|
||||
Silver,
|
||||
Gold,
|
||||
Platinum
|
||||
};
|
||||
|
||||
enum MoneySubtypes
|
||||
{
|
||||
Personal,
|
||||
Bank,
|
||||
Cursor,
|
||||
SharedBank // Platinum Only
|
||||
};
|
||||
|
||||
namespace RaidLootType {
|
||||
constexpr uint32 LeaderOnly = 1;
|
||||
constexpr uint32 LeaderAndGroupLeadersOnly = 2;
|
||||
constexpr uint32 LeaderSelected = 3;
|
||||
constexpr uint32 EntireRaid = 4;
|
||||
}
|
||||
|
||||
namespace LeadershipAbilitySlot {
|
||||
constexpr uint16 HealthOfTargetsTarget = 14;
|
||||
}
|
||||
|
||||
enum ExpSource
|
||||
{
|
||||
Quest,
|
||||
GM,
|
||||
Kill,
|
||||
Death,
|
||||
Resurrection,
|
||||
LDoNChest,
|
||||
Task,
|
||||
Sacrifice
|
||||
};
|
||||
|
||||
#define PARCEL_SEND_ITEMS 0
|
||||
#define PARCEL_SEND_MONEY 1
|
||||
#define PARCEL_MONEY_ITEM_ID 99990 // item id of money
|
||||
#define PARCEL_LIMIT 5
|
||||
#define PARCEL_BEGIN_SLOT 1
|
||||
|
||||
namespace DoorType {
|
||||
constexpr uint32 BuyerStall = 155;
|
||||
}
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
+1026
-243
File diff suppressed because it is too large
Load Diff
+111
-15
@@ -20,9 +20,12 @@
|
||||
#include "eqemu_config.h"
|
||||
#include "misc_functions.h"
|
||||
#include "strings.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "json/json.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
|
||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||
@@ -111,13 +114,12 @@ void EQEmuConfig::parse_config()
|
||||
DisableConfigChecks = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* UCS
|
||||
*/
|
||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
|
||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
|
||||
|
||||
|
||||
CheckUcsConfigConversion();
|
||||
|
||||
m_ucs_host = _root["server"]["ucs"].get("host", "eqchat.eqemulator.net").asString();
|
||||
m_ucs_port = Strings::ToUnsignedInt(_root["server"]["ucs"].get("port", "7778").asString());
|
||||
|
||||
/**
|
||||
* Database
|
||||
@@ -169,6 +171,7 @@ void EQEmuConfig::parse_config()
|
||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||
OpcodeDir = _root["server"]["directories"].get("opcodes", "./").asString();
|
||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||
|
||||
@@ -246,16 +249,16 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
||||
return (WorldHTTPEnabled ? "true" : "false");
|
||||
}
|
||||
if (var_name == "ChatHost") {
|
||||
return (ChatHost);
|
||||
return (m_ucs_host);
|
||||
}
|
||||
if (var_name == "ChatPort") {
|
||||
return (itoa(ChatPort));
|
||||
return (itoa(m_ucs_port));
|
||||
}
|
||||
if (var_name == "MailHost") {
|
||||
return (MailHost);
|
||||
return (m_ucs_host);
|
||||
}
|
||||
if (var_name == "MailPort") {
|
||||
return (itoa(MailPort));
|
||||
return (itoa(m_ucs_port));
|
||||
}
|
||||
if (var_name == "DatabaseHost") {
|
||||
return (DatabaseHost);
|
||||
@@ -362,10 +365,8 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
|
||||
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
|
||||
std::cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << std::endl;
|
||||
std::cout << "ChatHost = " << ChatHost << std::endl;
|
||||
std::cout << "ChatPort = " << ChatPort << std::endl;
|
||||
std::cout << "MailHost = " << MailHost << std::endl;
|
||||
std::cout << "MailPort = " << MailPort << std::endl;
|
||||
std::cout << "UCSHost = " << m_ucs_host << std::endl;
|
||||
std::cout << "UCSPort = " << m_ucs_port << std::endl;
|
||||
std::cout << "DatabaseHost = " << DatabaseHost << std::endl;
|
||||
std::cout << "DatabaseUsername = " << DatabaseUsername << std::endl;
|
||||
std::cout << "DatabasePassword = " << DatabasePassword << std::endl;
|
||||
@@ -392,3 +393,98 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||
}
|
||||
|
||||
const std::string &EQEmuConfig::GetUCSHost() const
|
||||
{
|
||||
return m_ucs_host;
|
||||
}
|
||||
|
||||
uint16 EQEmuConfig::GetUCSPort() const
|
||||
{
|
||||
return m_ucs_port;
|
||||
}
|
||||
|
||||
void EQEmuConfig::CheckUcsConfigConversion()
|
||||
{
|
||||
std::string chat_host = _root["server"]["chatserver"].get("host", "").asString();
|
||||
uint32 chat_port = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "0").asString());
|
||||
std::string mail_host = _root["server"]["mailserver"].get("host", "").asString();
|
||||
uint32 mail_port = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "0").asString());
|
||||
std::string ucs_host = _root["server"]["ucs"].get("host", "").asString();
|
||||
|
||||
// automatic ucs legacy configuration migration
|
||||
// if old configuration values are set, let's backup the existing configuration
|
||||
// and migrate to to use the new fields and write the new config
|
||||
if ((!chat_host.empty() || !mail_host.empty()) && ucs_host.empty()) {
|
||||
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
|
||||
|
||||
std::string config_file_path = std::filesystem::path{
|
||||
path.GetServerPath() + "/eqemu_config.json"
|
||||
}.string();
|
||||
|
||||
std::string config_file_bak_path = std::filesystem::path{
|
||||
path.GetServerPath() + "/eqemu_config.ucs-migrate-json.bak"
|
||||
}.string();
|
||||
|
||||
// copy eqemu_config.json to eqemu_config.json.bak
|
||||
std::ifstream src(config_file_path, std::ios::binary);
|
||||
std::ofstream dst(config_file_bak_path, std::ios::binary);
|
||||
dst << src.rdbuf();
|
||||
src.close();
|
||||
|
||||
LogInfo("Old configuration backed up to [{}]", config_file_bak_path);
|
||||
|
||||
// read eqemu_config.json, transplant new fields and write to eqemu_config.json
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
std::ifstream file(config_file_path);
|
||||
if (!reader.parse(file, root)) {
|
||||
LogError("Failed to parse configuration file");
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
|
||||
// get old fields
|
||||
std::string host = !chat_host.empty() ? chat_host : mail_host;
|
||||
if (host.empty()) {
|
||||
host = "eqchat.eqemulator.net";
|
||||
}
|
||||
std::string port = chat_port > 0 ? std::to_string(chat_port) : std::to_string(mail_port);
|
||||
if (port.empty()) {
|
||||
port = "7778";
|
||||
}
|
||||
|
||||
// set new fields
|
||||
root["server"]["ucs"]["host"] = host;
|
||||
root["server"]["ucs"]["port"] = port;
|
||||
|
||||
// unset old fields
|
||||
root["server"].removeMember("chatserver");
|
||||
root["server"].removeMember("mailserver");
|
||||
|
||||
// get Json::Value raw string
|
||||
std::string config = root.toStyledString();
|
||||
|
||||
// format using more modern json library
|
||||
nlohmann::json data = nlohmann::json::parse(config);
|
||||
|
||||
// write to file
|
||||
std::ofstream o(config_file_path);
|
||||
o << std::setw(1) << data << std::endl;
|
||||
o.close();
|
||||
|
||||
// write new config
|
||||
LogInfo("New configuration written to [{}]", config_file_path);
|
||||
LogInfo("Migration complete, please review the new configuration file");
|
||||
|
||||
// reload config internally
|
||||
try {
|
||||
std::ifstream fconfig(config_file_path, std::ifstream::binary);
|
||||
fconfig >> _config->_root;
|
||||
_config->parse_config();
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,14 +62,6 @@ class EQEmuConfig
|
||||
std::string SharedKey;
|
||||
bool DisableConfigChecks;
|
||||
|
||||
// From <chatserver/>
|
||||
std::string ChatHost;
|
||||
uint16 ChatPort;
|
||||
|
||||
// From <mailserver/>
|
||||
std::string MailHost;
|
||||
uint16 MailPort;
|
||||
|
||||
// From <database/>
|
||||
std::string DatabaseHost;
|
||||
std::string DatabaseUsername;
|
||||
@@ -103,6 +95,7 @@ class EQEmuConfig
|
||||
std::string PluginDir;
|
||||
std::string LuaModuleDir;
|
||||
std::string PatchDir;
|
||||
std::string OpcodeDir;
|
||||
std::string SharedMemDir;
|
||||
std::string LogDir;
|
||||
|
||||
@@ -122,12 +115,18 @@ class EQEmuConfig
|
||||
|
||||
bool auto_database_updates;
|
||||
|
||||
const std::string &GetUCSHost() const;
|
||||
uint16 GetUCSPort() const;
|
||||
|
||||
// uint16 DynamicCount;
|
||||
|
||||
// map<string,uint16> StaticZones;
|
||||
|
||||
protected:
|
||||
|
||||
std::string m_ucs_host;
|
||||
uint16 m_ucs_port;
|
||||
|
||||
static EQEmuConfig *_config;
|
||||
Json::Value _root;
|
||||
static std::string ConfigFile;
|
||||
@@ -186,6 +185,7 @@ class EQEmuConfig
|
||||
}
|
||||
|
||||
void Dump() const;
|
||||
void CheckUcsConfigConversion();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+15
-7
@@ -100,6 +100,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::EqTime].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* RFC 5424
|
||||
@@ -649,6 +651,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
}
|
||||
|
||||
// Auto inject categories that don't exist in the database...
|
||||
|
||||
std::vector<LogsysCategoriesRepository::LogsysCategories> db_categories_to_add{};
|
||||
|
||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||
|
||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||
@@ -663,11 +668,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
}
|
||||
|
||||
if (is_missing_in_database && !is_deprecated_category) {
|
||||
LogInfo(
|
||||
"Automatically adding new log category [{}] ({})",
|
||||
Logs::LogCategoryName[i],
|
||||
i
|
||||
);
|
||||
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
|
||||
|
||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||
new_category.log_category_id = i;
|
||||
@@ -676,11 +677,16 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
||||
new_category.log_to_file = log_settings[i].log_to_file;
|
||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
||||
|
||||
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
|
||||
db_categories_to_add.emplace_back(new_category);
|
||||
}
|
||||
}
|
||||
|
||||
if (!db_categories_to_add.empty()) {
|
||||
LogsysCategoriesRepository::ReplaceMany(*m_database, db_categories_to_add);
|
||||
LoadLogDatabaseSettings();
|
||||
return this;
|
||||
}
|
||||
|
||||
LogInfo("Loaded [{}] log categories", categories.size());
|
||||
|
||||
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
||||
@@ -695,6 +701,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_file = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,9 @@ namespace Logs {
|
||||
PlayerEvents,
|
||||
DataBuckets,
|
||||
Zoning,
|
||||
EqTime,
|
||||
Corpses,
|
||||
XTargets,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -237,6 +240,9 @@ namespace Logs {
|
||||
"PlayerEvents",
|
||||
"DataBuckets",
|
||||
"Zoning",
|
||||
"EqTime",
|
||||
"Corpses",
|
||||
"XTargets"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -814,6 +814,36 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEqTime(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::EqTime))\
|
||||
OutF(LogSys, Logs::General, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEqTimeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EqTime))\
|
||||
OutF(LogSys, Logs::Detail, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCorpses(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Corpses))\
|
||||
OutF(LogSys, Logs::General, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCorpsesDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Corpses))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogXTargets(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::XTargets))\
|
||||
OutF(LogSys, Logs::General, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogXTargetsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::XTargets))\
|
||||
OutF(LogSys, Logs::Detail, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
+51
-7
@@ -46,16 +46,16 @@ EQTime::EQTime()
|
||||
timezone = 0;
|
||||
memset(&eqTime, 0, sizeof(eqTime));
|
||||
//Defaults for time
|
||||
TimeOfDay_Struct start;
|
||||
start.day = 1;
|
||||
start.hour = 9;
|
||||
start.minute = 0;
|
||||
start.month = 1;
|
||||
start.year = 3100;
|
||||
TimeOfDay_Struct t{};
|
||||
t.day = 1;
|
||||
t.hour = 9;
|
||||
t.minute = 0;
|
||||
t.month = 1;
|
||||
t.year = 3100;
|
||||
//Set default time zone
|
||||
timezone = 0;
|
||||
//Start EQTimer
|
||||
SetCurrentEQTimeOfDay(start, time(0));
|
||||
SetCurrentEQTimeOfDay(t, time(nullptr));
|
||||
}
|
||||
|
||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
||||
@@ -200,3 +200,47 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
||||
buf[127] = '\0';
|
||||
str = buf;
|
||||
}
|
||||
|
||||
bool EQTime::IsDayTime() {
|
||||
TimeOfDay_Struct tod{}; //Day time is 5am to 6:59pm (14 hours in-game)
|
||||
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||
|
||||
if (tod.hour >= 5 || tod.hour < 19) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQTime::IsNightTime() {
|
||||
TimeOfDay_Struct tod{}; //Night time is 7pm to 4:59am (10 hours in-game)
|
||||
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||
|
||||
if (tod.hour >= 19 || tod.hour < 5) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQTime::IsInbetweenTime(uint8 min_time, uint8 max_time) {
|
||||
TimeOfDay_Struct tod{};
|
||||
GetCurrentEQTimeOfDay(&tod);
|
||||
|
||||
if (min_time == 0 || max_time == 0 || min_time > 24 || max_time > 24) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (max_time < min_time) {
|
||||
if ((tod.hour >= min_time && tod.hour > max_time) || (tod.hour < min_time && tod.hour <= max_time)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tod.hour >= min_time && tod.hour <= max_time) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ public:
|
||||
uint32 getEQTimeZone() { return timezone; }
|
||||
uint32 getEQTimeZoneHr() { return timezone/60; }
|
||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||
bool IsDayTime();
|
||||
bool IsNightTime();
|
||||
bool IsInbetweenTime(uint8 min_time, uint8 max_time);
|
||||
|
||||
//Set functions
|
||||
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA */
|
||||
|
||||
/* Error messages for mysql clients */
|
||||
/* error messages for the demon is in share/language/errmsg.sys */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void init_client_errs(void);
|
||||
extern const char *client_errors[]; /* Error messages */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CR_MIN_ERROR 2000 /* For easier client code */
|
||||
#define CR_MAX_ERROR 2999
|
||||
#if defined(OS2) && defined( MYSQL_SERVER)
|
||||
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
|
||||
#else
|
||||
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
|
||||
#endif
|
||||
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
|
||||
|
||||
#define CR_UNKNOWN_ERROR 2000
|
||||
#define CR_SOCKET_CREATE_ERROR 2001
|
||||
#define CR_CONNECTION_ERROR 2002
|
||||
#define CR_CONN_HOST_ERROR 2003
|
||||
#define CR_IPSOCK_ERROR 2004
|
||||
#define CR_UNKNOWN_HOST 2005
|
||||
#define CR_SERVER_GONE_ERROR 2006
|
||||
#define CR_VERSION_ERROR 2007
|
||||
#define CR_OUT_OF_MEMORY 2008
|
||||
#define CR_WRONG_HOST_INFO 2009
|
||||
#define CR_LOCALHOST_CONNECTION 2010
|
||||
#define CR_TCP_CONNECTION 2011
|
||||
#define CR_SERVER_HANDSHAKE_ERR 2012
|
||||
#define CR_SERVER_LOST 2013
|
||||
#define CR_COMMANDS_OUT_OF_SYNC 2014
|
||||
#define CR_NAMEDPIPE_CONNECTION 2015
|
||||
#define CR_NAMEDPIPEWAIT_ERROR 2016
|
||||
#define CR_NAMEDPIPEOPEN_ERROR 2017
|
||||
#define CR_NAMEDPIPESETSTATE_ERROR 2018
|
||||
#define CR_CANT_READ_CHARSET 2019
|
||||
#define CR_NET_PACKET_TOO_LARGE 2020
|
||||
@@ -789,50 +789,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 = {};
|
||||
|
||||
|
||||
BuildDiscordField(&f, "NPC", npc_info);
|
||||
|
||||
if (!handin_items_info.empty()) {
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Handin Items",
|
||||
fmt::format(
|
||||
"{}",
|
||||
handin_items_info
|
||||
)
|
||||
);
|
||||
BuildDiscordField(&f, "Handin Items", handin_items_info);
|
||||
}
|
||||
|
||||
if (!handin_money_info.empty()) {
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Handin Money",
|
||||
fmt::format(
|
||||
"{}",
|
||||
handin_money_info
|
||||
)
|
||||
);
|
||||
BuildDiscordField(&f, "Handin Money", handin_money_info);
|
||||
}
|
||||
|
||||
if (!return_items_info.empty()) {
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Return Items",
|
||||
fmt::format(
|
||||
"{}",
|
||||
return_items_info
|
||||
)
|
||||
);
|
||||
BuildDiscordField(&f, "Return Items", return_items_info);
|
||||
}
|
||||
|
||||
if (!return_money_info.empty()) {
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Return Money",
|
||||
fmt::format(
|
||||
"{}",
|
||||
return_money_info
|
||||
)
|
||||
);
|
||||
BuildDiscordField(&f, "Return Money", return_money_info);
|
||||
}
|
||||
|
||||
std::vector<DiscordEmbed> embeds = {};
|
||||
|
||||
@@ -37,6 +37,8 @@ void PlayerEventLogs::Init()
|
||||
db.emplace_back(e.id);
|
||||
}
|
||||
|
||||
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
||||
|
||||
// insert entries that don't exist in database
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
||||
@@ -56,21 +58,21 @@ void PlayerEventLogs::Init()
|
||||
|
||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
||||
LogInfo(
|
||||
"[New] PlayerEvent [{}] ({})",
|
||||
PlayerEvent::EventName[i],
|
||||
i
|
||||
);
|
||||
LogInfo("[New] PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||
|
||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
||||
c.id = i;
|
||||
c.event_name = PlayerEvent::EventName[i];
|
||||
c.event_enabled = m_settings[i].event_enabled;
|
||||
c.retention_days = m_settings[i].retention_days;
|
||||
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
||||
settings_to_insert.emplace_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (!settings_to_insert.empty()) {
|
||||
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
|
||||
}
|
||||
|
||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||
|
||||
@@ -611,7 +613,7 @@ void PlayerEventLogs::Process()
|
||||
|
||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||
{
|
||||
LogInfo("Running truncation");
|
||||
LogPlayerEvents("Running truncation");
|
||||
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
if (m_settings[i].retention_days > 0) {
|
||||
@@ -640,6 +642,10 @@ void PlayerEventLogs::ProcessRetentionTruncation()
|
||||
void PlayerEventLogs::ReloadSettings()
|
||||
{
|
||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
||||
if (e.id >= PlayerEvent::MAX || e.id < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_settings[e.id] = e;
|
||||
}
|
||||
}
|
||||
@@ -648,53 +654,59 @@ const int32_t RETENTION_DAYS_DEFAULT = 7;
|
||||
|
||||
void PlayerEventLogs::SetSettingsDefaults()
|
||||
{
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_PLAT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_SEND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_RETRIEVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_DELETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BARTER_TRANSACTION].event_enabled = 1;
|
||||
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||
|
||||
@@ -56,6 +56,12 @@ namespace PlayerEvent {
|
||||
KILLED_NAMED_NPC,
|
||||
KILLED_RAID_NPC,
|
||||
ITEM_CREATION,
|
||||
GUILD_TRIBUTE_DONATE_ITEM,
|
||||
GUILD_TRIBUTE_DONATE_PLAT,
|
||||
PARCEL_SEND,
|
||||
PARCEL_RETRIEVE,
|
||||
PARCEL_DELETE,
|
||||
BARTER_TRANSACTION,
|
||||
MAX // dont remove
|
||||
};
|
||||
|
||||
@@ -64,7 +70,7 @@ namespace PlayerEvent {
|
||||
// If event is unimplemented just tag (Unimplemented) in the name
|
||||
// Events don't get saved to the database if unimplemented or deprecated
|
||||
// Events tagged as deprecated will get automatically removed
|
||||
static const char *EventName[PlayerEvent::MAX] = {
|
||||
static const char *EventName[EventType::MAX] = {
|
||||
"None",
|
||||
"GM Command",
|
||||
"Zoning",
|
||||
@@ -112,7 +118,13 @@ namespace PlayerEvent {
|
||||
"Killed NPC",
|
||||
"Killed Named NPC",
|
||||
"Killed Raid NPC",
|
||||
"Item Creation"
|
||||
"Item Creation",
|
||||
"Guild Tribute Donate Item",
|
||||
"Guild Tribute Donate Platinum",
|
||||
"Parcel Item Sent",
|
||||
"Parcel Item Retrieved",
|
||||
"Parcel Prune Routine",
|
||||
"Barter Transaction"
|
||||
};
|
||||
|
||||
// Generic struct used by all events
|
||||
@@ -848,10 +860,12 @@ namespace PlayerEvent {
|
||||
|
||||
class HandinEntry {
|
||||
public:
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
std::vector<uint32> augment_ids;
|
||||
std::vector<std::string> augment_names;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -860,6 +874,8 @@ namespace PlayerEvent {
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(augment_ids),
|
||||
CEREAL_NVP(augment_names),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(attuned)
|
||||
);
|
||||
@@ -893,6 +909,7 @@ namespace PlayerEvent {
|
||||
HandinMoney handin_money;
|
||||
std::vector<HandinEntry> return_items;
|
||||
HandinMoney return_money;
|
||||
bool is_quest_handin;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -904,7 +921,8 @@ namespace PlayerEvent {
|
||||
CEREAL_NVP(handin_items),
|
||||
CEREAL_NVP(handin_money),
|
||||
CEREAL_NVP(return_items),
|
||||
CEREAL_NVP(return_money)
|
||||
CEREAL_NVP(return_money),
|
||||
CEREAL_NVP(is_quest_handin)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -942,6 +960,161 @@ namespace PlayerEvent {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItem {
|
||||
uint32 item_id;
|
||||
uint32 guild_favor;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(guild_favor)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildTributeDonatePlat {
|
||||
uint32 plat;
|
||||
uint32 guild_favor;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(plat),
|
||||
CEREAL_NVP(guild_favor)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelRetrieve {
|
||||
uint32 item_id;
|
||||
uint32 quantity;
|
||||
std::string from_player_name;
|
||||
uint32 sent_date;
|
||||
uint32 aug_slot_1;
|
||||
uint32 aug_slot_2;
|
||||
uint32 aug_slot_3;
|
||||
uint32 aug_slot_4;
|
||||
uint32 aug_slot_5;
|
||||
uint32 aug_slot_6;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(from_player_name),
|
||||
CEREAL_NVP(sent_date),
|
||||
CEREAL_NVP(aug_slot_1),
|
||||
CEREAL_NVP(aug_slot_2),
|
||||
CEREAL_NVP(aug_slot_3),
|
||||
CEREAL_NVP(aug_slot_4),
|
||||
CEREAL_NVP(aug_slot_5),
|
||||
CEREAL_NVP(aug_slot_6)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelSend {
|
||||
uint32 item_id;
|
||||
uint32 quantity;
|
||||
std::string from_player_name;
|
||||
std::string to_player_name;
|
||||
uint32 sent_date;
|
||||
uint32 aug_slot_1;
|
||||
uint32 aug_slot_2;
|
||||
uint32 aug_slot_3;
|
||||
uint32 aug_slot_4;
|
||||
uint32 aug_slot_5;
|
||||
uint32 aug_slot_6;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(from_player_name),
|
||||
CEREAL_NVP(to_player_name),
|
||||
CEREAL_NVP(sent_date),
|
||||
CEREAL_NVP(aug_slot_1),
|
||||
CEREAL_NVP(aug_slot_2),
|
||||
CEREAL_NVP(aug_slot_3),
|
||||
CEREAL_NVP(aug_slot_4),
|
||||
CEREAL_NVP(aug_slot_5),
|
||||
CEREAL_NVP(aug_slot_6)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelDelete {
|
||||
uint32 item_id;
|
||||
uint32 quantity;
|
||||
uint32 char_id;
|
||||
std::string from_name;
|
||||
std::string note;
|
||||
uint32 sent_date;
|
||||
uint32 aug_slot_1;
|
||||
uint32 aug_slot_2;
|
||||
uint32 aug_slot_3;
|
||||
uint32 aug_slot_4;
|
||||
uint32 aug_slot_5;
|
||||
uint32 aug_slot_6;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(char_id),
|
||||
CEREAL_NVP(from_name),
|
||||
CEREAL_NVP(note),
|
||||
CEREAL_NVP(sent_date),
|
||||
CEREAL_NVP(aug_slot_1),
|
||||
CEREAL_NVP(aug_slot_2),
|
||||
CEREAL_NVP(aug_slot_3),
|
||||
CEREAL_NVP(aug_slot_4),
|
||||
CEREAL_NVP(aug_slot_5),
|
||||
CEREAL_NVP(aug_slot_6)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct BarterTransaction {
|
||||
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)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENTS_H
|
||||
|
||||
+2
-2
@@ -96,12 +96,12 @@ bool IsOfEqualRace(int r1, int r2)
|
||||
// TODO: add more values
|
||||
switch (r1) {
|
||||
case DARK_ELF:
|
||||
if (r2 == RACE_NERIAK_CITIZEN_77) {
|
||||
if (r2 == Race::NeriakCitizen) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case BARBARIAN:
|
||||
if (r2 == RACE_HALAS_CITIZEN_90) {
|
||||
if (r2 == Race::HalasCitizen) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-27
@@ -24,17 +24,15 @@
|
||||
#include <string>
|
||||
|
||||
enum FACTION_VALUE {
|
||||
FACTION_ALLY = 1,
|
||||
FACTION_WARMLY = 2,
|
||||
FACTION_KINDLY = 3,
|
||||
FACTION_AMIABLY = 4,
|
||||
|
||||
FACTION_INDIFFERENTLY = 5,
|
||||
|
||||
FACTION_ALLY = 1,
|
||||
FACTION_WARMLY = 2,
|
||||
FACTION_KINDLY = 3,
|
||||
FACTION_AMIABLY = 4,
|
||||
FACTION_INDIFFERENTLY = 5,
|
||||
FACTION_APPREHENSIVELY = 6,
|
||||
FACTION_DUBIOUSLY = 7,
|
||||
FACTION_THREATENINGLY = 8,
|
||||
FACTION_SCOWLS = 9
|
||||
FACTION_DUBIOUSLY = 7,
|
||||
FACTION_THREATENINGLY = 8,
|
||||
FACTION_SCOWLS = 9
|
||||
};
|
||||
|
||||
struct NPCFactionList {
|
||||
@@ -75,23 +73,6 @@ struct NPCFaction
|
||||
uint8 temp;
|
||||
};
|
||||
|
||||
// Faction Associations give a much more live like faction system
|
||||
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
|
||||
|
||||
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
|
||||
#define MAX_FACTION_ASSOC 10
|
||||
|
||||
// this is the ID of a faction association and it's multiplier
|
||||
struct FactionAssociationHit {
|
||||
int id;
|
||||
float multiplier;
|
||||
};
|
||||
|
||||
struct FactionAssociations {
|
||||
// maybe there should be more data here, fine for now
|
||||
FactionAssociationHit hits[MAX_FACTION_ASSOC];
|
||||
};
|
||||
|
||||
const char *FactionValueToString(FACTION_VALUE faction_value);
|
||||
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
||||
#endif
|
||||
|
||||
@@ -35,11 +35,6 @@ Core Zone features
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//Uncomment this to cause a zone to basically idle
|
||||
//when there are no players in it, mobs stop wandering, etc..
|
||||
#define IDLE_WHEN_EMPTY
|
||||
|
||||
#ifdef EMBPERL
|
||||
//Enable the new XS based perl parser
|
||||
#define EMBPERL_XS
|
||||
@@ -238,25 +233,6 @@ enum { //some random constants
|
||||
// Timer to update aggrometer
|
||||
#define AGGRO_METER_UPDATE_MS 1000
|
||||
|
||||
//Some hard coded statuses from commands and other places:
|
||||
enum {
|
||||
minStatusToBeGM = 40,
|
||||
minStatusToUseGMCommands = 80,
|
||||
minStatusToKick = 150,
|
||||
minStatusToAvoidFalling = 100,
|
||||
minStatusToIgnoreZoneFlags = 80,
|
||||
minStatusToSeeOthersZoneFlags = 80,
|
||||
minStatusToEditOtherGuilds = 80,
|
||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
||||
commandCastSpecials = 100, //can cast special spells
|
||||
commandDoAnimOthers = 100, //can #doanim on others
|
||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
||||
};
|
||||
|
||||
|
||||
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
||||
#define SAYLINK_ITEM_ID 0xFFFFF
|
||||
|
||||
|
||||
+8
-8
@@ -38,21 +38,21 @@
|
||||
#include <fmt/format.h>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
|
||||
bool File::Exists(const std::string &name)
|
||||
{
|
||||
return fs::exists(fs::path{name});
|
||||
struct stat sb{};
|
||||
if (stat(name.c_str(), &sb) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void File::Makedir(const std::string &directory_name)
|
||||
{
|
||||
try {
|
||||
|
||||
+1006
-821
File diff suppressed because it is too large
Load Diff
+135
-82
@@ -5,6 +5,42 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "timer.h"
|
||||
#include "../common/repositories/guild_members_repository.h"
|
||||
#include "../common/repositories/guilds_repository.h"
|
||||
|
||||
struct DefaultPermissionStruct {
|
||||
GuildAction id;
|
||||
uint32 value;
|
||||
};
|
||||
|
||||
struct DefaultRankNamesStruct {
|
||||
uint32 id;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct GuildTributeStruct {
|
||||
Timer timer;
|
||||
uint32 id_1;
|
||||
uint32 id_2;
|
||||
uint32 id_1_tier;
|
||||
uint32 id_2_tier;
|
||||
uint32 favor;
|
||||
uint32 time_remaining;
|
||||
uint32 enabled;
|
||||
bool send_timer;
|
||||
};
|
||||
|
||||
class TributeData {
|
||||
public:
|
||||
//this level data stored in regular byte order and must be flipped before sending
|
||||
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
|
||||
uint8 tier_count;
|
||||
uint32 unknown;
|
||||
std::string name;
|
||||
std::string description;
|
||||
bool is_guild; //is a guild tribute item
|
||||
};
|
||||
|
||||
class Database;
|
||||
|
||||
@@ -12,22 +48,23 @@ class CharGuildInfo
|
||||
{
|
||||
public:
|
||||
//fields from `characer_`
|
||||
uint32 char_id;
|
||||
uint32 char_id;
|
||||
std::string char_name;
|
||||
uint8 class_;
|
||||
uint16 level;
|
||||
uint32 time_last_on;
|
||||
uint32 zone_id;
|
||||
uint8 class_;
|
||||
uint16 level;
|
||||
uint32 time_last_on;
|
||||
uint32 zone_id;
|
||||
|
||||
//fields from `guild_members`
|
||||
uint32 guild_id;
|
||||
uint8 rank;
|
||||
bool tribute_enable;
|
||||
uint32 total_tribute;
|
||||
uint32 last_tribute; //timestamp
|
||||
bool banker;
|
||||
bool alt;
|
||||
uint32 guild_id;
|
||||
uint8 rank;
|
||||
bool tribute_enable;
|
||||
uint32 total_tribute;
|
||||
uint32 last_tribute; //timestamp
|
||||
bool banker;
|
||||
bool alt;
|
||||
std::string public_note;
|
||||
bool online;
|
||||
};
|
||||
|
||||
//this object holds guild functionality shared between world and zone.
|
||||
@@ -38,21 +75,31 @@ class BaseGuildManager
|
||||
virtual ~BaseGuildManager();
|
||||
|
||||
//this must be called before doing anything else with this object
|
||||
void SetDatabase(Database *db)
|
||||
BaseGuildManager * SetDatabase(Database *db)
|
||||
{
|
||||
m_db = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
BaseGuildManager * SetContentDatabase(Database *db)
|
||||
{
|
||||
m_content_db = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool LoadGuilds();
|
||||
bool RefreshGuild(uint32 guild_id);
|
||||
virtual bool RefreshGuild(uint32 guild_id);
|
||||
|
||||
//guild edit actions.
|
||||
uint32 CreateGuild(const char* name, uint32 leader_char_id);
|
||||
uint32 CreateGuild(std::string name, uint32 leader_char_id);
|
||||
bool StoreGuildDB(uint32 guild_id);
|
||||
bool DeleteGuild(uint32 guild_id);
|
||||
bool RenameGuild(uint32 guild_id, const char* name);
|
||||
bool SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
||||
bool SetGuildURL(uint32 GuildID, const char* URL);
|
||||
bool SetGuildChannel(uint32 GuildID, const char* Channel);
|
||||
bool RenameGuild(uint32 guild_id, std::string name);
|
||||
bool SetGuildMOTD(uint32 guild_id, std::string motd, std::string setter);
|
||||
bool SetGuildURL(uint32 guild_id, std::string URL);
|
||||
bool SetGuildChannel(uint32 guild_id, std::string Channel);
|
||||
|
||||
//character edit actions
|
||||
bool SetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
@@ -62,9 +109,16 @@ class BaseGuildManager
|
||||
bool ForceRankUpdate(uint32 charid);
|
||||
bool GetAltFlag(uint32 CharID);
|
||||
bool SetAltFlag(uint32 charid, bool is_alt);
|
||||
bool GetBankerFlag(uint32 CharID);
|
||||
bool GetBankerFlag(uint32 CharID, bool compat_mode = false);
|
||||
bool GetGuildBankerStatus(uint32 guild_id, uint32 guild_rank);
|
||||
bool SetTributeFlag(uint32 charid, bool enabled);
|
||||
bool SetPublicNote(uint32 charid, const char *note);
|
||||
bool SetPublicNote(uint32 charid, std::string public_note);
|
||||
uint32 UpdateDbGuildFavor(uint32 guild_id, uint32 enabled);
|
||||
bool UpdateDbGuildTributeEnabled(uint32 guild_id, uint32 enabled);
|
||||
bool UpdateDbMemberTributeEnabled(uint32 guild_id, uint32 char_id, uint32 enabled);
|
||||
bool UpdateDbTributeTimeRemaining(uint32 guild_id, uint32 enabled);
|
||||
uint32 UpdateDbMemberFavor(uint32 guild_id, uint32 char_id, uint32 favor);
|
||||
bool UpdateDbMemberOnline(uint32 char_id, bool status);
|
||||
|
||||
//queries
|
||||
bool GetCharInfo(const char *char_name, CharGuildInfo &into);
|
||||
@@ -74,29 +128,24 @@ class BaseGuildManager
|
||||
bool GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *setter_buffer) const;
|
||||
bool GetGuildURL(uint32 GuildID, char *URLBuffer) const;
|
||||
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
||||
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
||||
const char *GetGuildName(uint32 guild_id) const;
|
||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
||||
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
||||
uint32 GetGuildIDByName(const char *GuildName);
|
||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
||||
// uint32 Getguild_id(uint32 eqid);
|
||||
uint32 FindGuildByLeader(uint32 leader) const;
|
||||
// void GetGuildMembers(uint32 guild_id,GuildMember_Struct* gms);
|
||||
uint32 NumberInGuild(uint32 guild_id);
|
||||
// bool GetGuildRanks(uint32 guildeqid, GuildRanks_Struct* gr);
|
||||
// bool EditGuild(uint32 guild_id, uint8 ranknum, GuildRankLevel_Struct* grl);
|
||||
|
||||
uint8 *MakeGuildList(const char *head_name, uint32 &length) const; //make a guild list packet, returns ownership of the buffer.
|
||||
|
||||
static const char *const GuildActionNames[_MaxGuildAction];
|
||||
uint32 DoesAccountContainAGuildLeader(uint32 AccountID);
|
||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
||||
bool GetGuildNameByID(uint32 guild_id, std::string& into) const;
|
||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
||||
bool UpdateDbBankerFlag(uint32 charid, bool is_banker);
|
||||
GuildsListMessaging_Struct MakeGuildList();
|
||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||
uint32 GetGuildIDByName(const char *GuildName);
|
||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
||||
uint32 FindGuildByLeader(uint32 leader) const;
|
||||
uint32 NumberInGuild(uint32 guild_id);
|
||||
uint32 DoesAccountContainAGuildLeader(uint32 AccountID);
|
||||
const char* GetRankName(uint32 guild_id, uint8 rank) const;
|
||||
const char* GetGuildName(uint32 guild_id) const;
|
||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
||||
std::vector<GuildMembersRepository::GuildMembers> GetGuildMembers(uint32 guild_id);
|
||||
|
||||
protected:
|
||||
//the methods which must be defined by base classes.
|
||||
@@ -105,58 +154,62 @@ class BaseGuildManager
|
||||
virtual void SendRankUpdate(uint32 CharID) = 0;
|
||||
virtual void SendGuildDelete(uint32 guild_id) = 0;
|
||||
|
||||
uint32 DBCreateGuild(const char* name, uint32 leader_char_id);
|
||||
bool DBDeleteGuild(uint32 guild_id);
|
||||
bool DBRenameGuild(uint32 guild_id, const char* name);
|
||||
bool DBSetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
bool DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
||||
bool DBSetGuildURL(uint32 GuildID, const char* URL);
|
||||
bool DBSetGuildChannel(uint32 GuildID, const char* Channel);
|
||||
bool DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
||||
bool DBSetGuildRank(uint32 charid, uint8 rank);
|
||||
bool DBSetBankerFlag(uint32 charid, bool is_banker);
|
||||
bool DBSetAltFlag(uint32 charid, bool is_alt);
|
||||
bool DBSetTributeFlag(uint32 charid, bool enabled);
|
||||
bool DBSetPublicNote(uint32 charid, const char *note);
|
||||
uint32 UpdateDbCreateGuild(std::string name, uint32 leader_char_id);
|
||||
bool UpdateDbDeleteGuild(uint32 guild_id, bool local_delete = true, bool db_delete = true);
|
||||
bool UpdateDbRenameGuild(uint32 guild_id, std::string name);
|
||||
bool UpdateDbGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
bool UpdateDbGuildMOTD(uint32 guild_id, std::string motd, std::string setter);
|
||||
bool UpdateDbGuildURL(uint32 GuildID, std::string URL);
|
||||
bool UpdateDbGuildChannel(uint32 GuildID, std::string Channel);
|
||||
bool UpdateDbGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
||||
bool UpdateDbGuildRank(uint32 charid, uint8 rank);
|
||||
bool UpdateDbAltFlag(uint32 charid, bool is_alt);
|
||||
bool UpdateDbTributeFlag(uint32 charid, bool enabled);
|
||||
bool UpdateDbPublicNote(uint32 charid, std::string public_note);
|
||||
bool QueryWithLogging(std::string query, const char *errmsg);
|
||||
// void DBSetPublicNote(uint32 guild_id,char* charname, char* note);
|
||||
|
||||
bool LocalDeleteGuild(uint32 guild_id);
|
||||
|
||||
class RankInfo
|
||||
struct RankInfo
|
||||
{
|
||||
public:
|
||||
RankInfo();
|
||||
std::string name;
|
||||
bool permissions[_MaxGuildAction];
|
||||
RankInfo();
|
||||
std::string rank_name;
|
||||
};
|
||||
class GuildInfo
|
||||
struct Functions
|
||||
{
|
||||
public:
|
||||
GuildInfo();
|
||||
std::string name;
|
||||
std::string motd;
|
||||
std::string motd_setter;
|
||||
std::string url;
|
||||
std::string channel;
|
||||
|
||||
uint32 leader_char_id;
|
||||
uint8 minstatus;
|
||||
//tribute is not in here on purpose, since it is only valid in world!
|
||||
RankInfo ranks[GUILD_MAX_RANK + 1];
|
||||
uint32 id;
|
||||
uint32 perm_id;
|
||||
uint32 guild_id;
|
||||
uint32 perm_value;
|
||||
};
|
||||
public:
|
||||
class GuildInfo {
|
||||
public:
|
||||
GuildInfo();
|
||||
std::string name;
|
||||
std::string motd;
|
||||
std::string motd_setter;
|
||||
std::string url;
|
||||
std::string channel;
|
||||
uint32 leader;
|
||||
uint8 minstatus;
|
||||
std::string rank_names[GUILD_MAX_RANK + 1];
|
||||
Functions functions[GUILD_MAX_FUNCTIONS + 1];
|
||||
GuildTributeStruct tribute;
|
||||
};
|
||||
virtual BaseGuildManager::GuildInfo* GetGuildByGuildID(uint32 guild_id);
|
||||
uint32 GetGuildTributeTimeRemaining(uint32 guild_id);
|
||||
|
||||
protected:
|
||||
std::map<uint32, GuildInfo *> m_guilds; //we own the pointers in this map
|
||||
void ClearGuilds(); //clears internal structure
|
||||
|
||||
Database *m_db; //we do not own this
|
||||
Database *m_db;
|
||||
Database *m_content_db;
|
||||
|
||||
bool _StoreGuildDB(uint32 guild_id);
|
||||
GuildInfo *_CreateGuild(uint32 guild_id, const char *guild_name, uint32 account_id, uint8 minstatus, const char *guild_motd, const char *motd_setter, const char *Channel, const char *URL);
|
||||
uint32 _GetFreeGuildID();
|
||||
GuildInfo* _CreateGuild(uint32 guild_id, std::string guild_name, uint32 leader_char_id, uint8 minstatus, std::string guild_motd, std::string motd_setter, std::string Channel, std::string URL, uint32 favour);
|
||||
GuildsRepository::Guilds CreateGuildRepoFromGuildInfo(uint32 guild_id, BaseGuildManager::GuildInfo& in);
|
||||
};
|
||||
|
||||
|
||||
#endif /*GUILD_BASE_H_*/
|
||||
|
||||
|
||||
|
||||
+56
-16
@@ -16,31 +16,71 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef GUILD_H
|
||||
#define GUILD_H
|
||||
#ifndef GUILDS_H
|
||||
#define GUILDS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define GUILD_NONE 0xFFFFFFFF // user has no guild
|
||||
|
||||
#define GUILD_MAX_RANK 8 // 0-2 - some places in the code assume a single digit, dont go above 9
|
||||
#define GUILD_MAX_RANK 8 // 0-2 - some places in the code assume a single digit, dont go above 9
|
||||
#define GUILD_MAX_FUNCTIONS 30
|
||||
#define GUILD_TRIBUTES_MODIFY 1
|
||||
#define GUILD_TRIBUTES_SAVE 0
|
||||
#define GUILD_TRIBUTES_OFF 0
|
||||
#define GUILD_TRIBUTES_ON 1
|
||||
#define GUILD_INVITE_DECLINE 9
|
||||
|
||||
//defines for standard ranks
|
||||
#define GUILD_MEMBER 0
|
||||
#define GUILD_OFFICER 1
|
||||
#define GUILD_LEADER 2
|
||||
#define GUILD_RANK_NONE (GUILD_MAX_RANK+1)
|
||||
#define GUILD_MEMBER_TI 0
|
||||
#define GUILD_OFFICER_TI 1
|
||||
#define GUILD_LEADER_TI 2
|
||||
#define GUILD_RANK_NONE_TI (GUILD_MAX_RANK + 1)
|
||||
|
||||
//defines for standard ranks base on RoF2 definitions
|
||||
#define GUILD_RANK_NONE 0
|
||||
#define GUILD_LEADER 1
|
||||
#define GUILD_SENIOR_OFFICER 2
|
||||
#define GUILD_OFFICER 3
|
||||
#define GUILD_SENIOR_MEMBER 4
|
||||
#define GUILD_MEMBER 5
|
||||
#define GUILD_JUNIOR_MEMBER 6
|
||||
#define GUILD_INITIATE 7
|
||||
#define GUILD_RECRUIT 8
|
||||
|
||||
typedef enum {
|
||||
GUILD_HEAR = 0,
|
||||
GUILD_SPEAK = 1,
|
||||
GUILD_INVITE = 2,
|
||||
GUILD_REMOVE = 3,
|
||||
GUILD_PROMOTE = 4,
|
||||
GUILD_DEMOTE = 5,
|
||||
GUILD_MOTD = 6,
|
||||
GUILD_WARPEACE = 7,
|
||||
_MaxGuildAction
|
||||
GUILD_ACTION_BANNER_CHANGE = 1,
|
||||
GUILD_ACTION_BANNER_PLANT = 2,
|
||||
GUILD_ACTION_BANNER_REMOVE = 3,
|
||||
GUILD_ACTION_DISPLAY_GUILD_NAME = 4,
|
||||
GUILD_ACTION_RANKS_CHANGE_PERMISSIONS = 5,
|
||||
GUILD_ACTION_RANKS_CHANGE_RANK_NAMES = 6,
|
||||
GUILD_ACTION_MEMBERS_INVITE = 7,
|
||||
GUILD_ACTION_MEMBERS_PROMOTE = 8,
|
||||
GUILD_ACTION_MEMBERS_DEMOTE = 9,
|
||||
GUILD_ACTION_MEMBERS_REMOVE = 10,
|
||||
GUILD_ACTION_EDIT_RECRUITING_SETTINGS = 11,
|
||||
GUILD_ACTION_EDIT_PUBLIC_NOTES = 12,
|
||||
GUILD_ACTION_BANK_DEPOSIT_ITEMS = 13,
|
||||
GUILD_ACTION_BANK_WITHDRAW_ITEMS = 14,
|
||||
GUILD_ACTION_BANK_VIEW_ITEMS = 15,
|
||||
GUILD_ACTION_BANK_PROMOTE_ITEMS = 16,
|
||||
GUILD_ACTION_BANK_CHANGE_ITEM_PERMISSIONS = 17,
|
||||
GUILD_ACTION_CHANGE_THE_MOTD = 18,
|
||||
GUILD_ACTION_GUILD_CHAT_SEE = 19,
|
||||
GUILD_ACTION_GUILD_CHAT_SPEAK_IN = 20,
|
||||
GUILD_ACTION_SEND_THE_WHOLE_GUILD_E_MAIL = 21,
|
||||
GUILD_ACTION_TRIBUTE_CHANGE_FOR_OTHERS = 22,
|
||||
GUILD_ACTION_TRIBUTE_CHANGE_ACTIVE_BENEFIT = 23,
|
||||
GUILD_ACTION_TROPHY_TRIBUTE_CHANGE_FOR_OTHERS = 24,
|
||||
GUILD_ACTION_TROPHY_TRIBUTE_CHANGE_ACTIVE_BENEFIT = 25,
|
||||
GUILD_ACTION_MEMBERS_CHANGE_ALT_FLAG_FOR_OTHER = 26,
|
||||
GUILD_ACTION_REAL_ESTATE_GUILD_PLOT_BUY = 27,
|
||||
GUILD_ACTION_REAL_ESTATE_GUILD_PLOT_SELL = 28,
|
||||
GUILD_ACTION_REAL_ESTATE_MODIFY_TROPHIES = 29,
|
||||
GUILD_ACTION_MEMBERS_DEMOTE_SELF = 30,
|
||||
} GuildAction;
|
||||
|
||||
constexpr int format_as(GuildAction action) { return static_cast<int>(action); }
|
||||
|
||||
#endif
|
||||
|
||||
+583
-481
File diff suppressed because it is too large
Load Diff
@@ -132,7 +132,7 @@ namespace EQ
|
||||
|
||||
// Swap items in inventory
|
||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = RACE_DOUG_0, uint8 class_id = NO_CLASS, 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
|
||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
||||
@@ -176,6 +176,7 @@ namespace EQ
|
||||
// Locate an available inventory slot
|
||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
||||
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||
@@ -197,12 +198,6 @@ namespace EQ
|
||||
|
||||
uint8 FindBrightestLightType();
|
||||
|
||||
void dumpEntireInventory();
|
||||
void dumpWornItems();
|
||||
void dumpInventory();
|
||||
void dumpBankItems();
|
||||
void dumpSharedBankItems();
|
||||
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
|
||||
@@ -215,8 +210,6 @@ namespace EQ
|
||||
///////////////////////////////
|
||||
|
||||
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
|
||||
void dumpItemCollection(const std::map<int16, ItemInstance*> &collection);
|
||||
void dumpBagContents(ItemInstance *inst, std::map<int16, ItemInstance*>::const_iterator *it);
|
||||
|
||||
// Retrieves item within an inventory bucket
|
||||
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
|
||||
|
||||
+55
-21
@@ -81,45 +81,79 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets local address - pings google to inspect what interface was used locally
|
||||
* @return
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#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()
|
||||
{
|
||||
char my_ip_address[16];
|
||||
unsigned int my_port;
|
||||
#ifdef _WIN32
|
||||
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 my_address{};
|
||||
int sockfd;
|
||||
int sockfd;
|
||||
|
||||
// Connect to server
|
||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
// Create a UDP socket
|
||||
#ifdef _WIN32
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd == INVALID_SOCKET) {
|
||||
WSACleanup();
|
||||
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));
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
|
||||
server_address.sin_port = htons(80);
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = inet_addr("8.8.8.8"); // Google DNS
|
||||
server_address.sin_port = htons(53); // DNS port
|
||||
|
||||
// Connect to server
|
||||
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
|
||||
close(sockfd);
|
||||
return "";
|
||||
}
|
||||
// Perform a dummy connection to the server (UDP)
|
||||
connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
|
||||
|
||||
// Get my ip address and port
|
||||
// Get my IP address
|
||||
memset(&my_address, 0, sizeof(my_address));
|
||||
socklen_t len = sizeof(my_address);
|
||||
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
|
||||
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
|
||||
* Uses various websites as options to return raw public IP back to the client
|
||||
|
||||
+70
-66
@@ -58,72 +58,75 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum ItemType : uint8 {
|
||||
/*9138*/ ItemType1HSlash = 0,
|
||||
/*9141*/ ItemType2HSlash,
|
||||
/*9140*/ ItemType1HPiercing,
|
||||
/*9139*/ ItemType1HBlunt,
|
||||
/*9142*/ ItemType2HBlunt,
|
||||
/*5504*/ ItemTypeBow, // 5
|
||||
/*----*/ ItemTypeUnknown1,
|
||||
/*----*/ ItemTypeLargeThrowing,
|
||||
/*5505*/ ItemTypeShield,
|
||||
/*5506*/ ItemTypeScroll,
|
||||
/*5507*/ ItemTypeArmor, // 10
|
||||
/*5508*/ ItemTypeMisc, // a lot of random crap has this item use.
|
||||
/*7564*/ ItemTypeLockPick,
|
||||
/*----*/ ItemTypeUnknown2,
|
||||
/*5509*/ ItemTypeFood,
|
||||
/*5510*/ ItemTypeDrink, // 15
|
||||
/*5511*/ ItemTypeLight,
|
||||
/*5512*/ ItemTypeCombinable, // not all stackable items are this use...
|
||||
/*5513*/ ItemTypeBandage,
|
||||
/*----*/ ItemTypeSmallThrowing,
|
||||
/*----*/ ItemTypeSpell, // 20 // spells and tomes
|
||||
/*5514*/ ItemTypePotion,
|
||||
/*----*/ ItemTypeUnknown3,
|
||||
/*0406*/ ItemTypeWindInstrument,
|
||||
/*0407*/ ItemTypeStringedInstrument,
|
||||
/*0408*/ ItemTypeBrassInstrument, // 25
|
||||
/*0405*/ ItemTypePercussionInstrument,
|
||||
/*5515*/ ItemTypeArrow,
|
||||
/*----*/ ItemTypeUnknown4,
|
||||
/*5521*/ ItemTypeJewelry,
|
||||
/*----*/ ItemTypeSkull, // 30
|
||||
/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...)
|
||||
/*5517*/ ItemTypeNote,
|
||||
/*5518*/ ItemTypeKey,
|
||||
/*----*/ ItemTypeCoin,
|
||||
/*5520*/ ItemType2HPiercing, // 35
|
||||
/*----*/ ItemTypeFishingPole,
|
||||
/*----*/ ItemTypeFishingBait,
|
||||
/*5519*/ ItemTypeAlcohol,
|
||||
/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?)
|
||||
/*----*/ ItemTypeCompass, // 40
|
||||
/*----*/ ItemTypeUnknown5,
|
||||
/*----*/ ItemTypePoison, // might be wrong, but includes poisons
|
||||
/*----*/ ItemTypeUnknown6,
|
||||
/*----*/ ItemTypeUnknown7,
|
||||
/*5522*/ ItemTypeMartial, // 45
|
||||
/*----*/ ItemTypeUnknown8,
|
||||
/*----*/ ItemTypeUnknown9,
|
||||
/*----*/ ItemTypeUnknown10,
|
||||
/*----*/ ItemTypeUnknown11,
|
||||
/*----*/ ItemTypeSinging, // 50
|
||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||
/*5776*/ ItemTypeCharm,
|
||||
/*----*/ ItemTypeDye,
|
||||
/*----*/ ItemTypeAugmentation,
|
||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||
/*----*/ ItemTypeAugmentationDistiller,
|
||||
/*----*/ ItemTypeUnknown12,
|
||||
/*----*/ ItemTypeFellowshipKit,
|
||||
/*----*/ ItemTypeUnknown13,
|
||||
/*----*/ ItemTypeRecipe, // 60
|
||||
/*----*/ ItemTypeAdvancedRecipe,
|
||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||
/*----*/ ItemTypeCount
|
||||
/*9138*/ ItemType1HSlash = 0,
|
||||
/*9141*/ ItemType2HSlash,
|
||||
/*9140*/ ItemType1HPiercing,
|
||||
/*9139*/ ItemType1HBlunt,
|
||||
/*9142*/ ItemType2HBlunt,
|
||||
/*5504*/ ItemTypeBow, // 5
|
||||
/*----*/ ItemTypeUnknown1,
|
||||
/*----*/ ItemTypeLargeThrowing,
|
||||
/*5505*/ ItemTypeShield,
|
||||
/*5506*/ ItemTypeScroll,
|
||||
/*5507*/ ItemTypeArmor, // 10
|
||||
/*5508*/ ItemTypeMisc, // a lot of random crap has this item use.
|
||||
/*7564*/ ItemTypeLockPick,
|
||||
/*----*/ ItemTypeUnknown2,
|
||||
/*5509*/ ItemTypeFood,
|
||||
/*5510*/ ItemTypeDrink, // 15
|
||||
/*5511*/ ItemTypeLight,
|
||||
/*5512*/ ItemTypeCombinable, // not all stackable items are this use...
|
||||
/*5513*/ ItemTypeBandage,
|
||||
/*----*/ ItemTypeSmallThrowing,
|
||||
/*----*/ ItemTypeSpell, // 20 // spells and tomes
|
||||
/*5514*/ ItemTypePotion,
|
||||
/*----*/ ItemTypeUnknown3,
|
||||
/*0406*/ ItemTypeWindInstrument,
|
||||
/*0407*/ ItemTypeStringedInstrument,
|
||||
/*0408*/ ItemTypeBrassInstrument, // 25
|
||||
/*0405*/ ItemTypePercussionInstrument,
|
||||
/*5515*/ ItemTypeArrow,
|
||||
/*----*/ ItemTypeUnknown4,
|
||||
/*5521*/ ItemTypeJewelry,
|
||||
/*----*/ ItemTypeSkull, // 30
|
||||
/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...)
|
||||
/*5517*/ ItemTypeNote,
|
||||
/*5518*/ ItemTypeKey,
|
||||
/*----*/ ItemTypeCoin,
|
||||
/*5520*/ ItemType2HPiercing, // 35
|
||||
/*----*/ ItemTypeFishingPole,
|
||||
/*----*/ ItemTypeFishingBait,
|
||||
/*5519*/ ItemTypeAlcohol,
|
||||
/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?)
|
||||
/*----*/ ItemTypeCompass, // 40
|
||||
/*----*/ ItemTypeUnknown5,
|
||||
/*----*/ ItemTypePoison, // might be wrong, but includes poisons
|
||||
/*----*/ ItemTypeUnknown6,
|
||||
/*----*/ ItemTypeUnknown7,
|
||||
/*5522*/ ItemTypeMartial, // 45
|
||||
/*----*/ ItemTypeAllEffects,
|
||||
/*----*/ ItemTypeUnknown9,
|
||||
/*----*/ ItemTypeUnknown10,
|
||||
/*----*/ ItemTypeFocusEffect,
|
||||
/*----*/ ItemTypeSinging, // 50
|
||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||
/*5776*/ ItemTypeCharm,
|
||||
/*----*/ ItemTypeDye,
|
||||
/*----*/ ItemTypeAugmentation,
|
||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||
/*----*/ ItemTypeAugmentationDistiller,
|
||||
/*----*/ ItemTypeAlternateAbility,
|
||||
/*----*/ ItemTypeFellowshipKit,
|
||||
/*----*/ ItemTypeUnknown13,
|
||||
/*----*/ ItemTypeRecipe, // 60
|
||||
/*----*/ ItemTypeAdvancedRecipe,
|
||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||
/*----*/ ItemTypeCount,
|
||||
/*----*/ ItemTypeCollectible,
|
||||
/*----*/ ItemTypeContainer,
|
||||
/*----*/ ItemTypeAll = 0xFF
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
@@ -356,6 +359,7 @@ namespace EQ
|
||||
struct ItemData {
|
||||
// Non packet based fields
|
||||
uint8 MinStatus {};
|
||||
char Comment[255] {};
|
||||
|
||||
// Packet based fields
|
||||
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
||||
|
||||
+197
-37
@@ -32,10 +32,11 @@
|
||||
|
||||
//#include <iostream>
|
||||
|
||||
int32 NextItemInstSerialNumber = 1;
|
||||
|
||||
static inline int32 GetNextItemInstSerialNumber() {
|
||||
int32 next_item_serial_number = 1;
|
||||
std::unordered_set<uint64> guids{};
|
||||
|
||||
static inline int32 GetNextItemInstSerialNumber()
|
||||
{
|
||||
// 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
|
||||
// is used in Bazaar packets to identify the item a player is buying or inspecting.
|
||||
@@ -46,12 +47,18 @@ static inline int32 GetNextItemInstSerialNumber() {
|
||||
// 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.
|
||||
if(NextItemInstSerialNumber >= INT_MAX)
|
||||
NextItemInstSerialNumber = 1;
|
||||
else
|
||||
NextItemInstSerialNumber++;
|
||||
if (next_item_serial_number >= INT32_MAX) {
|
||||
next_item_serial_number = 1;
|
||||
}
|
||||
else {
|
||||
next_item_serial_number++;
|
||||
}
|
||||
|
||||
return NextItemInstSerialNumber;
|
||||
while (guids.contains(next_item_serial_number)) {
|
||||
next_item_serial_number++;
|
||||
}
|
||||
|
||||
return next_item_serial_number;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -303,47 +310,34 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
auto i = invaug::SOCKET_BEGIN;
|
||||
for (; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetItem(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[i] &&
|
||||
((1 << (m_item->AugSlotType[i] - 1)) & augment_type)
|
||||
)
|
||||
) {
|
||||
break;
|
||||
for (int16 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||
if (IsAugmentSlotAvailable(augment_type, slot_id)) {
|
||||
return slot_id;
|
||||
}
|
||||
}
|
||||
|
||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (
|
||||
return (
|
||||
(
|
||||
!GetItem(slot) &&
|
||||
m_item->AugSlotVisible[slot]
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
)
|
||||
) &&
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
RuleB(Items, AugmentItemAllowInvisibleAugments) ||
|
||||
m_item->AugSlotVisible[slot]
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
);
|
||||
}
|
||||
|
||||
// Retrieve item inside container
|
||||
@@ -1273,7 +1267,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bool augments) const
|
||||
|
||||
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||
{
|
||||
int race = RACE_DOUG_0;
|
||||
int race = Race::Doug;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
race = item->BaneDmgRace;
|
||||
@@ -1292,7 +1286,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||
return race;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
|
||||
int EQ::ItemInstance::GetItemBaneDamageBody(uint8 against, bool augments) const
|
||||
{
|
||||
int64 damage = 0;
|
||||
const auto item = GetItem();
|
||||
@@ -1791,6 +1785,172 @@ int EQ::ItemInstance::RemoveTaskDeliveredItems()
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32 EQ::ItemInstance::GetItemGuildFavor() const
|
||||
{
|
||||
uint32 total = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
return total = item->GuildFavor;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<uint32> EQ::ItemInstance::GetAugmentIDs() const
|
||||
{
|
||||
std::vector<uint32> augments;
|
||||
|
||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
|
||||
augments.push_back(GetAugment(slot_id) ? GetAugmentItemID(slot_id) : 0);
|
||||
}
|
||||
|
||||
return augments;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
//
|
||||
// class EvolveInfo
|
||||
//
|
||||
|
||||
+13
-1
@@ -265,11 +265,12 @@ namespace EQ
|
||||
// these two are just quick checks
|
||||
int GetItemBaneDamageBody(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 GetItemMagical(bool augments = false) const;
|
||||
int GetItemHP(bool augments = false) const;
|
||||
int GetItemMana(bool augments = false) const;
|
||||
int GetItemManaRegen(bool augments = false) const;
|
||||
int GetItemEndur(bool augments = false) const;
|
||||
int GetItemAttack(bool augments = false) const;
|
||||
int GetItemStr(bool augments = false) const;
|
||||
@@ -299,6 +300,17 @@ namespace EQ
|
||||
int GetItemHeroicDR(bool augments = false) const;
|
||||
int GetItemHeroicCorrup(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;
|
||||
std::vector<uint32> GetAugmentIDs() const;
|
||||
static void AddGUIDToMap(uint64 existing_serial_number);
|
||||
static void ClearGUIDMap();
|
||||
|
||||
protected:
|
||||
//////////////////////////
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef LANGUAGES_H
|
||||
#define LANGUAGES_H
|
||||
#include "../common/types.h"
|
||||
|
||||
#define LANG_COMMON_TONGUE 0
|
||||
#define LANG_BARBARIAN 1
|
||||
#define LANG_ERUDIAN 2
|
||||
#define LANG_ELVISH 3
|
||||
#define LANG_DARK_ELVISH 4
|
||||
#define LANG_DWARVISH 5
|
||||
#define LANG_TROLL 6
|
||||
#define LANG_OGRE 7
|
||||
#define LANG_GNOMISH 8
|
||||
#define LANG_HALFLING 9
|
||||
#define LANG_THIEVES_CANT 10
|
||||
#define LANG_OLD_ERUDIAN 11
|
||||
#define LANG_ELDER_ELVISH 12
|
||||
#define LANG_FROGLOK 13
|
||||
#define LANG_GOBLIN 14
|
||||
#define LANG_GNOLL 15
|
||||
#define LANG_COMBINE_TONGUE 16
|
||||
#define LANG_ELDER_TEIRDAL 17
|
||||
#define LANG_LIZARDMAN 18
|
||||
#define LANG_ORCISH 19
|
||||
#define LANG_FAERIE 20
|
||||
#define LANG_DRAGON 21
|
||||
#define LANG_ELDER_DRAGON 22
|
||||
#define LANG_DARK_SPEECH 23
|
||||
#define LANG_VAH_SHIR 24
|
||||
#define LANG_ALARAN 25
|
||||
#define LANG_HADAL 26
|
||||
#define LANG_UNKNOWN 27
|
||||
|
||||
#define MAX_LANGUAGE_SKILL 100
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef CODE_LOOT_H
|
||||
#define CODE_LOOT_H
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "../common/types.h"
|
||||
|
||||
struct LootItem {
|
||||
uint32 item_id;
|
||||
int16 equip_slot;
|
||||
uint16 charges;
|
||||
uint16 lootslot;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
uint32 aug_6;
|
||||
bool attuned;
|
||||
std::string custom_data;
|
||||
uint32 ornamenticon{};
|
||||
uint32 ornamentidfile{};
|
||||
uint32 ornament_hero_model{};
|
||||
uint16 trivial_min_level;
|
||||
uint16 trivial_max_level;
|
||||
uint16 npc_min_level;
|
||||
uint16 npc_max_level;
|
||||
};
|
||||
|
||||
typedef std::list<LootItem*> LootItems;
|
||||
|
||||
|
||||
#endif //CODE_LOOT_H
|
||||
@@ -1,68 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _EQEMU_LOOTTABLE_H
|
||||
#define _EQEMU_LOOTTABLE_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#pragma pack(1)
|
||||
struct LootTableEntries_Struct {
|
||||
uint32 lootdrop_id;
|
||||
uint8 droplimit;
|
||||
uint8 mindrop;
|
||||
uint8 multiplier;
|
||||
float probability;
|
||||
};
|
||||
|
||||
struct ContentFlags {
|
||||
int16 min_expansion;
|
||||
int16 max_expansion;
|
||||
char content_flags[100];
|
||||
char content_flags_disabled[100];
|
||||
};
|
||||
|
||||
struct LootTable_Struct {
|
||||
uint32 mincash;
|
||||
uint32 maxcash;
|
||||
uint32 avgcoin;
|
||||
uint32 NumEntries;
|
||||
ContentFlags content_flags;
|
||||
LootTableEntries_Struct Entries[0];
|
||||
};
|
||||
|
||||
struct LootDropEntries_Struct {
|
||||
uint32 item_id;
|
||||
int8 item_charges;
|
||||
uint8 equip_item;
|
||||
float chance;
|
||||
uint16 trivial_min_level;
|
||||
uint16 trivial_max_level;
|
||||
uint16 npc_min_level;
|
||||
uint16 npc_max_level;
|
||||
uint8 multiplier;
|
||||
};
|
||||
|
||||
struct LootDrop_Struct {
|
||||
uint32 NumEntries;
|
||||
ContentFlags content_flags;
|
||||
LootDropEntries_Struct Entries[0];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,586 @@
|
||||
#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>
|
||||
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
|
||||
{
|
||||
// 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
|
||||
+59
-84
@@ -202,7 +202,7 @@ namespace RoF
|
||||
unsigned char *emu_buffer = in->pBuffer;
|
||||
uint32 opcode = *((uint32*)emu_buffer);
|
||||
|
||||
if (opcode == 8) {
|
||||
if (opcode == AlternateCurrencyMode::Populate) {
|
||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(
|
||||
@@ -1308,13 +1308,13 @@ namespace RoF
|
||||
PutFieldN(class_);
|
||||
|
||||
/* Translate older ranks to new values */
|
||||
switch (emu_e->rank) {
|
||||
case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
|
||||
case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
|
||||
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
|
||||
default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
|
||||
}
|
||||
|
||||
//switch (emu_e->rank) {
|
||||
//case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
|
||||
//case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
|
||||
//case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
|
||||
//default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
|
||||
//}
|
||||
PutFieldN(rank);
|
||||
PutFieldN(time_last_on);
|
||||
PutFieldN(tribute_enable);
|
||||
e->unknown01 = 0;
|
||||
@@ -2621,7 +2621,7 @@ namespace RoF
|
||||
general->parameter = RaidCommandAcceptInvite;
|
||||
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
safe_delete(inapp);
|
||||
@@ -3051,19 +3051,12 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
||||
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct);
|
||||
|
||||
eq->GuildID = emu->Unknown00;
|
||||
eq->guild_id = emu->Unknown00;
|
||||
eq->rank = emu->rank;
|
||||
|
||||
/* Translate older ranks to new values */
|
||||
switch (emu->Rank) {
|
||||
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
|
||||
case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1
|
||||
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
|
||||
default: { eq->Rank = emu->Rank; break; }
|
||||
}
|
||||
|
||||
memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName));
|
||||
OUT(Banker);
|
||||
eq->Unknown76 = 1;
|
||||
memcpy(eq->member_name, emu->member_name, sizeof(eq->member_name));
|
||||
OUT(banker);
|
||||
eq->unknown76 = 1;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -3096,21 +3089,6 @@ namespace RoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Merchant_Click_Struct);
|
||||
SETUP_DIRECT_ENCODE(Merchant_Click_Struct, structs::Merchant_Click_Struct);
|
||||
|
||||
OUT(npcid);
|
||||
OUT(playerid);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
eq->unknown01 = 3; // Not sure what these values do yet, but list won't display without them
|
||||
eq->unknown02 = 2592000;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SkillUpdate)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(SkillUpdate_Struct);
|
||||
@@ -3165,7 +3143,7 @@ namespace RoF
|
||||
|
||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
||||
|
||||
if (sas->type != AT_Size)
|
||||
if (sas->type != AppearanceType::Size)
|
||||
{
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
@@ -3516,14 +3494,13 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(ClickTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||
|
||||
eq->Code = emu->Code;
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
for (uint32 i = 0; i < 200; i++)
|
||||
eq->Code = emu->action;
|
||||
for (uint32 i = 0; i < RoF::invtype::BAZAAR_SIZE; i++)
|
||||
{
|
||||
strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
||||
eq->items[i].Unknown18 = 0;
|
||||
if (i < 80) {
|
||||
eq->ItemCost[i] = emu->ItemCost[i];
|
||||
eq->ItemCost[i] = emu->item_cost[i];
|
||||
}
|
||||
else {
|
||||
eq->ItemCost[i] = 0;
|
||||
@@ -3537,9 +3514,9 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(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));
|
||||
eq->TraderID = emu->TraderID;
|
||||
eq->TraderID = emu->entity_id;
|
||||
eq->Stacksize = 0;
|
||||
eq->Price = 0;
|
||||
|
||||
@@ -3565,13 +3542,13 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
OUT(item_id);
|
||||
OUT(quantity);
|
||||
OUT(already_sold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -3868,8 +3845,8 @@ namespace RoF
|
||||
}
|
||||
|
||||
float SpawnSize = emu->size;
|
||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
||||
if (!((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin))
|
||||
)
|
||||
{
|
||||
PacketSize += 60;
|
||||
@@ -3973,10 +3950,22 @@ namespace RoF
|
||||
|
||||
/* Translate older ranks to new values */
|
||||
switch (emu->guildrank) {
|
||||
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
|
||||
case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
|
||||
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
|
||||
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
|
||||
case 0: {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5);
|
||||
break;
|
||||
} // GUILD_MEMBER 0
|
||||
case 1: {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3);
|
||||
break;
|
||||
} // GUILD_OFFICER 1
|
||||
case 2: {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1);
|
||||
break;
|
||||
} // GUILD_LEADER 2
|
||||
default: {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank);
|
||||
break;
|
||||
} //
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4002,8 +3991,8 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
||||
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||
)
|
||||
{
|
||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||
@@ -5042,19 +5031,6 @@ namespace RoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Merchant_Click_Struct);
|
||||
SETUP_DIRECT_DECODE(Merchant_Click_Struct, structs::Merchant_Click_Struct);
|
||||
|
||||
IN(npcid);
|
||||
IN(playerid);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Trader)
|
||||
{
|
||||
uint32 psize = __packet->size;
|
||||
@@ -5064,12 +5040,11 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||
MEMSET_IN(ClickTrader_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
for (uint32 i = 0; i < 80; i++)
|
||||
emu->action = eq->Code;
|
||||
for (uint32 i = 0; i < RoF::invtype::BAZAAR_SIZE; i++)
|
||||
{
|
||||
emu->SerialNumber[i] = 0; // eq->SerialNumber[i];
|
||||
emu->ItemCost[i] = eq->ItemCost[i];
|
||||
emu->serial_number[i] = 0; // eq->SerialNumber[i];
|
||||
emu->item_cost[i] = eq->ItemCost[i];
|
||||
}
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -5080,8 +5055,8 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
MEMSET_IN(Trader_ShowItems_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
emu->TraderID = eq->TraderID;
|
||||
emu->action = eq->Code;
|
||||
emu->entity_id = eq->TraderID;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -5103,12 +5078,12 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
+1286
-410
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -37,7 +37,7 @@ namespace RoF2
|
||||
|
||||
const bool AllowOverLevelEquipment = true;
|
||||
|
||||
const bool AllowEmptyBagInBag = true;
|
||||
const bool AllowEmptyBagInBag = true;
|
||||
const bool AllowClickCastFromBag = true;
|
||||
|
||||
} /*inventory*/
|
||||
@@ -77,38 +77,38 @@ namespace RoF2
|
||||
} // namespace enum_
|
||||
using namespace enum_;
|
||||
|
||||
const int16 POSSESSIONS_SIZE = 34;
|
||||
const int16 BANK_SIZE = 24;
|
||||
const int16 SHARED_BANK_SIZE = 2;
|
||||
const int16 TRADE_SIZE = 8;
|
||||
const int16 WORLD_SIZE = 10;
|
||||
const int16 LIMBO_SIZE = 36;
|
||||
const int16 TRIBUTE_SIZE = 5;
|
||||
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
|
||||
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
|
||||
const int16 MERCHANT_SIZE = 200;
|
||||
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
|
||||
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
|
||||
const int16 BAZAAR_SIZE = 200;
|
||||
const int16 INSPECT_SIZE = 23;
|
||||
const int16 REAL_ESTATE_SIZE = 0;//unknown
|
||||
const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE;
|
||||
const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE;
|
||||
const int16 POSSESSIONS_SIZE = 34;
|
||||
const int16 BANK_SIZE = 24;
|
||||
const int16 SHARED_BANK_SIZE = 2;
|
||||
const int16 TRADE_SIZE = 8;
|
||||
const int16 WORLD_SIZE = 10;
|
||||
const int16 LIMBO_SIZE = 36;
|
||||
const int16 TRIBUTE_SIZE = 5;
|
||||
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
|
||||
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
|
||||
const int16 MERCHANT_SIZE = 500;
|
||||
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
|
||||
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
|
||||
const int16 BAZAAR_SIZE = 200;
|
||||
const int16 INSPECT_SIZE = 23;
|
||||
const int16 REAL_ESTATE_SIZE = 0;//unknown
|
||||
const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE;
|
||||
const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE;
|
||||
const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE;
|
||||
const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE;
|
||||
const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank"
|
||||
const int16 ARCHIVED_SIZE = 0;//unknown
|
||||
const int16 MAIL_SIZE = 0;//unknown
|
||||
const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE;
|
||||
const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank"
|
||||
const int16 ARCHIVED_SIZE = 0;//unknown
|
||||
const int16 MAIL_SIZE = 0;//unknown
|
||||
const int16 GUILD_TROPHY_TRIBUTE_SIZE = 0;//unknown
|
||||
const int16 KRONO_SIZE = 0;//unknown
|
||||
const int16 OTHER_SIZE = 0;//unknown
|
||||
const int16 KRONO_SIZE = 0;//unknown
|
||||
const int16 OTHER_SIZE = 0;//unknown
|
||||
|
||||
const int16 TRADE_NPC_SIZE = 4; // defined by implication
|
||||
|
||||
const int16 TYPE_INVALID = IINVALID;
|
||||
const int16 TYPE_BEGIN = typePossessions;
|
||||
const int16 TYPE_END = typeOther;
|
||||
const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1;
|
||||
const int16 TYPE_BEGIN = typePossessions;
|
||||
const int16 TYPE_END = typeOther;
|
||||
const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1;
|
||||
|
||||
int16 GetInvTypeSize(int16 inv_type);
|
||||
const char* GetInvTypeName(int16 inv_type);
|
||||
@@ -158,36 +158,58 @@ namespace RoF2
|
||||
slotCursor
|
||||
};
|
||||
|
||||
constexpr int16 format_as(InventorySlots slot) { return static_cast<int16>(slot); }
|
||||
} // namespace enum_
|
||||
using namespace enum_;
|
||||
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
|
||||
const int16 BANK_BEGIN = 2000;
|
||||
const int16 BANK_END = (BANK_BEGIN + invtype::BANK_SIZE) - 1;
|
||||
|
||||
const int16 SHARED_BANK_BEGIN = 2500;
|
||||
const int16 SHARED_BANK_END = (SHARED_BANK_BEGIN + invtype::SHARED_BANK_SIZE) - 1;
|
||||
|
||||
const int16 TRADE_BEGIN = 3000;
|
||||
const int16 TRADE_END = (TRADE_BEGIN + invtype::TRADE_SIZE) - 1;
|
||||
|
||||
const int16 TRADE_NPC_END = (TRADE_BEGIN + invtype::TRADE_NPC_SIZE) - 1; // defined by implication
|
||||
|
||||
const int16 WORLD_BEGIN = 4000;
|
||||
const int16 WORLD_END = (WORLD_BEGIN + invtype::WORLD_SIZE) - 1;
|
||||
|
||||
const int16 TRIBUTE_BEGIN = 400;
|
||||
const int16 TRIBUTE_END = (TRIBUTE_BEGIN + invtype::TRIBUTE_SIZE) - 1;
|
||||
|
||||
const int16 GUILD_TRIBUTE_BEGIN = 450;
|
||||
const int16 GUILD_TRIBUTE_END = (GUILD_TRIBUTE_BEGIN + invtype::GUILD_TRIBUTE_SIZE) - 1;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
const int16 EQUIPMENT_BEGIN = slotCharm;
|
||||
const int16 EQUIPMENT_END = slotAmmo;
|
||||
const int16 EQUIPMENT_END = slotAmmo;
|
||||
const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN) + 1;
|
||||
|
||||
const int16 GENERAL_BEGIN = slotGeneral1;
|
||||
const int16 GENERAL_END = slotGeneral10;
|
||||
const int16 GENERAL_END = slotGeneral10;
|
||||
const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN) + 1;
|
||||
|
||||
const int16 BONUS_BEGIN = invslot::slotCharm;
|
||||
const int16 BONUS_STAT_END = invslot::slotPowerSource;
|
||||
const int16 BONUS_BEGIN = invslot::slotCharm;
|
||||
const int16 BONUS_STAT_END = invslot::slotPowerSource;
|
||||
const int16 BONUS_SKILL_END = invslot::slotAmmo;
|
||||
|
||||
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
|
||||
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
|
||||
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
|
||||
|
||||
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
|
||||
const uint64 GENERAL_BITMASK = 0x00000001FF800000;
|
||||
const uint64 CURSOR_BITMASK = 0x0000000200000000;
|
||||
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
|
||||
const uint64 GENERAL_BITMASK = 0x00000001FF800000;
|
||||
const uint64 CURSOR_BITMASK = 0x0000000200000000;
|
||||
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
|
||||
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
|
||||
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
|
||||
|
||||
|
||||
const char* GetInvPossessionsSlotName(int16 inv_slot);
|
||||
@@ -198,10 +220,21 @@ namespace RoF2
|
||||
namespace invbag {
|
||||
inline EQ::versions::ClientVersion GetInvBagRef() { return EQ::versions::ClientVersion::RoF2; }
|
||||
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
const int16 SLOT_END = 9; //254;
|
||||
const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test)
|
||||
const int16 SLOT_TRADESKILL_EXPERIMENT_COMBINE = 1000;
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
const int16 SLOT_COUNT = 200;
|
||||
const int16 SLOT_END = SLOT_COUNT - 1;
|
||||
|
||||
const int16 GENERAL_BAGS_BEGIN = 251;
|
||||
|
||||
const int16 CURSOR_BAG_BEGIN = 351;
|
||||
|
||||
const int16 BANK_BAGS_BEGIN = 2031;
|
||||
|
||||
const int16 SHARED_BANK_BAGS_BEGIN = 2531;
|
||||
|
||||
const int16 TRADE_BAGS_BEGIN = 3031;
|
||||
|
||||
const char* GetInvBagIndexName(int16 bag_index);
|
||||
|
||||
@@ -211,9 +244,9 @@ namespace RoF2
|
||||
inline EQ::versions::ClientVersion GetInvAugRef() { return EQ::versions::ClientVersion::RoF2; }
|
||||
|
||||
const int16 SOCKET_INVALID = IINVALID;
|
||||
const int16 SOCKET_BEGIN = INULL;
|
||||
const int16 SOCKET_END = 5;
|
||||
const int16 SOCKET_COUNT = 6;
|
||||
const int16 SOCKET_BEGIN = INULL;
|
||||
const int16 SOCKET_END = 5;
|
||||
const int16 SOCKET_COUNT = 6;
|
||||
|
||||
const char* GetInvAugIndexName(int16 aug_index);
|
||||
|
||||
@@ -270,6 +303,7 @@ namespace RoF2
|
||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 56;
|
||||
const uint32 MAX_GUILD_ID = 50000;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
@@ -289,7 +323,7 @@ namespace RoF2
|
||||
|
||||
namespace spells {
|
||||
inline EQ::versions::ClientVersion GetSkillsRef() { return EQ::versions::ClientVersion::RoF2; }
|
||||
|
||||
|
||||
enum class CastingSlot : uint32 {
|
||||
Gem1 = 0,
|
||||
Gem2 = 1,
|
||||
@@ -312,7 +346,7 @@ namespace RoF2
|
||||
const int SPELL_ID_MAX = 45000;
|
||||
const int SPELLBOOK_SIZE = 720;
|
||||
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
|
||||
|
||||
|
||||
const int LONG_BUFFS = 42;
|
||||
const int SHORT_BUFFS = 20;
|
||||
const int DISC_BUFFS = 1;
|
||||
|
||||
@@ -43,10 +43,12 @@ E(OP_ApplyPoison)
|
||||
E(OP_AugmentInfo)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_BeginCast)
|
||||
E(OP_BlockedBuffs)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_BuyerItems)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_CastSpell)
|
||||
E(OP_ChannelMessage)
|
||||
@@ -82,6 +84,7 @@ E(OP_GuildBank)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildMemberUpdate)
|
||||
E(OP_GuildsList)
|
||||
E(OP_GuildTributeDonateItem)
|
||||
E(OP_HPUpdate)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectBuffs)
|
||||
@@ -115,7 +118,6 @@ E(OP_SendZonepoints)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
@@ -148,11 +150,13 @@ D(OP_Animation)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Barter)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_BlockedBuffs)
|
||||
D(OP_BookButton)
|
||||
D(OP_Buff)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_BuyerItems)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
@@ -182,6 +186,7 @@ D(OP_GuildBank)
|
||||
D(OP_GuildDemote)
|
||||
D(OP_GuildRemove)
|
||||
D(OP_GuildStatus)
|
||||
D(OP_GuildTributeDonateItem)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
@@ -198,7 +203,7 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_ShopSendParcel)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
|
||||
+348
-159
@@ -354,15 +354,15 @@ struct Spawn_Struct_Bitfields
|
||||
/*29*/ unsigned showname:1;
|
||||
/*30*/ unsigned idleanimationsoff:1; // what we called statue?
|
||||
/*31*/ unsigned untargetable:1; // bClickThrough
|
||||
/* do these later
|
||||
32 unsigned buyer:1;
|
||||
33 unsigned offline:1;
|
||||
34 unsigned interactiveobject:1;
|
||||
35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
||||
36 unsigned title:1;
|
||||
37 unsigned suffix:1;
|
||||
38 unsigned padding1:1;
|
||||
39 unsigned padding2:1;
|
||||
// byte 5
|
||||
/*32 unsigned buyer:1;
|
||||
/*33 unsigned offline:1;
|
||||
/*34 unsigned interactiveobject:1;
|
||||
/*35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
||||
/*36 unsigned title:1;
|
||||
/*37 unsigned suffix:1;
|
||||
/*38 unsigned padding1:1;
|
||||
/*39 unsigned padding2:1;
|
||||
40 unsinged padding3:1;
|
||||
*/
|
||||
/*
|
||||
@@ -2011,6 +2011,31 @@ struct GuildBankClear_Struct
|
||||
/*16*/ uint32 MainAreaCount;
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItemRequest_Struct {
|
||||
/*000*/ uint32 type;
|
||||
/*004*/ uint16 slot;
|
||||
/*006*/ uint16 sub_index;
|
||||
/*008*/ uint16 aug_index;
|
||||
/*010*/ uint16 unknown10;
|
||||
/*012*/ uint32 quantity;
|
||||
/*016*/ uint32 tribute_master_id;
|
||||
/*020*/ uint32 unknown20;
|
||||
/*024*/ uint32 guild_id;
|
||||
/*028*/ uint32 unknown28;
|
||||
/*032*/ uint32 unknown32;
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItemReply_Struct {
|
||||
/*000*/ uint32 type;
|
||||
/*004*/ uint16 slot;
|
||||
/*006*/ uint16 sub_index;
|
||||
/*008*/ uint16 aug_index;
|
||||
/*010*/ uint16 unknown10;
|
||||
/*012*/ uint32 quantity;
|
||||
/*016*/ uint32 unknown20;
|
||||
/*020*/ uint32 favor;
|
||||
};
|
||||
|
||||
/*
|
||||
** Money Loot
|
||||
** Length: 22 Bytes
|
||||
@@ -2222,15 +2247,17 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 unknown01; // Seen 3 from Server or -1 from Client
|
||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -3079,28 +3106,163 @@ struct EnvDamage2_Struct {
|
||||
};
|
||||
|
||||
//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
|
||||
};
|
||||
|
||||
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 {
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_CustomerBrowsing = 13,
|
||||
BazaarInspectItem = 18,
|
||||
BazaarSearchDone2 = 19,
|
||||
BazaarInspectItem = 18,
|
||||
BazaarSearchDone2 = 19,
|
||||
BazaarTrader_StartTraderMode2 = 22
|
||||
};
|
||||
|
||||
enum {
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_UpdatePrice = 1,
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
};
|
||||
|
||||
struct BazaarWindowStart_Struct {
|
||||
@@ -3109,34 +3271,51 @@ struct BazaarWindowStart_Struct {
|
||||
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 {
|
||||
uint32 Code;
|
||||
uint32 EntityID;
|
||||
uint32 Traders;
|
||||
uint32 Items;
|
||||
uint32 Traders2;
|
||||
uint32 Items2;
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 num_of_traders;
|
||||
uint32 num_of_items;
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 TraderID;
|
||||
uint32 Class_;
|
||||
uint32 Race;
|
||||
uint32 ItemStat;
|
||||
uint32 Slot;
|
||||
uint32 Type;
|
||||
char Name[64];
|
||||
uint32 MinPrice;
|
||||
uint32 MaxPrice;
|
||||
uint32 Minlevel;
|
||||
uint32 MaxLlevel;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint8 search_scope;//1 all traders 0 local traders
|
||||
/*005*/ uint8 unknown_005{0};
|
||||
/*006*/ uint16 unknown_006{0};
|
||||
/*008*/ uint32 unknown_008{0};
|
||||
/*012*/ uint32 unknown_012{0};
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ uint32 _class;
|
||||
/*024*/ uint32 race;
|
||||
/*028*/ uint32 item_stat;
|
||||
/*032*/ uint32 slot;
|
||||
/*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{
|
||||
uint32 ItemID;
|
||||
uint32 Unknown004;
|
||||
char Name[64];
|
||||
|
||||
struct BazaarInspect_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 trader_id;
|
||||
char serial_number[17];
|
||||
char unknown_029[3];
|
||||
uint32 item_id;
|
||||
uint32 unknown_036;
|
||||
};
|
||||
|
||||
struct NewBazaarInspect_Struct {
|
||||
@@ -3157,18 +3336,23 @@ struct BazaarReturnDone_Struct{
|
||||
uint32 Unknown016;
|
||||
};
|
||||
|
||||
struct BazaarSearchResults_Struct {
|
||||
/*000*/ BazaarWindowStart_Struct Beginning;
|
||||
/*004*/ uint32 SellerID;
|
||||
/*008*/ char SellerName[64];
|
||||
/*072*/ uint32 NumItems;
|
||||
/*076*/ uint32 ItemID;
|
||||
/*080*/ uint32 SerialNumber;
|
||||
/*084*/ uint32 Unknown084;
|
||||
/*088*/ char ItemName[64];
|
||||
/*152*/ uint32 Cost;
|
||||
/*156*/ uint32 ItemStat;
|
||||
/*160*/
|
||||
struct BazaarSearchDetails_Struct { //24+name+17
|
||||
/*014*/ uint32 trader_id;
|
||||
/*018*/ char serial_num[17];
|
||||
/*022*/ uint32 cost;
|
||||
/*026*/ uint32 quanity;
|
||||
/*030*/ uint32 id;
|
||||
/*034*/ uint32 icon;
|
||||
/*038*/ char name[1];
|
||||
/*039*/ uint32 stat;
|
||||
};
|
||||
|
||||
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 {
|
||||
@@ -3371,21 +3555,26 @@ struct WhoAllPlayerPart4 {
|
||||
};
|
||||
|
||||
struct TraderItemSerial_Struct {
|
||||
char SerialNumber[17];
|
||||
uint8 Unknown18;
|
||||
char serial_number[17];
|
||||
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 {
|
||||
/*0000*/ uint32 Code;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 ItemCost[200];
|
||||
struct BeginTrader_Struct {
|
||||
/*0000*/ uint32 action;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 item_cost[200];
|
||||
/*4404*/
|
||||
};
|
||||
|
||||
struct ClickTrader_Struct {
|
||||
/*0000*/ uint32 Code;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 ItemCost[200];
|
||||
/*0000*/ uint32 action;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 item_cost[200];
|
||||
/*4404*/
|
||||
};
|
||||
|
||||
@@ -3394,67 +3583,55 @@ struct GetItems_Struct {
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct {
|
||||
uint32 id;
|
||||
uint32 code;
|
||||
uint32 entity_id;
|
||||
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 {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint16 TraderID;
|
||||
/*008*/ uint32 Unknown08;
|
||||
/*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*/
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 entity_id;
|
||||
/*008*/ uint32 unknown_008;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct TraderStatus_Struct {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 Uknown04;
|
||||
/*008*/ uint32 Uknown08;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 sub_action;
|
||||
/*008*/ uint32 uknown_008;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Unknown008;
|
||||
/*012*/ uint32 Unknown012;
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char BuyerName[64];
|
||||
/*084*/ char SellerName[64];
|
||||
/*148*/ char Unknown148[32];
|
||||
/*180*/ char ItemName[64];
|
||||
/*244*/ char SerialNumber[16];
|
||||
/*260*/ uint32 Unknown076;
|
||||
/*264*/ uint32 ItemID;
|
||||
/*268*/ uint32 Price;
|
||||
/*272*/ uint32 AlreadySold;
|
||||
/*276*/ uint32 Unknown276;
|
||||
/*280*/ uint32 Quantity;
|
||||
/*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*/
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 method;
|
||||
/*008*/ uint32 sub_action;
|
||||
/*012*/ uint32 unknown_012;
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ char buyer_name[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{
|
||||
@@ -3475,15 +3652,15 @@ struct MoneyUpdate_Struct{
|
||||
struct TraderDelItem_Struct{
|
||||
/*000*/ uint32 Unknown000;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ char SerialNumber[16];
|
||||
/*008*/ char SerialNumber[17];
|
||||
/*024*/ uint32 Unknown012;
|
||||
/*028*/
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ uint32 Approval;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 trader_id;
|
||||
/*008*/ uint32 unknown_008;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
@@ -3600,11 +3777,11 @@ struct GuildMakeLeader {
|
||||
// Update a guild members rank and banker status
|
||||
struct GuildSetRank_Struct
|
||||
{
|
||||
/*00*/ uint32 GuildID; // Was Unknown00
|
||||
/*04*/ uint32 Rank;
|
||||
/*08*/ char MemberName[64];
|
||||
/*72*/ uint32 Banker;
|
||||
/*76*/ uint32 Unknown76; // Seen 1 - Maybe Banker?
|
||||
/*00*/ uint32 guild_id; // Was Unknown00
|
||||
/*04*/ uint32 rank;
|
||||
/*08*/ char member_name[64];
|
||||
/*72*/ uint32 banker;
|
||||
/*76*/ uint32 unknown76; // Seen 1 - Maybe Banker?
|
||||
/*80*/
|
||||
};
|
||||
|
||||
@@ -3619,7 +3796,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint32 min_dmg;
|
||||
uint32 max_dmg;
|
||||
};
|
||||
struct Ground_Spawn{
|
||||
struct GroundSpawn{
|
||||
float max_x;
|
||||
float max_y;
|
||||
float min_x;
|
||||
@@ -3631,8 +3808,8 @@ struct Ground_Spawn{
|
||||
uint32 max_allowed;
|
||||
uint32 respawntimer;
|
||||
};
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
struct GroundSpawns {
|
||||
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
@@ -3722,15 +3899,15 @@ struct TributeItem_Struct
|
||||
|
||||
struct TributePoint_Struct {
|
||||
int32 tribute_points;
|
||||
uint32 unknown04;
|
||||
uint32 unknown04;
|
||||
int32 career_tribute_points;
|
||||
uint32 unknown12;
|
||||
uint32 unknown12;
|
||||
};
|
||||
|
||||
struct TributeMoney_Struct {
|
||||
uint32 platinum;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
int32 tribute_points;
|
||||
};
|
||||
|
||||
|
||||
@@ -4547,25 +4724,25 @@ struct RoF2SlotStruct
|
||||
|
||||
struct ItemSerializationHeader
|
||||
{
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
/*026*/ uint16 main_slot;
|
||||
/*028*/ uint16 sub_slot;
|
||||
/*030*/ uint16 aug_slot; // 0xffff
|
||||
/*032*/ uint32 price;
|
||||
/*036*/ uint32 merchant_slot; //1 if not a merchant item
|
||||
/*040*/ uint32 scaled_value; //0
|
||||
/*044*/ uint32 instance_id; //unique instance id if not merchant item, else is merchant slot
|
||||
/*048*/ uint32 unknown028; //0
|
||||
/*052*/ uint32 last_cast_time; // Unix Time from PP of last cast for this recast type if recast delay > 0
|
||||
/*056*/ uint32 charges; //Total Charges an item has (-1 for unlimited)
|
||||
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
|
||||
/*064*/ uint32 unknown044; // 0
|
||||
/*068*/ uint32 unknown048; // 0
|
||||
/*072*/ uint32 unknown052; // 0
|
||||
uint8 isEvolving;
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
/*026*/ uint16 main_slot;
|
||||
/*028*/ uint16 sub_slot;
|
||||
/*030*/ uint16 aug_slot; // 0xffff
|
||||
/*032*/ uint32 price;
|
||||
/*036*/ uint32 merchant_slot; // 1 if not a merchant item
|
||||
/*040*/ uint32 scaled_value; // 0
|
||||
/*044*/ uint32 instance_id; // unique instance id if not merchant item, else is merchant slot
|
||||
/*048*/ uint32 parcel_item_id;
|
||||
/*052*/ uint32 last_cast_time; // Unix Time from PP of last cast for this recast type if recast delay > 0
|
||||
/*056*/ uint32 charges; // Total Charges an item has (-1 for unlimited)
|
||||
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
|
||||
/*064*/ uint32 unknown044; // 0
|
||||
/*068*/ uint32 unknown048; // 0
|
||||
/*072*/ uint32 unknown052; // 0
|
||||
uint8 isEvolving;
|
||||
};
|
||||
|
||||
struct EvolvingItem {
|
||||
@@ -5236,6 +5413,18 @@ struct Checksum_Struct {
|
||||
uint8_t data[2048];
|
||||
};
|
||||
|
||||
struct Parcel_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id;
|
||||
/*004*/ TypelessInventorySlot_Struct inventory_slot;
|
||||
/*012*/ uint32 quantity;
|
||||
/*016*/ uint32 money_flag;
|
||||
/*020*/ char send_to[64];
|
||||
/*084*/ char note[128];
|
||||
/*212*/ uint32 unknown_212;
|
||||
/*216*/ uint32 unknown_216;
|
||||
/*220*/ uint32 unknown_220;
|
||||
};
|
||||
}; /*structs*/
|
||||
|
||||
}; /*RoF2*/
|
||||
|
||||
@@ -101,7 +101,6 @@ E(OP_SendZonepoints)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
@@ -183,7 +182,6 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
|
||||
@@ -2200,15 +2200,17 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 unknown01; // Seen 3 from Server or -1 from Client
|
||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -3374,17 +3376,17 @@ struct TraderStatus_Struct {
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*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;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 unknown_004;
|
||||
/*008*/ uint32 price;
|
||||
/*012*/ uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ char item_name[64];
|
||||
/*084*/ uint32 unknown_076;
|
||||
/*088*/ uint32 item_id;
|
||||
/*092*/ uint32 already_sold;
|
||||
/*096*/ uint32 quantity;
|
||||
/*100*/ uint32 unknown_092;
|
||||
/*104*/
|
||||
};
|
||||
|
||||
@@ -3537,11 +3539,11 @@ struct GuildMakeLeader {
|
||||
// Update a guild members rank and banker status
|
||||
struct GuildSetRank_Struct
|
||||
{
|
||||
/*00*/ uint32 GuildID; // Was Unknown00
|
||||
/*04*/ uint32 Rank;
|
||||
/*08*/ char MemberName[64];
|
||||
/*72*/ uint32 Banker;
|
||||
/*76*/ uint32 Unknown76; // Seen 1 - Maybe Banker?
|
||||
/*00*/ uint32 guild_id; // Was Unknown00
|
||||
/*04*/ uint32 rank;
|
||||
/*08*/ char member_name[64];
|
||||
/*72*/ uint32 banker;
|
||||
/*76*/ uint32 unknown76; // Seen 1 - Maybe Banker?
|
||||
/*80*/
|
||||
};
|
||||
|
||||
@@ -3556,7 +3558,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint32 min_dmg;
|
||||
uint32 max_dmg;
|
||||
};
|
||||
struct Ground_Spawn{
|
||||
struct GroundSpawn{
|
||||
float max_x;
|
||||
float max_y;
|
||||
float min_x;
|
||||
@@ -3568,8 +3570,8 @@ struct Ground_Spawn{
|
||||
uint32 max_allowed;
|
||||
uint32 respawntimer;
|
||||
};
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
struct GroundSpawns {
|
||||
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
|
||||
+47
-19
@@ -2026,6 +2026,19 @@ namespace SoD
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MerchantClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
OUT(npc_id);
|
||||
OUT(player_id);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SomeItemPacketMaybe)
|
||||
{
|
||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||
@@ -2273,13 +2286,13 @@ namespace SoD
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
OUT(item_id);
|
||||
OUT(quantity);
|
||||
OUT(already_sold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -2507,8 +2520,8 @@ namespace SoD
|
||||
}
|
||||
|
||||
float SpawnSize = emu->size;
|
||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
||||
if (!((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin))
|
||||
)
|
||||
{
|
||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQ::textures::materialCount);
|
||||
@@ -2706,8 +2719,8 @@ namespace SoD
|
||||
|
||||
Buffer += sizeof(structs::Spawn_Struct_Position);
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
||||
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||
)
|
||||
{
|
||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||
@@ -2733,8 +2746,8 @@ namespace SoD
|
||||
}
|
||||
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
||||
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||
)
|
||||
{
|
||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||
@@ -3483,18 +3496,33 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MerchantClick_Struct);
|
||||
SETUP_DIRECT_DECODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
IN(npc_id);
|
||||
IN(player_id);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
emu->tab_display = 0;
|
||||
emu->unknown020 = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderBuy)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
@@ -141,6 +142,7 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
|
||||
@@ -1845,12 +1845,16 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -2875,20 +2879,21 @@ struct Trader_ShowItems_Struct{
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*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;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 unknown_004;
|
||||
/*008*/ uint32 price;
|
||||
/*012*/ uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ char item_name[64];
|
||||
/*084*/ uint32 unknown_076;
|
||||
/*088*/ uint32 item_id;
|
||||
/*092*/ uint32 already_sold;
|
||||
/*096*/ uint32 quantity;
|
||||
/*100*/ uint32 unknown_092;
|
||||
/*104*/
|
||||
};
|
||||
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
uint32 unknown0;
|
||||
uint32 traderid;
|
||||
@@ -3026,7 +3031,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint32 min_dmg;
|
||||
uint32 max_dmg;
|
||||
};
|
||||
struct Ground_Spawn{
|
||||
struct GroundSpawn{
|
||||
float max_x;
|
||||
float max_y;
|
||||
float min_x;
|
||||
@@ -3038,8 +3043,8 @@ struct Ground_Spawn{
|
||||
uint32 max_allowed;
|
||||
uint32 respawntimer;
|
||||
};
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
struct GroundSpawns {
|
||||
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
|
||||
+44
-16
@@ -270,8 +270,8 @@ namespace SoF
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
|
||||
OUT(ID);
|
||||
OUT(Code);
|
||||
OUT(trader_id);
|
||||
OUT(action);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -1683,6 +1683,19 @@ namespace SoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MerchantClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
OUT(npc_id);
|
||||
OUT(player_id);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SomeItemPacketMaybe)
|
||||
{
|
||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||
@@ -1889,13 +1902,13 @@ namespace SoF
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
OUT(item_id);
|
||||
OUT(quantity);
|
||||
OUT(already_sold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -2336,7 +2349,7 @@ namespace SoF
|
||||
DECODE_LENGTH_EXACT(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));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -2874,18 +2887,33 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MerchantClick_Struct);
|
||||
SETUP_DIRECT_DECODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
IN(npc_id);
|
||||
IN(player_id);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
emu->tab_display = 0;
|
||||
emu->unknown020 = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderBuy)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
@@ -128,6 +129,7 @@ D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
|
||||
@@ -1859,12 +1859,16 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -2767,8 +2771,8 @@ struct GetItems_Struct{
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct{
|
||||
uint32 ID;
|
||||
uint32 Code;
|
||||
uint32 trader_id;
|
||||
uint32 action;
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct{
|
||||
@@ -2778,15 +2782,15 @@ struct Trader_ShowItems_Struct{
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Price;
|
||||
/*008*/ uint32 TraderID;
|
||||
/*012*/ char ItemName[64];
|
||||
/*076*/ uint32 Unknown076;
|
||||
/*080*/ uint32 ItemID;
|
||||
/*084*/ uint32 AlreadySold;
|
||||
/*088*/ uint32 Quantity;
|
||||
/*092*/ uint32 Unknown092;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 price;
|
||||
/*008*/ uint32 trader_id;
|
||||
/*012*/ char item_name[64];
|
||||
/*076*/ uint32 unknown_076;
|
||||
/*080*/ uint32 item_id;
|
||||
/*084*/ uint32 already_sold;
|
||||
/*088*/ uint32 quantity;
|
||||
/*092*/ uint32 unknown_092;
|
||||
};
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
@@ -2951,7 +2955,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint32 min_dmg;
|
||||
uint32 max_dmg;
|
||||
};
|
||||
struct Ground_Spawn{
|
||||
struct GroundSpawn{
|
||||
float max_x;
|
||||
float max_y;
|
||||
float min_x;
|
||||
@@ -2963,8 +2967,8 @@ struct Ground_Spawn{
|
||||
uint32 max_allowed;
|
||||
uint32 respawntimer;
|
||||
};
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
struct GroundSpawns {
|
||||
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
|
||||
|
||||
#define ALLOC_LEN_ENCODE(len) \
|
||||
__packet->pBuffer = new unsigned char[len]; \
|
||||
__packet->pBuffer = new unsigned char[len] {}; \
|
||||
__packet->size = len; \
|
||||
memset(__packet->pBuffer, 0, len); \
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
#define SETUP_DIRECT_DECODE(emu_struct, eq_struct) \
|
||||
unsigned char *__eq_buffer = __packet->pBuffer; \
|
||||
__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; \
|
||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
||||
auto size = strlen(in->var_field); \
|
||||
__packet->size = sizeof(emu_struct) + size + 1; \
|
||||
__packet->pBuffer = new unsigned char[__packet->size]; \
|
||||
__packet->pBuffer = new unsigned char[__packet->size] {}; \
|
||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||
|
||||
|
||||
+854
-82
File diff suppressed because it is too large
Load Diff
@@ -287,6 +287,7 @@ namespace Titanium
|
||||
const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 45;
|
||||
const uint32 MAX_GUILD_ID = 1500;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
|
||||
@@ -44,8 +44,14 @@ E(OP_DzSetLeaderName)
|
||||
E(OP_Emote)
|
||||
E(OP_FormattedMessage)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_GuildsList)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildMemberAdd)
|
||||
E(OP_GuildMemberRankAltBanker)
|
||||
E(OP_SendGuildTributes)
|
||||
E(OP_GuildTributeDonateItem)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectAnswer)
|
||||
E(OP_InspectRequest)
|
||||
@@ -69,11 +75,14 @@ E(OP_SendCharInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SetFace)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_TaskDescription)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TraderShop)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
@@ -84,6 +93,7 @@ E(OP_ZoneSpawns)
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
@@ -100,9 +110,11 @@ D(OP_DzRemovePlayer)
|
||||
D(OP_DzSwapPlayer)
|
||||
D(OP_Emote)
|
||||
D(OP_FaceChange)
|
||||
D(OP_GuildDemote)
|
||||
D(OP_InspectAnswer)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_GuildTributeDonateItem)
|
||||
D(OP_LFGuild)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
@@ -112,7 +124,10 @@ D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TraderShop)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -1423,6 +1423,23 @@ struct GuildUpdate_Struct {
|
||||
GuildsListEntry_Struct entry;
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItemRequest_Struct {
|
||||
/*000*/ uint32 slot;
|
||||
/*004*/ uint32 quantity;
|
||||
/*008*/ uint32 tribute_master_id;
|
||||
/*012*/ uint32 unknown12;
|
||||
/*016*/ uint32 guild_id;
|
||||
/*020*/ uint32 unknown20;
|
||||
/*024*/ uint32 unknown24;
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItemReply_Struct {
|
||||
/*000*/ uint32 slot;
|
||||
/*004*/ uint32 quantity;
|
||||
/*008*/ uint32 unknown8;
|
||||
/*012*/ uint32 favor;
|
||||
};
|
||||
|
||||
/*
|
||||
** Money Loot
|
||||
** Length: 22 Bytes
|
||||
@@ -1652,9 +1669,9 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
struct MerchantClick_Struct {
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
};
|
||||
@@ -2256,24 +2273,29 @@ struct BazaarWelcome_Struct {
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
BazaarWindowStart_Struct beginning;
|
||||
uint32 traderid;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 stat;
|
||||
uint32 slot;
|
||||
uint32 type;
|
||||
char name[64];
|
||||
uint32 minprice;
|
||||
uint32 maxprice;
|
||||
uint32 minlevel;
|
||||
uint32 maxlevel;
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 TraderID;
|
||||
uint32 Class_;
|
||||
uint32 Race;
|
||||
uint32 ItemStat;
|
||||
uint32 Slot;
|
||||
uint32 Type;
|
||||
char Name[64];
|
||||
uint32 MinPrice;
|
||||
uint32 MaxPrice;
|
||||
uint32 Minlevel;
|
||||
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 unknown;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
struct BazaarReturnDone_Struct{
|
||||
uint32 type;
|
||||
uint32 traderid;
|
||||
@@ -2281,16 +2303,17 @@ struct BazaarReturnDone_Struct{
|
||||
uint32 unknown12;
|
||||
uint32 unknown16;
|
||||
};
|
||||
|
||||
struct BazaarSearchResults_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 SellerID;
|
||||
uint32 NumItems; // Don't know. Don't know the significance of this field.
|
||||
uint32 SerialNumber;
|
||||
uint32 Unknown016;
|
||||
uint32 Unknown020; // Something to do with stats as well
|
||||
char ItemName[64];
|
||||
uint32 Cost;
|
||||
uint32 ItemStat;
|
||||
uint32 entity_id;
|
||||
uint32 unknown_008;
|
||||
uint32 item_id;
|
||||
uint32 serial_number;
|
||||
uint32 unknown_020;
|
||||
char item_name[64];
|
||||
uint32 item_cost;
|
||||
uint32 item_stat;
|
||||
};
|
||||
|
||||
struct ServerSideFilters_Struct {
|
||||
@@ -2437,44 +2460,52 @@ struct WhoAllReturnStruct {
|
||||
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 {
|
||||
uint32 code;
|
||||
uint32 itemid[160];
|
||||
uint32 unknown;
|
||||
uint32 itemcost[80];
|
||||
uint32 action;
|
||||
uint32 unknown004;
|
||||
uint64 item_id[EQ::invtype::BAZAAR_SIZE];
|
||||
uint32 item_cost[EQ::invtype::BAZAAR_SIZE];
|
||||
};
|
||||
|
||||
struct ClickTrader_Struct {
|
||||
uint32 code;
|
||||
uint32 unknown[161];//damn soe this is totally pointless :/ but at least your finally using memset! Good job :) -LE
|
||||
uint32 itemcost[80];
|
||||
uint32 itemcost[EQ::invtype::BAZAAR_SIZE];
|
||||
};
|
||||
|
||||
struct GetItems_Struct{
|
||||
uint32 items[80];
|
||||
uint32 items[EQ::invtype::BAZAAR_SIZE];
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct{
|
||||
uint32 ID;
|
||||
uint32 Code;
|
||||
struct BecomeTrader_Struct {
|
||||
uint32 entity_id;
|
||||
uint32 action;
|
||||
char trader_name[64];
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct{
|
||||
uint32 code;
|
||||
uint32 traderid;
|
||||
uint32 action;
|
||||
uint32 entity_id;
|
||||
uint32 unknown08[3];
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Price;
|
||||
/*008*/ uint32 TraderID;
|
||||
/*012*/ char ItemName[64];
|
||||
/*076*/ uint32 Unknown076;
|
||||
/*080*/ uint32 ItemID;
|
||||
/*084*/ uint32 AlreadySold;
|
||||
/*088*/ uint32 Quantity;
|
||||
/*092*/ uint32 Unknown092;
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 price;
|
||||
/*008*/ uint32 trader_id;
|
||||
/*012*/ char item_name[64];
|
||||
/*076*/ uint32 unknown_076;
|
||||
/*080*/ uint32 item_id;
|
||||
/*084*/ uint32 already_sold;
|
||||
/*088*/ uint32 quantity;
|
||||
/*092*/ uint32 unknown_092;
|
||||
};
|
||||
|
||||
|
||||
@@ -2500,8 +2531,9 @@ struct TraderDelItem_Struct{
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
uint32 traderid;
|
||||
uint32 unknown4[2];
|
||||
uint32 trader_id;
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 approval;
|
||||
};
|
||||
|
||||
@@ -2604,7 +2636,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint32 min_dmg;
|
||||
uint32 max_dmg;
|
||||
};
|
||||
struct Ground_Spawn{
|
||||
struct GroundSpawn{
|
||||
float max_x;
|
||||
float max_y;
|
||||
float min_x;
|
||||
@@ -2616,8 +2648,8 @@ struct Ground_Spawn{
|
||||
uint32 max_allowed;
|
||||
uint32 respawntimer;
|
||||
};
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
struct GroundSpawns {
|
||||
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
@@ -3508,7 +3540,7 @@ struct LFGuild_GuildToggle_Struct
|
||||
/*540*/ uint32 TimeZone;
|
||||
/*544*/ uint8 Toggle;
|
||||
/*545*/ uint8 Unknown545[3];
|
||||
/*548*/ uint32 Expires;
|
||||
/*548*/ uint32 TimePosted;
|
||||
/*552*/ char Name[64];
|
||||
/*616*/
|
||||
};
|
||||
@@ -3699,6 +3731,49 @@ struct SayLinkBodyFrame_Struct {
|
||||
/*045*/
|
||||
};
|
||||
|
||||
struct GuildSetRank_Struct
|
||||
{
|
||||
/*00*/ uint32 unknown00;
|
||||
/*04*/ uint32 unknown04;
|
||||
/*08*/ uint32 rank;
|
||||
/*72*/ char member_name[64];
|
||||
/*76*/ uint32 banker;
|
||||
};
|
||||
|
||||
struct GuildMemberAdd_Struct {
|
||||
/*000*/ uint32 guild_id;
|
||||
/*004*/ uint32 unknown04;
|
||||
/*008*/ uint32 level;
|
||||
/*012*/ uint32 class_;
|
||||
/*016*/ uint32 rank_;
|
||||
/*020*/ uint32 zone_id;
|
||||
/*024*/ uint32 last_on;
|
||||
/*028*/ char player_name[64];
|
||||
};
|
||||
|
||||
struct GuildMemberRank_Struct {
|
||||
/*000*/ uint32 guild_id;
|
||||
/*004*/ uint32 unknown_004;
|
||||
/*008*/ uint32 rank_;
|
||||
/*012*/ char player_name[64];
|
||||
/*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*/
|
||||
|
||||
}; /*Titanium*/
|
||||
|
||||
+739
-130
File diff suppressed because it is too large
Load Diff
@@ -289,6 +289,7 @@ namespace UF
|
||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 50;
|
||||
const uint32 MAX_GUILD_ID = 50000;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ E(OP_ApplyPoison)
|
||||
E(OP_AugmentInfo)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_CancelTrade)
|
||||
@@ -58,6 +59,10 @@ E(OP_GroupInvite)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildsList)
|
||||
E(OP_GuildMemberAdd)
|
||||
E(OP_SendGuildTributes)
|
||||
E(OP_GuildMemberRankAltBanker)
|
||||
E(OP_GuildTributeDonateItem)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectBuffs)
|
||||
E(OP_InspectRequest)
|
||||
@@ -82,8 +87,10 @@ E(OP_RespondAA)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
@@ -94,6 +101,7 @@ E(OP_TaskDescription)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TraderShop)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
@@ -138,6 +146,8 @@ D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_GuildDemote)
|
||||
D(OP_GuildTributeDonateItem)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
@@ -151,7 +161,10 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TraderShop)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
|
||||
+128
-45
@@ -1670,6 +1670,15 @@ struct Surname_Struct
|
||||
/*0100*/
|
||||
};
|
||||
|
||||
struct GuildSetRank_Struct
|
||||
{
|
||||
/*00*/ uint32 unknown00;
|
||||
/*04*/ uint32 unknown04;
|
||||
/*08*/ uint32 rank;
|
||||
/*72*/ char member_name[64];
|
||||
/*76*/ uint32 banker;
|
||||
};
|
||||
|
||||
struct GuildsListEntry_Struct {
|
||||
char name[64];
|
||||
};
|
||||
@@ -1685,6 +1694,27 @@ struct GuildUpdate_Struct {
|
||||
GuildsListEntry_Struct entry;
|
||||
};
|
||||
|
||||
struct GuildMemberAdd_Struct {
|
||||
/*000*/ uint32 guild_id;
|
||||
/*004*/ uint32 unknown04;
|
||||
/*008*/ uint32 unknown08;
|
||||
/*012*/ uint32 unknown12;
|
||||
/*016*/ uint32 level;
|
||||
/*020*/ uint32 class_;
|
||||
/*024*/ uint32 rank_;
|
||||
/*028*/ uint32 zone_id;
|
||||
/*032*/ uint32 last_on;
|
||||
/*036*/ char player_name[64];
|
||||
};
|
||||
|
||||
struct GuildMemberRank_Struct {
|
||||
/*000*/ uint32 guild_id;
|
||||
/*004*/ uint32 unknown_004;
|
||||
/*008*/ uint32 rank_;
|
||||
/*012*/ char player_name[64];
|
||||
/*076*/ uint32 alt_banker; //Banker/Alt bit 00 - none 10 - Alt 11 - Alt and Banker 01 - Banker. Banker not functional for RoF2+
|
||||
};
|
||||
|
||||
/*
|
||||
** Money Loot
|
||||
** Length: 22 Bytes
|
||||
@@ -1886,9 +1916,9 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
struct MerchantClick_Struct {
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
};
|
||||
@@ -2610,23 +2640,23 @@ struct EnvDamage2_Struct {
|
||||
//Bazaar Stuff
|
||||
|
||||
enum {
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_CustomerBrowsing = 13
|
||||
};
|
||||
|
||||
enum {
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_UpdatePrice = 1,
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
};
|
||||
|
||||
struct BazaarWindowStart_Struct {
|
||||
@@ -2657,10 +2687,14 @@ struct BazaarSearch_Struct {
|
||||
uint32 Minlevel;
|
||||
uint32 MaxLlevel;
|
||||
};
|
||||
struct BazaarInspect_Struct{
|
||||
uint32 ItemID;
|
||||
uint32 Unknown004;
|
||||
char Name[64];
|
||||
|
||||
struct BazaarInspect_Struct {
|
||||
uint32 action;
|
||||
char player_name[64];
|
||||
uint32 unknown_068;
|
||||
uint32 serial_number;
|
||||
uint32 unknown_076;
|
||||
uint32 item_id;
|
||||
};
|
||||
|
||||
struct NewBazaarInspect_Struct {
|
||||
@@ -2899,10 +2933,17 @@ struct WhoAllPlayerPart4 {
|
||||
};
|
||||
|
||||
struct Trader_Struct {
|
||||
uint32 code;
|
||||
uint32 itemid[160];
|
||||
uint32 unknown;
|
||||
uint32 itemcost[80];
|
||||
uint32 action;
|
||||
uint32 unknown004;
|
||||
uint64 item_id[80];
|
||||
uint32 item_cost[80];
|
||||
};
|
||||
|
||||
struct BeginTrader_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown04;
|
||||
uint64 serial_number[80];
|
||||
uint32 cost[80];
|
||||
};
|
||||
|
||||
struct ClickTrader_Struct {
|
||||
@@ -2915,30 +2956,30 @@ struct GetItems_Struct{
|
||||
uint32 items[80];
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct{
|
||||
uint32 id;
|
||||
uint32 code;
|
||||
struct BecomeTrader_Struct {
|
||||
uint32 entity_id;
|
||||
uint32 action;
|
||||
char trader_name[64];
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct{
|
||||
uint32 code;
|
||||
uint32 traderid;
|
||||
uint32 action;
|
||||
uint32 entity_id;
|
||||
uint32 unknown08[3];
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*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*/
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 price;
|
||||
uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||
uint32 trader_id;
|
||||
char item_name[64];
|
||||
uint32 unknown_076;
|
||||
uint32 item_id;
|
||||
uint32 already_sold;
|
||||
uint32 quantity;
|
||||
uint32 unknown_092;
|
||||
};
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
@@ -2972,8 +3013,9 @@ struct TraderDelItem_Struct{
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
uint32 traderid;
|
||||
uint32 unknown4[2];
|
||||
uint32 trader_id;
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 approval;
|
||||
};
|
||||
|
||||
@@ -3067,6 +3109,23 @@ struct GuildMakeLeader{
|
||||
char target[64];
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItemRequest_Struct {
|
||||
/*000*/ uint32 slot;
|
||||
/*004*/ uint32 quantity;
|
||||
/*008*/ uint32 tribute_master_id;
|
||||
/*012*/ uint32 unknown12;
|
||||
/*016*/ uint32 guild_id;
|
||||
/*020*/ uint32 unknown20;
|
||||
/*024*/ uint32 unknown24;
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItemReply_Struct {
|
||||
/*000*/ uint32 slot;
|
||||
/*004*/ uint32 quantity;
|
||||
/*008*/ uint32 unknown8;
|
||||
/*012*/ uint32 favor;
|
||||
};
|
||||
|
||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint8 level;
|
||||
uint8 class_;
|
||||
@@ -3078,7 +3137,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||
uint32 min_dmg;
|
||||
uint32 max_dmg;
|
||||
};
|
||||
struct Ground_Spawn{
|
||||
struct GroundSpawn{
|
||||
float max_x;
|
||||
float max_y;
|
||||
float min_x;
|
||||
@@ -3090,8 +3149,8 @@ struct Ground_Spawn{
|
||||
uint32 max_allowed;
|
||||
uint32 respawntimer;
|
||||
};
|
||||
struct Ground_Spawns {
|
||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||
struct GroundSpawns {
|
||||
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||
};
|
||||
|
||||
//struct PetitionBug_Struct{
|
||||
@@ -4627,6 +4686,30 @@ struct SayLinkBodyFrame_Struct {
|
||||
/*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*/
|
||||
|
||||
}; /*UF*/
|
||||
|
||||
@@ -74,6 +74,11 @@ void PathManager::LoadPaths()
|
||||
m_patch_path = fs::relative(fs::path{m_server_path + "/" + c->PatchDir}).string();
|
||||
}
|
||||
|
||||
// patches
|
||||
if (File::Exists(fs::path{ m_server_path + "/" + c->OpcodeDir }.string())) {
|
||||
m_opcode_path = fs::relative(fs::path{ m_server_path + "/" + c->OpcodeDir }).string();
|
||||
}
|
||||
|
||||
// shared_memory_path
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->SharedMemDir}.string())) {
|
||||
m_shared_memory_path = fs::relative(fs::path{ m_server_path + "/" + c->SharedMemDir }).string();
|
||||
@@ -89,6 +94,7 @@ void PathManager::LoadPaths()
|
||||
LogInfo("lua_modules path [{}]", m_lua_modules_path);
|
||||
LogInfo("maps path [{}]", m_maps_path);
|
||||
LogInfo("patches path [{}]", m_patch_path);
|
||||
LogInfo("opcode path [{}]", m_opcode_path);
|
||||
LogInfo("plugins path [{}]", m_plugins_path);
|
||||
LogInfo("quests path [{}]", m_quests_path);
|
||||
LogInfo("shared_memory path [{}]", m_shared_memory_path);
|
||||
@@ -129,6 +135,11 @@ const std::string &PathManager::GetPatchPath() const
|
||||
return m_patch_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetOpcodePath() const
|
||||
{
|
||||
return m_opcode_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetLuaModulesPath() const
|
||||
{
|
||||
return m_lua_modules_path;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user