mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 09:06:46 +00:00
Compare commits
845 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 0a3972deb9 | |||
| 9d2f258390 | |||
| 0b452f4ec1 | |||
| fef629e1df | |||
| a5a51fbe44 | |||
| 47db92cdb6 | |||
| 690301e80d | |||
| 1887e48b76 | |||
| af2691eb12 | |||
| 2df4289588 | |||
| 49d4d0acc3 | |||
| 5a663910a5 | |||
| b027edd21e | |||
| 0bbfcf7adc | |||
| 7962a0bd38 | |||
| 4d9b51df0a | |||
| 508ecec6ea | |||
| f0c6fa2a26 | |||
| ad6dbb7beb | |||
| 6ddbb41617 | |||
| 8a558f6a29 | |||
| 0585be0360 | |||
| 6927baef7f | |||
| 52d64781b5 | |||
| 0667fe435f | |||
| 9959070f24 | |||
| 2a91f08845 | |||
| adc64005f1 | |||
| 605480f1c4 | |||
| 3b95601c62 | |||
| a4f2ed28f1 | |||
| e19b969541 | |||
| 4241556f75 | |||
| 961332b40c | |||
| a1a861e0c4 | |||
| 4bbb1aa92f | |||
| 1212ccefef | |||
| c203fec9b4 | |||
| 16ab1839e8 | |||
| f5e4c6a127 | |||
| 166c87c931 | |||
| 345dd442dd | |||
| 565baec675 | |||
| 9884c442e9 | |||
| ad0b5d6a1c | |||
| b82b32e1d2 | |||
| 2fb72e5729 | |||
| 3791bc788f | |||
| 833fa55fdf | |||
| 4fc3c27715 | |||
| cea3ad6a42 | |||
| d8926cd5f3 | |||
| efb03164c7 | |||
| 455eb2e6d9 | |||
| b5b0e53da2 | |||
| 68cb94b39c | |||
| 3d95b6c184 | |||
| 7db7631308 | |||
| f053cd3b56 | |||
| cf27f2bc88 | |||
| 79918ebaba | |||
| 2a648507f2 | |||
| f395ee0508 | |||
| 7166fcc650 | |||
| ae8e58ddc5 | |||
| 26e72c6857 | |||
| df1d740ae6 | |||
| d7e810232a | |||
| 9b992167f0 | |||
| 65d4533568 | |||
| eb545a18a4 | |||
| f2f0228aa4 | |||
| 06337fe762 | |||
| 604c7ad4ab | |||
| bab16771aa | |||
| d3a414a048 | |||
| e85a8db8c4 | |||
| 12cc3c90ea | |||
| 9c656bc498 | |||
| bc337979bb | |||
| a64425ebe6 | |||
| ca933fce45 | |||
| 9c3498b431 | |||
| d7e09a1f3b | |||
| 1652e7a976 | |||
| 37dda9bf41 | |||
| a2b78ff4e6 | |||
| 79a3ce8d7e | |||
| d857fb3c48 | |||
| 2b4cd292e4 | |||
| 3b7cfa6454 | |||
| c5fa7e28c8 | |||
| 5d133a2b47 | |||
| 7122ac33b2 | |||
| c47644ea46 | |||
| a61f951d0e | |||
| 4357b8c731 | |||
| 9cbe25f712 | |||
| c14a17e4de | |||
| ab04a4c6df | |||
| c0cf9bb5aa | |||
| b5d23389ee | |||
| dc35ab5251 | |||
| 9cbfd5c8f0 | |||
| 5631a0711f | |||
| 00e02b61ca | |||
| 108397b138 | |||
| 9a07142a9b | |||
| 919a92bda3 | |||
| 140aba9f69 | |||
| c3d41e08f4 | |||
| 5d6a1aad50 | |||
| af91b2b41c | |||
| 2660aa79ab | |||
| 730738faf9 | |||
| 2bb7bba724 | |||
| e93081dde0 | |||
| 3a46bf7383 | |||
| aa6421afdf | |||
| 6a7eaae122 | |||
| 714b474d2c | |||
| e24d82f0fe | |||
| 33a375677e | |||
| 8fce86c396 | |||
| 68b40f0239 | |||
| 2dc2bac456 | |||
| 00a8a0cf88 | |||
| 5a466da96c | |||
| de4f5ae491 | |||
| fb20d92166 | |||
| 6cff433d23 | |||
| 2da7ddad57 | |||
| 55161e18c8 | |||
| 063d4fbd1a | |||
| c25cb0cc23 | |||
| ddac326239 | |||
| 14fe396510 | |||
| c968a0acdc | |||
| 8c4cd34e01 | |||
| 0dbcf83a11 | |||
| a75648f73f | |||
| 6c2886a71d | |||
| 1d96ddb60d | |||
| c30074be66 | |||
| b5652e6010 | |||
| 202d2ed496 | |||
| 81cee49ea1 | |||
| 2d61cd2b9a | |||
| b06505b80a | |||
| 4c2f9a4423 | |||
| fb3159b657 | |||
| 8ebf5bbb78 | |||
| d2aae4d79c | |||
| f9dc9da42b | |||
| 3f3bbe98b5 | |||
| 59537ae977 | |||
| ee45a28efe | |||
| 70ce81fb0a | |||
| e06d28ad20 | |||
| d57489781c | |||
| 21d65c73b7 | |||
| 8f6d606f53 | |||
| f25e37d0c5 | |||
| e55f9b9d27 | |||
| b01486d767 | |||
| 50ce99ce3e | |||
| 4854201b2a | |||
| c81d05940a | |||
| 47be17e2af | |||
| 809b3b6099 | |||
| f06c7e8834 | |||
| 096448d23c | |||
| e55fb1cafd | |||
| d4962bb2ab | |||
| 98e56bdfe9 | |||
| 5c1be3643e | |||
| c2fa61b3a2 | |||
| 01a1186e63 | |||
| 7427318213 | |||
| d3c3d7b384 | |||
| e9e8143778 | |||
| bc71997518 | |||
| 4a9a9fa197 | |||
| ee14aed8de | |||
| 2717fcc339 | |||
| dc28c8d485 | |||
| a633784f78 | |||
| 5519c3e781 | |||
| 9401323708 | |||
| 251993c61b | |||
| 728ce0c519 | |||
| 6a80bcecc7 | |||
| 6324e3687a | |||
| d16ac99033 | |||
| e12368f002 | |||
| a13fa07e68 | |||
| 7873ad3771 | |||
| dfadc237e5 | |||
| a1f2764978 | |||
| 927d379e75 | |||
| a1f154749c | |||
| 42a2e19e73 | |||
| c56b2e3e03 | |||
| b05f1d3218 | |||
| a004924112 | |||
| 8d986c95cd | |||
| ef7a3cae17 | |||
| 050aba65b6 | |||
| 9154c90418 | |||
| d558f9ece2 | |||
| 327dacdbe1 | |||
| f2ff4245c0 | |||
| 3ceb743195 | |||
| 021f04c17d | |||
| f7e2dbdce6 | |||
| 2a679f1002 | |||
| 8c9849ec73 | |||
| 10086ce97c | |||
| 223ae22f73 | |||
| 4330494f57 | |||
| 64ae7e4529 | |||
| 58c3e267e1 | |||
| 598483a1a4 | |||
| c1122022b9 | |||
| f2c4babd8d | |||
| 5249b065d3 | |||
| 9312261444 | |||
| 85054fedf8 | |||
| 6d7beb1796 | |||
| 66e377fd4a | |||
| 67c4c26f70 | |||
| b1c8e3890a | |||
| d6e06a19a7 | |||
| 4092b3a2cb | |||
| f4f0619618 | |||
| 71ca7f9b39 | |||
| 5fcc83b4b6 | |||
| 1f25639dd3 | |||
| 2a176835b1 | |||
| fff3e77a6e | |||
| 6efb9ec228 | |||
| a663c822e8 | |||
| cf49b2fe49 | |||
| b45e0e80b5 | |||
| 3200145d01 | |||
| 53563b9720 | |||
| 1e22baf267 | |||
| d99c3145ad | |||
| 57243c6799 | |||
| 1100668f21 | |||
| 0cf454dc29 |
@@ -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:
|
steps:
|
||||||
- name: Build Linux X64
|
- name: Build Linux X64
|
||||||
image: akkadius/eqemu-server:v11
|
image: akkadius/eqemu-server:v14
|
||||||
environment:
|
environment:
|
||||||
GITHUB_TOKEN:
|
GITHUB_TOKEN:
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||||
|
|||||||
@@ -61,9 +61,6 @@ bin/
|
|||||||
compile_flags.txt
|
compile_flags.txt
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
# vscode generated settings
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Build pipeline
|
# Build pipeline
|
||||||
!utils/scripts/build/
|
!utils/scripts/build/
|
||||||
!utils/scripts/build/should-release/should-release
|
!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",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2071
File diff suppressed because it is too large
Load Diff
+42
-1
@@ -16,6 +16,28 @@ SET(CMAKE_CXX_STANDARD 20)
|
|||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
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)
|
||||||
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
||||||
|
MESSAGE(STATUS "Building with static linking")
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
||||||
|
IF (UNIX)
|
||||||
|
SET(PERL_LIBRARY "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/libperl.so")
|
||||||
|
SET(PERL_INCLUDE_PATH "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/")
|
||||||
|
SET(PERL_EXECUTABLE "/opt/eqemu-perl/bin/perl")
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF (EQEMU_BUILD_STATIC)
|
||||||
|
|
||||||
|
|
||||||
|
# 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)
|
IF(MSVC)
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
@@ -23,7 +45,11 @@ IF(MSVC)
|
|||||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
|
||||||
|
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
||||||
|
IF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||||
|
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||||
|
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||||
ELSE(MSVC)
|
ELSE(MSVC)
|
||||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
@@ -120,6 +146,13 @@ ELSE()
|
|||||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
|
||||||
|
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
|
||||||
|
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
|
||||||
|
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
|
||||||
|
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
|
||||||
|
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
|
||||||
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
|
|
||||||
#options
|
#options
|
||||||
@@ -307,6 +340,10 @@ ELSE()
|
|||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF (EQEMU_BUILD_STATIC)
|
||||||
|
SET(ZLIB_LIBRARY_LIBS libz.a)
|
||||||
|
ENDIF(EQEMU_BUILD_STATIC)
|
||||||
|
|
||||||
MESSAGE(STATUS "")
|
MESSAGE(STATUS "")
|
||||||
MESSAGE(STATUS "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
MESSAGE(STATUS "* Library Usage *")
|
MESSAGE(STATUS "* Library Usage *")
|
||||||
@@ -371,6 +408,10 @@ IF(PERL_LIBRARY_ENABLED)
|
|||||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||||
ADD_DEFINITIONS(-DEMBPERL)
|
ADD_DEFINITIONS(-DEMBPERL)
|
||||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||||
|
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
||||||
|
IF (UNIX AND EQEMU_BUILD_STATIC)
|
||||||
|
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
|
||||||
|
ENDIF ()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||||
|
|
||||||
add_subdirectory(import)
|
add_subdirectory(import)
|
||||||
add_subdirectory(export)
|
add_subdirectory(export)
|
||||||
|
|||||||
@@ -29,11 +29,15 @@
|
|||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
#include "../../common/zone_store.h"
|
||||||
#include "../../common/path_manager.h"
|
#include "../../common/path_manager.h"
|
||||||
|
#include "../../common/repositories/skill_caps_repository.h"
|
||||||
|
#include "../../common/file.h"
|
||||||
|
#include "../../common/events/player_event_logs.h"
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
ZoneStore zone_store;
|
||||||
PathManager path;
|
PathManager path;
|
||||||
|
PlayerEventLogs player_event_logs;
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase *db);
|
void ExportSpells(SharedDatabase *db);
|
||||||
void ExportSkillCaps(SharedDatabase *db);
|
void ExportSkillCaps(SharedDatabase *db);
|
||||||
@@ -164,81 +168,76 @@ void ExportSpells(SharedDatabase *db)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
bool SkillUsable(SharedDatabase* db, int skill_id, int class_id)
|
||||||
{
|
{
|
||||||
|
const auto& l = SkillCapsRepository::GetWhere(
|
||||||
bool res = false;
|
*db,
|
||||||
|
fmt::format(
|
||||||
std::string query = StringFormat(
|
"`class_id` = {} AND `skill_id` = {} ORDER BY `cap` DESC LIMIT 1",
|
||||||
"SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
|
class_id,
|
||||||
class_id, skill_id
|
skill_id
|
||||||
|
)
|
||||||
);
|
);
|
||||||
auto results = db->QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
return !l.empty();
|
||||||
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)
|
uint32 GetSkill(SharedDatabase* db, int skill_id, int class_id, int level)
|
||||||
{
|
{
|
||||||
|
const auto& l = SkillCapsRepository::GetWhere(
|
||||||
std::string query = StringFormat(
|
*db,
|
||||||
"SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
|
fmt::format(
|
||||||
class_id, skill_id, level
|
"`class_id` = {} AND `skill_id` = {} AND `level` = {}",
|
||||||
|
class_id,
|
||||||
|
skill_id,
|
||||||
|
level
|
||||||
|
)
|
||||||
);
|
);
|
||||||
auto results = db->QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
if (l.empty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
auto e = l.front();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
return e.cap;
|
||||||
return Strings::ToInt(row[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase *db)
|
void ExportSkillCaps(SharedDatabase* db)
|
||||||
{
|
{
|
||||||
LogInfo("Exporting Skill Caps");
|
LogInfo("Exporting Skill Caps");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
if (!file || !file.is_open()) {
|
||||||
if (!f) {
|
|
||||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int cl = 1; cl <= 16; ++cl) {
|
const uint8 skill_cap_max_level = (
|
||||||
for (int skill = 0; skill <= 77; ++skill) {
|
RuleI(Character, SkillCapMaxLevel) > 0 ?
|
||||||
if (SkillUsable(db, skill, cl)) {
|
RuleI(Character, SkillCapMaxLevel) :
|
||||||
int previous_cap = 0;
|
RuleI(Character, MaxLevel)
|
||||||
for (int level = 1; level <= 100; ++level) {
|
);
|
||||||
int cap = GetSkill(db, skill, cl, level);
|
|
||||||
|
for (uint8 class_id = Class::Warrior; class_id <= Class::Berserker; class_id++) {
|
||||||
|
for (uint8 skill_id = EQ::skills::Skill1HBlunt; skill_id <= EQ::skills::Skill2HPiercing; skill_id++) {
|
||||||
|
if (SkillUsable(db, skill_id, class_id)) {
|
||||||
|
uint32 previous_cap = 0;
|
||||||
|
for (uint8 level = 1; level <= skill_cap_max_level; level++) {
|
||||||
|
uint32 cap = GetSkill(db, skill_id, class_id, level);
|
||||||
if (cap < previous_cap) {
|
if (cap < previous_cap) {
|
||||||
cap = previous_cap;
|
cap = previous_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "%d^%d^%d^%d^0\n", cl, skill, level, cap);
|
file << fmt::format("{}^{}^{}^{}^0", class_id, skill_id, level, cap) << std::endl;
|
||||||
|
|
||||||
previous_cap = cap;
|
previous_cap = cap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportBaseData(SharedDatabase *db)
|
void ExportBaseData(SharedDatabase *db)
|
||||||
|
|||||||
@@ -27,11 +27,15 @@
|
|||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
#include "../../common/zone_store.h"
|
||||||
#include "../../common/path_manager.h"
|
#include "../../common/path_manager.h"
|
||||||
|
#include "../../common/repositories/base_data_repository.h"
|
||||||
|
#include "../../common/file.h"
|
||||||
|
#include "../../common/events/player_event_logs.h"
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
ZoneStore zone_store;
|
||||||
PathManager path;
|
PathManager path;
|
||||||
|
PlayerEventLogs player_event_logs;
|
||||||
|
|
||||||
void ImportSpells(SharedDatabase *db);
|
void ImportSpells(SharedDatabase *db);
|
||||||
void ImportSkillCaps(SharedDatabase *db);
|
void ImportSkillCaps(SharedDatabase *db);
|
||||||
@@ -255,50 +259,45 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportBaseData(SharedDatabase *db) {
|
void ImportBaseData(SharedDatabase *db)
|
||||||
|
{
|
||||||
LogInfo("Importing Base Data");
|
LogInfo("Importing Base Data");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
const std::string& file_name = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
const auto& file_contents = File::GetContents(file_name);
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
if (!file_contents.error.empty()) {
|
||||||
return;
|
LogError("{}", file_contents.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string delete_sql = "DELETE FROM base_data";
|
db->QueryDatabase("DELETE FROM base_data");
|
||||||
db->QueryDatabase(delete_sql);
|
|
||||||
|
|
||||||
char buffer[2048];
|
std::vector<BaseDataRepository::BaseData> v;
|
||||||
while(fgets(buffer, 2048, f)) {
|
|
||||||
auto split = Strings::Split(buffer, '^');
|
|
||||||
|
|
||||||
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sql;
|
e.level = static_cast<uint8_t>(Strings::ToUnsignedInt(line_data[0]));
|
||||||
int level, class_id;
|
e.class_ = static_cast<uint8_t>(Strings::ToUnsignedInt(line_data[1]));
|
||||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
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());
|
v.emplace_back(e);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
BaseDataRepository::InsertMany(*db, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportDBStrings(SharedDatabase *db) {
|
void ImportDBStrings(SharedDatabase *db) {
|
||||||
|
|||||||
+31
-15
@@ -13,8 +13,10 @@ SET(common_sources
|
|||||||
crc32.cpp
|
crc32.cpp
|
||||||
database/database_dump_service.cpp
|
database/database_dump_service.cpp
|
||||||
database.cpp
|
database.cpp
|
||||||
database_conversions.cpp
|
|
||||||
database_instances.cpp
|
database_instances.cpp
|
||||||
|
database/database_update_manifest.cpp
|
||||||
|
database/database_update_manifest_bots.cpp
|
||||||
|
database/database_update.cpp
|
||||||
dbcore.cpp
|
dbcore.cpp
|
||||||
deity.cpp
|
deity.cpp
|
||||||
dynamic_zone_base.cpp
|
dynamic_zone_base.cpp
|
||||||
@@ -67,6 +69,7 @@ SET(common_sources
|
|||||||
perl_eqdb.cpp
|
perl_eqdb.cpp
|
||||||
perl_eqdb_res.cpp
|
perl_eqdb_res.cpp
|
||||||
process/process.cpp
|
process/process.cpp
|
||||||
|
process.cpp
|
||||||
proc_launcher.cpp
|
proc_launcher.cpp
|
||||||
profanity_manager.cpp
|
profanity_manager.cpp
|
||||||
ptimer.cpp
|
ptimer.cpp
|
||||||
@@ -80,6 +83,7 @@ SET(common_sources
|
|||||||
shared_tasks.cpp
|
shared_tasks.cpp
|
||||||
shareddb.cpp
|
shareddb.cpp
|
||||||
skills.cpp
|
skills.cpp
|
||||||
|
skill_caps.cpp
|
||||||
spdat.cpp
|
spdat.cpp
|
||||||
strings.cpp
|
strings.cpp
|
||||||
struct_strategy.cpp
|
struct_strategy.cpp
|
||||||
@@ -87,6 +91,7 @@ SET(common_sources
|
|||||||
timer.cpp
|
timer.cpp
|
||||||
unix.cpp
|
unix.cpp
|
||||||
platform.cpp
|
platform.cpp
|
||||||
|
json/json.hpp
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
zone_store.cpp
|
zone_store.cpp
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
@@ -172,6 +177,7 @@ SET(repositories
|
|||||||
repositories/base/base_character_leadership_abilities_repository.h
|
repositories/base/base_character_leadership_abilities_repository.h
|
||||||
repositories/base/base_character_material_repository.h
|
repositories/base/base_character_material_repository.h
|
||||||
repositories/base/base_character_memmed_spells_repository.h
|
repositories/base/base_character_memmed_spells_repository.h
|
||||||
|
repositories/base/base_character_parcels_repository.h
|
||||||
repositories/base/base_character_peqzone_flags_repository.h
|
repositories/base/base_character_peqzone_flags_repository.h
|
||||||
repositories/base/base_character_pet_buffs_repository.h
|
repositories/base/base_character_pet_buffs_repository.h
|
||||||
repositories/base/base_character_pet_info_repository.h
|
repositories/base/base_character_pet_info_repository.h
|
||||||
@@ -218,6 +224,9 @@ SET(repositories
|
|||||||
repositories/base/base_group_leaders_repository.h
|
repositories/base/base_group_leaders_repository.h
|
||||||
repositories/base/base_guilds_repository.h
|
repositories/base/base_guilds_repository.h
|
||||||
repositories/base/base_guild_ranks_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_guild_relations_repository.h
|
||||||
repositories/base/base_horses_repository.h
|
repositories/base/base_horses_repository.h
|
||||||
repositories/base/base_instance_list_repository.h
|
repositories/base/base_instance_list_repository.h
|
||||||
@@ -226,7 +235,6 @@ SET(repositories
|
|||||||
repositories/base/base_inventory_snapshots_repository.h
|
repositories/base/base_inventory_snapshots_repository.h
|
||||||
repositories/base/base_ip_exemptions_repository.h
|
repositories/base/base_ip_exemptions_repository.h
|
||||||
repositories/base/base_items_repository.h
|
repositories/base/base_items_repository.h
|
||||||
repositories/base/base_item_tick_repository.h
|
|
||||||
repositories/base/base_ldon_trap_entries_repository.h
|
repositories/base/base_ldon_trap_entries_repository.h
|
||||||
repositories/base/base_ldon_trap_templates_repository.h
|
repositories/base/base_ldon_trap_templates_repository.h
|
||||||
repositories/base/base_level_exp_mods_repository.h
|
repositories/base/base_level_exp_mods_repository.h
|
||||||
@@ -350,6 +358,7 @@ SET(repositories
|
|||||||
repositories/character_leadership_abilities_repository.h
|
repositories/character_leadership_abilities_repository.h
|
||||||
repositories/character_material_repository.h
|
repositories/character_material_repository.h
|
||||||
repositories/character_memmed_spells_repository.h
|
repositories/character_memmed_spells_repository.h
|
||||||
|
repositories/character_parcels_repository.h
|
||||||
repositories/character_peqzone_flags_repository.h
|
repositories/character_peqzone_flags_repository.h
|
||||||
repositories/character_pet_buffs_repository.h
|
repositories/character_pet_buffs_repository.h
|
||||||
repositories/character_pet_info_repository.h
|
repositories/character_pet_info_repository.h
|
||||||
@@ -396,6 +405,9 @@ SET(repositories
|
|||||||
repositories/group_leaders_repository.h
|
repositories/group_leaders_repository.h
|
||||||
repositories/guilds_repository.h
|
repositories/guilds_repository.h
|
||||||
repositories/guild_ranks_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/guild_relations_repository.h
|
||||||
repositories/horses_repository.h
|
repositories/horses_repository.h
|
||||||
repositories/instance_list_repository.h
|
repositories/instance_list_repository.h
|
||||||
@@ -404,7 +416,6 @@ SET(repositories
|
|||||||
repositories/inventory_snapshots_repository.h
|
repositories/inventory_snapshots_repository.h
|
||||||
repositories/ip_exemptions_repository.h
|
repositories/ip_exemptions_repository.h
|
||||||
repositories/items_repository.h
|
repositories/items_repository.h
|
||||||
repositories/item_tick_repository.h
|
|
||||||
repositories/ldon_trap_entries_repository.h
|
repositories/ldon_trap_entries_repository.h
|
||||||
repositories/ldon_trap_templates_repository.h
|
repositories/ldon_trap_templates_repository.h
|
||||||
repositories/level_exp_mods_repository.h
|
repositories/level_exp_mods_repository.h
|
||||||
@@ -484,12 +495,11 @@ SET(repositories
|
|||||||
repositories/zone_repository.h
|
repositories/zone_repository.h
|
||||||
repositories/zone_points_repository.h
|
repositories/zone_points_repository.h
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(common_headers
|
SET(common_headers
|
||||||
additive_lagged_fibonacci_engine.h
|
additive_lagged_fibonacci_engine.h
|
||||||
base_packet.h
|
base_packet.h
|
||||||
base_data.h
|
|
||||||
bodytypes.h
|
bodytypes.h
|
||||||
classes.h
|
classes.h
|
||||||
compression.h
|
compression.h
|
||||||
@@ -506,6 +516,7 @@ SET(common_headers
|
|||||||
data_verification.h
|
data_verification.h
|
||||||
database.h
|
database.h
|
||||||
database_schema.h
|
database_schema.h
|
||||||
|
database/database_update.h
|
||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
discord/discord.h
|
discord/discord.h
|
||||||
@@ -535,7 +546,6 @@ SET(common_headers
|
|||||||
events/player_event_logs.h
|
events/player_event_logs.h
|
||||||
events/player_event_discord_formatter.h
|
events/player_event_discord_formatter.h
|
||||||
events/player_events.h
|
events/player_events.h
|
||||||
errmsg.h
|
|
||||||
event_sub.h
|
event_sub.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
extprofile.h
|
extprofile.h
|
||||||
@@ -557,10 +567,9 @@ SET(common_headers
|
|||||||
item_fieldlist.h
|
item_fieldlist.h
|
||||||
item_instance.h
|
item_instance.h
|
||||||
json_config.h
|
json_config.h
|
||||||
languages.h
|
|
||||||
light_source.h
|
light_source.h
|
||||||
linked_list.h
|
linked_list.h
|
||||||
loottable.h
|
loot.h
|
||||||
mail_oplist.h
|
mail_oplist.h
|
||||||
md5.h
|
md5.h
|
||||||
memory_buffer.h
|
memory_buffer.h
|
||||||
@@ -579,12 +588,14 @@ SET(common_headers
|
|||||||
path_manager.cpp
|
path_manager.cpp
|
||||||
platform.h
|
platform.h
|
||||||
process/process.h
|
process/process.h
|
||||||
|
process.h
|
||||||
proc_launcher.h
|
proc_launcher.h
|
||||||
profanity_manager.h
|
profanity_manager.h
|
||||||
profiler.h
|
profiler.h
|
||||||
ptimer.h
|
ptimer.h
|
||||||
queue.h
|
queue.h
|
||||||
races.h
|
races.h
|
||||||
|
raid.h
|
||||||
random.h
|
random.h
|
||||||
rdtsc.h
|
rdtsc.h
|
||||||
rulesys.h
|
rulesys.h
|
||||||
@@ -598,6 +609,7 @@ SET(common_headers
|
|||||||
shared_tasks.h
|
shared_tasks.h
|
||||||
shareddb.h
|
shareddb.h
|
||||||
skills.h
|
skills.h
|
||||||
|
skill_caps.h
|
||||||
spdat.h
|
spdat.h
|
||||||
strings.h
|
strings.h
|
||||||
struct_strategy.h
|
struct_strategy.h
|
||||||
@@ -666,19 +678,20 @@ SET(common_headers
|
|||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.h)
|
util/uuid.h
|
||||||
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Event FILES
|
SOURCE_GROUP(Event FILES
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
event/task.h
|
event/task.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Json FILES
|
SOURCE_GROUP(Json FILES
|
||||||
json/json.h
|
json/json.h
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Net FILES
|
SOURCE_GROUP(Net FILES
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
@@ -715,7 +728,7 @@ SOURCE_GROUP(Net FILES
|
|||||||
net/websocket_server.h
|
net/websocket_server.h
|
||||||
net/websocket_server_connection.cpp
|
net/websocket_server_connection.cpp
|
||||||
net/websocket_server_connection.h
|
net/websocket_server_connection.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Patches FILES
|
SOURCE_GROUP(Patches FILES
|
||||||
patches/patches.h
|
patches/patches.h
|
||||||
@@ -759,12 +772,12 @@ SOURCE_GROUP(Patches FILES
|
|||||||
patches/titanium_limits.cpp
|
patches/titanium_limits.cpp
|
||||||
patches/uf.cpp
|
patches/uf.cpp
|
||||||
patches/uf_limits.cpp
|
patches/uf_limits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(StackWalker FILES
|
SOURCE_GROUP(StackWalker FILES
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
StackWalker/StackWalker.cpp
|
StackWalker/StackWalker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Util FILES
|
SOURCE_GROUP(Util FILES
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
@@ -772,7 +785,7 @@ SOURCE_GROUP(Util FILES
|
|||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.cpp
|
util/uuid.cpp
|
||||||
util/uuid.h
|
util/uuid.h
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||||
|
|
||||||
@@ -783,5 +796,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)
|
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)
|
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)
|
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
|
|
||||||
@@ -64,4 +64,6 @@ typedef enum {
|
|||||||
} bodyType;
|
} bodyType;
|
||||||
/* bodytypes above 64 make the mob not show up */
|
/* bodytypes above 64 make the mob not show up */
|
||||||
|
|
||||||
|
constexpr int format_as(bodyType type) { return static_cast<int>(type); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+327
-455
File diff suppressed because it is too large
Load Diff
+99
-92
@@ -19,98 +19,106 @@
|
|||||||
#define CLASSES_CH
|
#define CLASSES_CH
|
||||||
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
|
#include "../common/rulesys.h"
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#define NO_CLASS 0
|
namespace Class {
|
||||||
#define WARRIOR 1
|
constexpr uint8 None = 0;
|
||||||
#define CLERIC 2
|
constexpr uint8 Warrior = 1;
|
||||||
#define PALADIN 3
|
constexpr uint8 Cleric = 2;
|
||||||
#define RANGER 4
|
constexpr uint8 Paladin = 3;
|
||||||
#define SHADOWKNIGHT 5
|
constexpr uint8 Ranger = 4;
|
||||||
#define DRUID 6
|
constexpr uint8 ShadowKnight = 5;
|
||||||
#define MONK 7
|
constexpr uint8 Druid = 6;
|
||||||
#define BARD 8
|
constexpr uint8 Monk = 7;
|
||||||
#define ROGUE 9
|
constexpr uint8 Bard = 8;
|
||||||
#define SHAMAN 10
|
constexpr uint8 Rogue = 9;
|
||||||
#define NECROMANCER 11
|
constexpr uint8 Shaman = 10;
|
||||||
#define WIZARD 12
|
constexpr uint8 Necromancer = 11;
|
||||||
#define MAGICIAN 13
|
constexpr uint8 Wizard = 12;
|
||||||
#define ENCHANTER 14
|
constexpr uint8 Magician = 13;
|
||||||
#define BEASTLORD 15
|
constexpr uint8 Enchanter = 14;
|
||||||
#define BERSERKER 16
|
constexpr uint8 Beastlord = 15;
|
||||||
#define WARRIORGM 20
|
constexpr uint8 Berserker = 16;
|
||||||
#define CLERICGM 21
|
constexpr uint8 WarriorGM = 20;
|
||||||
#define PALADINGM 22
|
constexpr uint8 ClericGM = 21;
|
||||||
#define RANGERGM 23
|
constexpr uint8 PaladinGM = 22;
|
||||||
#define SHADOWKNIGHTGM 24
|
constexpr uint8 RangerGM = 23;
|
||||||
#define DRUIDGM 25
|
constexpr uint8 ShadowKnightGM = 24;
|
||||||
#define MONKGM 26
|
constexpr uint8 DruidGM = 25;
|
||||||
#define BARDGM 27
|
constexpr uint8 MonkGM = 26;
|
||||||
#define ROGUEGM 28
|
constexpr uint8 BardGM = 27;
|
||||||
#define SHAMANGM 29
|
constexpr uint8 RogueGM = 28;
|
||||||
#define NECROMANCERGM 30
|
constexpr uint8 ShamanGM = 29;
|
||||||
#define WIZARDGM 31
|
constexpr uint8 NecromancerGM = 30;
|
||||||
#define MAGICIANGM 32
|
constexpr uint8 WizardGM = 31;
|
||||||
#define ENCHANTERGM 33
|
constexpr uint8 MagicianGM = 32;
|
||||||
#define BEASTLORDGM 34
|
constexpr uint8 EnchanterGM = 33;
|
||||||
#define BERSERKERGM 35
|
constexpr uint8 BeastlordGM = 34;
|
||||||
#define BANKER 40
|
constexpr uint8 BerserkerGM = 35;
|
||||||
#define MERCHANT 41
|
constexpr uint8 Banker = 40;
|
||||||
#define DISCORD_MERCHANT 59
|
constexpr uint8 Merchant = 41;
|
||||||
#define ADVENTURE_RECRUITER 60
|
constexpr uint8 DiscordMerchant = 59;
|
||||||
#define ADVENTURE_MERCHANT 61
|
constexpr uint8 AdventureRecruiter = 60;
|
||||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
|
constexpr uint8 AdventureMerchant = 61;
|
||||||
#define TRIBUTE_MASTER 63
|
constexpr uint8 LDoNTreasure = 62;
|
||||||
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
constexpr uint8 TributeMaster = 63;
|
||||||
#define GUILD_BANKER 66
|
constexpr uint8 GuildTributeMaster = 64;
|
||||||
#define NORRATHS_KEEPERS_MERCHANT 67
|
constexpr uint8 GuildBanker = 66;
|
||||||
#define DARK_REIGN_MERCHANT 68
|
constexpr uint8 NorrathsKeepersMerchant = 67;
|
||||||
#define FELLOWSHIP_MASTER 69
|
constexpr uint8 DarkReignMerchant = 68;
|
||||||
#define ALT_CURRENCY_MERCHANT 70
|
constexpr uint8 FellowshipMaster = 69;
|
||||||
#define MERCENARY_MASTER 71
|
constexpr uint8 AlternateCurrencyMerchant = 70;
|
||||||
|
constexpr uint8 MercenaryLiaison = 71;
|
||||||
|
|
||||||
|
constexpr uint8 PLAYER_CLASS_COUNT = 16;
|
||||||
|
constexpr uint16 ALL_CLASSES_BITMASK = 65535;
|
||||||
|
};
|
||||||
|
|
||||||
// player class values
|
static std::map<uint8, uint16> player_class_bitmasks = {
|
||||||
#define PLAYER_CLASS_UNKNOWN 0
|
{Class::Warrior, 1},
|
||||||
#define PLAYER_CLASS_WARRIOR 1
|
{Class::Cleric, 2},
|
||||||
#define PLAYER_CLASS_CLERIC 2
|
{Class::Paladin, 4},
|
||||||
#define PLAYER_CLASS_PALADIN 3
|
{Class::Ranger, 8},
|
||||||
#define PLAYER_CLASS_RANGER 4
|
{Class::ShadowKnight, 16},
|
||||||
#define PLAYER_CLASS_SHADOWKNIGHT 5
|
{Class::Druid, 32},
|
||||||
#define PLAYER_CLASS_DRUID 6
|
{Class::Monk, 64},
|
||||||
#define PLAYER_CLASS_MONK 7
|
{Class::Bard, 128},
|
||||||
#define PLAYER_CLASS_BARD 8
|
{Class::Rogue, 256},
|
||||||
#define PLAYER_CLASS_ROGUE 9
|
{Class::Shaman, 512},
|
||||||
#define PLAYER_CLASS_SHAMAN 10
|
{Class::Necromancer, 1024},
|
||||||
#define PLAYER_CLASS_NECROMANCER 11
|
{Class::Wizard, 2048},
|
||||||
#define PLAYER_CLASS_WIZARD 12
|
{Class::Magician, 4096},
|
||||||
#define PLAYER_CLASS_MAGICIAN 13
|
{Class::Enchanter, 8192},
|
||||||
#define PLAYER_CLASS_ENCHANTER 14
|
{Class::Beastlord, 16384},
|
||||||
#define PLAYER_CLASS_BEASTLORD 15
|
{Class::Berserker, 32768},
|
||||||
#define PLAYER_CLASS_BERSERKER 16
|
};
|
||||||
|
|
||||||
#define PLAYER_CLASS_COUNT 16
|
static std::string shadow_knight_class_name = (
|
||||||
|
RuleB(World, UseOldShadowKnightClassExport) ?
|
||||||
|
"Shadowknight" :
|
||||||
|
"Shadow Knight"
|
||||||
|
);
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> class_names = {
|
||||||
// player class bits
|
{Class::Warrior, "Warrior"},
|
||||||
#define PLAYER_CLASS_UNKNOWN_BIT 0
|
{Class::Cleric, "Cleric"},
|
||||||
#define PLAYER_CLASS_WARRIOR_BIT 1
|
{Class::Paladin, "Paladin"},
|
||||||
#define PLAYER_CLASS_CLERIC_BIT 2
|
{Class::Ranger, "Ranger"},
|
||||||
#define PLAYER_CLASS_PALADIN_BIT 4
|
{Class::ShadowKnight, shadow_knight_class_name},
|
||||||
#define PLAYER_CLASS_RANGER_BIT 8
|
{Class::Druid, "Druid"},
|
||||||
#define PLAYER_CLASS_SHADOWKNIGHT_BIT 16
|
{Class::Monk, "Monk"},
|
||||||
#define PLAYER_CLASS_DRUID_BIT 32
|
{Class::Bard, "Bard"},
|
||||||
#define PLAYER_CLASS_MONK_BIT 64
|
{Class::Rogue, "Rogue"},
|
||||||
#define PLAYER_CLASS_BARD_BIT 128
|
{Class::Shaman, "Shaman"},
|
||||||
#define PLAYER_CLASS_ROGUE_BIT 256
|
{Class::Necromancer, "Necromancer"},
|
||||||
#define PLAYER_CLASS_SHAMAN_BIT 512
|
{Class::Wizard, "Wizard"},
|
||||||
#define PLAYER_CLASS_NECROMANCER_BIT 1024
|
{Class::Magician, "Magician"},
|
||||||
#define PLAYER_CLASS_WIZARD_BIT 2048
|
{Class::Enchanter, "Enchanter"},
|
||||||
#define PLAYER_CLASS_MAGICIAN_BIT 4096
|
{Class::Beastlord, "Beastlord"},
|
||||||
#define PLAYER_CLASS_ENCHANTER_BIT 8192
|
{Class::Berserker, "Berserker"},
|
||||||
#define PLAYER_CLASS_BEASTLORD_BIT 16384
|
};
|
||||||
#define PLAYER_CLASS_BERSERKER_BIT 32768
|
|
||||||
|
|
||||||
#define PLAYER_CLASS_ALL_MASK 65535 // was 65536
|
|
||||||
|
|
||||||
|
|
||||||
#define ARMOR_TYPE_UNKNOWN 0
|
#define ARMOR_TYPE_UNKNOWN 0
|
||||||
@@ -125,13 +133,12 @@
|
|||||||
|
|
||||||
|
|
||||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||||
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
|
||||||
|
|
||||||
uint32 GetPlayerClassValue(uint8 class_id);
|
bool IsPlayerClass(uint8 class_id);
|
||||||
uint32 GetPlayerClassBit(uint8 class_id);
|
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
||||||
|
|
||||||
uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value);
|
uint8 GetPlayerClassValue(uint8 class_id);
|
||||||
uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
uint16 GetPlayerClassBit(uint8 class_id);
|
||||||
|
|
||||||
bool IsFighterClass(uint8 class_id);
|
bool IsFighterClass(uint8 class_id);
|
||||||
bool IsSpellFighterClass(uint8 class_id);
|
bool IsSpellFighterClass(uint8 class_id);
|
||||||
|
|||||||
@@ -39,15 +39,15 @@ namespace EQEmuCommand {
|
|||||||
{
|
{
|
||||||
if (cmd[{"-d", "--debug"}]) {
|
if (cmd[{"-d", "--debug"}]) {
|
||||||
std::cout << "Positional args:\n";
|
std::cout << "Positional args:\n";
|
||||||
for (auto &pos_arg : cmd.pos_args())
|
for (auto &pos_arg: cmd.pos_args())
|
||||||
std::cout << '\t' << pos_arg << std::endl;
|
std::cout << '\t' << pos_arg << std::endl;
|
||||||
|
|
||||||
std::cout << "\nFlags:\n";
|
std::cout << "\nFlags:\n";
|
||||||
for (auto &flag : cmd.flags())
|
for (auto &flag: cmd.flags())
|
||||||
std::cout << '\t' << flag << std::endl;
|
std::cout << '\t' << flag << std::endl;
|
||||||
|
|
||||||
std::cout << "\nParameters:\n";
|
std::cout << "\nParameters:\n";
|
||||||
for (auto ¶m : cmd.params())
|
for (auto ¶m: cmd.params())
|
||||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,22 +69,22 @@ namespace EQEmuCommand {
|
|||||||
{
|
{
|
||||||
bool arguments_filled = true;
|
bool arguments_filled = true;
|
||||||
|
|
||||||
int index = 2;
|
int index = 2;
|
||||||
for (auto &arg : arguments) {
|
for (auto &arg: arguments) {
|
||||||
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
||||||
arguments_filled = false;
|
arguments_filled = false;
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
|
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
|
||||||
std::string arguments_string;
|
std::string arguments_string;
|
||||||
for (auto &arg : arguments) {
|
for (auto &arg: arguments) {
|
||||||
arguments_string += " " + arg;
|
arguments_string += " " + arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string options_string;
|
std::string options_string;
|
||||||
for (auto &opt : options) {
|
for (auto &opt: options) {
|
||||||
options_string += " " + opt + "\n";
|
options_string += " " + opt + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,14 +124,6 @@ namespace EQEmuCommand {
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::string description;
|
std::string description;
|
||||||
bool ran_command = false;
|
|
||||||
for (auto &it: in_function_map) {
|
|
||||||
if (it.first == argv[1]) {
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
|
||||||
ran_command = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd[{"-h", "--help"}]) {
|
if (cmd[{"-h", "--help"}]) {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout <<
|
std::cout <<
|
||||||
@@ -142,9 +134,7 @@ namespace EQEmuCommand {
|
|||||||
<< std::endl
|
<< std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
/**
|
// Get max command length for padding length
|
||||||
* Get max command length for padding length
|
|
||||||
*/
|
|
||||||
int max_command_length = 0;
|
int max_command_length = 0;
|
||||||
|
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
@@ -155,18 +145,14 @@ namespace EQEmuCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Display command menu
|
||||||
* Display command menu
|
|
||||||
*/
|
|
||||||
std::string command_section;
|
std::string command_section;
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
description.clear();
|
description.clear();
|
||||||
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
|
||||||
/**
|
// Print section header
|
||||||
* Print section header
|
|
||||||
*/
|
|
||||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
||||||
|
|
||||||
if (command_prefix.find("test") != std::string::npos) {
|
if (command_prefix.find("test") != std::string::npos) {
|
||||||
@@ -178,9 +164,7 @@ namespace EQEmuCommand {
|
|||||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
std::cout << termcolor::reset << command_prefix << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Print commands
|
||||||
* Print commands
|
|
||||||
*/
|
|
||||||
std::stringstream command;
|
std::stringstream command;
|
||||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
||||||
@@ -191,6 +175,15 @@ namespace EQEmuCommand {
|
|||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ran_command = false;
|
||||||
|
|
||||||
|
for (auto &it: in_function_map) {
|
||||||
|
if (it.first == argv[1]) {
|
||||||
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
ran_command = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ran_command) {
|
if (ran_command) {
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,11 @@
|
|||||||
/**
|
|
||||||
* 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 "world_content_service.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
#include "../database.h"
|
#include "../database.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../loottable.h"
|
#include "../repositories/instance_list_repository.h"
|
||||||
#include "../repositories/content_flags_repository.h"
|
|
||||||
|
|
||||||
|
|
||||||
WorldContentService::WorldContentService()
|
WorldContentService::WorldContentService()
|
||||||
@@ -120,7 +102,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
|||||||
/**
|
/**
|
||||||
* @param content_flags
|
* @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;
|
WorldContentService::content_flags = content_flags;
|
||||||
}
|
}
|
||||||
@@ -168,14 +150,14 @@ bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we don't have any enabled flag in enabled flags, we fail
|
// 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)) {
|
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we don't have any disabled flag in disabled flags, we fail
|
// 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)) {
|
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -196,11 +178,13 @@ void WorldContentService::ReloadContentFlags()
|
|||||||
LogInfo(
|
LogInfo(
|
||||||
"Loaded content flag [{}] [{}]",
|
"Loaded content flag [{}] [{}]",
|
||||||
f.flag_name,
|
f.flag_name,
|
||||||
(f.enabled ? "Enabled" : "Disabled")
|
(f.enabled ? "enabled" : "disabled")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetContentFlags(set_content_flags);
|
SetContentFlags(set_content_flags);
|
||||||
|
LoadZones();
|
||||||
|
LoadStaticGlobalZoneInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
Database *WorldContentService::GetDatabase() const
|
Database *WorldContentService::GetDatabase() const
|
||||||
@@ -215,6 +199,18 @@ WorldContentService *WorldContentService::SetDatabase(Database *database)
|
|||||||
return this;
|
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)
|
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
|
||||||
{
|
{
|
||||||
auto flags = ContentFlagsRepository::GetWhere(
|
auto flags = ContentFlagsRepository::GetWhere(
|
||||||
@@ -239,3 +235,135 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
|||||||
|
|
||||||
ReloadContentFlags();
|
ReloadContentFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleZoneRoutingMiddleware is meant to handle content and context aware zone routing
|
||||||
|
//
|
||||||
|
// example # 1
|
||||||
|
// lavastorm (pre-don) version 0 (classic)
|
||||||
|
// lavastorm (don) version 1
|
||||||
|
// we want to route players to the correct version of lavastorm based on the current server side expansion
|
||||||
|
// in order to do that the simplest and cleanest way we intercept the zoning process and route players to an "instance" of the zone
|
||||||
|
// the reason why we're doing this is because all of the zoning logic already is handled by two keys "zone_id" and "instance_id"
|
||||||
|
// we can leverage static, never expires instances to handle this but to the client they don't see it any other way than a public normal zone
|
||||||
|
// scripts handle all the same way, you don't have to think about instances, the middleware will handle the magic
|
||||||
|
// the versions of zones are represented by two zone entries that have potentially different min/max expansion and/or different content flags
|
||||||
|
// we decide to route the client to the correct version of the zone based on the current server side expansion
|
||||||
|
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
||||||
|
{
|
||||||
|
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_instances = InstanceListRepository::GetWhere(*GetDatabase(), fmt::format("never_expires = 1 AND is_global = 1"));
|
||||||
|
|
||||||
|
LogInfo("Loaded [{}] zone_instances", m_zone_instances.size());
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadZones sets the zones for the world content service
|
||||||
|
// this is used for zone routing middleware
|
||||||
|
// we pull the zone list from the zone repository and feed from the zone store for now
|
||||||
|
// we're holding a copy in the content service - but we're talking 250kb of data in memory to handle routing of zoning
|
||||||
|
WorldContentService * WorldContentService::LoadZones()
|
||||||
|
{
|
||||||
|
m_zones = ZoneRepository::All(*GetContentDatabase());
|
||||||
|
|
||||||
|
LogInfo("Loaded [{}] zones", m_zones.size());
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindZone is critical to the zone routing middleware and any logic that needs to route players to the correct zone
|
||||||
|
// era contextual routing, multiple version of zones, etc
|
||||||
|
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
|
||||||
|
{
|
||||||
|
// if there's an active dynamic instance, we don't need to route
|
||||||
|
if (instance_id > 0) {
|
||||||
|
auto inst = InstanceListRepository::FindOne(*GetDatabase(), instance_id);
|
||||||
|
if (inst.id != 0 && !inst.is_global && !inst.never_expires) {
|
||||||
|
return WorldContentService::FindZoneResult{
|
||||||
|
.zone_id = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &z: m_zones) {
|
||||||
|
if (z.zoneidnumber == zone_id) {
|
||||||
|
auto f = ContentFlags{
|
||||||
|
.min_expansion = z.min_expansion,
|
||||||
|
.max_expansion = z.max_expansion,
|
||||||
|
.content_flags = z.content_flags,
|
||||||
|
.content_flags_disabled = z.content_flags_disabled
|
||||||
|
};
|
||||||
|
|
||||||
|
if (DoesPassContentFiltering(f)) {
|
||||||
|
LogInfo(
|
||||||
|
"Attempting to route player to zone [{}] ({}) version [{}] long_name [{}]",
|
||||||
|
z.short_name,
|
||||||
|
z.zoneidnumber,
|
||||||
|
z.version,
|
||||||
|
z.long_name
|
||||||
|
);
|
||||||
|
|
||||||
|
// first pass, explicit match on public static global zone instances
|
||||||
|
for (auto &i: m_zone_instances) {
|
||||||
|
if (i.zone == zone_id && i.version == z.version) {
|
||||||
|
LogInfo(
|
||||||
|
"Routed player to 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo(
|
||||||
|
"Routed player to non-instance zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
||||||
|
z.short_name,
|
||||||
|
z.zoneidnumber,
|
||||||
|
z.version,
|
||||||
|
z.long_name,
|
||||||
|
z.note
|
||||||
|
);
|
||||||
|
|
||||||
|
return WorldContentService::FindZoneResult{
|
||||||
|
.zone_id = static_cast<uint32>(z.zoneidnumber),
|
||||||
|
.instance = InstanceListRepository::NewEntity(),
|
||||||
|
.zone = z
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WorldContentService::FindZoneResult{.zone_id = 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
|
||||||
|
{
|
||||||
|
for (auto &i: m_zone_instances) {
|
||||||
|
if (i.id == instance_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
#ifndef EQEMU_WORLD_CONTENT_SERVICE_H
|
||||||
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../loottable.h"
|
|
||||||
#include "../repositories/content_flags_repository.h"
|
#include "../repositories/content_flags_repository.h"
|
||||||
|
#include "../repositories/zone_repository.h"
|
||||||
|
#include "../repositories/instance_list_repository.h"
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
|
struct ContentFlags {
|
||||||
|
int16 min_expansion;
|
||||||
|
int16 max_expansion;
|
||||||
|
std::string content_flags;
|
||||||
|
std::string content_flags_disabled;
|
||||||
|
};
|
||||||
|
|
||||||
namespace Expansion {
|
namespace Expansion {
|
||||||
static const int EXPANSION_ALL = -1;
|
static const int EXPANSION_ALL = -1;
|
||||||
static const int EXPANSION_FILTER_MAX = 99;
|
static const int EXPANSION_FILTER_MAX = 99;
|
||||||
@@ -176,14 +164,35 @@ public:
|
|||||||
WorldContentService * SetDatabase(Database *database);
|
WorldContentService * SetDatabase(Database *database);
|
||||||
Database *GetDatabase() const;
|
Database *GetDatabase() const;
|
||||||
|
|
||||||
|
WorldContentService * SetContentDatabase(Database *database);
|
||||||
|
Database *GetContentDatabase() const;
|
||||||
|
|
||||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
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:
|
private:
|
||||||
int current_expansion{};
|
int current_expansion{};
|
||||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||||
|
|
||||||
// reference to database
|
// reference to database
|
||||||
Database *m_database;
|
Database *m_database;
|
||||||
|
Database *m_content_database;
|
||||||
|
|
||||||
|
// holds a record of the zone table from the database
|
||||||
|
std::vector<ZoneRepository::Zone> m_zones = {};
|
||||||
|
WorldContentService *LoadStaticGlobalZoneInstances();
|
||||||
|
std::vector<InstanceListRepository::InstanceList> m_zone_instances;
|
||||||
|
WorldContentService * LoadZones();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WorldContentService content_service;
|
extern WorldContentService content_service;
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define popen _popen
|
#define popen _popen
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ void SendCrashReport(const std::string &crash_report)
|
|||||||
{
|
{
|
||||||
// can configure multiple endpoints if need be
|
// can configure multiple endpoints if need be
|
||||||
std::vector<std::string> endpoints = {
|
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
|
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1346
-1660
File diff suppressed because it is too large
Load Diff
+150
-144
@@ -18,8 +18,8 @@
|
|||||||
#ifndef EQEMU_DATABASE_H
|
#ifndef EQEMU_DATABASE_H
|
||||||
#define EQEMU_DATABASE_H
|
#define EQEMU_DATABASE_H
|
||||||
|
|
||||||
#define AUTHENTICATION_TIMEOUT 60
|
#define AUTHENTICATION_TIMEOUT 60
|
||||||
#define INVALID_ID 0xFFFFFFFF
|
#define INVALID_ID 0xFFFFFFFF
|
||||||
|
|
||||||
#include "global_define.h"
|
#include "global_define.h"
|
||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
@@ -38,8 +38,7 @@
|
|||||||
class MySQLRequestResult;
|
class MySQLRequestResult;
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ {
|
||||||
{
|
|
||||||
class InventoryProfile;
|
class InventoryProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,10 +51,11 @@ struct npcDecayTimes_Struct {
|
|||||||
|
|
||||||
struct VarCache_Struct {
|
struct VarCache_Struct {
|
||||||
std::map<std::string, std::string> m_cache;
|
std::map<std::string, std::string> m_cache;
|
||||||
uint32 last_update;
|
uint32 last_update;
|
||||||
VarCache_Struct() : last_update(0) { }
|
VarCache_Struct() : last_update(0) { }
|
||||||
void Add(const std::string &key, const std::string &value) { m_cache[key] = value; }
|
void Add(const std::string& key, const std::string& value) { m_cache[key] = value; }
|
||||||
const std::string *Get(const std::string &key) {
|
const std::string* Get(const std::string& key)
|
||||||
|
{
|
||||||
auto it = m_cache.find(key);
|
auto it = m_cache.find(key);
|
||||||
return (it != m_cache.end() ? &it->second : nullptr);
|
return (it != m_cache.end() ? &it->second : nullptr);
|
||||||
}
|
}
|
||||||
@@ -76,37 +76,33 @@ class PTimerList;
|
|||||||
|
|
||||||
#define SQL(...) #__VA_ARGS__
|
#define SQL(...) #__VA_ARGS__
|
||||||
|
|
||||||
class LogSettings;
|
|
||||||
class Database : public DBcore {
|
class Database : public DBcore {
|
||||||
public:
|
public:
|
||||||
Database();
|
Database();
|
||||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
Database(
|
||||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port, std::string connection_label = "default");
|
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();
|
~Database();
|
||||||
|
|
||||||
/* Character Creation */
|
/* Character Creation */
|
||||||
|
bool DeleteCharacter(const std::string& name);
|
||||||
bool CreateCharacter(
|
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
|
||||||
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 MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||||
bool ReserveName(uint32 account_id, char *name);
|
bool ReserveName(uint32 account_id, const std::string& name);
|
||||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||||
bool UpdateName(const char *oldname, const char *newname);
|
bool UpdateName(const std::string& old_name, const std::string& new_name);
|
||||||
bool CopyCharacter(
|
bool CopyCharacter(
|
||||||
const std::string& source_character_name,
|
const std::string& source_character_name,
|
||||||
const std::string& destination_character_name,
|
const std::string& destination_character_name,
|
||||||
@@ -114,165 +110,175 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
/* General Information Queries */
|
/* 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.
|
uint32 GetAccountIDByChar(const std::string& name, uint32* character_id = 0);
|
||||||
bool AddToNameFilter(std::string name);
|
uint32 GetAccountIDByChar(uint32 character_id);
|
||||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
uint32 GetAccountIDByName(const std::string& account_name, const std::string& loginserver, int16* status = 0, uint32* lsid = 0);
|
||||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
uint32 GetCharacterID(const std::string& name);
|
||||||
bool CheckNameFilter(std::string name, bool surname = false);
|
uint32 GetGuildIDByCharID(uint32 character_id);
|
||||||
bool CheckUsedName(std::string name);
|
uint32 GetGroupIDByCharID(uint32 character_id);
|
||||||
|
uint32 GetRaidIDByCharID(uint32 character_id);
|
||||||
|
|
||||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
const std::string GetAccountName(uint32 account_id, uint32* lsaccount_id = 0);
|
||||||
uint32 GetAccountIDByChar(uint32 char_id);
|
const std::string GetCharName(uint32 character_id);
|
||||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
const std::string GetCharNameByID(uint32 character_id);
|
||||||
uint32 GetCharacterID(const char *name);
|
const std::string GetNPCNameByID(uint32 npc_id);
|
||||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
const std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
void LoginIP(uint32 account_id, const std::string& login_ip);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Instancing */
|
/* Instancing */
|
||||||
|
|
||||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
||||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
||||||
bool CheckInstanceExists(uint16 instance_id);
|
bool CheckInstanceExists(uint16 instance_id);
|
||||||
bool CheckInstanceExpired(uint16 instance_id);
|
bool CheckInstanceExpired(uint16 instance_id);
|
||||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
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 IsGlobalInstance(uint16 instance_id);
|
||||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||||
bool RemoveClientsFromInstance(uint16 instance_id);
|
bool RemoveClientsFromInstance(uint16 instance_id);
|
||||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
||||||
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_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);
|
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
||||||
uint8_t GetInstanceVersion(uint16 instance_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);
|
uint32 GetInstanceZoneID(uint16 instance_id);
|
||||||
|
|
||||||
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
void AssignGroupToInstance(uint32 group_id, uint32 instance_id);
|
||||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
void AssignRaidToInstance(uint32 raid_id, uint32 instance_id);
|
||||||
void DeleteInstance(uint16 instance_id);
|
void DeleteInstance(uint16 instance_id);
|
||||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id);
|
||||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_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 GetCharactersInInstance(uint16 instance_id, std::list<uint32>& character_ids);
|
||||||
void PurgeExpiredInstances();
|
void PurgeExpiredInstances();
|
||||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||||
|
void CleanupInstanceCorpses();
|
||||||
|
|
||||||
/* Adventure related. */
|
/* Adventure related. */
|
||||||
|
void UpdateAdventureStatsEntry(uint32 character_id, uint8 theme_id, bool is_win = false, bool is_remove = false);
|
||||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win = false, bool remove = false);
|
bool GetAdventureStats(uint32 character_id, AdventureStats_Struct* as);
|
||||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
|
||||||
|
|
||||||
/* Account Related */
|
/* 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 CheckStatus(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);
|
uint8 GetAgreementFlag(uint32 account_id);
|
||||||
bool GetLiveChar(uint32 account_id, char* cname);
|
void SetAgreementFlag(uint32 account_id);
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
int GetInstanceID(uint32 character_id, uint32 zone_id);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
/* Groups */
|
/* Groups */
|
||||||
|
std::string GetGroupLeaderForLogin(const std::string& character_name);
|
||||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
char* GetGroupLeadershipInfo(
|
||||||
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 group_id,
|
||||||
|
char* leaderbuf,
|
||||||
uint32 GetGroupID(const char* name);
|
char* maintank = nullptr,
|
||||||
|
char* assist = nullptr,
|
||||||
void ClearGroup(uint32 gid = 0);
|
char* puller = nullptr,
|
||||||
void ClearGroupLeader(uint32 gid = 0);
|
char* marknpc = nullptr,
|
||||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
char* mentoree = nullptr,
|
||||||
void SetGroupLeaderName(uint32 gid, const char* name);
|
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 */
|
/* 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();
|
||||||
|
|
||||||
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 */
|
/* 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);
|
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||||
bool SetVariable(const std::string& varname, const std::string &varvalue);
|
uint32 GetServerType();
|
||||||
bool LoadVariables();
|
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 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:
|
private:
|
||||||
|
Mutex Mvarcache;
|
||||||
Mutex Mvarcache;
|
|
||||||
VarCache_Struct varcache;
|
VarCache_Struct varcache;
|
||||||
|
|
||||||
/* Groups, utility methods. */
|
/* Groups, utility methods. */
|
||||||
void ClearAllGroupLeaders();
|
void ClearAllGroupLeaders();
|
||||||
void ClearAllGroups();
|
void ClearAllGroups();
|
||||||
|
|
||||||
/* Raid, utility methods. */
|
/* Raid, utility methods. */
|
||||||
void ClearAllRaids();
|
void ClearAllRaids();
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ std::string DatabaseDumpService::GetMySQLVersion()
|
|||||||
return Strings::Trim(version_output);
|
return Strings::Trim(version_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string CREDENTIALS_FILE = "login.my.cnf";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -101,21 +103,15 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
|||||||
auto config = EQEmuConfig::get();
|
auto config = EQEmuConfig::get();
|
||||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
"mysqldump --defaults-extra-file={} {}",
|
||||||
config->ContentDbUsername,
|
CREDENTIALS_FILE,
|
||||||
config->ContentDbPassword,
|
|
||||||
config->ContentDbHost,
|
|
||||||
config->ContentDbPort,
|
|
||||||
config->ContentDbName
|
config->ContentDbName
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
"mysqldump --defaults-extra-file={} {}",
|
||||||
config->DatabaseUsername,
|
CREDENTIALS_FILE,
|
||||||
config->DatabasePassword,
|
|
||||||
config->DatabaseHost,
|
|
||||||
config->DatabasePort,
|
|
||||||
config->DatabaseDB
|
config->DatabaseDB
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -283,6 +279,11 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsDumpStaticInstanceData()) {
|
||||||
|
tables_to_dump += "instance_list";
|
||||||
|
options += " --no-create-info --where=\"instance_list.is_global > 0 and instance_list.never_expires > 0\"";
|
||||||
|
}
|
||||||
|
|
||||||
if (!dump_descriptor.empty()) {
|
if (!dump_descriptor.empty()) {
|
||||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
||||||
}
|
}
|
||||||
@@ -309,6 +310,8 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
if (tables_to_dump.empty()) {
|
if (tables_to_dump.empty()) {
|
||||||
std::cerr << "No tables were specified" << std::endl;
|
std::cerr << "No tables were specified" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const auto execute_command = fmt::format(
|
const auto execute_command = fmt::format(
|
||||||
@@ -319,13 +322,20 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
pipe_file
|
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);
|
std::string execution_result = Process::execute(execute_command);
|
||||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||||
std::cout << execution_result;
|
std::cout << execution_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.EnableConsoleLogging();
|
if (!IsDumpOutputToConsole()) {
|
||||||
|
LogSys.LoadLogSettingsDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
if (!pipe_file.empty()) {
|
if (!pipe_file.empty()) {
|
||||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||||
@@ -350,10 +360,9 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
||||||
if (HasCompressionBinary()) {
|
if (HasCompressionBinary()) {
|
||||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsTarAvailable()) {
|
if (IsTarAvailable()) {
|
||||||
Process::execute(
|
Process::execute(
|
||||||
@@ -387,6 +396,8 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveCredentialsFile();
|
||||||
|
|
||||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||||
@@ -564,6 +575,58 @@ void DatabaseDumpService::RemoveSqlBackup()
|
|||||||
{
|
{
|
||||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||||
if (File::Exists(file)) {
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseDumpService::BuildCredentialsFile()
|
||||||
|
{
|
||||||
|
auto config = EQEmuConfig::get();
|
||||||
|
std::ofstream out(CREDENTIALS_FILE);
|
||||||
|
if (out.is_open()) {
|
||||||
|
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||||
|
out << "[mysqldump]" << std::endl;
|
||||||
|
out << "user=" << config->ContentDbUsername << std::endl;
|
||||||
|
out << "password=" << config->ContentDbPassword << std::endl;
|
||||||
|
out << "host=" << config->ContentDbHost << std::endl;
|
||||||
|
out << "port=" << config->ContentDbPort << std::endl;
|
||||||
|
out << "default-character-set=utf8" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out << "[mysqldump]" << std::endl;
|
||||||
|
out << "user=" << config->DatabaseUsername << std::endl;
|
||||||
|
out << "password=" << config->DatabasePassword << std::endl;
|
||||||
|
out << "host=" << config->DatabaseHost << std::endl;
|
||||||
|
out << "port=" << config->DatabasePort << std::endl;
|
||||||
|
out << "default-character-set=utf8" << std::endl;
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogError("Failed to open credentials file for writing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseDumpService::RemoveCredentialsFile()
|
||||||
|
{
|
||||||
|
if (File::Exists(CREDENTIALS_FILE)) {
|
||||||
|
std::filesystem::remove(CREDENTIALS_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DatabaseDumpService::IsDumpStaticInstanceData()
|
||||||
|
{
|
||||||
|
return dump_static_instance_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseDumpService::SetDumpStaticInstanceData(bool b)
|
||||||
|
{
|
||||||
|
dump_static_instance_data = b;
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ public:
|
|||||||
bool IsDumpMercTables() const;
|
bool IsDumpMercTables() const;
|
||||||
void SetDumpMercTables(bool dump_bot_tables);
|
void SetDumpMercTables(bool dump_bot_tables);
|
||||||
|
|
||||||
|
void SetDumpStaticInstanceData(bool b);
|
||||||
|
bool IsDumpStaticInstanceData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool dump_all_tables = false;
|
bool dump_all_tables = false;
|
||||||
bool dump_state_tables = false;
|
bool dump_state_tables = false;
|
||||||
@@ -73,6 +76,8 @@ private:
|
|||||||
bool dump_drop_table_syntax_only = false;
|
bool dump_drop_table_syntax_only = false;
|
||||||
bool dump_bot_tables = false;
|
bool dump_bot_tables = false;
|
||||||
bool dump_merc_tables = false;
|
bool dump_merc_tables = false;
|
||||||
|
bool dump_static_instance_data = false;
|
||||||
|
|
||||||
std::string dump_path;
|
std::string dump_path;
|
||||||
std::string dump_file_name;
|
std::string dump_file_name;
|
||||||
|
|
||||||
@@ -93,6 +98,8 @@ private:
|
|||||||
std::string GetSetDumpPath();
|
std::string GetSetDumpPath();
|
||||||
std::string GetQueryServTables();
|
std::string GetQueryServTables();
|
||||||
void RemoveSqlBackup();
|
void RemoveSqlBackup();
|
||||||
|
void BuildCredentialsFile();
|
||||||
|
void RemoveCredentialsFile();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,324 @@
|
|||||||
|
#include <filesystem>
|
||||||
|
#include "database_update.h"
|
||||||
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../database.h"
|
||||||
|
#include "../strings.h"
|
||||||
|
#include "../rulesys.h"
|
||||||
|
#include "../http/httplib.h"
|
||||||
|
|
||||||
|
#include "database_update_manifest.cpp"
|
||||||
|
#include "database_update_manifest_bots.cpp"
|
||||||
|
#include "database_dump_service.h"
|
||||||
|
|
||||||
|
constexpr int BREAK_LENGTH = 70;
|
||||||
|
|
||||||
|
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
||||||
|
{
|
||||||
|
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
|
||||||
|
if (!results.Success() || !results.RowCount()) {
|
||||||
|
LogError("Failed to read from [db_version] table!");
|
||||||
|
return DatabaseVersion{};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r = results.begin();
|
||||||
|
|
||||||
|
return DatabaseVersion{
|
||||||
|
.server_database_version = Strings::ToInt(r[0]),
|
||||||
|
.bots_database_version = Strings::ToInt(r[1]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
|
||||||
|
{
|
||||||
|
return DatabaseVersion{
|
||||||
|
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
|
||||||
|
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// the amount of versions we look-back to ensure we have all migrations
|
||||||
|
// we may not want to force these, but just warn about the look-backs
|
||||||
|
constexpr int LOOK_BACK_AMOUNT = 10;
|
||||||
|
|
||||||
|
// this check will take action
|
||||||
|
void DatabaseUpdate::CheckDbUpdates()
|
||||||
|
{
|
||||||
|
InjectBotsVersionColumn();
|
||||||
|
auto v = GetDatabaseVersions();
|
||||||
|
auto b = GetBinaryDatabaseVersions();
|
||||||
|
if (CheckVersionsUpToDate(v, b)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
|
||||||
|
LogInfo(
|
||||||
|
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||||
|
b.server_database_version,
|
||||||
|
v.server_database_version
|
||||||
|
);
|
||||||
|
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.bots_database_version > 0) {
|
||||||
|
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
|
||||||
|
LogInfo(
|
||||||
|
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||||
|
b.bots_database_version,
|
||||||
|
v.bots_database_version
|
||||||
|
);
|
||||||
|
m_database->QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE `db_version` SET `bots_version` = {}",
|
||||||
|
b.bots_database_version
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DatabaseUpdate::GetQueryResult(const ManifestEntry& e)
|
||||||
|
{
|
||||||
|
auto results = (e.content_schema_update ? m_content_database : m_database)->QueryDatabase(e.check);
|
||||||
|
|
||||||
|
std::vector<std::string> result_lines = {};
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
std::vector<std::string> cols;
|
||||||
|
|
||||||
|
int field_count = results.ColumnCount();
|
||||||
|
cols.reserve(field_count);
|
||||||
|
for (int i = 0; i < field_count; ++i) {
|
||||||
|
if (row[i] != nullptr) {
|
||||||
|
cols.emplace_back(row[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result_lines.emplace_back(Strings::Join(cols, " "));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Strings::Join(result_lines, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_result)
|
||||||
|
{
|
||||||
|
std::string r = Strings::Trim(query_result);
|
||||||
|
if (e.condition == "contains") {
|
||||||
|
return Strings::Contains(r, e.match);
|
||||||
|
}
|
||||||
|
else if (e.condition == "match") {
|
||||||
|
return r == e.match;
|
||||||
|
}
|
||||||
|
else if (e.condition == "missing") {
|
||||||
|
return !Strings::Contains(r, e.match);
|
||||||
|
}
|
||||||
|
else if (e.condition == "empty") {
|
||||||
|
return r.empty();
|
||||||
|
}
|
||||||
|
else if (e.condition == "not_empty") {
|
||||||
|
return !r.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
int version_low,
|
||||||
|
int version_high
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<int> missing_migrations = {};
|
||||||
|
if (version_low != version_high) {
|
||||||
|
|
||||||
|
LogSys.DisableMySQLErrorLogs();
|
||||||
|
for (int version = version_low + 1; version <= version_high; ++version) {
|
||||||
|
for (auto &e: entries) {
|
||||||
|
if (e.version == version) {
|
||||||
|
bool has_migration = true;
|
||||||
|
std::string r = GetQueryResult(e);
|
||||||
|
if (ShouldRunMigration(e, r)) {
|
||||||
|
has_migration = false;
|
||||||
|
missing_migrations.emplace_back(e.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string prefix = fmt::format(
|
||||||
|
"[{}]",
|
||||||
|
has_migration ? "ok" : "missing"
|
||||||
|
);
|
||||||
|
|
||||||
|
LogInfo(
|
||||||
|
"[{}] {:>10} | [{}]",
|
||||||
|
e.version,
|
||||||
|
prefix,
|
||||||
|
e.description
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogSys.EnableMySQLErrorLogs();
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
|
if (!missing_migrations.empty()) {
|
||||||
|
LogInfo("Automatically backing up database before applying updates");
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
auto s = DatabaseDumpService();
|
||||||
|
s.SetDumpAllTables(true);
|
||||||
|
s.SetDumpWithCompression(true);
|
||||||
|
s.DatabaseDump();
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!missing_migrations.empty()) {
|
||||||
|
LogInfo("Running database migrations. Please wait...");
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &m: missing_migrations) {
|
||||||
|
for (auto &e: entries) {
|
||||||
|
if (e.version == m) {
|
||||||
|
bool errored_migration = false;
|
||||||
|
|
||||||
|
auto r = (e.content_schema_update ? m_content_database : m_database)->QueryDatabaseMulti(e.sql);
|
||||||
|
|
||||||
|
// ignore empty query result "errors"
|
||||||
|
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
||||||
|
LogError("(#{}) [{}]", r.ErrorNumber(), r.ErrorMessage());
|
||||||
|
errored_migration = true;
|
||||||
|
|
||||||
|
LogInfo("Required database update failed. This could be a problem");
|
||||||
|
|
||||||
|
// if terminal attached then prompt for skip
|
||||||
|
if (is_atty()) {
|
||||||
|
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
||||||
|
|
||||||
|
// user input
|
||||||
|
std::string input;
|
||||||
|
bool gave_input = false;
|
||||||
|
time_t start_time = time(nullptr);
|
||||||
|
time_t wait_time_seconds = 60;
|
||||||
|
|
||||||
|
// spawn a concurrent thread that waits for input from std::cin
|
||||||
|
std::thread t1(
|
||||||
|
[&]() {
|
||||||
|
std::cin >> input;
|
||||||
|
gave_input = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
t1.detach();
|
||||||
|
|
||||||
|
// check the inputReceived flag once every 50ms for 10 seconds
|
||||||
|
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt for user skip
|
||||||
|
if (Strings::Trim(input) == "y") {
|
||||||
|
errored_migration = false;
|
||||||
|
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errored_migration = true;
|
||||||
|
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo(
|
||||||
|
"[{}] [{}] [{}]",
|
||||||
|
e.version,
|
||||||
|
e.description,
|
||||||
|
(errored_migration ? "error" : "ok")
|
||||||
|
);
|
||||||
|
|
||||||
|
if (errored_migration) {
|
||||||
|
LogError("Fatal | Database migration [{}] failed to run", e.description);
|
||||||
|
LogError("Fatal | Shutting down");
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_database = db;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseUpdate *DatabaseUpdate::SetContentDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_content_database = db;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||||
|
{
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
|
LogInfo(
|
||||||
|
"{:>8} | database [{}] binary [{}] {}",
|
||||||
|
"Server",
|
||||||
|
v.server_database_version,
|
||||||
|
b.server_database_version,
|
||||||
|
(v.server_database_version == b.server_database_version) ? "up to date" : "checking updates"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
|
||||||
|
LogInfo(
|
||||||
|
"{:>8} | database [{}] binary [{}] {}",
|
||||||
|
"Bots",
|
||||||
|
v.bots_database_version,
|
||||||
|
b.bots_database_version,
|
||||||
|
(v.bots_database_version == b.bots_database_version) ? "up to date" : "checking updates"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
|
||||||
|
|
||||||
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
|
// server database version is required
|
||||||
|
bool server_up_to_date = v.server_database_version >= b.server_database_version;
|
||||||
|
// bots database version is optional, if not enabled then it is always up-to-date
|
||||||
|
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version >= b.bots_database_version : true;
|
||||||
|
|
||||||
|
return server_up_to_date && bots_up_to_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks to see if there are pending updates
|
||||||
|
// used by zone to prevent launch or boot loop until updates are applied
|
||||||
|
bool DatabaseUpdate::HasPendingUpdates()
|
||||||
|
{
|
||||||
|
auto v = GetDatabaseVersions();
|
||||||
|
auto b = GetBinaryDatabaseVersions();
|
||||||
|
|
||||||
|
return !CheckVersionsUpToDate(v, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseUpdate::InjectBotsVersionColumn()
|
||||||
|
{
|
||||||
|
auto r = m_database->QueryDatabase("show columns from db_version where Field like '%bots_version%'");
|
||||||
|
if (r.RowCount() == 0) {
|
||||||
|
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef EQEMU_DATABASE_UPDATE_H
|
||||||
|
#define EQEMU_DATABASE_UPDATE_H
|
||||||
|
|
||||||
|
#include "../database.h"
|
||||||
|
|
||||||
|
struct ManifestEntry {
|
||||||
|
int version{}; // database version of the migration
|
||||||
|
std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
||||||
|
std::string check{}; // query that checks against the condition
|
||||||
|
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||||
|
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||||
|
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||||
|
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DatabaseVersion {
|
||||||
|
int server_database_version;
|
||||||
|
int bots_database_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DatabaseUpdate {
|
||||||
|
public:
|
||||||
|
DatabaseVersion GetDatabaseVersions();
|
||||||
|
DatabaseVersion GetBinaryDatabaseVersions();
|
||||||
|
void CheckDbUpdates();
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_DATABASE_UPDATE_H
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,175 @@
|
|||||||
|
#include "database_update.h"
|
||||||
|
|
||||||
|
std::vector<ManifestEntry> bot_manifest_entries = {
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9035,
|
||||||
|
.description = "2022_12_04_bot_archery.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `bot_data`
|
||||||
|
ADD COLUMN `archery_setting` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `enforce_spell_settings`;
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9036,
|
||||||
|
.description = "2023_01_19_drop_bot_views.sql",
|
||||||
|
.check = "SHOW TABLES LIKE 'vw_groups'",
|
||||||
|
.condition = "not_empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
DROP VIEW vw_bot_groups;
|
||||||
|
DROP VIEW vw_bot_character_mobs;
|
||||||
|
DROP VIEW vw_groups;
|
||||||
|
DROP VIEW vw_guild_members;
|
||||||
|
DROP TABLE bot_guild_members;
|
||||||
|
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9037,
|
||||||
|
.description = "2023_01_22_add_name_index.sql",
|
||||||
|
.check = "show index from bot_data WHERE key_name = 'name`",
|
||||||
|
.condition = "",
|
||||||
|
.match = "empty",
|
||||||
|
.sql = R"(
|
||||||
|
create index `name` on bot_data(`name`);
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9038,
|
||||||
|
.description = "2023_02_16_add_caster_range.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'",
|
||||||
|
.condition = "",
|
||||||
|
.match = "empty",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `bot_data`
|
||||||
|
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9039,
|
||||||
|
.description = "2023_03_31_remove_bot_groups.sql",
|
||||||
|
.check = "SHOW TABLES LIKE 'bot_groups'",
|
||||||
|
.condition = "",
|
||||||
|
.match = "not_empty",
|
||||||
|
.sql = R"(
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
DROP TABLE IF EXISTS `bot_groups`;
|
||||||
|
DROP TABLE IF EXISTS `bot_group_members`;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9040,
|
||||||
|
.description = "2023_11_16_bot_starting_items.sql",
|
||||||
|
.check = "SHOW TABLES LIKE 'bot_starting_items'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
CREATE TABLE `bot_starting_items` (
|
||||||
|
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`races` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`classes` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||||
|
`min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`slot_id` mediumint(9) NOT NULL DEFAULT -1,
|
||||||
|
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||||
|
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||||
|
`content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
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`;
|
||||||
|
)"
|
||||||
|
}
|
||||||
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
|
// ManifestEntry{
|
||||||
|
// .version = 9228,
|
||||||
|
// .description = "some_new_migration.sql",
|
||||||
|
// .check = "SHOW COLUMNS FROM `table_name` LIKE 'column_name'",
|
||||||
|
// .condition = "empty",
|
||||||
|
// .match = "",
|
||||||
|
// .sql = R"(
|
||||||
|
//
|
||||||
|
//)"
|
||||||
|
};
|
||||||
|
|
||||||
|
// see struct definitions for what each field does
|
||||||
|
// struct ManifestEntry {
|
||||||
|
// int version{}; // database version of the migration
|
||||||
|
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
||||||
|
// std::string check{}; // query that checks against the condition
|
||||||
|
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||||
|
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||||
|
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||||
|
// };
|
||||||
File diff suppressed because it is too large
Load Diff
+122
-61
@@ -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/raid_members_repository.h"
|
||||||
#include "../common/repositories/respawn_times_repository.h"
|
#include "../common/repositories/respawn_times_repository.h"
|
||||||
#include "../common/repositories/spawn_condition_values_repository.h"
|
#include "../common/repositories/spawn_condition_values_repository.h"
|
||||||
|
#include "repositories/spawn2_disabled_repository.h"
|
||||||
|
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
@@ -49,6 +50,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
||||||
{
|
{
|
||||||
auto e = InstanceListPlayerRepository::NewEntity();
|
auto e = InstanceListPlayerRepository::NewEntity();
|
||||||
@@ -131,85 +133,118 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
|||||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||||
{
|
{
|
||||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||||
uint32 max = 32000;
|
uint32 max_instance_id = 32000;
|
||||||
|
|
||||||
|
// sanity check reserved
|
||||||
|
if (max_reserved_instance_id >= max_instance_id) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// recycle instances
|
||||||
|
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||||
|
|
||||||
|
//query to get first unused id above reserved
|
||||||
|
auto query = fmt::format(
|
||||||
|
SQL(
|
||||||
|
SELECT id
|
||||||
|
FROM instance_list
|
||||||
|
WHERE id = {};
|
||||||
|
),
|
||||||
|
max_reserved_instance_id + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
// could not successfully query - bail out
|
||||||
|
if (!results.Success()) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first id is available
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
|
instance_id = max_reserved_instance_id + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now look for next available above reserved
|
||||||
|
query = fmt::format(
|
||||||
|
SQL(
|
||||||
|
SELECT MIN(i.id + 1) AS next_available
|
||||||
|
FROM instance_list i
|
||||||
|
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
||||||
|
WHERE i.id >= {}
|
||||||
|
AND i2.id IS NULL;
|
||||||
|
),
|
||||||
|
max_reserved_instance_id
|
||||||
|
);
|
||||||
|
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
|
// could not successfully query - bail out
|
||||||
|
if (!results.Success()) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// did not retrieve any rows - bail out
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
// check that id is within limits
|
||||||
|
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
|
||||||
|
instance_id = Strings::ToInt(row[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no available instance ids
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get max unused id above reserved
|
||||||
auto query = fmt::format(
|
auto query = fmt::format(
|
||||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||||
max_reserved_instance_id,
|
max_reserved_instance_id,
|
||||||
max_reserved_instance_id
|
max_reserved_instance_id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
|
||||||
query = (
|
|
||||||
SQL(
|
|
||||||
SELECT i.id + 1 AS next_available
|
|
||||||
FROM instance_list i
|
|
||||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
|
||||||
WHERE i2.id IS NULL
|
|
||||||
ORDER BY i.id
|
|
||||||
LIMIT 0, 1;
|
|
||||||
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
// could not successfully query - bail out
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// did not retrieve any rows - bail out
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0) {
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = 0;
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if (Strings::ToInt(row[0]) <= max) {
|
// no instances currently used
|
||||||
|
if (!row[0]) {
|
||||||
|
instance_id = max_reserved_instance_id + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that id is within limits
|
||||||
|
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||||
instance_id = Strings::ToInt(row[0]);
|
instance_id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance_id < max_reserved_instance_id) {
|
// no available instance ids
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = 0;
|
||||||
return true;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
|
||||||
results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success()) {
|
|
||||||
instance_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
|
||||||
instance_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
|
||||||
instance_id = max_reserved_instance_id;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_reserved_instance_id > max) {
|
|
||||||
instance_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_id = max_reserved_instance_id;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
bool Database::IsGlobalInstance(uint16 instance_id)
|
||||||
@@ -386,20 +421,25 @@ void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
|||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
auto zone_id = GetInstanceZoneID(instance_id);
|
||||||
auto version = GetInstanceVersion(instance_id);
|
auto version = GetInstanceVersion(instance_id);
|
||||||
|
|
||||||
auto l = GroupIdRepository::GetWhere(
|
const auto& l = GroupIdRepository::GetWhere(
|
||||||
*this,
|
*this,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"groupid = {}",
|
"`group_id` = {}",
|
||||||
group_id
|
group_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (l.empty()) {
|
if (l.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& e : l) {
|
for (const auto& e : l) {
|
||||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
if (!e.character_id) {
|
||||||
AddClientToInstance(instance_id, e.charid);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetInstanceID(zone_id, e.character_id, version)) {
|
||||||
|
AddClientToInstance(instance_id, e.character_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,7 +509,7 @@ void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 ch
|
|||||||
return;
|
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);
|
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
||||||
|
|
||||||
if (!raid_leader_instance_id) {
|
if (!raid_leader_instance_id) {
|
||||||
@@ -520,6 +560,7 @@ void Database::PurgeExpiredInstances()
|
|||||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
||||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", 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)
|
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||||
@@ -534,3 +575,23 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
|||||||
|
|
||||||
InstanceListRepository::UpdateOne(*this, i);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ namespace DatabaseSchema {
|
|||||||
{"character_leadership_abilities", "id"},
|
{"character_leadership_abilities", "id"},
|
||||||
{"character_material", "id"},
|
{"character_material", "id"},
|
||||||
{"character_memmed_spells", "id"},
|
{"character_memmed_spells", "id"},
|
||||||
|
{"character_parcels", "char_id"},
|
||||||
{"character_pet_buffs", "char_id"},
|
{"character_pet_buffs", "char_id"},
|
||||||
{"character_pet_info", "char_id"},
|
{"character_pet_info", "char_id"},
|
||||||
{"character_pet_inventory", "char_id"},
|
{"character_pet_inventory", "char_id"},
|
||||||
@@ -66,11 +67,12 @@ namespace DatabaseSchema {
|
|||||||
{"character_potionbelt", "id"},
|
{"character_potionbelt", "id"},
|
||||||
{"character_skills", "id"},
|
{"character_skills", "id"},
|
||||||
{"character_spells", "id"},
|
{"character_spells", "id"},
|
||||||
|
{"character_stats_record", "character_id"},
|
||||||
{"character_task_timers", "character_id"},
|
{"character_task_timers", "character_id"},
|
||||||
{"character_tasks", "charid"},
|
{"character_tasks", "charid"},
|
||||||
{"character_tribute", "character_id"},
|
{"character_tribute", "character_id"},
|
||||||
{"completed_tasks", "charid"},
|
{"completed_tasks", "charid"},
|
||||||
{"data_buckets", "id"},
|
{"data_buckets", "character_id"},
|
||||||
{"faction_values", "char_id"},
|
{"faction_values", "char_id"},
|
||||||
{"friends", "charid"},
|
{"friends", "charid"},
|
||||||
{"guild_members", "char_id"},
|
{"guild_members", "char_id"},
|
||||||
@@ -127,6 +129,7 @@ namespace DatabaseSchema {
|
|||||||
"character_leadership_abilities",
|
"character_leadership_abilities",
|
||||||
"character_material",
|
"character_material",
|
||||||
"character_memmed_spells",
|
"character_memmed_spells",
|
||||||
|
"character_parcels",
|
||||||
"character_pet_buffs",
|
"character_pet_buffs",
|
||||||
"character_pet_info",
|
"character_pet_info",
|
||||||
"character_pet_inventory",
|
"character_pet_inventory",
|
||||||
@@ -134,6 +137,7 @@ namespace DatabaseSchema {
|
|||||||
"character_potionbelt",
|
"character_potionbelt",
|
||||||
"character_skills",
|
"character_skills",
|
||||||
"character_spells",
|
"character_spells",
|
||||||
|
"character_stats_record",
|
||||||
"character_task_timers",
|
"character_task_timers",
|
||||||
"character_tasks",
|
"character_tasks",
|
||||||
"character_tribute",
|
"character_tribute",
|
||||||
@@ -144,8 +148,10 @@ namespace DatabaseSchema {
|
|||||||
"friends",
|
"friends",
|
||||||
"guild_bank",
|
"guild_bank",
|
||||||
"guild_members",
|
"guild_members",
|
||||||
|
"guild_permissions",
|
||||||
"guild_ranks",
|
"guild_ranks",
|
||||||
"guild_relations",
|
"guild_relations",
|
||||||
|
"guild_tributes",
|
||||||
"guilds",
|
"guilds",
|
||||||
"instance_list_player",
|
"instance_list_player",
|
||||||
"inventory",
|
"inventory",
|
||||||
@@ -256,7 +262,9 @@ namespace DatabaseSchema {
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"chatchannels",
|
"chatchannels",
|
||||||
|
"chatchannel_reserved_names",
|
||||||
"command_settings",
|
"command_settings",
|
||||||
|
"command_subsettings",
|
||||||
"content_flags",
|
"content_flags",
|
||||||
"db_str",
|
"db_str",
|
||||||
"eqtime",
|
"eqtime",
|
||||||
@@ -328,7 +336,6 @@ namespace DatabaseSchema {
|
|||||||
"group_leaders",
|
"group_leaders",
|
||||||
"instance_list",
|
"instance_list",
|
||||||
"ip_exemptions",
|
"ip_exemptions",
|
||||||
"item_tick",
|
|
||||||
"lfguild",
|
"lfguild",
|
||||||
"merc_buffs",
|
"merc_buffs",
|
||||||
"merchantlist_temp",
|
"merchantlist_temp",
|
||||||
@@ -341,6 +348,7 @@ namespace DatabaseSchema {
|
|||||||
"respawn_times",
|
"respawn_times",
|
||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"server_scheduled_events",
|
||||||
|
"spawn2_disabled",
|
||||||
"player_event_log_settings",
|
"player_event_log_settings",
|
||||||
"player_event_logs",
|
"player_event_logs",
|
||||||
"shared_task_activity_state",
|
"shared_task_activity_state",
|
||||||
|
|||||||
+133
-2
@@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
#include "dbcore.h"
|
#include "dbcore.h"
|
||||||
|
|
||||||
#include <errmsg.h>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@@ -137,7 +137,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
* Error logging
|
* Error logging
|
||||||
*/
|
*/
|
||||||
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
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);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
||||||
@@ -305,3 +305,134 @@ void DBcore::SetMutex(Mutex *mutex)
|
|||||||
|
|
||||||
DBcore::m_mutex = mutex;
|
DBcore::m_mutex = mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executes multiple statements in one query
|
||||||
|
// do not use this in application logic
|
||||||
|
// this was built and maintained for database migrations only
|
||||||
|
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
||||||
|
{
|
||||||
|
SetMultiStatementsOn();
|
||||||
|
|
||||||
|
BenchTimer timer;
|
||||||
|
timer.reset();
|
||||||
|
|
||||||
|
LockMutex lock(m_mutex);
|
||||||
|
|
||||||
|
// Reconnect if we are not connected before hand.
|
||||||
|
if (pStatus != Connected) {
|
||||||
|
Open();
|
||||||
|
}
|
||||||
|
auto r = MySQLRequestResult{};
|
||||||
|
|
||||||
|
int status = mysql_real_query(mysql, query.c_str(), query.length());
|
||||||
|
|
||||||
|
// process single result
|
||||||
|
if (status != 0) {
|
||||||
|
unsigned int error_number = mysql_errno(mysql);
|
||||||
|
|
||||||
|
if (error_number == CR_SERVER_GONE_ERROR) {
|
||||||
|
pStatus = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error logging
|
||||||
|
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
|
||||||
|
std::string error_raw = fmt::format("{}", mysql_error(mysql));
|
||||||
|
std::string mysql_err = Strings::Trim(error_raw);
|
||||||
|
std::string clean_query = Strings::Replace(query, "\n", "");
|
||||||
|
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
|
||||||
|
|
||||||
|
MYSQL_RES *res = mysql_store_result(mysql);
|
||||||
|
|
||||||
|
uint32 row_count = 0;
|
||||||
|
if (res) {
|
||||||
|
row_count = (uint32) mysql_num_rows(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = MySQLRequestResult(
|
||||||
|
res,
|
||||||
|
(uint32) mysql_affected_rows(mysql),
|
||||||
|
row_count,
|
||||||
|
(uint32) mysql_field_count(mysql),
|
||||||
|
(uint32) mysql_insert_id(mysql)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::string error_message = mysql_error(mysql);
|
||||||
|
r.SetErrorMessage(error_message);
|
||||||
|
r.SetErrorNumber(mysql_errno(mysql));
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
mysql_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetMultiStatementsOff();
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
// there could be a query with a semicolon in the actual data, this is best effort for
|
||||||
|
// logging / display purposes
|
||||||
|
// rare that we see this when this is only used in DDL statements
|
||||||
|
auto pieces = Strings::Split(query, ";");
|
||||||
|
|
||||||
|
// process each statement result
|
||||||
|
do {
|
||||||
|
uint32 row_count = 0;
|
||||||
|
MYSQL_RES *res = mysql_store_result(mysql);
|
||||||
|
|
||||||
|
r = MySQLRequestResult(
|
||||||
|
res,
|
||||||
|
(uint32) mysql_affected_rows(mysql),
|
||||||
|
row_count,
|
||||||
|
(uint32) mysql_field_count(mysql),
|
||||||
|
(uint32) mysql_insert_id(mysql)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pieces.size() >= index) {
|
||||||
|
auto piece = pieces[index];
|
||||||
|
LogMySQLQuery(
|
||||||
|
"{} -- ({} row{} affected) ({}s)",
|
||||||
|
piece,
|
||||||
|
r.RowsAffected(),
|
||||||
|
r.RowsAffected() == 1 ? "" : "s",
|
||||||
|
std::to_string(timer.elapsed())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
row_count = (uint32) mysql_num_rows(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
|
||||||
|
if ((status = mysql_next_result(mysql)) > 0) {
|
||||||
|
if (mysql_errno(mysql) > 0) {
|
||||||
|
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_free_result(res);
|
||||||
|
|
||||||
|
// error logging
|
||||||
|
std::string error_message = mysql_error(mysql);
|
||||||
|
r.SetErrorMessage(error_message);
|
||||||
|
r.SetErrorNumber(mysql_errno(mysql));
|
||||||
|
|
||||||
|
SetMultiStatementsOff();
|
||||||
|
|
||||||
|
// we handle errors elsewhere
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
mysql_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
} while (status == 0);
|
||||||
|
|
||||||
|
SetMultiStatementsOff();
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|||||||
+17
-1
@@ -14,6 +14,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#define CR_SERVER_GONE_ERROR 2006
|
||||||
|
#define CR_SERVER_LOST 2013
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
enum eStatus {
|
enum eStatus {
|
||||||
@@ -25,6 +28,7 @@ public:
|
|||||||
eStatus GetStatus() { return pStatus; }
|
eStatus GetStatus() { return pStatus; }
|
||||||
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
||||||
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
||||||
|
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
||||||
void TransactionBegin();
|
void TransactionBegin();
|
||||||
void TransactionCommit();
|
void TransactionCommit();
|
||||||
void TransactionRollback();
|
void TransactionRollback();
|
||||||
@@ -77,8 +81,20 @@ private:
|
|||||||
uint32 pPort;
|
uint32 pPort;
|
||||||
bool pSSL;
|
bool pSSL;
|
||||||
|
|
||||||
|
// allows multiple queries to be executed within the same query
|
||||||
|
// do not use this under normal operation
|
||||||
|
// we use this during database migrations only currently
|
||||||
|
void SetMultiStatementsOn()
|
||||||
|
{
|
||||||
|
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
// disables multiple statements to be executed in one query
|
||||||
|
void SetMultiStatementsOff()
|
||||||
|
{
|
||||||
|
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+68
-118
@@ -19,131 +19,81 @@
|
|||||||
|
|
||||||
#include "deity.h"
|
#include "deity.h"
|
||||||
|
|
||||||
|
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
||||||
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
|
||||||
{
|
{
|
||||||
switch (deity_type) {
|
switch (deity_type) {
|
||||||
case DeityBertoxxulous:
|
case DeityBertoxxulous:
|
||||||
return bit_DeityBertoxxulous;
|
return bit_DeityBertoxxulous;
|
||||||
case DeityBrellSirilis:
|
case DeityBrellSirilis:
|
||||||
return bit_DeityBrellSirilis;
|
return bit_DeityBrellSirilis;
|
||||||
case DeityCazicThule:
|
case DeityCazicThule:
|
||||||
return bit_DeityCazicThule;
|
return bit_DeityCazicThule;
|
||||||
case DeityErollisiMarr:
|
case DeityErollisiMarr:
|
||||||
return bit_DeityErollisiMarr;
|
return bit_DeityErollisiMarr;
|
||||||
case DeityBristlebane:
|
case DeityBristlebane:
|
||||||
return bit_DeityBristlebane;
|
return bit_DeityBristlebane;
|
||||||
case DeityInnoruuk:
|
case DeityInnoruuk:
|
||||||
return bit_DeityInnoruuk;
|
return bit_DeityInnoruuk;
|
||||||
case DeityKarana:
|
case DeityKarana:
|
||||||
return bit_DeityKarana;
|
return bit_DeityKarana;
|
||||||
case DeityMithanielMarr:
|
case DeityMithanielMarr:
|
||||||
return bit_DeityMithanielMarr;
|
return bit_DeityMithanielMarr;
|
||||||
case DeityPrexus:
|
case DeityPrexus:
|
||||||
return bit_DeityPrexus;
|
return bit_DeityPrexus;
|
||||||
case DeityQuellious:
|
case DeityQuellious:
|
||||||
return bit_DeityQuellious;
|
return bit_DeityQuellious;
|
||||||
case DeityRallosZek:
|
case DeityRallosZek:
|
||||||
return bit_DeityRallosZek;
|
return bit_DeityRallosZek;
|
||||||
case DeityRodcetNife:
|
case DeityRodcetNife:
|
||||||
return bit_DeityRodcetNife;
|
return bit_DeityRodcetNife;
|
||||||
case DeitySolusekRo:
|
case DeitySolusekRo:
|
||||||
return bit_DeitySolusekRo;
|
return bit_DeitySolusekRo;
|
||||||
case DeityTheTribunal:
|
case DeityTheTribunal:
|
||||||
return bit_DeityTheTribunal;
|
return bit_DeityTheTribunal;
|
||||||
case DeityTunare:
|
case DeityTunare:
|
||||||
return bit_DeityTunare;
|
return bit_DeityTunare;
|
||||||
case DeityVeeshan:
|
case DeityVeeshan:
|
||||||
return bit_DeityVeeshan;
|
return bit_DeityVeeshan;
|
||||||
case DeityAgnostic_LB:
|
case DeityAgnostic_LB:
|
||||||
case DeityAgnostic:
|
case DeityAgnostic:
|
||||||
return bit_DeityAgnostic;
|
return bit_DeityAgnostic;
|
||||||
default:
|
default:
|
||||||
return bit_DeityAll;
|
return bit_DeityAll;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
|
||||||
{
|
{
|
||||||
switch (deity_type_bit) {
|
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
|
||||||
case bit_DeityAgnostic:
|
{ DeityAgnostic, "Agnostic" },
|
||||||
return DeityAgnostic;
|
{ DeityAgnostic_LB, "Agnostic" },
|
||||||
case bit_DeityBertoxxulous:
|
{ DeityBertoxxulous, "Bertoxxulous" },
|
||||||
return DeityBertoxxulous;
|
{ DeityBrellSirilis, "Brell Serilis" },
|
||||||
case bit_DeityBrellSirilis:
|
{ DeityBristlebane, "Bristlebane" },
|
||||||
return DeityBrellSirilis;
|
{ DeityCazicThule, "Cazic-Thule" },
|
||||||
case bit_DeityCazicThule:
|
{ DeityErollisiMarr, "Erollisi Marr" },
|
||||||
return DeityCazicThule;
|
{ DeityInnoruuk, "Innoruuk" },
|
||||||
case bit_DeityErollisiMarr:
|
{ DeityKarana, "Karana" },
|
||||||
return DeityErollisiMarr;
|
{ DeityMithanielMarr, "Mithaniel Marr" },
|
||||||
case bit_DeityBristlebane:
|
{ DeityPrexus, "Prexus" },
|
||||||
return DeityBristlebane;
|
{ DeityQuellious, "Quellious" },
|
||||||
case bit_DeityInnoruuk:
|
{ DeityRallosZek, "Rallos Zek" },
|
||||||
return DeityInnoruuk;
|
{ DeityRodcetNife, "Rodcet Nife" },
|
||||||
case bit_DeityKarana:
|
{ DeitySolusekRo, "Solusek Ro" },
|
||||||
return DeityKarana;
|
{ DeityTheTribunal, "The Tribunal" },
|
||||||
case bit_DeityMithanielMarr:
|
{ DeityTunare, "Tunare" },
|
||||||
return DeityMithanielMarr;
|
{ DeityVeeshan, "Veeshan" }
|
||||||
case bit_DeityPrexus:
|
|
||||||
return DeityPrexus;
|
|
||||||
case bit_DeityQuellious:
|
|
||||||
return DeityQuellious;
|
|
||||||
case bit_DeityRallosZek:
|
|
||||||
return DeityRallosZek;
|
|
||||||
case bit_DeityRodcetNife:
|
|
||||||
return DeityRodcetNife;
|
|
||||||
case bit_DeitySolusekRo:
|
|
||||||
return DeitySolusekRo;
|
|
||||||
case bit_DeityTheTribunal:
|
|
||||||
return DeityTheTribunal;
|
|
||||||
case bit_DeityTunare:
|
|
||||||
return DeityTunare;
|
|
||||||
case bit_DeityVeeshan:
|
|
||||||
return DeityVeeshan;
|
|
||||||
default:
|
|
||||||
return DeityUnknown;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return deity_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* EQ::deity::DeityName(DeityType deity_type)
|
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
||||||
{
|
{
|
||||||
switch (deity_type) {
|
|
||||||
case DeityBertoxxulous:
|
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
||||||
return "Bertoxxulous";
|
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
||||||
case DeityBrellSirilis:
|
}
|
||||||
return "Brell Serilis";
|
|
||||||
case DeityCazicThule:
|
return std::string();
|
||||||
return "Cazic-Thule";
|
|
||||||
case DeityErollisiMarr:
|
|
||||||
return "Erollisi Marr";
|
|
||||||
case DeityBristlebane:
|
|
||||||
return "Bristlebane";
|
|
||||||
case DeityInnoruuk:
|
|
||||||
return "Innoruuk";
|
|
||||||
case DeityKarana:
|
|
||||||
return "Karana";
|
|
||||||
case DeityMithanielMarr:
|
|
||||||
return "Mithaniel Marr";
|
|
||||||
case DeityPrexus:
|
|
||||||
return "Prexus";
|
|
||||||
case DeityQuellious:
|
|
||||||
return "Quellious";
|
|
||||||
case DeityRallosZek:
|
|
||||||
return "Rallos Zek";
|
|
||||||
case DeityRodcetNife:
|
|
||||||
return "Rodcet Nife";
|
|
||||||
case DeitySolusekRo:
|
|
||||||
return "Solusek Ro";
|
|
||||||
case DeityTheTribunal:
|
|
||||||
return "The Tribunal";
|
|
||||||
case DeityTunare:
|
|
||||||
return "Tunare";
|
|
||||||
case DeityVeeshan:
|
|
||||||
return "Veeshan";
|
|
||||||
case DeityAgnostic_LB:
|
|
||||||
case DeityAgnostic:
|
|
||||||
return "Agnostic";
|
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-21
@@ -21,6 +21,8 @@
|
|||||||
#define COMMON_DEITY_H
|
#define COMMON_DEITY_H
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
@@ -49,30 +51,31 @@ namespace EQ
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum DeityTypeBit : uint32 {
|
enum DeityTypeBit : uint32 {
|
||||||
bit_DeityNone = 0x00000000,
|
bit_DeityAgnostic = 0x00000001,
|
||||||
bit_DeityAgnostic = 0x00000001,
|
bit_DeityBertoxxulous = 0x00000002,
|
||||||
bit_DeityBertoxxulous = 0x00000002,
|
bit_DeityBrellSirilis = 0x00000004,
|
||||||
bit_DeityBrellSirilis = 0x00000004,
|
bit_DeityCazicThule = 0x00000008,
|
||||||
bit_DeityCazicThule = 0x00000008,
|
bit_DeityErollisiMarr = 0x00000010,
|
||||||
bit_DeityErollisiMarr = 0x00000010,
|
bit_DeityBristlebane = 0x00000020,
|
||||||
bit_DeityBristlebane = 0x00000020,
|
bit_DeityInnoruuk = 0x00000040,
|
||||||
bit_DeityInnoruuk = 0x00000040,
|
bit_DeityKarana = 0x00000080,
|
||||||
bit_DeityKarana = 0x00000080,
|
|
||||||
bit_DeityMithanielMarr = 0x00000100,
|
bit_DeityMithanielMarr = 0x00000100,
|
||||||
bit_DeityPrexus = 0x00000200,
|
bit_DeityPrexus = 0x00000200,
|
||||||
bit_DeityQuellious = 0x00000400,
|
bit_DeityQuellious = 0x00000400,
|
||||||
bit_DeityRallosZek = 0x00000800,
|
bit_DeityRallosZek = 0x00000800,
|
||||||
bit_DeityRodcetNife = 0x00001000,
|
bit_DeityRodcetNife = 0x00001000,
|
||||||
bit_DeitySolusekRo = 0x00002000,
|
bit_DeitySolusekRo = 0x00002000,
|
||||||
bit_DeityTheTribunal = 0x00004000,
|
bit_DeityTheTribunal = 0x00004000,
|
||||||
bit_DeityTunare = 0x00008000,
|
bit_DeityTunare = 0x00008000,
|
||||||
bit_DeityVeeshan = 0x00010000,
|
bit_DeityVeeshan = 0x00010000,
|
||||||
bit_DeityAll = 0xFFFFFFFF
|
bit_DeityAll = UINT32_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
|
constexpr int format_as(DeityType type) { return static_cast<int>(type); }
|
||||||
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
|
|
||||||
extern const char* DeityName(DeityType deity_type);
|
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
||||||
|
extern std::string GetDeityName(DeityType deity_type);
|
||||||
|
extern const std::map<DeityType, std::string>& GetDeityMap();
|
||||||
|
|
||||||
} /*deity*/
|
} /*deity*/
|
||||||
|
|
||||||
|
|||||||
+191
-35
@@ -22,7 +22,6 @@
|
|||||||
#include "data_verification.h"
|
#include "data_verification.h"
|
||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
#include "eqemu_logsys_log_aliases.h"
|
#include "eqemu_logsys_log_aliases.h"
|
||||||
#include "languages.h"
|
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
|
|
||||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||||
@@ -159,45 +158,45 @@ int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
|
||||||
{
|
{
|
||||||
static const std::map<int, std::string> language_map = {
|
static const std::map<uint8, std::string> language_map = {
|
||||||
{ LANG_COMMON_TONGUE, "Common Tongue" },
|
{ Language::CommonTongue, "Common Tongue" },
|
||||||
{ LANG_BARBARIAN, "Barbarian" },
|
{ Language::Barbarian, "Barbarian" },
|
||||||
{ LANG_ERUDIAN, "Erudian" },
|
{ Language::Erudian, "Erudian" },
|
||||||
{ LANG_ELVISH, "Elvish" },
|
{ Language::Elvish, "Elvish" },
|
||||||
{ LANG_DARK_ELVISH, "Dark Elvish" },
|
{ Language::DarkElvish, "Dark Elvish" },
|
||||||
{ LANG_DWARVISH, "Dwarvish" },
|
{ Language::Dwarvish, "Dwarvish" },
|
||||||
{ LANG_TROLL, "Troll" },
|
{ Language::Troll, "Troll" },
|
||||||
{ LANG_OGRE, "Ogre" },
|
{ Language::Ogre, "Ogre" },
|
||||||
{ LANG_GNOMISH, "Gnomish" },
|
{ Language::Gnomish, "Gnomish" },
|
||||||
{ LANG_HALFLING, "Halfling" },
|
{ Language::Halfling, "Halfling" },
|
||||||
{ LANG_THIEVES_CANT, "Thieves Cant" },
|
{ Language::ThievesCant, "Thieves Cant" },
|
||||||
{ LANG_OLD_ERUDIAN, "Old Erudian" },
|
{ Language::OldErudian, "Old Erudian" },
|
||||||
{ LANG_ELDER_ELVISH, "Elder Elvish" },
|
{ Language::ElderElvish, "Elder Elvish" },
|
||||||
{ LANG_FROGLOK, "Froglok" },
|
{ Language::Froglok, "Froglok" },
|
||||||
{ LANG_GOBLIN, "Goblin" },
|
{ Language::Goblin, "Goblin" },
|
||||||
{ LANG_GNOLL, "Gnoll" },
|
{ Language::Gnoll, "Gnoll" },
|
||||||
{ LANG_COMBINE_TONGUE, "Combine Tongue" },
|
{ Language::CombineTongue, "Combine Tongue" },
|
||||||
{ LANG_ELDER_TEIRDAL, "Elder Teirdal" },
|
{ Language::ElderTeirDal, "Elder Teir'Dal" },
|
||||||
{ LANG_LIZARDMAN, "Lizardman" },
|
{ Language::Lizardman, "Lizardman" },
|
||||||
{ LANG_ORCISH, "Orcish" },
|
{ Language::Orcish, "Orcish" },
|
||||||
{ LANG_FAERIE, "Faerie" },
|
{ Language::Faerie, "Faerie" },
|
||||||
{ LANG_DRAGON, "Dragon" },
|
{ Language::Dragon, "Dragon" },
|
||||||
{ LANG_ELDER_DRAGON, "Elder Dragon" },
|
{ Language::ElderDragon, "Elder Dragon" },
|
||||||
{ LANG_DARK_SPEECH, "Dark Speech" },
|
{ Language::DarkSpeech, "Dark Speech" },
|
||||||
{ LANG_VAH_SHIR, "Vah Shir" },
|
{ Language::VahShir, "Vah Shir" },
|
||||||
{ LANG_ALARAN, "Alaran" },
|
{ Language::Alaran, "Alaran" },
|
||||||
{ LANG_HADAL, "Hadal" },
|
{ Language::Hadal, "Hadal" },
|
||||||
{ LANG_UNKNOWN, "Unknown" }
|
{ Language::Unknown27, "Unknown" }
|
||||||
};
|
};
|
||||||
|
|
||||||
return language_map;
|
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();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,7 +508,6 @@ std::string EQ::constants::GetObjectTypeName(int object_type)
|
|||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||||
@@ -564,6 +562,7 @@ std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
|||||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||||
{
|
{
|
||||||
static const std::map<uint8, std::string> emote_type_map = {
|
static const std::map<uint8, std::string> emote_type_map = {
|
||||||
|
{ EmoteTypes::Say, "Say" },
|
||||||
{ EmoteTypes::Emote, "Emote" },
|
{ EmoteTypes::Emote, "Emote" },
|
||||||
{ EmoteTypes::Shout, "Shout" },
|
{ EmoteTypes::Shout, "Shout" },
|
||||||
{ EmoteTypes::Proximity, "Proximity" }
|
{ EmoteTypes::Proximity, "Proximity" }
|
||||||
@@ -574,9 +573,166 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
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 std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map<uint32, std::string>& EQ::constants::GetSpecialAbilityMap()
|
||||||
|
{
|
||||||
|
static const std::map<uint32, std::string> special_ability_map = {
|
||||||
|
{ SPECATK_SUMMON, "Summon" },
|
||||||
|
{ SPECATK_ENRAGE, "Enrage" },
|
||||||
|
{ SPECATK_RAMPAGE, "Rampage" },
|
||||||
|
{ SPECATK_AREA_RAMPAGE, "Area Rampage" },
|
||||||
|
{ SPECATK_FLURRY, "Flurry" },
|
||||||
|
{ SPECATK_TRIPLE, "Triple Attack" },
|
||||||
|
{ SPECATK_QUAD, "Quadruple Attack" },
|
||||||
|
{ SPECATK_INNATE_DW, "Dual Wield" },
|
||||||
|
{ SPECATK_BANE, "Bane Attack" },
|
||||||
|
{ SPECATK_MAGICAL, "Magical Attack" },
|
||||||
|
{ SPECATK_RANGED_ATK, "Ranged Attack" },
|
||||||
|
{ UNSLOWABLE, "Immune to Slow" },
|
||||||
|
{ UNMEZABLE, "Immune to Mesmerize" },
|
||||||
|
{ UNCHARMABLE, "Immune to Charm" },
|
||||||
|
{ UNSTUNABLE, "Immune to Stun" },
|
||||||
|
{ UNSNAREABLE, "Immune to Snare" },
|
||||||
|
{ UNFEARABLE, "Immune to Fear" },
|
||||||
|
{ UNDISPELLABLE, "Immune to Dispell" },
|
||||||
|
{ IMMUNE_MELEE, "Immune to Melee" },
|
||||||
|
{ IMMUNE_MAGIC, "Immune to Magic" },
|
||||||
|
{ IMMUNE_FLEEING, "Immune to Fleeing" },
|
||||||
|
{ IMMUNE_MELEE_EXCEPT_BANE, "Immune to Melee except Bane" },
|
||||||
|
{ IMMUNE_MELEE_NONMAGICAL, "Immune to Non-Magical Melee" },
|
||||||
|
{ IMMUNE_AGGRO, "Immune to Aggro" },
|
||||||
|
{ IMMUNE_AGGRO_ON, "Immune to Being Aggro" },
|
||||||
|
{ IMMUNE_CASTING_FROM_RANGE, "Immune to Ranged Spells" },
|
||||||
|
{ IMMUNE_FEIGN_DEATH, "Immune to Feign Death" },
|
||||||
|
{ IMMUNE_TAUNT, "Immune to Taunt" },
|
||||||
|
{ NPC_TUNNELVISION, "Tunnel Vision" },
|
||||||
|
{ NPC_NO_BUFFHEAL_FRIENDS, "Does Not Heal of Buff Allies" },
|
||||||
|
{ IMMUNE_PACIFY, "Immune to Pacify" },
|
||||||
|
{ LEASH, "Leashed" },
|
||||||
|
{ TETHER, "Tethered" },
|
||||||
|
{ DESTRUCTIBLE_OBJECT, "Destructible Object" },
|
||||||
|
{ NO_HARM_FROM_CLIENT, "Immune to Harm from Client" },
|
||||||
|
{ ALWAYS_FLEE, "Always Flees" },
|
||||||
|
{ FLEE_PERCENT, "Flee Percentage" },
|
||||||
|
{ ALLOW_BENEFICIAL, "Allows Beneficial Spells" },
|
||||||
|
{ DISABLE_MELEE, "Melee is Disabled" },
|
||||||
|
{ NPC_CHASE_DISTANCE, "Chase Distance" },
|
||||||
|
{ ALLOW_TO_TANK, "Allowed to Tank" },
|
||||||
|
{ IGNORE_ROOT_AGGRO_RULES, "Ignores Root Aggro" },
|
||||||
|
{ CASTING_RESIST_DIFF, "Casting Resist Difficulty" },
|
||||||
|
{ COUNTER_AVOID_DAMAGE, "Counter Damage Avoidance" },
|
||||||
|
{ PROX_AGGRO, "Proximity Aggro" },
|
||||||
|
{ IMMUNE_RANGED_ATTACKS, "Immune to Ranged Attacks" },
|
||||||
|
{ IMMUNE_DAMAGE_CLIENT, "Immune to Client Damage" },
|
||||||
|
{ IMMUNE_DAMAGE_NPC, "Immune to NPC Damage" },
|
||||||
|
{ IMMUNE_AGGRO_CLIENT, "Immune to Client Aggro" },
|
||||||
|
{ IMMUNE_AGGRO_NPC, "Immune to NPC Aggro" },
|
||||||
|
{ MODIFY_AVOID_DAMAGE, "Modify Damage Avoidance" },
|
||||||
|
{ IMMUNE_FADING_MEMORIES, "Immune to Memory Fades" },
|
||||||
|
{ IMMUNE_OPEN, "Immune to Open" },
|
||||||
|
{ IMMUNE_ASSASSINATE, "Immune to Assassinate" },
|
||||||
|
{ IMMUNE_HEADSHOT, "Immune to Headshot" },
|
||||||
|
{ IMMUNE_AGGRO_BOT, "Immune to Bot Aggro" },
|
||||||
|
{ IMMUNE_DAMAGE_BOT, "Immune to Bot Damage" },
|
||||||
|
};
|
||||||
|
|
||||||
|
return special_ability_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string EQ::constants::GetSpecialAbilityName(uint32 ability_id)
|
||||||
|
{
|
||||||
|
const auto& a = EQ::constants::GetSpecialAbilityMap().find(ability_id);
|
||||||
|
if (a != EQ::constants::GetSpecialAbilityMap().end()) {
|
||||||
|
return a->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|||||||
+84
-2
@@ -350,6 +350,7 @@ namespace EQ
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum EmoteTypes : uint8 {
|
enum EmoteTypes : uint8 {
|
||||||
|
Say,
|
||||||
Emote,
|
Emote,
|
||||||
Shout,
|
Shout,
|
||||||
Proximity
|
Proximity
|
||||||
@@ -358,8 +359,8 @@ namespace EQ
|
|||||||
const char *GetStanceName(StanceType stance_type);
|
const char *GetStanceName(StanceType stance_type);
|
||||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||||
|
|
||||||
extern const std::map<int, std::string>& GetLanguageMap();
|
extern const std::map<uint8, std::string>& GetLanguageMap();
|
||||||
std::string GetLanguageName(int language_id);
|
std::string GetLanguageName(uint8 language_id);
|
||||||
|
|
||||||
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
||||||
std::string GetLDoNThemeName(uint32 theme_id);
|
std::string GetLDoNThemeName(uint32 theme_id);
|
||||||
@@ -397,6 +398,15 @@ namespace EQ
|
|||||||
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
||||||
std::string GetEmoteTypeName(uint8 emote_type);
|
std::string GetEmoteTypeName(uint8 emote_type);
|
||||||
|
|
||||||
|
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
||||||
|
std::string GetAppearanceTypeName(uint32 animation_type);
|
||||||
|
|
||||||
|
extern const std::map<uint32, std::string>& GetSpecialAbilityMap();
|
||||||
|
std::string GetSpecialAbilityName(uint32 ability_id);
|
||||||
|
|
||||||
|
extern const std::map<uint32, std::string>& GetConsiderColorMap();
|
||||||
|
std::string GetConsiderColorName(uint32 consider_color);
|
||||||
|
|
||||||
const int STANCE_TYPE_FIRST = stancePassive;
|
const int STANCE_TYPE_FIRST = stancePassive;
|
||||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||||
@@ -552,6 +562,17 @@ enum ConsiderLevel : uint8 {
|
|||||||
Scowls
|
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 {
|
enum TargetDescriptionType : uint8 {
|
||||||
LCSelf,
|
LCSelf,
|
||||||
UCSelf,
|
UCSelf,
|
||||||
@@ -593,6 +614,67 @@ enum class ApplySpellType {
|
|||||||
Raid
|
Raid
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SPECATK_SUMMON = 1,
|
||||||
|
SPECATK_ENRAGE = 2,
|
||||||
|
SPECATK_RAMPAGE = 3,
|
||||||
|
SPECATK_AREA_RAMPAGE = 4,
|
||||||
|
SPECATK_FLURRY = 5,
|
||||||
|
SPECATK_TRIPLE = 6,
|
||||||
|
SPECATK_QUAD = 7,
|
||||||
|
SPECATK_INNATE_DW = 8,
|
||||||
|
SPECATK_BANE = 9,
|
||||||
|
SPECATK_MAGICAL = 10,
|
||||||
|
SPECATK_RANGED_ATK = 11,
|
||||||
|
UNSLOWABLE = 12,
|
||||||
|
UNMEZABLE = 13,
|
||||||
|
UNCHARMABLE = 14,
|
||||||
|
UNSTUNABLE = 15,
|
||||||
|
UNSNAREABLE = 16,
|
||||||
|
UNFEARABLE = 17,
|
||||||
|
UNDISPELLABLE = 18,
|
||||||
|
IMMUNE_MELEE = 19,
|
||||||
|
IMMUNE_MAGIC = 20,
|
||||||
|
IMMUNE_FLEEING = 21,
|
||||||
|
IMMUNE_MELEE_EXCEPT_BANE = 22,
|
||||||
|
IMMUNE_MELEE_NONMAGICAL = 23,
|
||||||
|
IMMUNE_AGGRO = 24,
|
||||||
|
IMMUNE_AGGRO_ON = 25,
|
||||||
|
IMMUNE_CASTING_FROM_RANGE = 26,
|
||||||
|
IMMUNE_FEIGN_DEATH = 27,
|
||||||
|
IMMUNE_TAUNT = 28,
|
||||||
|
NPC_TUNNELVISION = 29,
|
||||||
|
NPC_NO_BUFFHEAL_FRIENDS = 30,
|
||||||
|
IMMUNE_PACIFY = 31,
|
||||||
|
LEASH = 32,
|
||||||
|
TETHER = 33,
|
||||||
|
DESTRUCTIBLE_OBJECT = 34,
|
||||||
|
NO_HARM_FROM_CLIENT = 35,
|
||||||
|
ALWAYS_FLEE = 36,
|
||||||
|
FLEE_PERCENT = 37,
|
||||||
|
ALLOW_BENEFICIAL = 38,
|
||||||
|
DISABLE_MELEE = 39,
|
||||||
|
NPC_CHASE_DISTANCE = 40,
|
||||||
|
ALLOW_TO_TANK = 41,
|
||||||
|
IGNORE_ROOT_AGGRO_RULES = 42,
|
||||||
|
CASTING_RESIST_DIFF = 43,
|
||||||
|
COUNTER_AVOID_DAMAGE = 44, // Modify by percent NPC's opponents chance to riposte, block, parry or dodge individually, or for all skills
|
||||||
|
PROX_AGGRO = 45,
|
||||||
|
IMMUNE_RANGED_ATTACKS = 46,
|
||||||
|
IMMUNE_DAMAGE_CLIENT = 47,
|
||||||
|
IMMUNE_DAMAGE_NPC = 48,
|
||||||
|
IMMUNE_AGGRO_CLIENT = 49,
|
||||||
|
IMMUNE_AGGRO_NPC = 50,
|
||||||
|
MODIFY_AVOID_DAMAGE = 51, // Modify by percent the NPCs chance to riposte, block, parry or dodge individually, or for all skills
|
||||||
|
IMMUNE_FADING_MEMORIES = 52,
|
||||||
|
IMMUNE_OPEN = 53,
|
||||||
|
IMMUNE_ASSASSINATE = 54,
|
||||||
|
IMMUNE_HEADSHOT = 55,
|
||||||
|
IMMUNE_AGGRO_BOT = 56,
|
||||||
|
IMMUNE_DAMAGE_BOT = 57,
|
||||||
|
MAX_SPECIAL_ATTACK = 58
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace HeroicBonusBucket
|
namespace HeroicBonusBucket
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ typedef enum { //EQEmu internal opcodes list
|
|||||||
_maxEmuOpcode
|
_maxEmuOpcode
|
||||||
} EmuOpcode;
|
} EmuOpcode;
|
||||||
|
|
||||||
|
constexpr int format_as(EmuOpcode opcode) { return static_cast<int>(opcode); }
|
||||||
extern const char *OpcodeNames[_maxEmuOpcode+1];
|
extern const char *OpcodeNames[_maxEmuOpcode+1];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+30
-1
@@ -62,6 +62,7 @@ N(OP_BeginCast),
|
|||||||
N(OP_Bind_Wound),
|
N(OP_Bind_Wound),
|
||||||
N(OP_BlockedBuffs),
|
N(OP_BlockedBuffs),
|
||||||
N(OP_BoardBoat),
|
N(OP_BoardBoat),
|
||||||
|
N(OP_BookButton),
|
||||||
N(OP_Buff),
|
N(OP_Buff),
|
||||||
N(OP_BuffCreate),
|
N(OP_BuffCreate),
|
||||||
N(OP_BuffRemoveRequest),
|
N(OP_BuffRemoveRequest),
|
||||||
@@ -227,6 +228,7 @@ N(OP_GuildBank),
|
|||||||
N(OP_GuildBankItemList),
|
N(OP_GuildBankItemList),
|
||||||
N(OP_GuildCreate),
|
N(OP_GuildCreate),
|
||||||
N(OP_GuildDelete),
|
N(OP_GuildDelete),
|
||||||
|
N(OP_GuildDeleteGuild),
|
||||||
N(OP_GuildDemote),
|
N(OP_GuildDemote),
|
||||||
N(OP_GuildInvite),
|
N(OP_GuildInvite),
|
||||||
N(OP_GuildInviteAccept),
|
N(OP_GuildInviteAccept),
|
||||||
@@ -238,15 +240,33 @@ N(OP_GuildManageStatus),
|
|||||||
N(OP_GuildMemberLevelUpdate),
|
N(OP_GuildMemberLevelUpdate),
|
||||||
N(OP_GuildMemberList),
|
N(OP_GuildMemberList),
|
||||||
N(OP_GuildMemberUpdate),
|
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_GuildMOTD),
|
||||||
N(OP_GuildPeace),
|
N(OP_GuildPeace),
|
||||||
N(OP_GuildPromote),
|
N(OP_GuildPromote),
|
||||||
N(OP_GuildPublicNote),
|
N(OP_GuildPublicNote),
|
||||||
N(OP_GuildRemove),
|
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_GuildsList),
|
||||||
N(OP_GuildStatus),
|
N(OP_GuildStatus),
|
||||||
N(OP_GuildTributeInfo),
|
N(OP_GuildTributeInfo),
|
||||||
N(OP_GuildUpdateURLAndChannel),
|
N(OP_GuildUpdate),
|
||||||
|
N(OP_GuildTributeDonateItem),
|
||||||
|
N(OP_GuildTributeDonatePlat),
|
||||||
N(OP_GuildWar),
|
N(OP_GuildWar),
|
||||||
N(OP_Heartbeat),
|
N(OP_Heartbeat),
|
||||||
N(OP_Hide),
|
N(OP_Hide),
|
||||||
@@ -316,6 +336,7 @@ N(OP_LootRequest),
|
|||||||
N(OP_ManaChange),
|
N(OP_ManaChange),
|
||||||
N(OP_ManaUpdate),
|
N(OP_ManaUpdate),
|
||||||
N(OP_MarkNPC),
|
N(OP_MarkNPC),
|
||||||
|
N(OP_MarkRaidNPC),
|
||||||
N(OP_Marquee),
|
N(OP_Marquee),
|
||||||
N(OP_MemorizeSpell),
|
N(OP_MemorizeSpell),
|
||||||
N(OP_Mend),
|
N(OP_Mend),
|
||||||
@@ -398,6 +419,8 @@ N(OP_PVPLeaderBoardRequest),
|
|||||||
N(OP_PVPStats),
|
N(OP_PVPStats),
|
||||||
N(OP_QueryResponseThing),
|
N(OP_QueryResponseThing),
|
||||||
N(OP_QueryUCSServerStatus),
|
N(OP_QueryUCSServerStatus),
|
||||||
|
N(OP_RaidDelegateAbility),
|
||||||
|
N(OP_RaidClearNPCMarks),
|
||||||
N(OP_RaidInvite),
|
N(OP_RaidInvite),
|
||||||
N(OP_RaidJoin),
|
N(OP_RaidJoin),
|
||||||
N(OP_RaidUpdate),
|
N(OP_RaidUpdate),
|
||||||
@@ -421,6 +444,7 @@ N(OP_ReqClientSpawn),
|
|||||||
N(OP_ReqNewZone),
|
N(OP_ReqNewZone),
|
||||||
N(OP_RequestClientZoneChange),
|
N(OP_RequestClientZoneChange),
|
||||||
N(OP_RequestDuel),
|
N(OP_RequestDuel),
|
||||||
|
N(OP_RequestGuildTributes),
|
||||||
N(OP_RequestKnowledgeBase),
|
N(OP_RequestKnowledgeBase),
|
||||||
N(OP_RequestTitles),
|
N(OP_RequestTitles),
|
||||||
N(OP_RespawnWindow),
|
N(OP_RespawnWindow),
|
||||||
@@ -486,6 +510,11 @@ N(OP_ShopEndConfirm),
|
|||||||
N(OP_ShopItem),
|
N(OP_ShopItem),
|
||||||
N(OP_ShopPlayerBuy),
|
N(OP_ShopPlayerBuy),
|
||||||
N(OP_ShopPlayerSell),
|
N(OP_ShopPlayerSell),
|
||||||
|
N(OP_ShopSendParcel),
|
||||||
|
N(OP_ShopDeleteParcel),
|
||||||
|
N(OP_ShopRespondParcel),
|
||||||
|
N(OP_ShopRetrieveParcel),
|
||||||
|
N(OP_ShopParcelIcon),
|
||||||
N(OP_ShopRequest),
|
N(OP_ShopRequest),
|
||||||
N(OP_SimpleMessage),
|
N(OP_SimpleMessage),
|
||||||
N(OP_SkillUpdate),
|
N(OP_SkillUpdate),
|
||||||
|
|||||||
+151
-54
@@ -23,61 +23,59 @@
|
|||||||
#include "skills.h"
|
#include "skills.h"
|
||||||
#include "types.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)
|
namespace Animation {
|
||||||
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
|
constexpr uint32 Standing = 100;
|
||||||
#define AT_WhoLevel 1 // the level that shows up on /who
|
constexpr uint32 Freeze = 102;
|
||||||
#define AT_HPMax 2 // idk
|
constexpr uint32 Looting = 105;
|
||||||
#define AT_Invis 3 // 0 = visible, 1 = invisible
|
constexpr uint32 Sitting = 110;
|
||||||
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
|
constexpr uint32 Crouching = 111;
|
||||||
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
|
constexpr uint32 Lying = 115;
|
||||||
#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
|
|
||||||
|
|
||||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||||
|
|
||||||
@@ -686,6 +684,53 @@ namespace Zones {
|
|||||||
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
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 {
|
typedef enum {
|
||||||
FilterNone = 0,
|
FilterNone = 0,
|
||||||
@@ -1052,4 +1097,56 @@ enum ScribeSpellActions
|
|||||||
Unmemorize
|
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
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
+472
-116
@@ -27,6 +27,9 @@
|
|||||||
#include "../common/version.h"
|
#include "../common/version.h"
|
||||||
#include "emu_constants.h"
|
#include "emu_constants.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
#include "../cereal/include/cereal/archives/binary.hpp"
|
||||||
|
#include "../cereal/include/cereal/types/string.hpp"
|
||||||
|
#include "../cereal/include/cereal/types/vector.hpp"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 BUFF_COUNT = 42;
|
static const uint32 BUFF_COUNT = 42;
|
||||||
@@ -124,6 +127,17 @@ struct LDoNTrapTemplate
|
|||||||
uint8 locked;
|
uint8 locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CrystalReclaimTypes
|
||||||
|
{
|
||||||
|
Ebon = 5,
|
||||||
|
Radiant = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace ItemStackSizeConstraint {
|
||||||
|
constexpr int16 Minimum = 1;
|
||||||
|
constexpr int16 Maximum = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
@@ -308,6 +322,7 @@ union
|
|||||||
uint32 DestructibleUnk9;
|
uint32 DestructibleUnk9;
|
||||||
bool targetable_with_hotkey;
|
bool targetable_with_hotkey;
|
||||||
bool show_name;
|
bool show_name;
|
||||||
|
bool guild_show;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerState_Struct {
|
struct PlayerState_Struct {
|
||||||
@@ -386,7 +401,7 @@ struct NewZone_Struct {
|
|||||||
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
|
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
|
||||||
/*0728*/ uint32 lava_damage; // Seen 50
|
/*0728*/ uint32 lava_damage; // Seen 50
|
||||||
/*0732*/ uint32 min_lava_damage; // Seen 10
|
/*0732*/ uint32 min_lava_damage; // Seen 10
|
||||||
/*0736*/
|
/*0736*/ float safe_heading;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -625,6 +640,12 @@ struct ConsentResponse_Struct {
|
|||||||
char zonename[32];
|
char zonename[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NameApproval_Struct {
|
||||||
|
char name[64];
|
||||||
|
uint32 race_id;
|
||||||
|
uint32 class_id;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Name Generator Struct
|
** Name Generator Struct
|
||||||
** Length: 72 bytes
|
** Length: 72 bytes
|
||||||
@@ -1515,20 +1536,32 @@ struct ExpUpdate_Struct
|
|||||||
** Packet Types: See ItemPacketType enum
|
** Packet Types: See ItemPacketType enum
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
enum ItemPacketType
|
enum ItemPacketType {
|
||||||
{
|
ItemPacketViewLink = 0x00,
|
||||||
ItemPacketViewLink = 0x00,
|
ItemPacketMerchant = 0x64,
|
||||||
ItemPacketMerchant = 0x64,
|
ItemPacketTradeView = 0x65,
|
||||||
ItemPacketTradeView = 0x65,
|
ItemPacketLoot = 0x66,
|
||||||
ItemPacketLoot = 0x66,
|
ItemPacketTrade = 0x67,
|
||||||
ItemPacketTrade = 0x67,
|
ItemPacketCharInventory = 0x69,
|
||||||
ItemPacketCharInventory = 0x69,
|
ItemPacketLimbo = 0x6A,
|
||||||
ItemPacketLimbo = 0x6A,
|
ItemPacketWorldContainer = 0x6B,
|
||||||
ItemPacketWorldContainer = 0x6B,
|
ItemPacketTributeItem = 0x6C,
|
||||||
ItemPacketTributeItem = 0x6C,
|
ItemPacketGuildTribute = 0x6D,
|
||||||
ItemPacketGuildTribute = 0x6D,
|
ItemPacketCharmUpdate = 0x6E, // noted as incorrect
|
||||||
ItemPacketCharmUpdate = 0x6E, // noted as incorrect
|
ItemPacketRecovery = 0x71,
|
||||||
ItemPacketInvalid = 0xFF
|
ItemPacketParcel = 0x73,
|
||||||
|
ItemPacketInvalid = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MerchantWindowTabDisplay {
|
||||||
|
None = 0x00,
|
||||||
|
SellBuy = 0x01,
|
||||||
|
Recover = 0x02,
|
||||||
|
SellBuyRecover = 0x03,
|
||||||
|
Parcel = 0x04,
|
||||||
|
SellBuyParcel = 0x05,
|
||||||
|
RecoverParcel = 0x06,
|
||||||
|
SellBuyRecoverParcel = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
//enum ItemPacketType
|
//enum ItemPacketType
|
||||||
@@ -1660,11 +1693,105 @@ struct GuildsList_Struct {
|
|||||||
GuildsListEntry_Struct Guilds[MAX_NUMBER_GUILDS];
|
GuildsListEntry_Struct Guilds[MAX_NUMBER_GUILDS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GuildsListMessagingEntry_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ std::string guild_name;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive& archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(guild_id),
|
||||||
|
CEREAL_NVP(guild_name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildsListMessaging_Struct {
|
||||||
|
/*000*/ char header[64];
|
||||||
|
/*064*/ uint32 no_of_guilds;
|
||||||
|
/*068*/ uint32 string_length;
|
||||||
|
/*072*/ std::vector<GuildsListMessagingEntry_Struct> guild_detail;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive& archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(header),
|
||||||
|
CEREAL_NVP(no_of_guilds),
|
||||||
|
CEREAL_NVP(string_length),
|
||||||
|
CEREAL_NVP(guild_detail)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct GuildUpdate_Struct {
|
struct GuildUpdate_Struct {
|
||||||
uint32 guildID;
|
uint32 guildID;
|
||||||
GuildsListEntry_Struct entry;
|
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 guild_show;
|
||||||
|
/*032*/ uint32 zone_id;
|
||||||
|
/*036*/ uint32 last_on;
|
||||||
|
/*040*/ char player_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildMemberLevel_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
/*068*/ uint32 level;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildMemberRank_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ uint32 rank_;
|
||||||
|
/*008*/ char player_name[64];
|
||||||
|
/*072*/ uint32 alt_banker; //Banker/Alt bit 00 - none 10 - Alt 11 - Alt and Banker 01 - Banker. Banker not functional for RoF2+
|
||||||
|
/*076*/ uint32 offline;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildMemberPublicNote_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
/*068*/ char public_note[256]; //RoF2 256
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildDelete_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildRenameGuild_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ char new_guild_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildRenameMember_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
/*068*/ char new_player_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildMemberDetails_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
/*068*/ uint32 zone_id;
|
||||||
|
/*072*/ uint32 last_on;
|
||||||
|
/*076*/ uint32 offline_mode; //1 Offline
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildMemberDelete_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Money Loot
|
** Money Loot
|
||||||
** Length: 22 Bytes
|
** Length: 22 Bytes
|
||||||
@@ -1713,10 +1840,10 @@ struct GuildJoin_Struct{
|
|||||||
/*092*/
|
/*092*/
|
||||||
};
|
};
|
||||||
struct GuildInviteAccept_Struct {
|
struct GuildInviteAccept_Struct {
|
||||||
char inviter[64];
|
char inviter[64];
|
||||||
char newmember[64];
|
char new_member[64];
|
||||||
uint32 response;
|
uint32 response;
|
||||||
uint32 guildeqid;
|
uint32 guild_id;
|
||||||
};
|
};
|
||||||
struct GuildManageRemove_Struct {
|
struct GuildManageRemove_Struct {
|
||||||
uint32 guildeqid;
|
uint32 guildeqid;
|
||||||
@@ -1748,6 +1875,14 @@ struct PopupResponse_Struct {
|
|||||||
/*0004*/ uint32 popupid;
|
/*0004*/ uint32 popupid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum GuildInformationActions
|
||||||
|
{
|
||||||
|
GuildUpdateURL = 0,
|
||||||
|
GuildUpdateChannel = 1,
|
||||||
|
GuildUpdateRanks = 4,
|
||||||
|
GuildUpdatePermissions = 5
|
||||||
|
};
|
||||||
|
|
||||||
struct GuildManageBanker_Struct {
|
struct GuildManageBanker_Struct {
|
||||||
uint32 unknown0;
|
uint32 unknown0;
|
||||||
char myname[64];
|
char myname[64];
|
||||||
@@ -1761,9 +1896,9 @@ struct GuildSetRank_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint32 Unknown00;
|
/*00*/ uint32 Unknown00;
|
||||||
/*04*/ uint32 Unknown04;
|
/*04*/ uint32 Unknown04;
|
||||||
/*08*/ uint32 Rank;
|
/*08*/ uint32 rank;
|
||||||
/*12*/ char MemberName[64];
|
/*12*/ char member_name[64];
|
||||||
/*76*/ uint32 Banker;
|
/*76*/ uint32 banker;
|
||||||
/*80*/
|
/*80*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1969,12 +2104,75 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
{
|
||||||
/*004*/ uint32 playerid;
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
/*004*/ uint32 player_id;
|
||||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
/*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*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MerchantActions {
|
||||||
|
Close = 0,
|
||||||
|
Open = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Parcel_Struct
|
||||||
|
{
|
||||||
|
/*000*/ uint32 npc_id;
|
||||||
|
/*004*/ uint32 item_slot;
|
||||||
|
/*008*/ uint32 quantity;
|
||||||
|
/*012*/ uint32 money_flag;
|
||||||
|
/*016*/ char send_to[64];
|
||||||
|
/*080*/ char note[128];
|
||||||
|
/*208*/ uint32 unknown_208;
|
||||||
|
/*212*/ uint32 unknown_212;
|
||||||
|
/*216*/ uint32 unknown_216;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParcelRetrieve_Struct
|
||||||
|
{
|
||||||
|
uint32 merchant_entity_id;
|
||||||
|
uint32 player_entity_id;
|
||||||
|
uint32 parcel_slot_id;
|
||||||
|
uint32 parcel_item_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParcelMessaging_Struct {
|
||||||
|
ItemPacketType packet_type;
|
||||||
|
std::string serialized_item;
|
||||||
|
uint32 sent_time;
|
||||||
|
std::string player_name;
|
||||||
|
std::string note;
|
||||||
|
uint32 slot_id;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(
|
||||||
|
CEREAL_NVP(packet_type),
|
||||||
|
CEREAL_NVP(serialized_item),
|
||||||
|
CEREAL_NVP(sent_time),
|
||||||
|
CEREAL_NVP(player_name),
|
||||||
|
CEREAL_NVP(note),
|
||||||
|
CEREAL_NVP(slot_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParcelIcon_Struct {
|
||||||
|
uint32 status; //0 off 1 on 2 overlimit
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ParcelIconActions {
|
||||||
|
IconOff = 0,
|
||||||
|
IconOn = 1,
|
||||||
|
Overlimit = 2
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unknowns:
|
Unknowns:
|
||||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||||
@@ -2559,7 +2757,10 @@ struct GMEmoteZone_Struct {
|
|||||||
struct BookText_Struct {
|
struct BookText_Struct {
|
||||||
uint8 window; // where to display the text (0xFF means new window)
|
uint8 window; // where to display the text (0xFF means new window)
|
||||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||||
uint32 invslot; // Only used in SoF and later clients.
|
int16 invslot; // Only used in SoF and later clients.
|
||||||
|
int32 target_id;
|
||||||
|
int8 can_cast;
|
||||||
|
int8 can_scribe;
|
||||||
char booktext[1]; // Variable Length
|
char booktext[1]; // Variable Length
|
||||||
};
|
};
|
||||||
// This is the request to read a book.
|
// This is the request to read a book.
|
||||||
@@ -2568,11 +2769,18 @@ struct BookText_Struct {
|
|||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
uint8 window; // where to display the text (0xFF means new window)
|
uint8 window; // where to display the text (0xFF means new window)
|
||||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||||
uint32 invslot; // Only used in Sof and later clients;
|
int16 invslot; // Only used in Sof and later clients;
|
||||||
int16 subslot; // The subslot inside of a bag if it is inside one.
|
int32 target_id;
|
||||||
char txtfile[20];
|
char txtfile[20];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
int16 invslot; // server slot
|
||||||
|
int32 target_id;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Object/Ground Spawn struct
|
** Object/Ground Spawn struct
|
||||||
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
||||||
@@ -2584,11 +2792,11 @@ struct BookRequest_Struct {
|
|||||||
struct Object_Struct {
|
struct Object_Struct {
|
||||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||||
/*08*/ float size; //
|
/*08*/ float size; //
|
||||||
/*10*/ uint16 solidtype; //
|
/*10*/ uint16 solid_type; //
|
||||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||||
/*18*/ uint16 zone_instance; //
|
/*18*/ uint16 zone_instance; //
|
||||||
/*20*/ uint32 unknown020; //
|
/*20*/ uint32 incline; //
|
||||||
/*24*/ uint32 unknown024; //
|
/*24*/ uint32 unknown024; //
|
||||||
/*28*/ float tilt_x;
|
/*28*/ float tilt_x;
|
||||||
/*32*/ float tilt_y;
|
/*32*/ float tilt_y;
|
||||||
@@ -3311,6 +3519,7 @@ struct Internal_GuildMemberEntry_Struct {
|
|||||||
// char public_note[1]; //variable length.
|
// char public_note[1]; //variable length.
|
||||||
uint16 zoneinstance; //network byte order
|
uint16 zoneinstance; //network byte order
|
||||||
uint16 zone_id; //network byte order
|
uint16 zone_id; //network byte order
|
||||||
|
uint32 online;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Internal_GuildMembers_Struct { //just for display purposes, this is not actually used in the message encoding.
|
struct Internal_GuildMembers_Struct { //just for display purposes, this is not actually used in the message encoding.
|
||||||
@@ -3337,7 +3546,42 @@ struct GuildUpdate_PublicNote{
|
|||||||
uint32 unknown0;
|
uint32 unknown0;
|
||||||
char name[64];
|
char name[64];
|
||||||
char target[64];
|
char target[64];
|
||||||
char note[1]; //variable length.
|
char note[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildUpdateURLAndChannelStruct {
|
||||||
|
char text[512];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildUpdatePermissionsStruct {
|
||||||
|
uint32 rank; // the rank that is being changed
|
||||||
|
uint32 function_id; // the id of the guild function
|
||||||
|
uint32 value; // 1 is on, 0 is off
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildUpdateRankNamesStruct {
|
||||||
|
uint32 rank; // the rank that is being updated
|
||||||
|
char rank_name[76]; // the rank name
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildUpdateUCPStruct {
|
||||||
|
uint32 action; // 0 and 1 use url and channel payload. 5 uses permissions payload
|
||||||
|
char unknown[76];
|
||||||
|
union {
|
||||||
|
GuildUpdateURLAndChannelStruct url_channel;
|
||||||
|
GuildUpdatePermissionsStruct permissions;
|
||||||
|
GuildUpdateRankNamesStruct rank_name;
|
||||||
|
}payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildPermission_Struct
|
||||||
|
{
|
||||||
|
uint32 Action; // 5 = Update function permission
|
||||||
|
char Unknown0004[76]; // not used
|
||||||
|
uint32 rank; // the rank that is being changed
|
||||||
|
uint32 function_id; // the id of the guild function
|
||||||
|
uint32 value; // 1 is on, 0 is off
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GuildUpdateURLAndChannel_Struct
|
struct GuildUpdateURLAndChannel_Struct
|
||||||
@@ -3356,7 +3600,7 @@ struct GuildUpdateURLAndChannel_Struct
|
|||||||
//The client sends this struct on changing a guild rank. The server sends each rank in 32 or less packets upon zonein if you are in a guild.
|
//The client sends this struct on changing a guild rank. The server sends each rank in 32 or less packets upon zonein if you are in a guild.
|
||||||
struct GuildUpdateRanks_Struct
|
struct GuildUpdateRanks_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint32 Action; // 0 = Update URL, 1 = Update Channel, 5 = RoF Ranks
|
/*0000*/ uint32 Action; // 0 = Update URL, 1 = Update Channel, 4 = Ranks 5 = Permissions
|
||||||
/*0004*/ uint32 Unknown0004; //Seen 00 00 00 00
|
/*0004*/ uint32 Unknown0004; //Seen 00 00 00 00
|
||||||
/*0008*/ uint32 Unknown0008; //Seen 96 29 00 00
|
/*0008*/ uint32 Unknown0008; //Seen 96 29 00 00
|
||||||
/*0008*/ char Unknown0012[64]; //Seen "CharacterName"
|
/*0008*/ char Unknown0012[64]; //Seen "CharacterName"
|
||||||
@@ -3378,6 +3622,7 @@ struct GuildStatus_Struct
|
|||||||
struct GuildDemoteStruct{
|
struct GuildDemoteStruct{
|
||||||
char name[64];
|
char name[64];
|
||||||
char target[64];
|
char target[64];
|
||||||
|
uint32 rank;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GuildRemoveStruct{
|
struct GuildRemoveStruct{
|
||||||
@@ -3387,9 +3632,9 @@ struct GuildRemoveStruct{
|
|||||||
uint32 leaderstatus; //?
|
uint32 leaderstatus; //?
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GuildMakeLeader{
|
struct GuildMakeLeader_Struct{
|
||||||
char name[64];
|
char requestor[64];
|
||||||
char target[64];
|
char new_leader[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BugReport_Struct {
|
struct BugReport_Struct {
|
||||||
@@ -3429,20 +3674,23 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
|
||||||
float max_x;
|
struct GroundSpawn {
|
||||||
float max_y;
|
float max_x = 0.0f;
|
||||||
float min_x;
|
float max_y = 0.0f;
|
||||||
float min_y;
|
float min_x = 0.0f;
|
||||||
float max_z;
|
float min_y = 0.0f;
|
||||||
float heading;
|
float max_z = 0.0f;
|
||||||
char name[20];
|
float heading = 0.0f;
|
||||||
uint32 item;
|
std::string name = std::string();
|
||||||
uint32 max_allowed;
|
uint32 item_id = 0;
|
||||||
uint32 respawntimer;
|
uint32 max_allowed = 1;
|
||||||
|
uint32 respawn_timer = 1;
|
||||||
|
bool fix_z = true;
|
||||||
};
|
};
|
||||||
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{
|
//struct PetitionBug_Struct{
|
||||||
@@ -3480,66 +3728,193 @@ struct ZoneInSendName_Struct2 {
|
|||||||
static const uint32 MAX_TRIBUTE_TIERS = 10;
|
static const uint32 MAX_TRIBUTE_TIERS = 10;
|
||||||
|
|
||||||
struct StartTribute_Struct {
|
struct StartTribute_Struct {
|
||||||
uint32 client_id;
|
uint32 client_id;
|
||||||
uint32 tribute_master_id;
|
uint32 tribute_master_id;
|
||||||
uint32 response;
|
uint32 response;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributeLevel_Struct {
|
struct TributeLevel_Struct {
|
||||||
uint32 level; //backwards byte order!
|
uint32 level; //backwards byte order!
|
||||||
uint32 tribute_item_id; //backwards byte order!
|
uint32 tribute_item_id; //backwards byte order!
|
||||||
uint32 cost; //backwards byte order!
|
uint32 cost; //backwards byte order!
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributeAbility_Struct {
|
struct TributeAbility_Struct {
|
||||||
uint32 tribute_id; //backwards byte order!
|
uint32 tribute_id; //backwards byte order!
|
||||||
uint32 tier_count; //backwards byte order!
|
uint32 tier_count; //backwards byte order!
|
||||||
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
|
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
|
||||||
char name[0];
|
char name[0];
|
||||||
};
|
|
||||||
|
|
||||||
struct GuildTributeAbility_Struct {
|
|
||||||
uint32 guild_id;
|
|
||||||
TributeAbility_Struct ability;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SelectTributeReq_Struct {
|
struct SelectTributeReq_Struct {
|
||||||
uint32 client_id; //? maybe action ID?
|
uint32 client_id; //? maybe action ID?
|
||||||
uint32 tribute_id;
|
uint32 tribute_id;
|
||||||
uint32 unknown8; //seen E3 00 00 00
|
uint32 unknown8; //seen E3 00 00 00
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeAbilityDetail_Struct {
|
||||||
|
uint32 tribute_id; //backwards byte order!
|
||||||
|
uint32 tier_count; //backwards byte order!
|
||||||
|
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
|
||||||
|
uint32 unknown132;
|
||||||
|
char name[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeAbility_Struct {
|
||||||
|
uint32 guild_id;
|
||||||
|
GuildTributeAbilityDetail_Struct ability;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeSelectReq_Struct {
|
||||||
|
uint32 tribute_id;
|
||||||
|
uint32 tier;
|
||||||
|
uint32 tribute_id2;
|
||||||
|
uint32 unknown12; //seen A7 01 00 00
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeSelectReply_Struct {
|
||||||
|
uint32 tribute_id;
|
||||||
|
uint32 tier;
|
||||||
|
uint32 tribute_id2;
|
||||||
|
char description;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeModifyBenefits_Struct {
|
||||||
|
/*000*/uint32 command;
|
||||||
|
/*004*/uint32 data;
|
||||||
|
/*008*/char unknown8[12];
|
||||||
|
/*020*/uint32 tribute_master_id;
|
||||||
|
/*024*/uint32 tribute_id_1;
|
||||||
|
/*028*/uint32 tribute_id_2;
|
||||||
|
/*032*/uint32 tribute_id_1_tier;
|
||||||
|
/*036*/uint32 tribute_id_2_tier;
|
||||||
|
/*040*/char unknown[40];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeOptInOutReq_Struct {
|
||||||
|
/*000*/uint32 guild_id;
|
||||||
|
/*004*/uint32 tribute_toggle;
|
||||||
|
/*008*/char player[64];
|
||||||
|
/*072*/uint32 command;
|
||||||
|
/*076*/uint32 tribute_master_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeOptInOutReply_Struct {
|
||||||
|
/*000*/uint32 guild_id;
|
||||||
|
/*004*/char player_name[64];
|
||||||
|
/*068*/uint32 tribute_toggle;// 0 off 1 on
|
||||||
|
/*072*/uint32 tribute_trophy_toggle;// 0 off 1 on not yet implemented
|
||||||
|
/*076*/uint32 no_donations;
|
||||||
|
/*080*/uint32 time;
|
||||||
|
/*084*/uint32 command;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeSaveActive_Struct {
|
||||||
|
/*000*/ uint32 command;
|
||||||
|
/*004*/ char unknown04[16];
|
||||||
|
/*020*/ uint32 master_tribute_id;
|
||||||
|
/*024*/ uint32 tribute_id_1;
|
||||||
|
/*028*/ uint32 tribute_id_2;
|
||||||
|
/*032*/ uint32 tribute_1_tier;
|
||||||
|
/*036*/ uint32 tribute_2_tier;
|
||||||
|
/*040*/ char unknown40[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeFavorTimer_Struct {
|
||||||
|
/*000*/ uint32 guild_id;
|
||||||
|
/*004*/ uint32 guild_favor;
|
||||||
|
/*008*/ uint32 tribute_timer;
|
||||||
|
/*012*/ uint32 trophy_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeSendActive_Struct {
|
||||||
|
/*000*/ uint32 not_used;
|
||||||
|
/*004*/ uint32 guild_favor;
|
||||||
|
/*008*/ uint32 tribute_timer;
|
||||||
|
/*012*/ uint32 tribute_enabled;
|
||||||
|
/*016*/ char unknown16[8];
|
||||||
|
/*024*/ uint32 tribute_id_1;
|
||||||
|
/*028*/ uint32 tribute_id_2;
|
||||||
|
/*032*/ uint32 tribute_id_1_tier;
|
||||||
|
/*036*/ uint32 tribute_id_2_tier;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeToggleReq_Struct {
|
||||||
|
/*000*/ uint32 command;
|
||||||
|
/*004*/ uint32 unknown4;
|
||||||
|
/*008*/ uint32 unknown8;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeDonatePlatRequest_Struct {
|
||||||
|
/*000*/ uint32 quantity;
|
||||||
|
/*004*/ uint32 tribute_master_id;
|
||||||
|
/*008*/ uint32 unknown08;
|
||||||
|
/*012*/ uint32 guild_id;
|
||||||
|
/*016*/ uint32 unknown16;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GuildTributeDonatePlatReply_Struct {
|
||||||
|
/*000*/ uint32 quantity;
|
||||||
|
/*004*/ uint32 unknown4;
|
||||||
|
/*008*/ uint32 favor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SelectTributeReply_Struct {
|
struct SelectTributeReply_Struct {
|
||||||
uint32 client_id; //echoed from request.
|
uint32 client_id; //echoed from request.
|
||||||
uint32 tribute_id;
|
uint32 tribute_id;
|
||||||
char desc[0];
|
char description[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributeInfo_Struct {
|
struct TributeInfo_Struct {
|
||||||
uint32 active; //0 == inactive, 1 == active
|
uint32 active; //0 == inactive, 1 == active
|
||||||
uint32 tributes[EQ::invtype::TRIBUTE_SIZE]; //-1 == NONE
|
uint32 tributes[EQ::invtype::TRIBUTE_SIZE]; //-1 == NONE
|
||||||
uint32 tiers[EQ::invtype::TRIBUTE_SIZE]; //all 00's
|
uint32 tiers[EQ::invtype::TRIBUTE_SIZE]; //all 00's
|
||||||
uint32 tribute_master_id;
|
uint32 tribute_master_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributeItem_Struct {
|
struct TributeItem_Struct {
|
||||||
uint32 slot;
|
uint32 slot;
|
||||||
uint32 quantity;
|
uint32 quantity;
|
||||||
uint32 tribute_master_id;
|
uint32 tribute_master_id;
|
||||||
int32 tribute_points;
|
int32 tribute_points;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributePoint_Struct {
|
struct TributePoint_Struct {
|
||||||
int32 tribute_points;
|
int32 tribute_points;
|
||||||
uint32 unknown04;
|
uint32 unknown04;
|
||||||
int32 career_tribute_points;
|
int32 career_tribute_points;
|
||||||
uint32 unknown12;
|
uint32 unknown12;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributeMoney_Struct {
|
struct TributeMoney_Struct {
|
||||||
uint32 platinum;
|
uint32 platinum;
|
||||||
uint32 tribute_master_id;
|
uint32 tribute_master_id;
|
||||||
int32 tribute_points;
|
int32 tribute_points;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -4105,7 +4480,9 @@ struct UpdateLeadershipAA_Struct {
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
GroupLeadershipAbility_MarkNPC = 0
|
GroupLeadershipAbility_MarkNPC = 0,
|
||||||
|
RaidLeadershipAbility_MarkNPC = 16,
|
||||||
|
RaidLeadershipAbility_MainAssist = 19
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DoGroupLeadershipAbility_Struct
|
struct DoGroupLeadershipAbility_Struct
|
||||||
@@ -4149,8 +4526,9 @@ struct InspectBuffs_Struct {
|
|||||||
struct RaidGeneral_Struct {
|
struct RaidGeneral_Struct {
|
||||||
/*00*/ uint32 action; //=10
|
/*00*/ uint32 action; //=10
|
||||||
/*04*/ char player_name[64]; //should both be the player's name
|
/*04*/ char player_name[64]; //should both be the player's name
|
||||||
/*64*/ char leader_name[64];
|
/*68*/ uint32 unknown1;
|
||||||
/*132*/ uint32 parameter;
|
/*72*/ char leader_name[64];
|
||||||
|
/*136*/ uint32 parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidAddMember_Struct {
|
struct RaidAddMember_Struct {
|
||||||
@@ -4161,9 +4539,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general;
|
||||||
/*136*/ char motd[0]; // max size is 1024, but reply is variable
|
/*140*/ char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
@@ -5110,8 +5493,6 @@ struct GroupMakeLeader_Struct
|
|||||||
//ex for a blank crowns window you would send:
|
//ex for a blank crowns window you would send:
|
||||||
//999999|1|999999|0
|
//999999|1|999999|0
|
||||||
//any items come after in much the same way adventure merchant items do except there is no theme included
|
//any items come after in much the same way adventure merchant items do except there is no theme included
|
||||||
#define ALT_CURRENCY_OP_POPULATE 8
|
|
||||||
#define ALT_CURRENCY_OP_UPDATE 7
|
|
||||||
|
|
||||||
//Server -> Client
|
//Server -> Client
|
||||||
//Populates the initial Alternate Currency Window
|
//Populates the initial Alternate Currency Window
|
||||||
@@ -5522,28 +5903,6 @@ struct MercenaryMerchantResponse_Struct {
|
|||||||
/*0004*/
|
/*0004*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerLootItem_Struct {
|
|
||||||
uint32 item_id; // uint32 item_id;
|
|
||||||
int16 equip_slot; // int16 equip_slot;
|
|
||||||
uint16 charges; // uint8 charges;
|
|
||||||
uint16 lootslot; // uint16 lootslot;
|
|
||||||
uint32 aug_1; // uint32 aug_1;
|
|
||||||
uint32 aug_2; // uint32 aug_2;
|
|
||||||
uint32 aug_3; // uint32 aug_3;
|
|
||||||
uint32 aug_4; // uint32 aug_4;
|
|
||||||
uint32 aug_5; // uint32 aug_5;
|
|
||||||
uint32 aug_6; // uint32 aug_5;
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Found in client near a ref to the string:
|
//Found in client near a ref to the string:
|
||||||
//"Got a broadcast message for ... %s ...\n"
|
//"Got a broadcast message for ... %s ...\n"
|
||||||
struct ClientMarqueeMessage_Struct {
|
struct ClientMarqueeMessage_Struct {
|
||||||
@@ -5562,9 +5921,6 @@ struct ClientMarqueeMessage_Struct {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<ServerLootItem_Struct*> ItemList;
|
|
||||||
|
|
||||||
|
|
||||||
struct fling_struct {
|
struct fling_struct {
|
||||||
/* 00 */ uint32 collision; // 0 collision is off, anything else it's on
|
/* 00 */ uint32 collision; // 0 collision is off, anything else it's on
|
||||||
/* 04 */ int32 travel_time; // ms -- UF we need to calc this, RoF+ -1 auto calcs
|
/* 04 */ int32 travel_time; // ms -- UF we need to calc this, RoF+ -1 auto calcs
|
||||||
|
|||||||
+116
-15
@@ -20,9 +20,12 @@
|
|||||||
#include "eqemu_config.h"
|
#include "eqemu_config.h"
|
||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
#include "eqemu_logsys.h"
|
||||||
|
#include "json/json.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||||
@@ -85,6 +88,12 @@ void EQEmuConfig::parse_config()
|
|||||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||||
Locked = false;
|
Locked = false;
|
||||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||||
|
|
||||||
|
auto_database_updates = false;
|
||||||
|
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
|
||||||
|
auto_database_updates = true;
|
||||||
|
}
|
||||||
|
|
||||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||||
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
||||||
|
|
||||||
@@ -105,13 +114,12 @@ void EQEmuConfig::parse_config()
|
|||||||
DisableConfigChecks = true;
|
DisableConfigChecks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* UCS
|
|
||||||
*/
|
CheckUcsConfigConversion();
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
|
||||||
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
|
m_ucs_host = _root["server"]["ucs"].get("host", "eqchat.eqemulator.net").asString();
|
||||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
m_ucs_port = Strings::ToUnsignedInt(_root["server"]["ucs"].get("port", "7778").asString());
|
||||||
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database
|
* Database
|
||||||
@@ -240,16 +248,16 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
|||||||
return (WorldHTTPEnabled ? "true" : "false");
|
return (WorldHTTPEnabled ? "true" : "false");
|
||||||
}
|
}
|
||||||
if (var_name == "ChatHost") {
|
if (var_name == "ChatHost") {
|
||||||
return (ChatHost);
|
return (m_ucs_host);
|
||||||
}
|
}
|
||||||
if (var_name == "ChatPort") {
|
if (var_name == "ChatPort") {
|
||||||
return (itoa(ChatPort));
|
return (itoa(m_ucs_port));
|
||||||
}
|
}
|
||||||
if (var_name == "MailHost") {
|
if (var_name == "MailHost") {
|
||||||
return (MailHost);
|
return (m_ucs_host);
|
||||||
}
|
}
|
||||||
if (var_name == "MailPort") {
|
if (var_name == "MailPort") {
|
||||||
return (itoa(MailPort));
|
return (itoa(m_ucs_port));
|
||||||
}
|
}
|
||||||
if (var_name == "DatabaseHost") {
|
if (var_name == "DatabaseHost") {
|
||||||
return (DatabaseHost);
|
return (DatabaseHost);
|
||||||
@@ -356,10 +364,8 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
|
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
|
||||||
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
|
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
|
||||||
std::cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << std::endl;
|
std::cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << std::endl;
|
||||||
std::cout << "ChatHost = " << ChatHost << std::endl;
|
std::cout << "UCSHost = " << m_ucs_host << std::endl;
|
||||||
std::cout << "ChatPort = " << ChatPort << std::endl;
|
std::cout << "UCSPort = " << m_ucs_port << std::endl;
|
||||||
std::cout << "MailHost = " << MailHost << std::endl;
|
|
||||||
std::cout << "MailPort = " << MailPort << std::endl;
|
|
||||||
std::cout << "DatabaseHost = " << DatabaseHost << std::endl;
|
std::cout << "DatabaseHost = " << DatabaseHost << std::endl;
|
||||||
std::cout << "DatabaseUsername = " << DatabaseUsername << std::endl;
|
std::cout << "DatabaseUsername = " << DatabaseUsername << std::endl;
|
||||||
std::cout << "DatabasePassword = " << DatabasePassword << std::endl;
|
std::cout << "DatabasePassword = " << DatabasePassword << std::endl;
|
||||||
@@ -386,3 +392,98 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
||||||
// std::cout << "DynamicCount = " << DynamicCount << 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;
|
std::string SharedKey;
|
||||||
bool DisableConfigChecks;
|
bool DisableConfigChecks;
|
||||||
|
|
||||||
// From <chatserver/>
|
|
||||||
std::string ChatHost;
|
|
||||||
uint16 ChatPort;
|
|
||||||
|
|
||||||
// From <mailserver/>
|
|
||||||
std::string MailHost;
|
|
||||||
uint16 MailPort;
|
|
||||||
|
|
||||||
// From <database/>
|
// From <database/>
|
||||||
std::string DatabaseHost;
|
std::string DatabaseHost;
|
||||||
std::string DatabaseUsername;
|
std::string DatabaseUsername;
|
||||||
@@ -120,12 +112,20 @@ class EQEmuConfig
|
|||||||
uint16 ZonePortHigh;
|
uint16 ZonePortHigh;
|
||||||
uint8 DefaultStatus;
|
uint8 DefaultStatus;
|
||||||
|
|
||||||
|
bool auto_database_updates;
|
||||||
|
|
||||||
|
const std::string &GetUCSHost() const;
|
||||||
|
uint16 GetUCSPort() const;
|
||||||
|
|
||||||
// uint16 DynamicCount;
|
// uint16 DynamicCount;
|
||||||
|
|
||||||
// map<string,uint16> StaticZones;
|
// map<string,uint16> StaticZones;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
std::string m_ucs_host;
|
||||||
|
uint16 m_ucs_port;
|
||||||
|
|
||||||
static EQEmuConfig *_config;
|
static EQEmuConfig *_config;
|
||||||
Json::Value _root;
|
Json::Value _root;
|
||||||
static std::string ConfigFile;
|
static std::string ConfigFile;
|
||||||
@@ -184,6 +184,7 @@ class EQEmuConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
void CheckUcsConfigConversion();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+107
-28
@@ -100,13 +100,15 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
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_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::EqTime].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RFC 5424
|
* RFC 5424
|
||||||
*/
|
*/
|
||||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Category enabled status on defaults
|
* Set Category enabled status on defaults
|
||||||
@@ -219,7 +221,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
|||||||
int line
|
int line
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool is_error = (
|
bool is_error = (
|
||||||
log_category == Logs::LogCategory::Error ||
|
log_category == Logs::LogCategory::Error ||
|
||||||
log_category == Logs::LogCategory::MySQLError ||
|
log_category == Logs::LogCategory::MySQLError ||
|
||||||
log_category == Logs::LogCategory::Crash ||
|
log_category == Logs::LogCategory::Crash ||
|
||||||
@@ -261,7 +263,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (log_category == Logs::LogCategory::MySQLQuery) {
|
if (log_category == Logs::LogCategory::MySQLQuery) {
|
||||||
auto s = Strings::Split(message, "--");
|
auto s = Strings::Split(message, "--");
|
||||||
if (s.size() > 1) {
|
if (s.size() > 1) {
|
||||||
std::string query = Strings::Trim(s[0]);
|
std::string query = Strings::Trim(s[0]);
|
||||||
std::string meta = Strings::Trim(s[1]);
|
std::string meta = Strings::Trim(s[1]);
|
||||||
@@ -297,19 +299,76 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_upper) {
|
// color matching in []
|
||||||
(!is_error ? std::cout : std::cerr)
|
// ex: [<red>variable] would produce [variable] with red inside brackets
|
||||||
<< rang::fgB::gray
|
std::map<std::string, rang::fgB> colors = {
|
||||||
<< "["
|
{"<black>", rang::fgB::black},
|
||||||
<< rang::style::bold
|
{"<green>", rang::fgB::green},
|
||||||
<< rang::fgB::yellow
|
{"<yellow>", rang::fgB::yellow},
|
||||||
<< e
|
{"<blue>", rang::fgB::blue},
|
||||||
<< rang::fgB::gray
|
{"<magenta>", rang::fgB::magenta},
|
||||||
<< "] "
|
{"<cyan>", rang::fgB::cyan},
|
||||||
;
|
{"<gray>", rang::fgB::gray},
|
||||||
|
{"<red>", rang::fgB::red},
|
||||||
|
};
|
||||||
|
|
||||||
|
bool match_color = false;
|
||||||
|
for (auto &c: colors) {
|
||||||
|
if (Strings::Contains(e, c.first)) {
|
||||||
|
e = Strings::Replace(e, c.first, "");
|
||||||
|
(!is_error ? std::cout : std::cerr)
|
||||||
|
<< rang::fgB::gray
|
||||||
|
<< "["
|
||||||
|
<< rang::style::bold
|
||||||
|
<< c.second
|
||||||
|
<< e
|
||||||
|
<< rang::style::reset
|
||||||
|
<< rang::fgB::gray
|
||||||
|
<< "] ";
|
||||||
|
match_color = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
// string match to colors
|
||||||
|
std::map<std::string, rang::fgB> matches = {
|
||||||
|
{"missing", rang::fgB::red},
|
||||||
|
{"error", rang::fgB::red},
|
||||||
|
{"ok", rang::fgB::green},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &c: matches) {
|
||||||
|
if (Strings::Contains(e, c.first)) {
|
||||||
|
(!is_error ? std::cout : std::cerr)
|
||||||
|
<< rang::fgB::gray
|
||||||
|
<< "["
|
||||||
|
<< rang::style::bold
|
||||||
|
<< c.second
|
||||||
|
<< e
|
||||||
|
<< rang::style::reset
|
||||||
|
<< rang::fgB::gray
|
||||||
|
<< "] ";
|
||||||
|
match_color = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't match a color in either the string matching or
|
||||||
|
// the color tag matching, we default to yellow inside brackets
|
||||||
|
// if uppercase, does not get colored
|
||||||
|
if (!match_color) {
|
||||||
|
if (!is_upper) {
|
||||||
|
(!is_error ? std::cout : std::cerr)
|
||||||
|
<< rang::fgB::gray
|
||||||
|
<< "["
|
||||||
|
<< rang::style::bold
|
||||||
|
<< rang::fgB::yellow
|
||||||
|
<< e
|
||||||
|
<< rang::style::reset
|
||||||
|
<< rang::fgB::gray
|
||||||
|
<< "] ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -389,6 +448,8 @@ void EQEmuLogSys::Out(
|
|||||||
// remove this when we remove all legacy logs
|
// remove this when we remove all legacy logs
|
||||||
bool ignore_log_legacy_format = (
|
bool ignore_log_legacy_format = (
|
||||||
log_category == Logs::Netcode ||
|
log_category == Logs::Netcode ||
|
||||||
|
log_category == Logs::MySQLQuery ||
|
||||||
|
log_category == Logs::MySQLError ||
|
||||||
log_category == Logs::PacketServerClient ||
|
log_category == Logs::PacketServerClient ||
|
||||||
log_category == Logs::PacketClientServer ||
|
log_category == Logs::PacketClientServer ||
|
||||||
log_category == Logs::PacketServerToServer
|
log_category == Logs::PacketServerToServer
|
||||||
@@ -523,6 +584,8 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
*/
|
*/
|
||||||
void EQEmuLogSys::SilenceConsoleLogging()
|
void EQEmuLogSys::SilenceConsoleLogging()
|
||||||
{
|
{
|
||||||
|
std::copy(std::begin(log_settings), std::end(log_settings), std::begin(pre_silence_settings));
|
||||||
|
|
||||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||||
log_settings[log_index].log_to_console = 0;
|
log_settings[log_index].log_to_console = 0;
|
||||||
log_settings[log_index].is_category_enabled = 0;
|
log_settings[log_index].is_category_enabled = 0;
|
||||||
@@ -536,10 +599,7 @@ void EQEmuLogSys::SilenceConsoleLogging()
|
|||||||
*/
|
*/
|
||||||
void EQEmuLogSys::EnableConsoleLogging()
|
void EQEmuLogSys::EnableConsoleLogging()
|
||||||
{
|
{
|
||||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
std::copy(std::begin(pre_silence_settings), std::end(pre_silence_settings), std::begin(log_settings));
|
||||||
log_settings[log_index].log_to_console = Logs::General;
|
|
||||||
log_settings[log_index].is_category_enabled = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||||
@@ -591,6 +651,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto inject categories that don't exist in the database...
|
// 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++) {
|
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();
|
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||||
@@ -605,11 +668,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_missing_in_database && !is_deprecated_category) {
|
if (is_missing_in_database && !is_deprecated_category) {
|
||||||
LogInfo(
|
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
|
||||||
"Automatically adding new log category [{}] ({})",
|
|
||||||
Logs::LogCategoryName[i],
|
|
||||||
i
|
|
||||||
);
|
|
||||||
|
|
||||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||||
new_category.log_category_id = i;
|
new_category.log_category_id = i;
|
||||||
@@ -618,11 +677,16 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
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_file = log_settings[i].log_to_file;
|
||||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
new_category.log_to_discord = log_settings[i].log_to_discord;
|
||||||
|
db_categories_to_add.emplace_back(new_category);
|
||||||
LogsysCategoriesRepository::InsertOne(*m_database, 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());
|
LogInfo("Loaded [{}] log categories", categories.size());
|
||||||
|
|
||||||
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
||||||
@@ -637,6 +701,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Crash].log_to_gmsay = 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::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;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -741,3 +807,16 @@ EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EQEmuLogSys::DisableMySQLErrorLogs()
|
||||||
|
{
|
||||||
|
log_settings[Logs::MySQLError].log_to_file = 0;
|
||||||
|
log_settings[Logs::MySQLError].log_to_console = 0;
|
||||||
|
log_settings[Logs::MySQLError].log_to_gmsay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQEmuLogSys::EnableMySQLErrorLogs()
|
||||||
|
{
|
||||||
|
log_settings[Logs::MySQLError].log_to_file = 1;
|
||||||
|
log_settings[Logs::MySQLError].log_to_console = 1;
|
||||||
|
log_settings[Logs::MySQLError].log_to_gmsay = 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -137,6 +137,11 @@ namespace Logs {
|
|||||||
Bugs,
|
Bugs,
|
||||||
QuestErrors,
|
QuestErrors,
|
||||||
PlayerEvents,
|
PlayerEvents,
|
||||||
|
DataBuckets,
|
||||||
|
Zoning,
|
||||||
|
EqTime,
|
||||||
|
Corpses,
|
||||||
|
XTargets,
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -233,6 +238,11 @@ namespace Logs {
|
|||||||
"Bugs",
|
"Bugs",
|
||||||
"QuestErrors",
|
"QuestErrors",
|
||||||
"PlayerEvents",
|
"PlayerEvents",
|
||||||
|
"DataBuckets",
|
||||||
|
"Zoning",
|
||||||
|
"EqTime",
|
||||||
|
"Corpses",
|
||||||
|
"XTargets"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,6 +334,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||||
|
|
||||||
|
// temporary bucket to re-load after silencing
|
||||||
|
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||||
|
|
||||||
struct LogEnabled {
|
struct LogEnabled {
|
||||||
bool log_to_file_enabled;
|
bool log_to_file_enabled;
|
||||||
bool log_to_console_enabled;
|
bool log_to_console_enabled;
|
||||||
@@ -374,6 +387,9 @@ public:
|
|||||||
[[nodiscard]] const std::string &GetLogPath() const;
|
[[nodiscard]] const std::string &GetLogPath() const;
|
||||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
||||||
|
|
||||||
|
void DisableMySQLErrorLogs();
|
||||||
|
void EnableMySQLErrorLogs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// reference to database
|
// reference to database
|
||||||
|
|||||||
@@ -794,6 +794,56 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogDataBuckets(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::DataBuckets))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogDataBucketsDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DataBuckets))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogZoning(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::Zoning))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogZoningDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Zoning))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogEqTime(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::EqTime))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogEqTimeDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EqTime))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define 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 {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
|||||||
+51
-7
@@ -46,16 +46,16 @@ EQTime::EQTime()
|
|||||||
timezone = 0;
|
timezone = 0;
|
||||||
memset(&eqTime, 0, sizeof(eqTime));
|
memset(&eqTime, 0, sizeof(eqTime));
|
||||||
//Defaults for time
|
//Defaults for time
|
||||||
TimeOfDay_Struct start;
|
TimeOfDay_Struct t{};
|
||||||
start.day = 1;
|
t.day = 1;
|
||||||
start.hour = 9;
|
t.hour = 9;
|
||||||
start.minute = 0;
|
t.minute = 0;
|
||||||
start.month = 1;
|
t.month = 1;
|
||||||
start.year = 3100;
|
t.year = 3100;
|
||||||
//Set default time zone
|
//Set default time zone
|
||||||
timezone = 0;
|
timezone = 0;
|
||||||
//Start EQTimer
|
//Start EQTimer
|
||||||
SetCurrentEQTimeOfDay(start, time(0));
|
SetCurrentEQTimeOfDay(t, time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
//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';
|
buf[127] = '\0';
|
||||||
str = buf;
|
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 getEQTimeZone() { return timezone; }
|
||||||
uint32 getEQTimeZoneHr() { return timezone/60; }
|
uint32 getEQTimeZoneHr() { return timezone/60; }
|
||||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||||
|
bool IsDayTime();
|
||||||
|
bool IsNightTime();
|
||||||
|
bool IsInbetweenTime(uint8 min_time, uint8 max_time);
|
||||||
|
|
||||||
//Set functions
|
//Set functions
|
||||||
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
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
|
|
||||||
@@ -37,6 +37,8 @@ void PlayerEventLogs::Init()
|
|||||||
db.emplace_back(e.id);
|
db.emplace_back(e.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
||||||
|
|
||||||
// insert entries that don't exist in database
|
// insert entries that don't exist in database
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
bool is_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();
|
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
||||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
||||||
LogInfo(
|
LogInfo("[New] PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||||
"[New] PlayerEvent [{}] ({})",
|
|
||||||
PlayerEvent::EventName[i],
|
|
||||||
i
|
|
||||||
);
|
|
||||||
|
|
||||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
||||||
c.id = i;
|
c.id = i;
|
||||||
c.event_name = PlayerEvent::EventName[i];
|
c.event_name = PlayerEvent::EventName[i];
|
||||||
c.event_enabled = m_settings[i].event_enabled;
|
c.event_enabled = m_settings[i].event_enabled;
|
||||||
c.retention_days = m_settings[i].retention_days;
|
c.retention_days = m_settings[i].retention_days;
|
||||||
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_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||||
|
|
||||||
@@ -611,7 +613,7 @@ void PlayerEventLogs::Process()
|
|||||||
|
|
||||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||||
{
|
{
|
||||||
LogInfo("Running truncation");
|
LogPlayerEvents("Running truncation");
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
if (m_settings[i].retention_days > 0) {
|
if (m_settings[i].retention_days > 0) {
|
||||||
@@ -695,6 +697,11 @@ void PlayerEventLogs::SetSettingsDefaults()
|
|||||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||||
m_settings[PlayerEvent::ITEM_CREATION].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;
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ namespace PlayerEvent {
|
|||||||
KILLED_NAMED_NPC,
|
KILLED_NAMED_NPC,
|
||||||
KILLED_RAID_NPC,
|
KILLED_RAID_NPC,
|
||||||
ITEM_CREATION,
|
ITEM_CREATION,
|
||||||
|
GUILD_TRIBUTE_DONATE_ITEM,
|
||||||
|
GUILD_TRIBUTE_DONATE_PLAT,
|
||||||
|
PARCEL_SEND,
|
||||||
|
PARCEL_RETRIEVE,
|
||||||
|
PARCEL_DELETE,
|
||||||
MAX // dont remove
|
MAX // dont remove
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,7 +69,7 @@ namespace PlayerEvent {
|
|||||||
// If event is unimplemented just tag (Unimplemented) in the name
|
// If event is unimplemented just tag (Unimplemented) in the name
|
||||||
// Events don't get saved to the database if unimplemented or deprecated
|
// Events don't get saved to the database if unimplemented or deprecated
|
||||||
// Events tagged as deprecated will get automatically removed
|
// Events tagged as deprecated will get automatically removed
|
||||||
static const char *EventName[PlayerEvent::MAX] = {
|
static const char *EventName[EventType::MAX] = {
|
||||||
"None",
|
"None",
|
||||||
"GM Command",
|
"GM Command",
|
||||||
"Zoning",
|
"Zoning",
|
||||||
@@ -112,7 +117,12 @@ namespace PlayerEvent {
|
|||||||
"Killed NPC",
|
"Killed NPC",
|
||||||
"Killed Named NPC",
|
"Killed Named NPC",
|
||||||
"Killed Raid 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"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic struct used by all events
|
// Generic struct used by all events
|
||||||
@@ -942,6 +952,135 @@ 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENTS_H
|
#endif //EQEMU_PLAYER_EVENTS_H
|
||||||
|
|||||||
+2
-2
@@ -96,12 +96,12 @@ bool IsOfEqualRace(int r1, int r2)
|
|||||||
// TODO: add more values
|
// TODO: add more values
|
||||||
switch (r1) {
|
switch (r1) {
|
||||||
case DARK_ELF:
|
case DARK_ELF:
|
||||||
if (r2 == RACE_NERIAK_CITIZEN_77) {
|
if (r2 == Race::NeriakCitizen) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BARBARIAN:
|
case BARBARIAN:
|
||||||
if (r2 == RACE_HALAS_CITIZEN_90) {
|
if (r2 == Race::HalasCitizen) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-27
@@ -24,17 +24,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum FACTION_VALUE {
|
enum FACTION_VALUE {
|
||||||
FACTION_ALLY = 1,
|
FACTION_ALLY = 1,
|
||||||
FACTION_WARMLY = 2,
|
FACTION_WARMLY = 2,
|
||||||
FACTION_KINDLY = 3,
|
FACTION_KINDLY = 3,
|
||||||
FACTION_AMIABLY = 4,
|
FACTION_AMIABLY = 4,
|
||||||
|
FACTION_INDIFFERENTLY = 5,
|
||||||
FACTION_INDIFFERENTLY = 5,
|
|
||||||
|
|
||||||
FACTION_APPREHENSIVELY = 6,
|
FACTION_APPREHENSIVELY = 6,
|
||||||
FACTION_DUBIOUSLY = 7,
|
FACTION_DUBIOUSLY = 7,
|
||||||
FACTION_THREATENINGLY = 8,
|
FACTION_THREATENINGLY = 8,
|
||||||
FACTION_SCOWLS = 9
|
FACTION_SCOWLS = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NPCFactionList {
|
struct NPCFactionList {
|
||||||
@@ -75,23 +73,6 @@ struct NPCFaction
|
|||||||
uint8 temp;
|
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);
|
const char *FactionValueToString(FACTION_VALUE faction_value);
|
||||||
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
||||||
#endif
|
#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
|
#ifdef EMBPERL
|
||||||
//Enable the new XS based perl parser
|
//Enable the new XS based perl parser
|
||||||
#define EMBPERL_XS
|
#define EMBPERL_XS
|
||||||
@@ -238,41 +233,6 @@ enum { //some random constants
|
|||||||
// Timer to update aggrometer
|
// Timer to update aggrometer
|
||||||
#define AGGRO_METER_UPDATE_MS 1000
|
#define AGGRO_METER_UPDATE_MS 1000
|
||||||
|
|
||||||
//Some hard coded statuses from commands and other places:
|
|
||||||
enum {
|
|
||||||
minStatusToBeGM = 40,
|
|
||||||
minStatusToUseGMCommands = 80,
|
|
||||||
minStatusToKick = 150,
|
|
||||||
minStatusToAvoidFalling = 100,
|
|
||||||
minStatusToHaveInvalidSpells = 80,
|
|
||||||
minStatusToHaveInvalidSkills = 80,
|
|
||||||
minStatusToIgnoreZoneFlags = 80,
|
|
||||||
minStatusToSeeOthersZoneFlags = 80,
|
|
||||||
minStatusToEditOtherGuilds = 80,
|
|
||||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
|
||||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
|
||||||
commandZoneToSpecials = 80, //zone to cshome, out of load zones
|
|
||||||
commandToggleAI = 250, //can turn NPC AI on and off
|
|
||||||
commandCastSpecials = 100, //can cast special spells
|
|
||||||
commandInstacast = 100, //insta-cast all #casted spells
|
|
||||||
commandLevelAboveCap = 100, //can #level players above level cap
|
|
||||||
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
|
|
||||||
commandSetSkillsOther = 100, //ability to setskills on others
|
|
||||||
commandRaceOthers = 100, //ability to #race on others
|
|
||||||
commandGenderOthers = 100, //ability to #gender on others
|
|
||||||
commandTextureOthers = 100, //ability to #texture on others
|
|
||||||
commandDoAnimOthers = 100, //can #doanim on others
|
|
||||||
commandLockZones = 101, //can lock or unlock zones
|
|
||||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
|
||||||
commandChangeFlags = 200, //ability to set/refresh flags
|
|
||||||
commandBanPlayers = 100, //can set bans on players
|
|
||||||
commandChangeDatarate = 201, //edit client's data rate
|
|
||||||
commandZoneToCoords = 0, //can #zone with coords
|
|
||||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
|
||||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
// 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
|
#define SAYLINK_ITEM_ID 0xFFFFF
|
||||||
|
|
||||||
|
|||||||
+16
-10
@@ -38,25 +38,31 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool File::Exists(const std::string &name)
|
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)
|
void File::Makedir(const std::string &directory_name)
|
||||||
{
|
{
|
||||||
fs::create_directory(directory_name);
|
try {
|
||||||
fs::permissions(directory_name, fs::perms::owner_all);
|
fs::create_directory(directory_name);
|
||||||
|
fs::permissions(directory_name, fs::perms::owner_all);
|
||||||
|
}
|
||||||
|
catch (const fs::filesystem_error &ex) {
|
||||||
|
std::cout << "Failed to create directory: " << directory_name << std::endl;
|
||||||
|
std::cout << ex.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string File::FindEqemuConfigPath()
|
std::string File::FindEqemuConfigPath()
|
||||||
|
|||||||
+1006
-821
File diff suppressed because it is too large
Load Diff
+135
-82
@@ -5,6 +5,42 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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;
|
class Database;
|
||||||
|
|
||||||
@@ -12,22 +48,23 @@ class CharGuildInfo
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//fields from `characer_`
|
//fields from `characer_`
|
||||||
uint32 char_id;
|
uint32 char_id;
|
||||||
std::string char_name;
|
std::string char_name;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
uint16 level;
|
uint16 level;
|
||||||
uint32 time_last_on;
|
uint32 time_last_on;
|
||||||
uint32 zone_id;
|
uint32 zone_id;
|
||||||
|
|
||||||
//fields from `guild_members`
|
//fields from `guild_members`
|
||||||
uint32 guild_id;
|
uint32 guild_id;
|
||||||
uint8 rank;
|
uint8 rank;
|
||||||
bool tribute_enable;
|
bool tribute_enable;
|
||||||
uint32 total_tribute;
|
uint32 total_tribute;
|
||||||
uint32 last_tribute; //timestamp
|
uint32 last_tribute; //timestamp
|
||||||
bool banker;
|
bool banker;
|
||||||
bool alt;
|
bool alt;
|
||||||
std::string public_note;
|
std::string public_note;
|
||||||
|
bool online;
|
||||||
};
|
};
|
||||||
|
|
||||||
//this object holds guild functionality shared between world and zone.
|
//this object holds guild functionality shared between world and zone.
|
||||||
@@ -38,21 +75,31 @@ class BaseGuildManager
|
|||||||
virtual ~BaseGuildManager();
|
virtual ~BaseGuildManager();
|
||||||
|
|
||||||
//this must be called before doing anything else with this object
|
//this must be called before doing anything else with this object
|
||||||
void SetDatabase(Database *db)
|
BaseGuildManager * SetDatabase(Database *db)
|
||||||
{
|
{
|
||||||
m_db = db;
|
m_db = db;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseGuildManager * SetContentDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_content_db = db;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadGuilds();
|
bool LoadGuilds();
|
||||||
bool RefreshGuild(uint32 guild_id);
|
virtual bool RefreshGuild(uint32 guild_id);
|
||||||
|
|
||||||
//guild edit actions.
|
//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 DeleteGuild(uint32 guild_id);
|
||||||
bool RenameGuild(uint32 guild_id, const char* name);
|
bool RenameGuild(uint32 guild_id, std::string name);
|
||||||
bool SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
bool SetGuildMOTD(uint32 guild_id, std::string motd, std::string setter);
|
||||||
bool SetGuildURL(uint32 GuildID, const char* URL);
|
bool SetGuildURL(uint32 guild_id, std::string URL);
|
||||||
bool SetGuildChannel(uint32 GuildID, const char* Channel);
|
bool SetGuildChannel(uint32 guild_id, std::string Channel);
|
||||||
|
|
||||||
//character edit actions
|
//character edit actions
|
||||||
bool SetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
bool SetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||||
@@ -62,9 +109,16 @@ class BaseGuildManager
|
|||||||
bool ForceRankUpdate(uint32 charid);
|
bool ForceRankUpdate(uint32 charid);
|
||||||
bool GetAltFlag(uint32 CharID);
|
bool GetAltFlag(uint32 CharID);
|
||||||
bool SetAltFlag(uint32 charid, bool is_alt);
|
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 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
|
//queries
|
||||||
bool GetCharInfo(const char *char_name, CharGuildInfo &into);
|
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 GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *setter_buffer) const;
|
||||||
bool GetGuildURL(uint32 GuildID, char *URLBuffer) const;
|
bool GetGuildURL(uint32 GuildID, char *URLBuffer) const;
|
||||||
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
||||||
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
||||||
const char *GetGuildName(uint32 guild_id) const;
|
bool GetGuildNameByID(uint32 guild_id, std::string& into) const;
|
||||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
||||||
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
bool UpdateDbBankerFlag(uint32 charid, bool is_banker);
|
||||||
uint32 GetGuildIDByName(const char *GuildName);
|
GuildsListMessaging_Struct MakeGuildList();
|
||||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
uint32 GetGuildIDByName(const char *GuildName);
|
||||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
||||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
uint32 FindGuildByLeader(uint32 leader) const;
|
||||||
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
uint32 NumberInGuild(uint32 guild_id);
|
||||||
// uint32 Getguild_id(uint32 eqid);
|
uint32 DoesAccountContainAGuildLeader(uint32 AccountID);
|
||||||
uint32 FindGuildByLeader(uint32 leader) const;
|
const char* GetRankName(uint32 guild_id, uint8 rank) const;
|
||||||
// void GetGuildMembers(uint32 guild_id,GuildMember_Struct* gms);
|
const char* GetGuildName(uint32 guild_id) const;
|
||||||
uint32 NumberInGuild(uint32 guild_id);
|
std::string GetGuildNameByID(uint32 guild_id) const;
|
||||||
// bool GetGuildRanks(uint32 guildeqid, GuildRanks_Struct* gr);
|
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
||||||
// bool EditGuild(uint32 guild_id, uint8 ranknum, GuildRankLevel_Struct* grl);
|
std::vector<GuildMembersRepository::GuildMembers> GetGuildMembers(uint32 guild_id);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//the methods which must be defined by base classes.
|
//the methods which must be defined by base classes.
|
||||||
@@ -105,58 +154,62 @@ class BaseGuildManager
|
|||||||
virtual void SendRankUpdate(uint32 CharID) = 0;
|
virtual void SendRankUpdate(uint32 CharID) = 0;
|
||||||
virtual void SendGuildDelete(uint32 guild_id) = 0;
|
virtual void SendGuildDelete(uint32 guild_id) = 0;
|
||||||
|
|
||||||
uint32 DBCreateGuild(const char* name, uint32 leader_char_id);
|
uint32 UpdateDbCreateGuild(std::string name, uint32 leader_char_id);
|
||||||
bool DBDeleteGuild(uint32 guild_id);
|
bool UpdateDbDeleteGuild(uint32 guild_id, bool local_delete = true, bool db_delete = true);
|
||||||
bool DBRenameGuild(uint32 guild_id, const char* name);
|
bool UpdateDbRenameGuild(uint32 guild_id, std::string name);
|
||||||
bool DBSetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
bool UpdateDbGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||||
bool DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
bool UpdateDbGuildMOTD(uint32 guild_id, std::string motd, std::string setter);
|
||||||
bool DBSetGuildURL(uint32 GuildID, const char* URL);
|
bool UpdateDbGuildURL(uint32 GuildID, std::string URL);
|
||||||
bool DBSetGuildChannel(uint32 GuildID, const char* Channel);
|
bool UpdateDbGuildChannel(uint32 GuildID, std::string Channel);
|
||||||
bool DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
bool UpdateDbGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
||||||
bool DBSetGuildRank(uint32 charid, uint8 rank);
|
bool UpdateDbGuildRank(uint32 charid, uint8 rank);
|
||||||
bool DBSetBankerFlag(uint32 charid, bool is_banker);
|
bool UpdateDbAltFlag(uint32 charid, bool is_alt);
|
||||||
bool DBSetAltFlag(uint32 charid, bool is_alt);
|
bool UpdateDbTributeFlag(uint32 charid, bool enabled);
|
||||||
bool DBSetTributeFlag(uint32 charid, bool enabled);
|
bool UpdateDbPublicNote(uint32 charid, std::string public_note);
|
||||||
bool DBSetPublicNote(uint32 charid, const char *note);
|
|
||||||
bool QueryWithLogging(std::string query, const char *errmsg);
|
bool QueryWithLogging(std::string query, const char *errmsg);
|
||||||
// void DBSetPublicNote(uint32 guild_id,char* charname, char* note);
|
|
||||||
|
|
||||||
bool LocalDeleteGuild(uint32 guild_id);
|
bool LocalDeleteGuild(uint32 guild_id);
|
||||||
|
|
||||||
class RankInfo
|
struct RankInfo
|
||||||
{
|
{
|
||||||
public:
|
RankInfo();
|
||||||
RankInfo();
|
std::string rank_name;
|
||||||
std::string name;
|
|
||||||
bool permissions[_MaxGuildAction];
|
|
||||||
};
|
};
|
||||||
class GuildInfo
|
struct Functions
|
||||||
{
|
{
|
||||||
public:
|
uint32 id;
|
||||||
GuildInfo();
|
uint32 perm_id;
|
||||||
std::string name;
|
uint32 guild_id;
|
||||||
std::string motd;
|
uint32 perm_value;
|
||||||
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];
|
|
||||||
};
|
};
|
||||||
|
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
|
std::map<uint32, GuildInfo *> m_guilds; //we own the pointers in this map
|
||||||
void ClearGuilds(); //clears internal structure
|
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);
|
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);
|
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);
|
||||||
uint32 _GetFreeGuildID();
|
GuildsRepository::Guilds CreateGuildRepoFromGuildInfo(uint32 guild_id, BaseGuildManager::GuildInfo& in);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /*GUILD_BASE_H_*/
|
#endif /*GUILD_BASE_H_*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+56
-16
@@ -16,31 +16,71 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GUILD_H
|
#ifndef GUILDS_H
|
||||||
#define GUILD_H
|
#define GUILDS_H
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define GUILD_NONE 0xFFFFFFFF // user has no guild
|
#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
|
//defines for standard ranks
|
||||||
#define GUILD_MEMBER 0
|
#define GUILD_MEMBER_TI 0
|
||||||
#define GUILD_OFFICER 1
|
#define GUILD_OFFICER_TI 1
|
||||||
#define GUILD_LEADER 2
|
#define GUILD_LEADER_TI 2
|
||||||
#define GUILD_RANK_NONE (GUILD_MAX_RANK+1)
|
#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 {
|
typedef enum {
|
||||||
GUILD_HEAR = 0,
|
GUILD_ACTION_BANNER_CHANGE = 1,
|
||||||
GUILD_SPEAK = 1,
|
GUILD_ACTION_BANNER_PLANT = 2,
|
||||||
GUILD_INVITE = 2,
|
GUILD_ACTION_BANNER_REMOVE = 3,
|
||||||
GUILD_REMOVE = 3,
|
GUILD_ACTION_DISPLAY_GUILD_NAME = 4,
|
||||||
GUILD_PROMOTE = 4,
|
GUILD_ACTION_RANKS_CHANGE_PERMISSIONS = 5,
|
||||||
GUILD_DEMOTE = 5,
|
GUILD_ACTION_RANKS_CHANGE_RANK_NAMES = 6,
|
||||||
GUILD_MOTD = 6,
|
GUILD_ACTION_MEMBERS_INVITE = 7,
|
||||||
GUILD_WARPEACE = 7,
|
GUILD_ACTION_MEMBERS_PROMOTE = 8,
|
||||||
_MaxGuildAction
|
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;
|
} GuildAction;
|
||||||
|
|
||||||
|
constexpr int format_as(GuildAction action) { return static_cast<int>(action); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -173,7 +173,8 @@ EQ::ItemInstance* EQ::InventoryProfile::GetItem(int16 slot_id) const
|
|||||||
result = _GetItem(m_inv, slot_id);
|
result = _GetItem(m_inv, slot_id);
|
||||||
}
|
}
|
||||||
else if ((slot_id >= invslot::EQUIPMENT_BEGIN && slot_id <= invslot::EQUIPMENT_END) ||
|
else if ((slot_id >= invslot::EQUIPMENT_BEGIN && slot_id <= invslot::EQUIPMENT_END) ||
|
||||||
(slot_id >= invslot::TRIBUTE_BEGIN && slot_id <= invslot::TRIBUTE_END)) {
|
(slot_id >= invslot::TRIBUTE_BEGIN && slot_id <= invslot::TRIBUTE_END) ||
|
||||||
|
(slot_id >= invslot::GUILD_TRIBUTE_BEGIN && slot_id <= invslot::GUILD_TRIBUTE_END)) {
|
||||||
// Equippable slots (on body)
|
// Equippable slots (on body)
|
||||||
result = _GetItem(m_worn, slot_id);
|
result = _GetItem(m_worn, slot_id);
|
||||||
}
|
}
|
||||||
@@ -353,7 +354,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapRaceClass;
|
fail_state = swapRaceClass;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) {
|
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
|
||||||
fail_state = swapDeity;
|
fail_state = swapDeity;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -379,7 +380,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapRaceClass;
|
fail_state = swapRaceClass;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) {
|
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
|
||||||
fail_state = swapDeity;
|
fail_state = swapDeity;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -465,6 +466,10 @@ EQ::ItemInstance* EQ::InventoryProfile::PopItem(int16 slot_id)
|
|||||||
p = m_worn[slot_id];
|
p = m_worn[slot_id];
|
||||||
m_worn.erase(slot_id);
|
m_worn.erase(slot_id);
|
||||||
}
|
}
|
||||||
|
else if (slot_id >= invslot::GUILD_TRIBUTE_BEGIN && slot_id <= invslot::GUILD_TRIBUTE_END) {
|
||||||
|
p = m_worn[slot_id];
|
||||||
|
m_worn.erase(slot_id);
|
||||||
|
}
|
||||||
else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) {
|
else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) {
|
||||||
p = m_bank[slot_id];
|
p = m_bank[slot_id];
|
||||||
m_bank.erase(slot_id);
|
m_bank.erase(slot_id);
|
||||||
@@ -801,34 +806,35 @@ int16 EQ::InventoryProfile::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
|||||||
// Returns slot_id when there's one available, else SLOT_INVALID
|
// Returns slot_id when there's one available, else SLOT_INVALID
|
||||||
int16 EQ::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
int16 EQ::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
||||||
{
|
{
|
||||||
// Check basic inventory
|
const int16 last_bag_slot = (RuleI(World, ExpansionSettings) == -1 || RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT) ? EQ::invslot::slotGeneral10 : EQ::invslot::slotGeneral8;
|
||||||
for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) {
|
|
||||||
if ((((uint64)1 << i) & m_lookup->PossessionsBitmask) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!GetItem(i))
|
for (int16 i = invslot::GENERAL_BEGIN; i <= last_bag_slot; i++) { // Check basic inventory
|
||||||
// Found available slot in personal inventory
|
if ((((uint64) 1 << i) & m_lookup->PossessionsBitmask) == 0) {
|
||||||
return i;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetItem(i)) {
|
||||||
|
return i; // Found available slot in personal inventory
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!for_bag) {
|
if (!for_bag) {
|
||||||
for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) {
|
for (int16 i = invslot::GENERAL_BEGIN; i <= last_bag_slot; i++) {
|
||||||
if ((((uint64)1 << i) & m_lookup->PossessionsBitmask) == 0)
|
if ((((uint64) 1 << i) & m_lookup->PossessionsBitmask) == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const ItemInstance* inst = GetItem(i);
|
const auto *inst = GetItem(i);
|
||||||
if (inst && inst->IsClassBag() && inst->GetItem()->BagSize >= min_size)
|
if (inst && inst->IsClassBag() && inst->GetItem()->BagSize >= min_size) {
|
||||||
{
|
if (inst->GetItem()->BagType == item::BagTypeQuiver &&
|
||||||
if (inst->GetItem()->BagType == item::BagTypeQuiver && inst->GetItem()->ItemType != item::ItemTypeArrow)
|
inst->GetItem()->ItemType != item::ItemTypeArrow) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 base_slot_id = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN);
|
const int16 base_slot_id = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN);
|
||||||
|
|
||||||
uint8 slots = inst->GetItem()->BagSlots;
|
const uint8 slots = inst->GetItem()->BagSlots;
|
||||||
uint8 j;
|
for (uint8 j = invbag::SLOT_BEGIN; j < slots; j++) {
|
||||||
for (j = invbag::SLOT_BEGIN; j<slots; j++) {
|
|
||||||
if (!GetItem(base_slot_id + j)) {
|
if (!GetItem(base_slot_id + j)) {
|
||||||
// Found available slot within bag
|
// Found available slot within bag
|
||||||
return (base_slot_id + j);
|
return (base_slot_id + j);
|
||||||
@@ -1418,6 +1424,10 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
|||||||
m_worn[slot_id] = inst;
|
m_worn[slot_id] = inst;
|
||||||
result = slot_id;
|
result = slot_id;
|
||||||
}
|
}
|
||||||
|
else if (slot_id >= invslot::GUILD_TRIBUTE_BEGIN && slot_id <= invslot::GUILD_TRIBUTE_END) {
|
||||||
|
m_worn[slot_id] = inst;
|
||||||
|
result = slot_id;
|
||||||
|
}
|
||||||
else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) {
|
else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) {
|
||||||
if (slot_id - EQ::invslot::BANK_BEGIN < m_lookup->InventoryTypeSize.Bank) {
|
if (slot_id - EQ::invslot::BANK_BEGIN < m_lookup->InventoryTypeSize.Bank) {
|
||||||
m_bank[slot_id] = inst;
|
m_bank[slot_id] = inst;
|
||||||
@@ -1444,7 +1454,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == INVALID_INDEX) {
|
if (result == INVALID_INDEX) {
|
||||||
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
LogError("Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
||||||
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ namespace EQ
|
|||||||
|
|
||||||
// Swap items in inventory
|
// Swap items in inventory
|
||||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = RACE_DOUG_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, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
||||||
|
|
||||||
// Remove item from inventory
|
// Remove item from inventory
|
||||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
||||||
|
|||||||
@@ -230,6 +230,10 @@ bool EQ::ItemData::IsTypeShield() const
|
|||||||
return (ItemType == item::ItemTypeShield);
|
return (ItemType == item::ItemTypeShield);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQ::ItemData::IsQuestItem() const {
|
||||||
|
return QuestItemFlag;
|
||||||
|
}
|
||||||
|
|
||||||
bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
|
bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
|
||||||
{
|
{
|
||||||
if (!l_item || !r_item)
|
if (!l_item || !r_item)
|
||||||
|
|||||||
@@ -356,6 +356,7 @@ namespace EQ
|
|||||||
struct ItemData {
|
struct ItemData {
|
||||||
// Non packet based fields
|
// Non packet based fields
|
||||||
uint8 MinStatus {};
|
uint8 MinStatus {};
|
||||||
|
char Comment[255] {};
|
||||||
|
|
||||||
// Packet based fields
|
// Packet based fields
|
||||||
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
||||||
@@ -546,6 +547,7 @@ namespace EQ
|
|||||||
bool IsType1HWeapon() const;
|
bool IsType1HWeapon() const;
|
||||||
bool IsType2HWeapon() const;
|
bool IsType2HWeapon() const;
|
||||||
bool IsTypeShield() const;
|
bool IsTypeShield() const;
|
||||||
|
bool IsQuestItem() const;
|
||||||
|
|
||||||
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
||||||
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
|
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
|
||||||
|
|||||||
@@ -720,12 +720,14 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
|
|||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmented()
|
bool EQ::ItemInstance::IsAugmented()
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon())
|
if (!m_item || !m_item->IsClassCommon()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||||
if (GetAugmentItemID(index))
|
if (GetAugmentItemID(slot_id)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1271,7 +1273,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bool augments) const
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||||
{
|
{
|
||||||
int race = RACE_DOUG_0;
|
int race = Race::Doug;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
race = item->BaneDmgRace;
|
race = item->BaneDmgRace;
|
||||||
@@ -1789,6 +1791,27 @@ int EQ::ItemInstance::RemoveTaskDeliveredItems()
|
|||||||
return count;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// class EvolveInfo
|
// class EvolveInfo
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -299,6 +299,8 @@ namespace EQ
|
|||||||
int GetItemHeroicDR(bool augments = false) const;
|
int GetItemHeroicDR(bool augments = false) const;
|
||||||
int GetItemHeroicCorrup(bool augments = false) const;
|
int GetItemHeroicCorrup(bool augments = false) const;
|
||||||
int GetItemHaste(bool augments = false) const;
|
int GetItemHaste(bool augments = false) const;
|
||||||
|
uint32 GetItemGuildFavor() const;
|
||||||
|
std::vector<uint32> GetAugmentIDs() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|||||||
+24640
File diff suppressed because it is too large
Load Diff
@@ -1,52 +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
|
|
||||||
|
|
||||||
#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
|
|
||||||
-117
@@ -214,123 +214,6 @@ std::string x;
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadItemDBFieldNames() {
|
|
||||||
DBFieldNames[0]="N/A"; // Charges
|
|
||||||
DBFieldNames[1]="unknown002"; // ?
|
|
||||||
DBFieldNames[2]="N/A"; // Current Equip Slot
|
|
||||||
DBFieldNames[3]="unknown004";
|
|
||||||
DBFieldNames[4]="unknown005"; // ?
|
|
||||||
DBFieldNames[5]="itemclass"; // "Item Type (0=common, 1=container, 2=book)"
|
|
||||||
DBFieldNames[6]="name"; // Name
|
|
||||||
DBFieldNames[7]="lore"; // "Lore Name (*=lore, &=summoned, #=artifact)"
|
|
||||||
DBFieldNames[8]="idfile"; // IDFile
|
|
||||||
DBFieldNames[9]="id"; // ItemNumber
|
|
||||||
DBFieldNames[10]="weight"; // Weight
|
|
||||||
DBFieldNames[11]="norent"; // "NoRent (0=norent, 255=not norent)"
|
|
||||||
DBFieldNames[12]="nodrop"; // "NoDrop (0=nodrop, 255=not nodrop)"
|
|
||||||
DBFieldNames[13]="size"; // "Size (0=tiny, 1=small, 2=medium, 3=large, 4=giant)"
|
|
||||||
DBFieldNames[14]="slots"; // EquipSlots
|
|
||||||
DBFieldNames[15]="cost"; // Cost
|
|
||||||
DBFieldNames[16]="icon"; // IconNumber
|
|
||||||
DBFieldNames[17]="unknown018";
|
|
||||||
DBFieldNames[18]="unknown019";
|
|
||||||
DBFieldNames[19]="unknown020"; // ?
|
|
||||||
DBFieldNames[20]="tradeskills"; // "Tradeskill Item (1=is a tradeskill item, 0=not)"
|
|
||||||
DBFieldNames[21]="cr"; // SvCold
|
|
||||||
DBFieldNames[22]="dr"; // SvDisease
|
|
||||||
DBFieldNames[23]="pr"; // SvPoison
|
|
||||||
DBFieldNames[24]="mr"; // SvMagic
|
|
||||||
DBFieldNames[25]="fr"; // SvFire
|
|
||||||
DBFieldNames[26]="astr"; // STR
|
|
||||||
DBFieldNames[27]="asta"; // STA
|
|
||||||
DBFieldNames[28]="aagi"; // AGI
|
|
||||||
DBFieldNames[29]="adex"; // DEX
|
|
||||||
DBFieldNames[30]="acha"; // CHA
|
|
||||||
DBFieldNames[31]="aint"; // INT
|
|
||||||
DBFieldNames[32]="awis"; // WIS
|
|
||||||
DBFieldNames[33]="hp"; // HP
|
|
||||||
DBFieldNames[34]="mana"; // Mana
|
|
||||||
DBFieldNames[35]="ac"; // AC
|
|
||||||
DBFieldNames[36]="deity"; // Deity
|
|
||||||
DBFieldNames[37]="skillmodvalue"; // Skill Mod Value
|
|
||||||
DBFieldNames[38]="skillmodtype"; // Skill Mod Type
|
|
||||||
DBFieldNames[39]="banedmgrace"; // Bane Dmg Race
|
|
||||||
DBFieldNames[40]="banedmgamt"; // Band Dmg
|
|
||||||
DBFieldNames[41]="banedmgbody"; // Band Dmg Body
|
|
||||||
DBFieldNames[42]="magic"; // "Magic (0=not magic, 1=magic)"
|
|
||||||
DBFieldNames[43]="casttime2"; // Casttime appears twice
|
|
||||||
DBFieldNames[44]="hasteproclvl"; // "Level (Haste value, rather)"
|
|
||||||
DBFieldNames[45]="reqlevel"; // Required Level
|
|
||||||
DBFieldNames[46]="bardtype"; // Bard Type
|
|
||||||
DBFieldNames[47]="bardvalue"; // Bard Type Amount
|
|
||||||
DBFieldNames[48]="light"; // Light
|
|
||||||
DBFieldNames[49]="delay"; // Attack Delay
|
|
||||||
DBFieldNames[50]="reclevel"; // Recommended Level
|
|
||||||
DBFieldNames[51]="recskill"; // Recommended Skill
|
|
||||||
DBFieldNames[52]="elemdmgamt"; // "Elemental Dmg Type (1=magic, 2=fire, 3=cold, 4=poison, 5=disease)"
|
|
||||||
DBFieldNames[53]="elemdmgtype"; // Elemental Dmg
|
|
||||||
DBFieldNames[54]="effecttype"; // "Effect Type (0=combat, 1=clicky, 2=Worn, 3=Expendable charges, 4=Must Equip Clicky, 5=clicky)"
|
|
||||||
DBFieldNames[55]="range"; // Range
|
|
||||||
DBFieldNames[56]="damage"; // Damage
|
|
||||||
DBFieldNames[57]="color"; // Color
|
|
||||||
DBFieldNames[58]="classes"; // Classes
|
|
||||||
DBFieldNames[59]="races"; // Races
|
|
||||||
DBFieldNames[60]="unknown061";
|
|
||||||
DBFieldNames[61]="spellid"; // SpellId
|
|
||||||
DBFieldNames[62]="maxcharges"; // MaxCharges
|
|
||||||
DBFieldNames[63]="itemtype"; // "Skill (ItemType: 1hs, etc)"
|
|
||||||
DBFieldNames[64]="material"; // Material
|
|
||||||
DBFieldNames[65]="sellrate"; // ** Sell Rate
|
|
||||||
DBFieldNames[66]="unknown067";
|
|
||||||
DBFieldNames[67]="casttime"; // CastTime (milliseconds)
|
|
||||||
DBFieldNames[68]="unknown069";
|
|
||||||
DBFieldNames[69]="unknown070"; // ?
|
|
||||||
DBFieldNames[70]="focusid"; // Focus Effect Spell Id
|
|
||||||
DBFieldNames[71]="combateffects"; // CombatEffects
|
|
||||||
DBFieldNames[72]="shielding"; // Shielding
|
|
||||||
DBFieldNames[73]="stunresist"; // StunResist
|
|
||||||
DBFieldNames[74]="strikethrough"; // StrikeThrough
|
|
||||||
DBFieldNames[75]="unknown076";
|
|
||||||
DBFieldNames[76]="unknown077"; // ?
|
|
||||||
DBFieldNames[77]="spellshield"; // Spell Shield
|
|
||||||
DBFieldNames[78]="avoidance"; // Avoidance
|
|
||||||
DBFieldNames[79]="accuracy"; // Accuracy
|
|
||||||
DBFieldNames[80]="factionmod1"; // Faction Mod Index 1
|
|
||||||
DBFieldNames[81]="factionmod2"; // Faction Mod Index 2
|
|
||||||
DBFieldNames[82]="factionmod3"; // Faction Mod Index 3
|
|
||||||
DBFieldNames[83]="factionmod4"; // Faction Mod Index 4
|
|
||||||
DBFieldNames[84]="factionamt1"; // Faction Mod Value 1
|
|
||||||
DBFieldNames[85]="factionamt2"; // Faction Mod Value 2
|
|
||||||
DBFieldNames[86]="factionamt3"; // Faction Mod Value 3
|
|
||||||
DBFieldNames[87]="factionamt4"; // Faction Mod Value 4
|
|
||||||
DBFieldNames[88]="unknown089";
|
|
||||||
DBFieldNames[89]="charmfile"; // ** Charm File
|
|
||||||
DBFieldNames[90]="unknown091";
|
|
||||||
DBFieldNames[91]="augslot1type"; // Slot1Type
|
|
||||||
DBFieldNames[92]="augslot2type"; // Slot2Type
|
|
||||||
DBFieldNames[93]="augslot3type"; // Slot3Type
|
|
||||||
DBFieldNames[94]="augslot4type"; // Slot4Type
|
|
||||||
DBFieldNames[95]="augslot5type"; // Slot5Type
|
|
||||||
DBFieldNames[96]="ldonpointtheme";
|
|
||||||
DBFieldNames[97]="ldonpointcost"; // ?
|
|
||||||
DBFieldNames[98]="unknown099";
|
|
||||||
DBFieldNames[99]="bagtype"; // bag type
|
|
||||||
DBFieldNames[100]="bagslots"; // bag slots
|
|
||||||
DBFieldNames[101]="bagsize"; // bag size capacity
|
|
||||||
DBFieldNames[102]="bagwr"; // bag weight reduction
|
|
||||||
DBFieldNames[103]="booktype"; // "book type (0=rolled up note, 1=book)"
|
|
||||||
DBFieldNames[104]="unknown105";
|
|
||||||
DBFieldNames[105]="filename"; // Book Filename
|
|
||||||
DBFieldNames[106]="unknown107";
|
|
||||||
DBFieldNames[107]="unknown108";
|
|
||||||
DBFieldNames[108]="loreflag";
|
|
||||||
DBFieldNames[109]="unknown111";
|
|
||||||
DBFieldNames[110]="unknown112";
|
|
||||||
DBFieldNames[111]="unknown113";
|
|
||||||
DBFieldNames[112]="unknown114";
|
|
||||||
DBFieldNames[113]="unknown115"; // ? (end quote)
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
||||||
{
|
{
|
||||||
unsigned long i,j;
|
unsigned long i,j;
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::stri
|
|||||||
|
|
||||||
int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
||||||
|
|
||||||
void LoadItemDBFieldNames();
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int print_stacktrace();
|
int print_stacktrace();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ void MySQLRequestResult::ZeroOut()
|
|||||||
m_RowCount = 0;
|
m_RowCount = 0;
|
||||||
m_RowsAffected = 0;
|
m_RowsAffected = 0;
|
||||||
m_LastInsertedID = 0;
|
m_LastInsertedID = 0;
|
||||||
|
m_error_message = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLRequestResult::~MySQLRequestResult()
|
MySQLRequestResult::~MySQLRequestResult()
|
||||||
@@ -137,3 +138,23 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
|
|||||||
other.ZeroOut();
|
other.ZeroOut();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 MySQLRequestResult::GetErrorNumber() const
|
||||||
|
{
|
||||||
|
return m_ErrorNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySQLRequestResult::SetErrorNumber(uint32 m_error_number)
|
||||||
|
{
|
||||||
|
m_ErrorNumber = m_error_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &MySQLRequestResult::GetErrorMessage() const
|
||||||
|
{
|
||||||
|
return m_error_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySQLRequestResult::SetErrorMessage(const std::string &m_error_message)
|
||||||
|
{
|
||||||
|
MySQLRequestResult::m_error_message = m_error_message;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ private:
|
|||||||
uint32 m_LastInsertedID;
|
uint32 m_LastInsertedID;
|
||||||
uint32 m_ErrorNumber;
|
uint32 m_ErrorNumber;
|
||||||
|
|
||||||
|
std::string m_error_message;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -44,7 +45,13 @@ public:
|
|||||||
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
||||||
|
|
||||||
bool Success() const { return m_Success;}
|
bool Success() const { return m_Success;}
|
||||||
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
|
std::string ErrorMessage() const {
|
||||||
|
if (!m_error_message.empty()) {
|
||||||
|
return m_error_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");
|
||||||
|
}
|
||||||
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
||||||
uint32 RowsAffected() const {return m_RowsAffected;}
|
uint32 RowsAffected() const {return m_RowsAffected;}
|
||||||
uint32 RowCount() const {return m_RowCount;}
|
uint32 RowCount() const {return m_RowCount;}
|
||||||
@@ -57,6 +64,11 @@ public:
|
|||||||
MySQLRequestRow& begin() { return m_CurrentRow; }
|
MySQLRequestRow& begin() { return m_CurrentRow; }
|
||||||
MySQLRequestRow& end() { return m_OneBeyondRow; }
|
MySQLRequestRow& end() { return m_OneBeyondRow; }
|
||||||
|
|
||||||
|
uint32 GetErrorNumber() const;
|
||||||
|
void SetErrorNumber(uint32 m_error_number);
|
||||||
|
const std::string &GetErrorMessage() const;
|
||||||
|
void SetErrorMessage(const std::string &m_error_message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FreeInternals();
|
void FreeInternals();
|
||||||
void ZeroOut();
|
void ZeroOut();
|
||||||
|
|||||||
+169
-145
@@ -34,6 +34,7 @@
|
|||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -201,7 +202,7 @@ namespace RoF
|
|||||||
unsigned char *emu_buffer = in->pBuffer;
|
unsigned char *emu_buffer = in->pBuffer;
|
||||||
uint32 opcode = *((uint32*)emu_buffer);
|
uint32 opcode = *((uint32*)emu_buffer);
|
||||||
|
|
||||||
if (opcode == 8) {
|
if (opcode == AlternateCurrencyMode::Populate) {
|
||||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(
|
auto outapp = new EQApplicationPacket(
|
||||||
@@ -1307,13 +1308,13 @@ namespace RoF
|
|||||||
PutFieldN(class_);
|
PutFieldN(class_);
|
||||||
|
|
||||||
/* Translate older ranks to new values */
|
/* Translate older ranks to new values */
|
||||||
switch (emu_e->rank) {
|
//switch (emu_e->rank) {
|
||||||
case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
|
//case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
|
||||||
case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
|
//case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
|
||||||
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
|
//case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
|
||||||
default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
|
//default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
|
||||||
}
|
//}
|
||||||
|
PutFieldN(rank);
|
||||||
PutFieldN(time_last_on);
|
PutFieldN(time_last_on);
|
||||||
PutFieldN(tribute_enable);
|
PutFieldN(tribute_enable);
|
||||||
e->unknown01 = 0;
|
e->unknown01 = 0;
|
||||||
@@ -2608,88 +2609,124 @@ namespace RoF
|
|||||||
|
|
||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
*p = nullptr;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3014,19 +3051,12 @@ namespace RoF
|
|||||||
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
||||||
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::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 */
|
memcpy(eq->member_name, emu->member_name, sizeof(eq->member_name));
|
||||||
switch (emu->Rank) {
|
OUT(banker);
|
||||||
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
|
eq->unknown76 = 1;
|
||||||
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;
|
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -3059,21 +3089,6 @@ namespace RoF
|
|||||||
FINISH_ENCODE();
|
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(OP_SkillUpdate)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(SkillUpdate_Struct);
|
ENCODE_LENGTH_EXACT(SkillUpdate_Struct);
|
||||||
@@ -3128,7 +3143,7 @@ namespace RoF
|
|||||||
|
|
||||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
||||||
|
|
||||||
if (sas->type != AT_Size)
|
if (sas->type != AppearanceType::Size)
|
||||||
{
|
{
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
return;
|
||||||
@@ -3831,8 +3846,8 @@ namespace RoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
float SpawnSize = emu->size;
|
float SpawnSize = emu->size;
|
||||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if (!((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PacketSize += 60;
|
PacketSize += 60;
|
||||||
@@ -3936,10 +3951,22 @@ namespace RoF
|
|||||||
|
|
||||||
/* Translate older ranks to new values */
|
/* Translate older ranks to new values */
|
||||||
switch (emu->guildrank) {
|
switch (emu->guildrank) {
|
||||||
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
|
case 0: {
|
||||||
case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5);
|
||||||
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
|
break;
|
||||||
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); 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;
|
||||||
|
} //
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3965,8 +3992,8 @@ namespace RoF
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||||
@@ -4861,37 +4888,47 @@ namespace RoF
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
IN(general.action);
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
IN(general.parameter);
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
IN_str(motd);
|
||||||
IN(general.action);
|
|
||||||
IN(general.parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case raidSetNote:
|
||||||
case 36: { // raidPlayerNote unhandled
|
{
|
||||||
break;
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
}
|
|
||||||
default: {
|
IN(general.action);
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
IN(general.parameter);
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
IN_str(note);
|
||||||
IN(action);
|
|
||||||
IN(parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4995,19 +5032,6 @@ namespace RoF
|
|||||||
FINISH_DIRECT_DECODE();
|
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)
|
DECODE(OP_Trader)
|
||||||
{
|
{
|
||||||
uint32 psize = __packet->size;
|
uint32 psize = __packet->size;
|
||||||
|
|||||||
+370
-236
@@ -35,6 +35,7 @@
|
|||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../classes.h"
|
#include "../classes.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -273,7 +274,7 @@ namespace RoF2
|
|||||||
unsigned char *emu_buffer = in->pBuffer;
|
unsigned char *emu_buffer = in->pBuffer;
|
||||||
uint32 opcode = *((uint32*)emu_buffer);
|
uint32 opcode = *((uint32*)emu_buffer);
|
||||||
|
|
||||||
if (opcode == 8) {
|
if (opcode == AlternateCurrencyMode::Populate) {
|
||||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(
|
auto outapp = new EQApplicationPacket(
|
||||||
@@ -1318,6 +1319,7 @@ namespace RoF2
|
|||||||
buffer++;
|
buffer++;
|
||||||
|
|
||||||
// Guild ID
|
// Guild ID
|
||||||
|
//*((uint32*)buffer) = htonl(2);
|
||||||
buffer += sizeof(uint32);
|
buffer += sizeof(uint32);
|
||||||
|
|
||||||
//add member count.
|
//add member count.
|
||||||
@@ -1356,15 +1358,7 @@ namespace RoF2
|
|||||||
PutFieldN(level);
|
PutFieldN(level);
|
||||||
PutFieldN(banker);
|
PutFieldN(banker);
|
||||||
PutFieldN(class_);
|
PutFieldN(class_);
|
||||||
|
PutFieldN(rank);
|
||||||
/* 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
|
|
||||||
}
|
|
||||||
|
|
||||||
PutFieldN(time_last_on);
|
PutFieldN(time_last_on);
|
||||||
PutFieldN(tribute_enable);
|
PutFieldN(tribute_enable);
|
||||||
e->unknown01 = 0;
|
e->unknown01 = 0;
|
||||||
@@ -1394,8 +1388,10 @@ namespace RoF2
|
|||||||
|
|
||||||
OUT(GuildID);
|
OUT(GuildID);
|
||||||
memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName));
|
memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName));
|
||||||
OUT(ZoneID);
|
//OUT(ZoneID);
|
||||||
OUT(InstanceID);
|
//OUT(InstanceID);
|
||||||
|
eq->InstanceID = emu->InstanceID;
|
||||||
|
eq->ZoneID = emu->ZoneID;
|
||||||
OUT(LastSeen);
|
OUT(LastSeen);
|
||||||
eq->Unknown76 = 0;
|
eq->Unknown76 = 0;
|
||||||
|
|
||||||
@@ -1405,60 +1401,61 @@ namespace RoF2
|
|||||||
ENCODE(OP_GuildsList)
|
ENCODE(OP_GuildsList)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
uint32 NumberOfGuilds = in->size / 64;
|
GuildsListMessaging_Struct glms{};
|
||||||
uint32 PacketSize = 68; // 64 x 0x00 + a uint32 that I am guessing is the highest guild ID in use.
|
EQ::Util::MemoryStreamReader ss(reinterpret_cast<char *>(in->pBuffer), in->size);
|
||||||
|
cereal::BinaryInputArchive ar(ss);
|
||||||
|
ar(glms);
|
||||||
|
|
||||||
unsigned char *__emu_buffer = in->pBuffer;
|
auto packet_size = 64 + 4 + glms.guild_detail.size() * 4 + glms.string_length;
|
||||||
|
auto buffer = new uchar[packet_size];
|
||||||
|
auto buf_pos = buffer;
|
||||||
|
|
||||||
char *InBuffer = (char *)__emu_buffer;
|
memset(buf_pos, 0, 64);
|
||||||
|
buf_pos += 64;
|
||||||
|
|
||||||
uint32 HighestGuildID = 0;
|
VARSTRUCT_ENCODE_TYPE(uint32, buf_pos, glms.no_of_guilds);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < NumberOfGuilds; ++i)
|
for (auto const &g: glms.guild_detail) {
|
||||||
{
|
if (g.guild_id < RoF2::constants::MAX_GUILD_ID) {
|
||||||
if (InBuffer[0])
|
VARSTRUCT_ENCODE_TYPE(uint32, buf_pos, g.guild_id);
|
||||||
{
|
strn0cpy((char *) buf_pos, g.guild_name.c_str(), g.guild_name.length() + 1);
|
||||||
PacketSize += (5 + strlen(InBuffer));
|
buf_pos += g.guild_name.length() + 1;
|
||||||
HighestGuildID = i - 1;
|
|
||||||
}
|
}
|
||||||
InBuffer += 64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketSize++; // Appears to be an extra 0x00 at the very end.
|
auto outapp = new EQApplicationPacket(OP_GuildsList);
|
||||||
|
outapp->size = packet_size;
|
||||||
|
outapp->pBuffer = buffer;
|
||||||
|
|
||||||
in->size = PacketSize;
|
dest->FastQueuePacket(&outapp);
|
||||||
in->pBuffer = new unsigned char[in->size];
|
|
||||||
|
|
||||||
InBuffer = (char *)__emu_buffer;
|
|
||||||
|
|
||||||
char *OutBuffer = (char *)in->pBuffer;
|
|
||||||
|
|
||||||
// Init the first 64 bytes to zero, as per live.
|
|
||||||
//
|
|
||||||
memset(OutBuffer, 0, 64);
|
|
||||||
|
|
||||||
OutBuffer += 64;
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, HighestGuildID);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < NumberOfGuilds; ++i)
|
|
||||||
{
|
|
||||||
if (InBuffer[0])
|
|
||||||
{
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, i - 1);
|
|
||||||
VARSTRUCT_ENCODE_STRING(OutBuffer, InBuffer);
|
|
||||||
}
|
|
||||||
InBuffer += 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0x00);
|
|
||||||
|
|
||||||
delete[] __emu_buffer;
|
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_GuildTributeDonateItem)
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_ENCODE(GuildTributeDonateItemReply_Struct, structs::GuildTributeDonateItemReply_Struct);
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::Netcode, "RoF2::ENCODE(OP_GuildTributeDonateItem)");
|
||||||
|
|
||||||
|
OUT(type);
|
||||||
|
OUT(sub_index);
|
||||||
|
OUT(aug_index);
|
||||||
|
OUT(quantity);
|
||||||
|
OUT(unknown10);
|
||||||
|
OUT(unknown20);
|
||||||
|
OUT(favor);
|
||||||
|
|
||||||
|
structs::InventorySlot_Struct iss;
|
||||||
|
iss = ServerToRoF2Slot(emu->slot);
|
||||||
|
|
||||||
|
eq->slot = iss.Slot;
|
||||||
|
eq->sub_index = iss.SubIndex;
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ENCODE(OP_HPUpdate)
|
ENCODE(OP_HPUpdate)
|
||||||
{
|
{
|
||||||
SETUP_DIRECT_ENCODE(SpawnHPUpdate_Struct, structs::SpawnHPUpdate_Struct);
|
SETUP_DIRECT_ENCODE(SpawnHPUpdate_Struct, structs::SpawnHPUpdate_Struct);
|
||||||
@@ -1559,30 +1556,75 @@ namespace RoF2
|
|||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
//store away the emu struct
|
//store away the emu struct
|
||||||
uchar* __emu_buffer = in->pBuffer;
|
uchar *__emu_buffer = in->pBuffer;
|
||||||
|
ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *) __emu_buffer;
|
||||||
|
|
||||||
ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
|
switch(old_item_pkt->PacketType)
|
||||||
EQ::InternalSerializedItem_Struct* int_struct = (EQ::InternalSerializedItem_Struct*)(&__emu_buffer[4]);
|
{
|
||||||
|
case ItemPacketParcel: {
|
||||||
|
ParcelMessaging_Struct pms{};
|
||||||
|
EQ::Util::MemoryStreamReader ss(reinterpret_cast<char *>(in->pBuffer), in->size);
|
||||||
|
cereal::BinaryInputArchive ar(ss);
|
||||||
|
ar(pms);
|
||||||
|
|
||||||
EQ::OutBuffer ob;
|
uint32 player_name_length = pms.player_name.length();
|
||||||
EQ::OutBuffer::pos_type last_pos = ob.tellp();
|
uint32 note_length = pms.note.length();
|
||||||
|
|
||||||
ob.write((const char*)__emu_buffer, 4);
|
auto *int_struct = (EQ::InternalSerializedItem_Struct *) pms.serialized_item.data();
|
||||||
|
|
||||||
SerializeItem(ob, (const EQ::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
EQ::OutBuffer ob;
|
||||||
if (ob.tellp() == last_pos) {
|
EQ::OutBuffer::pos_type last_pos = ob.tellp();
|
||||||
LogNetcode("RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
ob.write(reinterpret_cast<const char *>(&pms.packet_type), 4);
|
||||||
delete in;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
in->size = ob.size();
|
SerializeItem(ob, (const EQ::ItemInstance *) int_struct->inst, pms.slot_id, 0, ItemPacketParcel);
|
||||||
in->pBuffer = ob.detach();
|
|
||||||
|
|
||||||
delete[] __emu_buffer;
|
if (ob.tellp() == last_pos) {
|
||||||
|
LogNetcode("RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", pms.slot_id);
|
||||||
|
safe_delete_array(__emu_buffer);
|
||||||
|
safe_delete(in);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
ob.write((const char *) &pms.sent_time, 4);
|
||||||
}
|
ob.write((const char *) &player_name_length, 4);
|
||||||
|
ob.write(pms.player_name.c_str(), pms.player_name.length());
|
||||||
|
ob.write((const char *) ¬e_length, 4);
|
||||||
|
ob.write(pms.note.c_str(), pms.note.length());
|
||||||
|
|
||||||
|
in->size = ob.size();
|
||||||
|
in->pBuffer = ob.detach();
|
||||||
|
|
||||||
|
safe_delete_array(__emu_buffer);
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
EQ::InternalSerializedItem_Struct *int_struct = (EQ::InternalSerializedItem_Struct *)(&__emu_buffer[4]);
|
||||||
|
|
||||||
|
EQ::OutBuffer ob;
|
||||||
|
EQ::OutBuffer::pos_type last_pos = ob.tellp();
|
||||||
|
|
||||||
|
ob.write((const char *)__emu_buffer, 4);
|
||||||
|
|
||||||
|
SerializeItem(ob, (const EQ::ItemInstance *)int_struct->inst, int_struct->slot_id, 0,
|
||||||
|
old_item_pkt->PacketType);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
|
LogNetcode("RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]",
|
||||||
|
int_struct->slot_id);
|
||||||
|
safe_delete_array(__emu_buffer);
|
||||||
|
safe_delete(in);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
in->size = ob.size();
|
||||||
|
in->pBuffer = ob.detach();
|
||||||
|
|
||||||
|
safe_delete_array(__emu_buffer);
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_ItemVerifyReply)
|
ENCODE(OP_ItemVerifyReply)
|
||||||
{
|
{
|
||||||
@@ -2465,6 +2507,8 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
outapp->WriteUInt32(0xffffffff);
|
outapp->WriteUInt32(0xffffffff);
|
||||||
outapp->WriteUInt32(0);
|
outapp->WriteUInt32(0);
|
||||||
|
// outapp->WriteUInt32(60);
|
||||||
|
// outapp->WriteUInt32(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(0); // Unknown
|
outapp->WriteUInt32(0); // Unknown
|
||||||
@@ -2677,88 +2721,124 @@ namespace RoF2
|
|||||||
|
|
||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
*p = nullptr;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2772,7 +2852,10 @@ namespace RoF2
|
|||||||
else
|
else
|
||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(invslot);
|
eq->invslot = ServerToRoF2TypelessSlot(emu->invslot, invtype::typePossessions);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@@ -3064,19 +3147,12 @@ namespace RoF2
|
|||||||
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
||||||
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::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 */
|
memcpy(eq->member_name, emu->member_name, sizeof(eq->member_name));
|
||||||
switch (emu->Rank) {
|
OUT(banker);
|
||||||
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
|
eq->unknown76 = 1;
|
||||||
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;
|
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -3109,21 +3185,6 @@ namespace RoF2
|
|||||||
FINISH_ENCODE();
|
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(OP_SkillUpdate)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(SkillUpdate_Struct);
|
ENCODE_LENGTH_EXACT(SkillUpdate_Struct);
|
||||||
@@ -3178,7 +3239,7 @@ namespace RoF2
|
|||||||
|
|
||||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
||||||
|
|
||||||
if (sas->type != AT_Size)
|
if (sas->type != AppearanceType::Size)
|
||||||
{
|
{
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
return;
|
||||||
@@ -3946,7 +4007,7 @@ namespace RoF2
|
|||||||
if (strlen(emu->suffix))
|
if (strlen(emu->suffix))
|
||||||
PacketSize += strlen(emu->suffix) + 1;
|
PacketSize += strlen(emu->suffix) + 1;
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
if (emu->DestructibleObject)
|
if (emu->DestructibleObject)
|
||||||
PacketSize = PacketSize - 4; // No bodytype
|
PacketSize = PacketSize - 4; // No bodytype
|
||||||
@@ -3967,8 +4028,8 @@ namespace RoF2
|
|||||||
}
|
}
|
||||||
|
|
||||||
float SpawnSize = emu->size;
|
float SpawnSize = emu->size;
|
||||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if (!((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PacketSize += 60;
|
PacketSize += 60;
|
||||||
@@ -4036,7 +4097,7 @@ namespace RoF2
|
|||||||
// actually part of bitfields
|
// actually part of bitfields
|
||||||
uint8 OtherData = 0;
|
uint8 OtherData = 0;
|
||||||
|
|
||||||
if (emu->class_ == LDON_TREASURE) //LDoN Chest
|
if (emu->class_ == Class::LDoNTreasure) //LDoN Chest
|
||||||
{
|
{
|
||||||
OtherData = OtherData | 0x04;
|
OtherData = OtherData | 0x04;
|
||||||
}
|
}
|
||||||
@@ -4064,7 +4125,7 @@ namespace RoF2
|
|||||||
// int DefaultEmitterID
|
// int DefaultEmitterID
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
||||||
@@ -4138,12 +4199,13 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID);
|
||||||
|
|
||||||
/* Translate older ranks to new values */
|
/* Translate older ranks to new values */
|
||||||
switch (emu->guildrank) {
|
//switch (emu->guildrank) {
|
||||||
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
|
//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 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
|
||||||
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
|
//case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
|
||||||
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
|
//default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
|
||||||
}
|
//}
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank);
|
||||||
}
|
}
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_);
|
||||||
@@ -4159,7 +4221,7 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->lastName);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->lastName);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // aatitle
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // aatitle
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->NPC ? 0 : 1); // unknown - Must be 1 for guild name to be shown abover players head.
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->guild_show);
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // TempPet
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // TempPet
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||||
@@ -4172,8 +4234,8 @@ namespace RoF2
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // These do something with OP_WeaponEquip1
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // These do something with OP_WeaponEquip1
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // ^
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // ^
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||||
@@ -4398,6 +4460,17 @@ namespace RoF2
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->slot, invtype::typePossessions));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@@ -4904,7 +4977,7 @@ namespace RoF2
|
|||||||
|
|
||||||
strn0cpy(emu->target, eq->target, sizeof(emu->target));
|
strn0cpy(emu->target, eq->target, sizeof(emu->target));
|
||||||
strn0cpy(emu->name, eq->name, sizeof(emu->name));
|
strn0cpy(emu->name, eq->name, sizeof(emu->name));
|
||||||
// IN(rank);
|
IN(rank);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -4932,6 +5005,38 @@ namespace RoF2
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_GuildTributeDonateItem)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::GuildTributeDonateItemRequest_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(GuildTributeDonateItemRequest_Struct, structs::GuildTributeDonateItemRequest_Struct);
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::Netcode, "RoF2::DECODE(OP_GuildTributeDonateItem)");
|
||||||
|
|
||||||
|
IN(type);
|
||||||
|
IN(slot);
|
||||||
|
IN(sub_index);
|
||||||
|
IN(aug_index);
|
||||||
|
IN(unknown10);
|
||||||
|
IN(quantity);
|
||||||
|
IN(tribute_master_id);
|
||||||
|
IN(unknown20);
|
||||||
|
IN(guild_id);
|
||||||
|
IN(unknown28);
|
||||||
|
IN(unknown32);
|
||||||
|
|
||||||
|
structs::InventorySlot_Struct iss;
|
||||||
|
iss.Slot = eq->slot;
|
||||||
|
iss.SubIndex = eq->sub_index;
|
||||||
|
iss.AugIndex = eq->aug_index;
|
||||||
|
iss.Type = eq->type;
|
||||||
|
iss.Unknown01 = 0;
|
||||||
|
iss.Unknown02 = 0;
|
||||||
|
|
||||||
|
emu->slot = RoF2ToServerSlot(iss);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
/*DECODE(OP_InspectAnswer)
|
/*DECODE(OP_InspectAnswer)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::InspectResponse_Struct);
|
DECODE_LENGTH_EXACT(structs::InspectResponse_Struct);
|
||||||
@@ -5064,37 +5169,47 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
IN(general.action);
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
IN(general.parameter);
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
IN_str(motd);
|
||||||
IN(general.action);
|
|
||||||
IN(general.parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case raidSetNote:
|
||||||
case 36: { // raidPlayerNote unhandled
|
{
|
||||||
break;
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
}
|
|
||||||
default: {
|
IN(general.action);
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
IN(general.parameter);
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
IN_str(note);
|
||||||
IN(action);
|
|
||||||
IN(parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5104,8 +5219,8 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
IN(invslot);
|
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->invslot, invtype::typePossessions));
|
||||||
IN(subslot);
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
@@ -5199,15 +5314,17 @@ namespace RoF2
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODE(OP_ShopRequest)
|
DECODE(OP_ShopSendParcel)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::Merchant_Click_Struct);
|
DECODE_LENGTH_EXACT(structs::Parcel_Struct);
|
||||||
SETUP_DIRECT_DECODE(Merchant_Click_Struct, structs::Merchant_Click_Struct);
|
SETUP_DIRECT_DECODE(Parcel_Struct, structs::Parcel_Struct);
|
||||||
|
|
||||||
IN(npcid);
|
IN(npc_id);
|
||||||
IN(playerid);
|
IN(quantity);
|
||||||
IN(command);
|
IN(money_flag);
|
||||||
IN(rate);
|
emu->item_slot = RoF2ToServerTypelessSlot(eq->inventory_slot, invtype::typePossessions);
|
||||||
|
strn0cpy(emu->send_to, eq->send_to, sizeof(emu->send_to));
|
||||||
|
strn0cpy(emu->note, eq->note, sizeof(emu->note));
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -5426,11 +5543,24 @@ namespace RoF2
|
|||||||
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
||||||
|
|
||||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
|
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
|
||||||
|
if (packet_type == ItemPacketParcel) {
|
||||||
|
strn0cpy(
|
||||||
|
hdr.unknown000,
|
||||||
|
fmt::format(
|
||||||
|
"{:03}PAR{:010}\0",
|
||||||
|
inst->GetMerchantSlot(),
|
||||||
|
item->ID
|
||||||
|
).c_str(),
|
||||||
|
sizeof(hdr.unknown000)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
|
hdr.stacksize =
|
||||||
|
item->ID == PARCEL_MONEY_ITEM_ID ? inst->GetPrice() : (inst->IsStackable() ? ((inst->GetCharges() > 1000)
|
||||||
|
? 0xFFFFFFFF : inst->GetCharges()) : 1);
|
||||||
hdr.unknown004 = 0;
|
hdr.unknown004 = 0;
|
||||||
|
|
||||||
structs::InventorySlot_Struct slot_id;
|
structs::InventorySlot_Struct slot_id{};
|
||||||
switch (packet_type) {
|
switch (packet_type) {
|
||||||
case ItemPacketLoot:
|
case ItemPacketLoot:
|
||||||
slot_id = ServerToRoF2CorpseSlot(slot_id_in);
|
slot_id = ServerToRoF2CorpseSlot(slot_id_in);
|
||||||
@@ -5440,22 +5570,24 @@ namespace RoF2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr.slot_type = (inst->GetMerchantSlot() ? invtype::typeMerchant : slot_id.Type);
|
hdr.slot_type = (inst->GetMerchantSlot() ? invtype::typeMerchant : slot_id.Type);
|
||||||
hdr.main_slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id.Slot);
|
hdr.main_slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id.Slot);
|
||||||
hdr.sub_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.SubIndex);
|
hdr.sub_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.SubIndex);
|
||||||
hdr.aug_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.AugIndex);
|
hdr.aug_slot = (inst->GetMerchantSlot() ? 0xffff : slot_id.AugIndex);
|
||||||
hdr.price = inst->GetPrice();
|
hdr.price = inst->GetPrice();
|
||||||
hdr.merchant_slot = (inst->GetMerchantSlot() ? inst->GetMerchantCount() : 1);
|
hdr.merchant_slot = ((inst->GetMerchantSlot() ? inst->GetMerchantCount() : 1));
|
||||||
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
||||||
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
||||||
hdr.unknown028 = 0;
|
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
|
||||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||||
hdr.charges = (inst->IsStackable() ? (item->MaxCharges ? 1 : 0) : ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()));
|
hdr.charges = (inst->IsStackable() ? (item->MaxCharges ? 1 : 0) : ((inst->GetCharges() > 254)
|
||||||
hdr.inst_nodrop = (inst->IsAttuned() ? 1 : 0);
|
? 0xFFFFFFFF
|
||||||
hdr.unknown044 = 0;
|
: inst->GetCharges()));
|
||||||
hdr.unknown048 = 0;
|
hdr.inst_nodrop = (inst->IsAttuned() ? 1 : 0);
|
||||||
hdr.unknown052 = 0;
|
hdr.unknown044 = 0;
|
||||||
hdr.isEvolving = item->EvolvingItem;
|
hdr.unknown048 = 0;
|
||||||
|
hdr.unknown052 = 0;
|
||||||
|
hdr.isEvolving = item->EvolvingItem;
|
||||||
|
|
||||||
ob.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
ob.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
|
||||||
|
|
||||||
@@ -5513,9 +5645,10 @@ namespace RoF2
|
|||||||
|
|
||||||
ob.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
|
ob.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
|
||||||
|
|
||||||
if (strlen(item->Name) > 0)
|
if (strlen(item->Name) > 0) {
|
||||||
ob.write(item->Name, strlen(item->Name));
|
ob.write(item->Name, strlen(item->Name));
|
||||||
ob.write("\0", 1);
|
ob.write("\0", 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen(item->Lore) > 0)
|
if (strlen(item->Lore) > 0)
|
||||||
ob.write(item->Lore, strlen(item->Lore));
|
ob.write(item->Lore, strlen(item->Lore));
|
||||||
@@ -5676,10 +5809,11 @@ namespace RoF2
|
|||||||
itbs.unknown5 = 0;
|
itbs.unknown5 = 0;
|
||||||
|
|
||||||
itbs.potion_belt_enabled = item->PotionBelt;
|
itbs.potion_belt_enabled = item->PotionBelt;
|
||||||
itbs.potion_belt_slots = item->PotionBeltSlots;
|
itbs.potion_belt_slots = item->PotionBeltSlots;
|
||||||
itbs.stacksize = (inst->IsStackable() ? item->StackSize : 0);
|
itbs.stacksize =
|
||||||
itbs.no_transfer = item->NoTransfer;
|
item->ID == PARCEL_MONEY_ITEM_ID ? 0x7FFFFFFF : ((inst->IsStackable() ? item->StackSize : 0));
|
||||||
itbs.expendablearrow = item->ExpendableArrow;
|
itbs.no_transfer = item->NoTransfer;
|
||||||
|
itbs.expendablearrow = item->ExpendableArrow;
|
||||||
|
|
||||||
// Done to hack older clients to label expendable fishing poles as such
|
// Done to hack older clients to label expendable fishing poles as such
|
||||||
// July 28th, 2018 patch
|
// July 28th, 2018 patch
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ namespace RoF2
|
|||||||
slotCursor
|
slotCursor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr int16 format_as(InventorySlots slot) { return static_cast<int16>(slot); }
|
||||||
} // namespace enum_
|
} // namespace enum_
|
||||||
using namespace enum_;
|
using namespace enum_;
|
||||||
|
|
||||||
@@ -270,6 +271,7 @@ namespace RoF2
|
|||||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||||
|
|
||||||
const size_t SAY_LINK_BODY_SIZE = 56;
|
const size_t SAY_LINK_BODY_SIZE = 56;
|
||||||
|
const uint32 MAX_GUILD_ID = 50000;
|
||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ E(OP_GuildBank)
|
|||||||
E(OP_GuildMemberList)
|
E(OP_GuildMemberList)
|
||||||
E(OP_GuildMemberUpdate)
|
E(OP_GuildMemberUpdate)
|
||||||
E(OP_GuildsList)
|
E(OP_GuildsList)
|
||||||
|
E(OP_GuildTributeDonateItem)
|
||||||
E(OP_HPUpdate)
|
E(OP_HPUpdate)
|
||||||
E(OP_Illusion)
|
E(OP_Illusion)
|
||||||
E(OP_InspectBuffs)
|
E(OP_InspectBuffs)
|
||||||
@@ -115,7 +116,6 @@ E(OP_SendZonepoints)
|
|||||||
E(OP_SetGuildRank)
|
E(OP_SetGuildRank)
|
||||||
E(OP_ShopPlayerBuy)
|
E(OP_ShopPlayerBuy)
|
||||||
E(OP_ShopPlayerSell)
|
E(OP_ShopPlayerSell)
|
||||||
E(OP_ShopRequest)
|
|
||||||
E(OP_SkillUpdate)
|
E(OP_SkillUpdate)
|
||||||
E(OP_SomeItemPacketMaybe)
|
E(OP_SomeItemPacketMaybe)
|
||||||
E(OP_SpawnAppearance)
|
E(OP_SpawnAppearance)
|
||||||
@@ -150,6 +150,7 @@ D(OP_AugmentInfo)
|
|||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
D(OP_BlockedBuffs)
|
D(OP_BlockedBuffs)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_BuffRemoveRequest)
|
D(OP_BuffRemoveRequest)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
@@ -181,6 +182,7 @@ D(OP_GuildBank)
|
|||||||
D(OP_GuildDemote)
|
D(OP_GuildDemote)
|
||||||
D(OP_GuildRemove)
|
D(OP_GuildRemove)
|
||||||
D(OP_GuildStatus)
|
D(OP_GuildStatus)
|
||||||
|
D(OP_GuildTributeDonateItem)
|
||||||
D(OP_InspectRequest)
|
D(OP_InspectRequest)
|
||||||
D(OP_ItemLinkClick)
|
D(OP_ItemLinkClick)
|
||||||
D(OP_ItemVerifyRequest)
|
D(OP_ItemVerifyRequest)
|
||||||
@@ -197,7 +199,7 @@ D(OP_Save)
|
|||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerBuy)
|
D(OP_ShopPlayerBuy)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
D(OP_ShopRequest)
|
D(OP_ShopSendParcel)
|
||||||
D(OP_Trader)
|
D(OP_Trader)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
|
|||||||
+101
-49
@@ -2011,6 +2011,31 @@ struct GuildBankClear_Struct
|
|||||||
/*16*/ uint32 MainAreaCount;
|
/*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
|
** Money Loot
|
||||||
** Length: 22 Bytes
|
** Length: 22 Bytes
|
||||||
@@ -2222,15 +2247,17 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
{
|
||||||
/*004*/ uint32 playerid;
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
/*004*/ uint32 player_id;
|
||||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||||
/*016*/ int32 unknown01; // Seen 3 from Server or -1 from Client
|
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||||
/*024*/
|
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||||
|
/*024*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unknowns:
|
Unknowns:
|
||||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||||
@@ -2868,15 +2895,23 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint16 invslot; // Is the slot, but the RoF2 conversion causes it to fail. Turned to 0 since it isnt required anyway.
|
/*0004*/ TypelessInventorySlot_Struct invslot; // book ItemIndex (with int16_t alignment padding)
|
||||||
/*0006*/ int16 subslot; // Inventory sub-slot (0-x)
|
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0008*/ uint16 unknown006; // Seen FFFF
|
/*0016*/ uint32 target_id; // client's target when using the book
|
||||||
/*0010*/ uint16 unknown008; // seen 0000
|
/*0020*/ uint8 can_cast; // show Cast Spell button in book window
|
||||||
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0021*/ uint8 can_scribe; // show Scribe button in book window
|
||||||
/*0016*/ uint32 unknown0012;
|
/*0022*/ char txtfile[8194];
|
||||||
/*0020*/ uint16 unknown0016;
|
/*8216*/
|
||||||
/*0022*/ char txtfile[8194];
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ TypelessInventorySlot_Struct slot; // book ItemIndex (with int16_t alignment padding)
|
||||||
|
/*0008*/ int32 target_id; // client's target when using the book button
|
||||||
|
/*0012*/ int32 unused; // always 0 from button packets
|
||||||
|
/*0016*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3592,11 +3627,11 @@ struct GuildMakeLeader {
|
|||||||
// Update a guild members rank and banker status
|
// Update a guild members rank and banker status
|
||||||
struct GuildSetRank_Struct
|
struct GuildSetRank_Struct
|
||||||
{
|
{
|
||||||
/*00*/ uint32 GuildID; // Was Unknown00
|
/*00*/ uint32 guild_id; // Was Unknown00
|
||||||
/*04*/ uint32 Rank;
|
/*04*/ uint32 rank;
|
||||||
/*08*/ char MemberName[64];
|
/*08*/ char member_name[64];
|
||||||
/*72*/ uint32 Banker;
|
/*72*/ uint32 banker;
|
||||||
/*76*/ uint32 Unknown76; // Seen 1 - Maybe Banker?
|
/*76*/ uint32 unknown76; // Seen 1 - Maybe Banker?
|
||||||
/*80*/
|
/*80*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3611,7 +3646,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
struct GroundSpawn{
|
||||||
float max_x;
|
float max_x;
|
||||||
float max_y;
|
float max_y;
|
||||||
float min_x;
|
float min_x;
|
||||||
@@ -3623,8 +3658,8 @@ struct Ground_Spawn{
|
|||||||
uint32 max_allowed;
|
uint32 max_allowed;
|
||||||
uint32 respawntimer;
|
uint32 respawntimer;
|
||||||
};
|
};
|
||||||
struct Ground_Spawns {
|
struct GroundSpawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct PetitionBug_Struct{
|
//struct PetitionBug_Struct{
|
||||||
@@ -3714,15 +3749,15 @@ struct TributeItem_Struct
|
|||||||
|
|
||||||
struct TributePoint_Struct {
|
struct TributePoint_Struct {
|
||||||
int32 tribute_points;
|
int32 tribute_points;
|
||||||
uint32 unknown04;
|
uint32 unknown04;
|
||||||
int32 career_tribute_points;
|
int32 career_tribute_points;
|
||||||
uint32 unknown12;
|
uint32 unknown12;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TributeMoney_Struct {
|
struct TributeMoney_Struct {
|
||||||
uint32 platinum;
|
uint32 platinum;
|
||||||
uint32 tribute_master_id;
|
uint32 tribute_master_id;
|
||||||
int32 tribute_points;
|
int32 tribute_points;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -4190,9 +4225,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general;
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
@@ -4534,25 +4574,25 @@ struct RoF2SlotStruct
|
|||||||
|
|
||||||
struct ItemSerializationHeader
|
struct ItemSerializationHeader
|
||||||
{
|
{
|
||||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||||
/*017*/ uint32 stacksize;
|
/*017*/ uint32 stacksize;
|
||||||
/*021*/ uint32 unknown004;
|
/*021*/ uint32 unknown004;
|
||||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||||
/*026*/ uint16 main_slot;
|
/*026*/ uint16 main_slot;
|
||||||
/*028*/ uint16 sub_slot;
|
/*028*/ uint16 sub_slot;
|
||||||
/*030*/ uint16 aug_slot; // 0xffff
|
/*030*/ uint16 aug_slot; // 0xffff
|
||||||
/*032*/ uint32 price;
|
/*032*/ uint32 price;
|
||||||
/*036*/ uint32 merchant_slot; //1 if not a merchant item
|
/*036*/ uint32 merchant_slot; // 1 if not a merchant item
|
||||||
/*040*/ uint32 scaled_value; //0
|
/*040*/ uint32 scaled_value; // 0
|
||||||
/*044*/ uint32 instance_id; //unique instance id if not merchant item, else is merchant slot
|
/*044*/ uint32 instance_id; // unique instance id if not merchant item, else is merchant slot
|
||||||
/*048*/ uint32 unknown028; //0
|
/*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
|
/*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)
|
/*056*/ uint32 charges; // Total Charges an item has (-1 for unlimited)
|
||||||
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
|
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
|
||||||
/*064*/ uint32 unknown044; // 0
|
/*064*/ uint32 unknown044; // 0
|
||||||
/*068*/ uint32 unknown048; // 0
|
/*068*/ uint32 unknown048; // 0
|
||||||
/*072*/ uint32 unknown052; // 0
|
/*072*/ uint32 unknown052; // 0
|
||||||
uint8 isEvolving;
|
uint8 isEvolving;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EvolvingItem {
|
struct EvolvingItem {
|
||||||
@@ -5223,6 +5263,18 @@ struct Checksum_Struct {
|
|||||||
uint8_t data[2048];
|
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*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*RoF2*/
|
}; /*RoF2*/
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ E(OP_SendZonepoints)
|
|||||||
E(OP_SetGuildRank)
|
E(OP_SetGuildRank)
|
||||||
E(OP_ShopPlayerBuy)
|
E(OP_ShopPlayerBuy)
|
||||||
E(OP_ShopPlayerSell)
|
E(OP_ShopPlayerSell)
|
||||||
E(OP_ShopRequest)
|
|
||||||
E(OP_SkillUpdate)
|
E(OP_SkillUpdate)
|
||||||
E(OP_SomeItemPacketMaybe)
|
E(OP_SomeItemPacketMaybe)
|
||||||
E(OP_SpawnAppearance)
|
E(OP_SpawnAppearance)
|
||||||
@@ -183,7 +182,6 @@ D(OP_Save)
|
|||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerBuy)
|
D(OP_ShopPlayerBuy)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
D(OP_ShopRequest)
|
|
||||||
D(OP_Trader)
|
D(OP_Trader)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
|
|||||||
@@ -2200,15 +2200,17 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
{
|
||||||
/*004*/ uint32 playerid;
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
/*004*/ uint32 player_id;
|
||||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||||
/*016*/ int32 unknown01; // Seen 3 from Server or -1 from Client
|
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||||
/*024*/
|
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||||
|
/*024*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unknowns:
|
Unknowns:
|
||||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||||
@@ -3537,11 +3539,11 @@ struct GuildMakeLeader {
|
|||||||
// Update a guild members rank and banker status
|
// Update a guild members rank and banker status
|
||||||
struct GuildSetRank_Struct
|
struct GuildSetRank_Struct
|
||||||
{
|
{
|
||||||
/*00*/ uint32 GuildID; // Was Unknown00
|
/*00*/ uint32 guild_id; // Was Unknown00
|
||||||
/*04*/ uint32 Rank;
|
/*04*/ uint32 rank;
|
||||||
/*08*/ char MemberName[64];
|
/*08*/ char member_name[64];
|
||||||
/*72*/ uint32 Banker;
|
/*72*/ uint32 banker;
|
||||||
/*76*/ uint32 Unknown76; // Seen 1 - Maybe Banker?
|
/*76*/ uint32 unknown76; // Seen 1 - Maybe Banker?
|
||||||
/*80*/
|
/*80*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3556,7 +3558,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
struct GroundSpawn{
|
||||||
float max_x;
|
float max_x;
|
||||||
float max_y;
|
float max_y;
|
||||||
float min_x;
|
float min_x;
|
||||||
@@ -3568,8 +3570,8 @@ struct Ground_Spawn{
|
|||||||
uint32 max_allowed;
|
uint32 max_allowed;
|
||||||
uint32 respawntimer;
|
uint32 respawntimer;
|
||||||
};
|
};
|
||||||
struct Ground_Spawns {
|
struct GroundSpawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct PetitionBug_Struct{
|
//struct PetitionBug_Struct{
|
||||||
@@ -4136,9 +4138,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
+185
-95
@@ -34,6 +34,7 @@
|
|||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1686,88 +1687,124 @@ namespace SoD
|
|||||||
|
|
||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
*p = nullptr;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1782,6 +1819,9 @@ namespace SoD
|
|||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->invslot = ServerToSoDSlot(emu->invslot);
|
eq->invslot = ServerToSoDSlot(emu->invslot);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@@ -1986,6 +2026,19 @@ namespace SoD
|
|||||||
FINISH_ENCODE();
|
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)
|
ENCODE(OP_SomeItemPacketMaybe)
|
||||||
{
|
{
|
||||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||||
@@ -2467,8 +2520,8 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
float SpawnSize = emu->size;
|
float SpawnSize = emu->size;
|
||||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if (!((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQ::textures::materialCount);
|
PacketSize -= (sizeof(structs::Texture_Struct) * EQ::textures::materialCount);
|
||||||
@@ -2666,8 +2719,8 @@ namespace SoD
|
|||||||
|
|
||||||
Buffer += sizeof(structs::Spawn_Struct_Position);
|
Buffer += sizeof(structs::Spawn_Struct_Position);
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||||
@@ -2693,8 +2746,8 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||||
@@ -2817,6 +2870,17 @@ namespace SoD
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@@ -3324,37 +3388,47 @@ namespace SoD
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
IN(general.action);
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
IN(general.parameter);
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
IN_str(motd);
|
||||||
IN(general.action);
|
|
||||||
IN(general.parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case raidSetNote:
|
||||||
case 36: { // raidPlayerNote unhandled
|
{
|
||||||
break;
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
}
|
|
||||||
default: {
|
IN(general.action);
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
IN(general.parameter);
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
IN_str(note);
|
||||||
IN(action);
|
|
||||||
IN(parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3364,7 +3438,8 @@ namespace SoD
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
emu->invslot = SoDToServerSlot(eq->invslot);
|
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
@@ -3421,6 +3496,21 @@ namespace SoD
|
|||||||
FINISH_DIRECT_DECODE();
|
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(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ E(OP_SendCharInfo)
|
|||||||
E(OP_SendZonepoints)
|
E(OP_SendZonepoints)
|
||||||
E(OP_ShopPlayerBuy)
|
E(OP_ShopPlayerBuy)
|
||||||
E(OP_ShopPlayerSell)
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_ShopRequest)
|
||||||
E(OP_SomeItemPacketMaybe)
|
E(OP_SomeItemPacketMaybe)
|
||||||
E(OP_SpawnDoor)
|
E(OP_SpawnDoor)
|
||||||
E(OP_SpecialMesg)
|
E(OP_SpecialMesg)
|
||||||
@@ -103,6 +104,7 @@ D(OP_ApplyPoison)
|
|||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
@@ -140,6 +142,7 @@ D(OP_Save)
|
|||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerBuy)
|
D(OP_ShopPlayerBuy)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_ShopRequest)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
D(OP_TributeItem)
|
D(OP_TributeItem)
|
||||||
|
|||||||
@@ -1845,12 +1845,16 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
{
|
||||||
/*004*/ uint32 playerid;
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
/*004*/ uint32 player_id;
|
||||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
/*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:
|
Unknowns:
|
||||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||||
@@ -2351,12 +2355,21 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0012*/ uint32 unknown0012;
|
/*0012*/ uint32 target_id;
|
||||||
/*0016*/ uint16 unknown0016;
|
/*0016*/ uint8 can_cast;
|
||||||
/*0018*/ char txtfile[8194];
|
/*0017*/ uint8 can_scribe;
|
||||||
|
/*0018*/ char txtfile[8194];
|
||||||
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ int32 invslot;
|
||||||
|
/*0004*/ int32 target_id; // client's target when using the book
|
||||||
|
/*0008*/ int32 unused; // always 0 from button packets
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3017,7 +3030,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
struct GroundSpawn{
|
||||||
float max_x;
|
float max_x;
|
||||||
float max_y;
|
float max_y;
|
||||||
float min_x;
|
float min_x;
|
||||||
@@ -3029,8 +3042,8 @@ struct Ground_Spawn{
|
|||||||
uint32 max_allowed;
|
uint32 max_allowed;
|
||||||
uint32 respawntimer;
|
uint32 respawntimer;
|
||||||
};
|
};
|
||||||
struct Ground_Spawns {
|
struct GroundSpawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct PetitionBug_Struct{
|
//struct PetitionBug_Struct{
|
||||||
@@ -3583,9 +3596,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
+179
-89
@@ -33,6 +33,7 @@
|
|||||||
#include "sof_structs.h"
|
#include "sof_structs.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1356,88 +1357,124 @@ namespace SoF
|
|||||||
|
|
||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
*p = nullptr;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1452,6 +1489,9 @@ namespace SoF
|
|||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->invslot = ServerToSoFSlot(emu->invslot);
|
eq->invslot = ServerToSoFSlot(emu->invslot);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@@ -1643,6 +1683,19 @@ namespace SoF
|
|||||||
FINISH_ENCODE();
|
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)
|
ENCODE(OP_SomeItemPacketMaybe)
|
||||||
{
|
{
|
||||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||||
@@ -2261,6 +2314,17 @@ namespace SoF
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@@ -2729,37 +2793,47 @@ namespace SoF
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
IN(general.action);
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
IN(general.parameter);
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
IN_str(motd);
|
||||||
IN(general.action);
|
|
||||||
IN(general.parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case raidSetNote:
|
||||||
case 36: { // raidPlayerNote unhandled
|
{
|
||||||
break;
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
}
|
|
||||||
default: {
|
IN(general.action);
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
IN(general.parameter);
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
IN_str(general.leader_name);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
IN_str(general.player_name);
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
IN_str(note);
|
||||||
IN(action);
|
|
||||||
IN(parameter);
|
FINISH_VAR_DECODE();
|
||||||
FINISH_DIRECT_DECODE();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2769,7 +2843,8 @@ namespace SoF
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
emu->invslot = SoFToServerSlot(eq->invslot);
|
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
@@ -2812,6 +2887,21 @@ namespace SoF
|
|||||||
FINISH_DIRECT_DECODE();
|
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(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ E(OP_SendAATable)
|
|||||||
E(OP_SendCharInfo)
|
E(OP_SendCharInfo)
|
||||||
E(OP_SendZonepoints)
|
E(OP_SendZonepoints)
|
||||||
E(OP_ShopPlayerSell)
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_ShopRequest)
|
||||||
E(OP_SomeItemPacketMaybe)
|
E(OP_SomeItemPacketMaybe)
|
||||||
E(OP_SpawnDoor)
|
E(OP_SpawnDoor)
|
||||||
E(OP_SpecialMesg)
|
E(OP_SpecialMesg)
|
||||||
@@ -94,6 +95,7 @@ D(OP_AltCurrencySellSelection)
|
|||||||
D(OP_ApplyPoison)
|
D(OP_ApplyPoison)
|
||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_Bug)
|
D(OP_Bug)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
@@ -127,6 +129,7 @@ D(OP_ReadBook)
|
|||||||
D(OP_Save)
|
D(OP_Save)
|
||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_ShopRequest)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
D(OP_TributeItem)
|
D(OP_TributeItem)
|
||||||
|
|||||||
@@ -1859,12 +1859,16 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
{
|
||||||
/*004*/ uint32 playerid;
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
/*004*/ uint32 player_id;
|
||||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
/*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:
|
Unknowns:
|
||||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||||
@@ -2321,12 +2325,21 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0012*/ uint32 unknown0012;
|
/*0012*/ uint32 target_id;
|
||||||
/*0016*/ uint16 unknown0016;
|
/*0016*/ uint8 can_cast;
|
||||||
/*0018*/ char txtfile[8194];
|
/*0017*/ uint8 can_scribe;
|
||||||
|
/*0018*/ char txtfile[8194];
|
||||||
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ int32 invslot;
|
||||||
|
/*0004*/ int32 target_id; // client's target when using the book
|
||||||
|
/*0008*/ int32 unused; // always 0 from button packets
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2942,7 +2955,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
struct GroundSpawn{
|
||||||
float max_x;
|
float max_x;
|
||||||
float max_y;
|
float max_y;
|
||||||
float min_x;
|
float min_x;
|
||||||
@@ -2954,8 +2967,8 @@ struct Ground_Spawn{
|
|||||||
uint32 max_allowed;
|
uint32 max_allowed;
|
||||||
uint32 respawntimer;
|
uint32 respawntimer;
|
||||||
};
|
};
|
||||||
struct Ground_Spawns {
|
struct GroundSpawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct PetitionBug_Struct{
|
//struct PetitionBug_Struct{
|
||||||
@@ -3508,9 +3521,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
@@ -128,6 +128,15 @@
|
|||||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||||
|
|
||||||
|
#define SETUP_VAR_DECODE(emu_struct, eq_struct, var_field) \
|
||||||
|
unsigned char *__eq_buffer = __packet->pBuffer; \
|
||||||
|
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
||||||
|
auto size = strlen(in->var_field); \
|
||||||
|
__packet->size = sizeof(emu_struct) + size + 1; \
|
||||||
|
__packet->pBuffer = new unsigned char[__packet->size]; \
|
||||||
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||||
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||||
|
|
||||||
#define MEMSET_IN(emu_struct) \
|
#define MEMSET_IN(emu_struct) \
|
||||||
memset(__packet->pBuffer, 0, sizeof(emu_struct));
|
memset(__packet->pBuffer, 0, sizeof(emu_struct));
|
||||||
|
|
||||||
@@ -146,6 +155,9 @@
|
|||||||
delete[] __eq_buffer; \
|
delete[] __eq_buffer; \
|
||||||
p->SetOpcode(OP_Unknown);
|
p->SetOpcode(OP_Unknown);
|
||||||
|
|
||||||
|
#define FINISH_VAR_DECODE() \
|
||||||
|
delete[] __eq_buffer;
|
||||||
|
|
||||||
//call to finish an encoder using SETUP_DIRECT_DECODE
|
//call to finish an encoder using SETUP_DIRECT_DECODE
|
||||||
#define FINISH_DIRECT_DECODE() \
|
#define FINISH_DIRECT_DECODE() \
|
||||||
delete[] __eq_buffer;
|
delete[] __eq_buffer;
|
||||||
|
|||||||
+619
-5
@@ -33,6 +33,8 @@
|
|||||||
#include "../item_instance.h"
|
#include "../item_instance.h"
|
||||||
#include "titanium_structs.h"
|
#include "titanium_structs.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
#include "../guilds.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -663,6 +665,177 @@ namespace Titanium
|
|||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_SetGuildRank)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct);
|
||||||
|
|
||||||
|
eq->unknown00 = 0;
|
||||||
|
eq->unknown04 = 0;
|
||||||
|
|
||||||
|
//Translate older ranks to new values* /
|
||||||
|
switch (emu->rank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->rank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->rank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->rank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
eq->rank = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(eq->member_name, emu->member_name, sizeof(eq->member_name));
|
||||||
|
OUT(banker);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_SpawnAppearance)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(SpawnAppearance_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(SpawnAppearance_Struct, structs::SpawnAppearance_Struct);
|
||||||
|
|
||||||
|
OUT(spawn_id);
|
||||||
|
OUT(type);
|
||||||
|
OUT(parameter);
|
||||||
|
switch (emu->type) {
|
||||||
|
case AppearanceType::GuildRank: {
|
||||||
|
//Translate new ranks to old values* /
|
||||||
|
switch (emu->parameter) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->parameter = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->parameter = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->parameter = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AppearanceType::GuildShow: {
|
||||||
|
FAIL_ENCODE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_GuildsList)
|
||||||
|
{
|
||||||
|
EQApplicationPacket* in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
|
||||||
|
GuildsListMessaging_Struct glms{};
|
||||||
|
EQ::Util::MemoryStreamReader ss(reinterpret_cast<char *>(in->pBuffer), in->size);
|
||||||
|
cereal::BinaryInputArchive ar(ss);
|
||||||
|
ar(glms);
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_GuildsList, sizeof(structs::GuildsList_Struct));
|
||||||
|
auto out = (structs::GuildsList_Struct *) outapp->pBuffer;
|
||||||
|
|
||||||
|
for (auto const& g : glms.guild_detail) {
|
||||||
|
if (g.guild_id < Titanium::constants::MAX_GUILD_ID) {
|
||||||
|
strn0cpy(out->Guilds[g.guild_id].name, g.guild_name.c_str(), sizeof(out->Guilds[g.guild_id].name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_GuildMemberAdd)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(GuildMemberAdd_Struct)
|
||||||
|
SETUP_DIRECT_ENCODE(GuildMemberAdd_Struct, structs::GuildMemberAdd_Struct)
|
||||||
|
|
||||||
|
OUT(guild_id)
|
||||||
|
OUT(level)
|
||||||
|
OUT(class_)
|
||||||
|
switch (emu->rank_) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->rank_ = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->rank_ = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->rank_ = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OUT(zone_id)
|
||||||
|
OUT(last_on)
|
||||||
|
OUT_str(player_name)
|
||||||
|
|
||||||
|
FINISH_ENCODE()
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_GuildMemberRankAltBanker)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(GuildMemberRank_Struct)
|
||||||
|
SETUP_DIRECT_ENCODE(GuildMemberRank_Struct, structs::GuildMemberRank_Struct)
|
||||||
|
|
||||||
|
OUT(guild_id)
|
||||||
|
OUT(alt_banker)
|
||||||
|
OUT_str(player_name)
|
||||||
|
|
||||||
|
switch (emu->rank_) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->rank_ = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->rank_ = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->rank_ = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FINISH_ENCODE()
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_GuildMemberList)
|
ENCODE(OP_GuildMemberList)
|
||||||
{
|
{
|
||||||
//consume the packet
|
//consume the packet
|
||||||
@@ -726,12 +899,34 @@ namespace Titanium
|
|||||||
str += sl + 1; \
|
str += sl + 1; \
|
||||||
}
|
}
|
||||||
#define PutFieldN(field) e->field = htonl(emu_e->field)
|
#define PutFieldN(field) e->field = htonl(emu_e->field)
|
||||||
|
/* Translate new ranks to older values */
|
||||||
SlideStructString(name, emu_name);
|
SlideStructString(name, emu_name);
|
||||||
PutFieldN(level);
|
PutFieldN(level);
|
||||||
PutFieldN(banker);
|
PutFieldN(banker);
|
||||||
PutFieldN(class_);
|
PutFieldN(class_);
|
||||||
PutFieldN(rank);
|
switch (emu_e->rank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
e->rank = htonl(GUILD_MEMBER_TI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
e->rank = htonl(GUILD_OFFICER_TI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
e->rank = htonl(GUILD_LEADER_TI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
e->rank = htonl(GUILD_MEMBER_TI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
PutFieldN(time_last_on);
|
PutFieldN(time_last_on);
|
||||||
PutFieldN(tribute_enable);
|
PutFieldN(tribute_enable);
|
||||||
PutFieldN(total_tribute);
|
PutFieldN(total_tribute);
|
||||||
@@ -752,6 +947,38 @@ namespace Titanium
|
|||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_SendGuildTributes)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_ATLEAST(structs::GuildTributeAbility_Struct);
|
||||||
|
SETUP_VAR_ENCODE(GuildTributeAbility_Struct);
|
||||||
|
ALLOC_VAR_ENCODE(structs::GuildTributeAbility_Struct, sizeof(GuildTributeAbility_Struct) + strlen(emu->ability.name));
|
||||||
|
|
||||||
|
eq->guild_id = emu->guild_id;;
|
||||||
|
strncpy(eq->ability.name, emu->ability.name, strlen(emu->ability.name));
|
||||||
|
eq->ability.tribute_id = emu->ability.tribute_id;
|
||||||
|
eq->ability.tier_count = emu->ability.tier_count;
|
||||||
|
for (int i = 0; i < ntohl(emu->ability.tier_count); i++) {
|
||||||
|
eq->ability.tiers[i].cost = emu->ability.tiers[i].cost;
|
||||||
|
eq->ability.tiers[i].level = emu->ability.tiers[i].level;
|
||||||
|
eq->ability.tiers[i].tribute_item_id = emu->ability.tiers[i].tribute_item_id;
|
||||||
|
}
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_GuildTributeDonateItem)
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_ENCODE(GuildTributeDonateItemReply_Struct, structs::GuildTributeDonateItemReply_Struct);
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::Netcode, "UF::ENCODE(OP_GuildTributeDonateItem)");
|
||||||
|
|
||||||
|
OUT(quantity);
|
||||||
|
OUT(favor);
|
||||||
|
eq->unknown8 = 0;
|
||||||
|
eq->slot = ServerToTitaniumSlot(emu->slot);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_Illusion)
|
ENCODE(OP_Illusion)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(Illusion_Struct);
|
ENCODE_LENGTH_EXACT(Illusion_Struct);
|
||||||
@@ -866,11 +1093,60 @@ namespace Titanium
|
|||||||
|
|
||||||
ENCODE(OP_LFGuild)
|
ENCODE(OP_LFGuild)
|
||||||
{
|
{
|
||||||
|
struct bit_mask_conversion {
|
||||||
|
uint32 titanium_mask;
|
||||||
|
uint32 rof2_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<bit_mask_conversion> bit_mask = {
|
||||||
|
{.titanium_mask = 2, .rof2_mask = 256},
|
||||||
|
{.titanium_mask = 4, .rof2_mask = 32768},
|
||||||
|
{.titanium_mask = 8, .rof2_mask = 65536},
|
||||||
|
{.titanium_mask = 16, .rof2_mask = 4},
|
||||||
|
{.titanium_mask = 32, .rof2_mask = 64},
|
||||||
|
{.titanium_mask = 64, .rof2_mask = 16384},
|
||||||
|
{.titanium_mask = 128, .rof2_mask = 8192},
|
||||||
|
{.titanium_mask = 256, .rof2_mask = 128},
|
||||||
|
{.titanium_mask = 512, .rof2_mask = 2048},
|
||||||
|
{.titanium_mask = 1024, .rof2_mask = 8},
|
||||||
|
{.titanium_mask = 2048, .rof2_mask = 16},
|
||||||
|
{.titanium_mask = 4096, .rof2_mask = 512},
|
||||||
|
{.titanium_mask = 8192, .rof2_mask = 32},
|
||||||
|
{.titanium_mask = 16384, .rof2_mask = 1024},
|
||||||
|
{.titanium_mask = 32768, .rof2_mask = 2},
|
||||||
|
{.titanium_mask = 65536, .rof2_mask = 4096},
|
||||||
|
};
|
||||||
|
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
|
||||||
|
|
||||||
uint32 Command = in->ReadUInt32();
|
uint32 Command = in->ReadUInt32();
|
||||||
|
|
||||||
|
if (Command == 1) {
|
||||||
|
ENCODE_LENGTH_EXACT(LFGuild_GuildToggle_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(LFGuild_GuildToggle_Struct, structs::LFGuild_GuildToggle_Struct);
|
||||||
|
|
||||||
|
OUT(Command);
|
||||||
|
OUT_str(Comment);
|
||||||
|
OUT(FromLevel);
|
||||||
|
OUT(ToLevel);
|
||||||
|
OUT(AACount);
|
||||||
|
OUT(TimeZone);
|
||||||
|
OUT(Toggle);
|
||||||
|
OUT(TimePosted);
|
||||||
|
OUT_str(Name);
|
||||||
|
|
||||||
|
uint32 emu_bitmask = emu->Classes;
|
||||||
|
uint32 ti_bitmask = 0;
|
||||||
|
for (auto const& b : bit_mask) {
|
||||||
|
(emu_bitmask & b.rof2_mask) != 0 ? ti_bitmask |= b.titanium_mask : ti_bitmask &= ~b.titanium_mask;
|
||||||
|
}
|
||||||
|
eq->Classes = ti_bitmask;
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = nullptr;
|
||||||
if (Command != 0)
|
if (Command != 0)
|
||||||
{
|
{
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
@@ -1148,7 +1424,29 @@ namespace Titanium
|
|||||||
OUT(pvp);
|
OUT(pvp);
|
||||||
OUT(anon);
|
OUT(anon);
|
||||||
OUT(gm);
|
OUT(gm);
|
||||||
OUT(guildrank);
|
switch (emu->guildrank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->guildrank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->guildrank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->guildrank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
eq->guildrank = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
OUT(guildbanker);
|
OUT(guildbanker);
|
||||||
// OUT(unknown13054[8]);
|
// OUT(unknown13054[8]);
|
||||||
OUT(exp);
|
OUT(exp);
|
||||||
@@ -1245,6 +1543,119 @@ namespace Titanium
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_MarkRaidNPC)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(MarkNPC_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(MarkNPC_Struct, MarkNPC_Struct);
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||||
|
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
|
||||||
|
mnpcs->TargetID = emu->TargetID;
|
||||||
|
mnpcs->Number = emu->Number;
|
||||||
|
dest->QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_RaidUpdate)
|
||||||
|
{
|
||||||
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
switch (raid_gen->action)
|
||||||
|
{
|
||||||
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(raidGen.action);
|
||||||
|
OUT(raidGen.parameter);
|
||||||
|
OUT_str(raidGen.leader_name);
|
||||||
|
OUT_str(raidGen.player_name);
|
||||||
|
OUT(_class);
|
||||||
|
OUT(level);
|
||||||
|
OUT(isGroupLeader);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case raidSetMotd:
|
||||||
|
{
|
||||||
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
|
{
|
||||||
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
safe_delete(inapp);
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_ReadBook)
|
ENCODE(OP_ReadBook)
|
||||||
{
|
{
|
||||||
// no apparent slot translation needed
|
// no apparent slot translation needed
|
||||||
@@ -1469,6 +1880,19 @@ namespace Titanium
|
|||||||
FINISH_ENCODE();
|
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_SpecialMesg)
|
ENCODE(OP_SpecialMesg)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
@@ -1750,7 +2174,28 @@ namespace Titanium
|
|||||||
eq->beard = emu->beard;
|
eq->beard = emu->beard;
|
||||||
strcpy(eq->suffix, emu->suffix);
|
strcpy(eq->suffix, emu->suffix);
|
||||||
eq->petOwnerId = emu->petOwnerId;
|
eq->petOwnerId = emu->petOwnerId;
|
||||||
eq->guildrank = emu->guildrank;
|
switch (emu->guildrank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->guildrank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->guildrank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->guildrank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// eq->unknown0194[3] = emu->unknown0194[3];
|
// eq->unknown0194[3] = emu->unknown0194[3];
|
||||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; k++) {
|
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; k++) {
|
||||||
eq->equipment.Slot[k].Material = emu->equipment.Slot[k].Material;
|
eq->equipment.Slot[k].Material = emu->equipment.Slot[k].Material;
|
||||||
@@ -2091,6 +2536,34 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_GuildDemote)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::GuildDemoteStruct);
|
||||||
|
SETUP_DIRECT_DECODE(GuildDemoteStruct, structs::GuildDemoteStruct);
|
||||||
|
|
||||||
|
memcpy(emu->name, eq->name, sizeof(emu->name));
|
||||||
|
memcpy(emu->target, eq->target, sizeof(emu->target));
|
||||||
|
emu->rank = GUILD_MEMBER;
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECODE(OP_GuildTributeDonateItem)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::GuildTributeDonateItemRequest_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(GuildTributeDonateItemRequest_Struct, structs::GuildTributeDonateItemRequest_Struct);
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::Netcode, "UF::DECODE(OP_GuildTributeDonateItem)");
|
||||||
|
|
||||||
|
IN(quantity);
|
||||||
|
IN(tribute_master_id);
|
||||||
|
IN(guild_id);
|
||||||
|
|
||||||
|
emu->slot = TitaniumToServerSlot(eq->slot);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_InspectAnswer)
|
DECODE(OP_InspectAnswer)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::InspectResponse_Struct);
|
DECODE_LENGTH_EXACT(structs::InspectResponse_Struct);
|
||||||
@@ -2146,8 +2619,77 @@ namespace Titanium
|
|||||||
|
|
||||||
DECODE(OP_LFGuild)
|
DECODE(OP_LFGuild)
|
||||||
{
|
{
|
||||||
|
struct bit_mask_conversion {
|
||||||
|
uint32 titanium_mask;
|
||||||
|
uint32 rof2_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<bit_mask_conversion> bit_mask = {
|
||||||
|
{.titanium_mask = 2, .rof2_mask = 256},
|
||||||
|
{.titanium_mask = 4, .rof2_mask = 32768},
|
||||||
|
{.titanium_mask = 8, .rof2_mask = 65536},
|
||||||
|
{.titanium_mask = 16, .rof2_mask = 4},
|
||||||
|
{.titanium_mask = 32, .rof2_mask = 64},
|
||||||
|
{.titanium_mask = 64, .rof2_mask = 16384},
|
||||||
|
{.titanium_mask = 128, .rof2_mask = 8192},
|
||||||
|
{.titanium_mask = 256, .rof2_mask = 128},
|
||||||
|
{.titanium_mask = 512, .rof2_mask = 2048},
|
||||||
|
{.titanium_mask = 1024, .rof2_mask = 8},
|
||||||
|
{.titanium_mask = 2048, .rof2_mask = 16},
|
||||||
|
{.titanium_mask = 4096, .rof2_mask = 512},
|
||||||
|
{.titanium_mask = 8192, .rof2_mask = 32},
|
||||||
|
{.titanium_mask = 16384, .rof2_mask = 1024},
|
||||||
|
{.titanium_mask = 32768, .rof2_mask = 2},
|
||||||
|
{.titanium_mask = 65536, .rof2_mask = 4096},
|
||||||
|
};
|
||||||
|
|
||||||
uint32 Command = __packet->ReadUInt32();
|
uint32 Command = __packet->ReadUInt32();
|
||||||
|
|
||||||
|
if (Command == 3) {
|
||||||
|
DECODE_LENGTH_EXACT(structs::LFGuild_SearchPlayer_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(LFGuild_SearchPlayer_Struct, structs::LFGuild_SearchPlayer_Struct);
|
||||||
|
|
||||||
|
IN(Command);
|
||||||
|
IN(Unknown04);
|
||||||
|
IN(FromLevel);
|
||||||
|
IN(ToLevel);
|
||||||
|
IN(MinAA);
|
||||||
|
IN(TimeZone);
|
||||||
|
|
||||||
|
uint32 new_bitmask = 0;
|
||||||
|
uint32 ti_bitmask = eq->Classes;
|
||||||
|
for (auto const& b : bit_mask) {
|
||||||
|
(ti_bitmask & b.titanium_mask) != 0 ? new_bitmask |= b.rof2_mask : new_bitmask &= ~b.rof2_mask;
|
||||||
|
}
|
||||||
|
emu->Classes = new_bitmask;
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Command == 1) {
|
||||||
|
DECODE_LENGTH_EXACT(structs::LFGuild_GuildToggle_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(LFGuild_GuildToggle_Struct, structs::LFGuild_GuildToggle_Struct);
|
||||||
|
|
||||||
|
IN(Command);
|
||||||
|
IN_str(Comment);
|
||||||
|
IN(FromLevel);
|
||||||
|
IN(ToLevel);
|
||||||
|
IN(AACount);
|
||||||
|
IN(TimeZone);
|
||||||
|
IN(Toggle);
|
||||||
|
IN(TimePosted);
|
||||||
|
IN_str(Name);
|
||||||
|
|
||||||
|
uint32 new_bitmask = 0;
|
||||||
|
uint32 ti_bitmask = eq->Classes;
|
||||||
|
for (auto const& b : bit_mask) {
|
||||||
|
(ti_bitmask & b.titanium_mask) != 0 ? new_bitmask |= b.rof2_mask : new_bitmask &= ~b.rof2_mask;
|
||||||
|
}
|
||||||
|
emu->Classes = new_bitmask;
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Command != 0)
|
if (Command != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2272,6 +2814,63 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_RaidInvite)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
|
|
||||||
|
switch (rgs->action)
|
||||||
|
{
|
||||||
|
case raidSetMotd:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
|
||||||
|
auto len = 0;
|
||||||
|
if (__packet->size < sizeof(structs::RaidMOTD_Struct)) {
|
||||||
|
len = __packet->size - sizeof(structs::RaidGeneral_Struct);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len = sizeof(eq->motd);
|
||||||
|
}
|
||||||
|
|
||||||
|
strn0cpy(emu->motd, eq->motd, len > 1024 ? 1024 : len);
|
||||||
|
emu->motd[len - 1] = '\0';
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_ReadBook)
|
DECODE(OP_ReadBook)
|
||||||
{
|
{
|
||||||
// no apparent slot translation needed
|
// no apparent slot translation needed
|
||||||
@@ -2311,6 +2910,21 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
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(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||||
|
|||||||
@@ -287,6 +287,7 @@ namespace Titanium
|
|||||||
const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
|
const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
|
||||||
|
|
||||||
const size_t SAY_LINK_BODY_SIZE = 45;
|
const size_t SAY_LINK_BODY_SIZE = 45;
|
||||||
|
const uint32 MAX_GUILD_ID = 1500;
|
||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,14 @@ E(OP_DzSetLeaderName)
|
|||||||
E(OP_Emote)
|
E(OP_Emote)
|
||||||
E(OP_FormattedMessage)
|
E(OP_FormattedMessage)
|
||||||
E(OP_GroundSpawn)
|
E(OP_GroundSpawn)
|
||||||
|
E(OP_SetGuildRank)
|
||||||
|
E(OP_GuildsList)
|
||||||
E(OP_GuildMemberLevelUpdate)
|
E(OP_GuildMemberLevelUpdate)
|
||||||
E(OP_GuildMemberList)
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_GuildMemberAdd)
|
||||||
|
E(OP_GuildMemberRankAltBanker)
|
||||||
|
E(OP_SendGuildTributes)
|
||||||
|
E(OP_GuildTributeDonateItem)
|
||||||
E(OP_Illusion)
|
E(OP_Illusion)
|
||||||
E(OP_InspectAnswer)
|
E(OP_InspectAnswer)
|
||||||
E(OP_InspectRequest)
|
E(OP_InspectRequest)
|
||||||
@@ -61,12 +67,16 @@ E(OP_OnLevelMessage)
|
|||||||
E(OP_PetBuffWindow)
|
E(OP_PetBuffWindow)
|
||||||
E(OP_PlayerProfile)
|
E(OP_PlayerProfile)
|
||||||
E(OP_NewSpawn)
|
E(OP_NewSpawn)
|
||||||
|
E(OP_MarkRaidNPC)
|
||||||
|
E(OP_RaidUpdate)
|
||||||
E(OP_ReadBook)
|
E(OP_ReadBook)
|
||||||
E(OP_RespondAA)
|
E(OP_RespondAA)
|
||||||
E(OP_SendCharInfo)
|
E(OP_SendCharInfo)
|
||||||
E(OP_SendAATable)
|
E(OP_SendAATable)
|
||||||
E(OP_SetFace)
|
E(OP_SetFace)
|
||||||
E(OP_ShopPlayerSell)
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_ShopRequest)
|
||||||
|
E(OP_SpawnAppearance)
|
||||||
E(OP_SpecialMesg)
|
E(OP_SpecialMesg)
|
||||||
E(OP_TaskDescription)
|
E(OP_TaskDescription)
|
||||||
E(OP_Track)
|
E(OP_Track)
|
||||||
@@ -98,17 +108,21 @@ D(OP_DzRemovePlayer)
|
|||||||
D(OP_DzSwapPlayer)
|
D(OP_DzSwapPlayer)
|
||||||
D(OP_Emote)
|
D(OP_Emote)
|
||||||
D(OP_FaceChange)
|
D(OP_FaceChange)
|
||||||
|
D(OP_GuildDemote)
|
||||||
D(OP_InspectAnswer)
|
D(OP_InspectAnswer)
|
||||||
D(OP_InspectRequest)
|
D(OP_InspectRequest)
|
||||||
D(OP_ItemLinkClick)
|
D(OP_ItemLinkClick)
|
||||||
|
D(OP_GuildTributeDonateItem)
|
||||||
D(OP_LFGuild)
|
D(OP_LFGuild)
|
||||||
D(OP_LoadSpellSet)
|
D(OP_LoadSpellSet)
|
||||||
D(OP_LootItem)
|
D(OP_LootItem)
|
||||||
D(OP_MoveItem)
|
D(OP_MoveItem)
|
||||||
D(OP_PetCommands)
|
D(OP_PetCommands)
|
||||||
|
D(OP_RaidInvite)
|
||||||
D(OP_ReadBook)
|
D(OP_ReadBook)
|
||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_ShopRequest)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
D(OP_TributeItem)
|
D(OP_TributeItem)
|
||||||
|
|||||||
@@ -1423,6 +1423,23 @@ struct GuildUpdate_Struct {
|
|||||||
GuildsListEntry_Struct entry;
|
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
|
** Money Loot
|
||||||
** Length: 22 Bytes
|
** Length: 22 Bytes
|
||||||
@@ -1652,9 +1669,9 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct {
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*004*/ uint32 playerid;
|
/*004*/ uint32 player_id;
|
||||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||||
};
|
};
|
||||||
@@ -2604,7 +2621,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
struct GroundSpawn{
|
||||||
float max_x;
|
float max_x;
|
||||||
float max_y;
|
float max_y;
|
||||||
float min_x;
|
float min_x;
|
||||||
@@ -2616,8 +2633,8 @@ struct Ground_Spawn{
|
|||||||
uint32 max_allowed;
|
uint32 max_allowed;
|
||||||
uint32 respawntimer;
|
uint32 respawntimer;
|
||||||
};
|
};
|
||||||
struct Ground_Spawns {
|
struct GroundSpawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct PetitionBug_Struct{
|
//struct PetitionBug_Struct{
|
||||||
@@ -3017,23 +3034,39 @@ struct leadExpUpdateStruct {
|
|||||||
/*0028*/ uint32 unknown0028;
|
/*0028*/ uint32 unknown0028;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct RaidGeneral_Struct {
|
struct RaidGeneral_Struct {
|
||||||
/*00*/ uint32 action; //=10
|
/*000*/ uint32 action; //=10
|
||||||
/*04*/ char player_name[64]; //should both be the player's name
|
/*004*/ char player_name[64]; //should both be the player's name
|
||||||
/*04*/ char leader_name[64];
|
/*068*/ char leader_name[64];
|
||||||
/*132*/ uint32 parameter;
|
/*132*/ uint32 parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidAdd_Struct {
|
struct RaidAddMember_Struct {
|
||||||
/*000*/ uint32 action; //=0
|
/*000*/ RaidGeneral_Struct raidGen;
|
||||||
/*004*/ char player_name[64]; //should both be the player's name
|
/*136*/ uint8 _class;
|
||||||
/*068*/ char leader_name[64];
|
/*137*/ uint8 level;
|
||||||
/*132*/ uint8 _class;
|
/*138*/ uint8 isGroupLeader;
|
||||||
/*133*/ uint8 level;
|
/*139*/ uint8 unknown139; //seems to be 0x42 or 0
|
||||||
/*134*/ uint8 has_group;
|
};
|
||||||
/*135*/ uint8 unknown135; //seems to be 0x42 or 0
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*136*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RaidMOTD_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
|
/*136*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
/*000*/ uint32 action;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
// /*068*/ uint32 Unknown068;
|
||||||
|
/*072*/ char leader_name[64];
|
||||||
|
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||||
|
/*200*/ RaidLeadershipAA_Struct raid;
|
||||||
|
/*264*/ char Unknown264[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidCreate_Struct {
|
struct RaidCreate_Struct {
|
||||||
@@ -3492,7 +3525,7 @@ struct LFGuild_GuildToggle_Struct
|
|||||||
/*540*/ uint32 TimeZone;
|
/*540*/ uint32 TimeZone;
|
||||||
/*544*/ uint8 Toggle;
|
/*544*/ uint8 Toggle;
|
||||||
/*545*/ uint8 Unknown545[3];
|
/*545*/ uint8 Unknown545[3];
|
||||||
/*548*/ uint32 Expires;
|
/*548*/ uint32 TimePosted;
|
||||||
/*552*/ char Name[64];
|
/*552*/ char Name[64];
|
||||||
/*616*/
|
/*616*/
|
||||||
};
|
};
|
||||||
@@ -3683,6 +3716,34 @@ struct SayLinkBodyFrame_Struct {
|
|||||||
/*045*/
|
/*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+
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*Titanium*/
|
}; /*Titanium*/
|
||||||
|
|||||||
+489
-151
@@ -35,6 +35,8 @@
|
|||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../classes.h"
|
#include "../classes.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
#include "../guilds.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -194,7 +196,7 @@ namespace UF
|
|||||||
unsigned char *emu_buffer = in->pBuffer;
|
unsigned char *emu_buffer = in->pBuffer;
|
||||||
uint32 opcode = *((uint32*)emu_buffer);
|
uint32 opcode = *((uint32*)emu_buffer);
|
||||||
|
|
||||||
if (opcode == 8) {
|
if (opcode == AlternateCurrencyMode::Populate) {
|
||||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(
|
auto outapp = new EQApplicationPacket(
|
||||||
@@ -1133,6 +1135,30 @@ namespace UF
|
|||||||
PutFieldN(level);
|
PutFieldN(level);
|
||||||
PutFieldN(banker);
|
PutFieldN(banker);
|
||||||
PutFieldN(class_);
|
PutFieldN(class_);
|
||||||
|
//Translate older ranks to new values* /
|
||||||
|
switch (emu_e->rank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
emu_e->rank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
emu_e->rank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
emu_e->rank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
emu_e->rank = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
PutFieldN(rank);
|
PutFieldN(rank);
|
||||||
PutFieldN(time_last_on);
|
PutFieldN(time_last_on);
|
||||||
PutFieldN(tribute_enable);
|
PutFieldN(tribute_enable);
|
||||||
@@ -1156,53 +1182,142 @@ namespace UF
|
|||||||
|
|
||||||
ENCODE(OP_GuildsList)
|
ENCODE(OP_GuildsList)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket* in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
uint32 NumberOfGuilds = in->size / 64;
|
GuildsListMessaging_Struct glms{};
|
||||||
uint32 PacketSize = 68; // 64 x 0x00 + a uint32 that I am guessing is the highest guild ID in use.
|
EQ::Util::MemoryStreamReader ss(reinterpret_cast<char *>(in->pBuffer), in->size);
|
||||||
|
cereal::BinaryInputArchive ar(ss);
|
||||||
|
ar(glms);
|
||||||
|
|
||||||
unsigned char *__emu_buffer = in->pBuffer;
|
auto packet_size = 64 + 4 + glms.guild_detail.size() * 4 + glms.string_length;
|
||||||
char *InBuffer = (char *)__emu_buffer;
|
auto buffer = new uchar[packet_size];
|
||||||
uint32 HighestGuildID = 0;
|
auto buf_pos = buffer;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < NumberOfGuilds; ++i)
|
memset(buf_pos, 0, 64);
|
||||||
{
|
buf_pos += 64;
|
||||||
if (InBuffer[0])
|
|
||||||
{
|
VARSTRUCT_ENCODE_TYPE(uint32, buf_pos, glms.no_of_guilds);
|
||||||
PacketSize += (5 + strlen(InBuffer));
|
|
||||||
HighestGuildID = i - 1;
|
for (auto const& g : glms.guild_detail) {
|
||||||
|
if (g.guild_id < UF::constants::MAX_GUILD_ID) {
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf_pos, g.guild_id);
|
||||||
|
strn0cpy((char *) buf_pos, g.guild_name.c_str(), g.guild_name.length() + 1);
|
||||||
|
buf_pos += g.guild_name.length() + 1;
|
||||||
}
|
}
|
||||||
InBuffer += 64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketSize++; // Appears to be an extra 0x00 at the very end.
|
auto outapp = new EQApplicationPacket(OP_GuildsList);
|
||||||
in->size = PacketSize;
|
|
||||||
in->pBuffer = new unsigned char[in->size];
|
|
||||||
InBuffer = (char *)__emu_buffer;
|
|
||||||
char *OutBuffer = (char *)in->pBuffer;
|
|
||||||
|
|
||||||
// Init the first 64 bytes to zero, as per live.
|
outapp->size = packet_size;
|
||||||
//
|
outapp->pBuffer = buffer;
|
||||||
memset(OutBuffer, 0, 64);
|
|
||||||
OutBuffer += 64;
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, HighestGuildID);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < NumberOfGuilds; ++i)
|
ENCODE(OP_GuildMemberAdd)
|
||||||
{
|
{
|
||||||
if (InBuffer[0])
|
ENCODE_LENGTH_EXACT(GuildMemberAdd_Struct)
|
||||||
{
|
SETUP_DIRECT_ENCODE(GuildMemberAdd_Struct, structs::GuildMemberAdd_Struct)
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, i - 1);
|
|
||||||
VARSTRUCT_ENCODE_STRING(OutBuffer, InBuffer);
|
OUT(guild_id)
|
||||||
|
OUT(level)
|
||||||
|
OUT(class_)
|
||||||
|
switch (emu->rank_) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->rank_ = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->rank_ = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->rank_ = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
eq->rank_ = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
InBuffer += 64;
|
|
||||||
}
|
}
|
||||||
|
OUT(zone_id)
|
||||||
|
OUT(last_on)
|
||||||
|
OUT_str(player_name)
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0x00);
|
FINISH_ENCODE()
|
||||||
|
}
|
||||||
|
|
||||||
delete[] __emu_buffer;
|
ENCODE(OP_GuildMemberRankAltBanker)
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(GuildMemberRank_Struct)
|
||||||
|
SETUP_DIRECT_ENCODE(GuildMemberRank_Struct, structs::GuildMemberRank_Struct)
|
||||||
|
|
||||||
|
OUT(guild_id)
|
||||||
|
OUT(alt_banker)
|
||||||
|
OUT_str(player_name)
|
||||||
|
|
||||||
|
switch (emu->rank_) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->rank_ = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->rank_ = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->rank_ = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
eq->rank_ = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FINISH_ENCODE()
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_SendGuildTributes)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_ATLEAST(structs::GuildTributeAbility_Struct)
|
||||||
|
SETUP_VAR_ENCODE(GuildTributeAbility_Struct)
|
||||||
|
ALLOC_VAR_ENCODE(structs::GuildTributeAbility_Struct, sizeof(GuildTributeAbility_Struct) + strlen(emu->ability.name))
|
||||||
|
|
||||||
|
eq->guild_id = emu->guild_id;
|
||||||
|
eq->ability.tribute_id = emu->ability.tribute_id;
|
||||||
|
eq->ability.tier_count = emu->ability.tier_count;
|
||||||
|
strncpy(eq->ability.name, emu->ability.name, strlen(emu->ability.name));
|
||||||
|
for (int i = 0; i < ntohl(emu->ability.tier_count); i++) {
|
||||||
|
eq->ability.tiers[i].cost = emu->ability.tiers[i].cost;
|
||||||
|
eq->ability.tiers[i].level = emu->ability.tiers[i].level;
|
||||||
|
eq->ability.tiers[i].tribute_item_id = emu->ability.tiers[i].tribute_item_id;
|
||||||
|
}
|
||||||
|
FINISH_ENCODE()
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_GuildTributeDonateItem)
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_ENCODE(GuildTributeDonateItemReply_Struct, structs::GuildTributeDonateItemReply_Struct);
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::Netcode, "UF::ENCODE(OP_GuildTributeDonateItem)");
|
||||||
|
|
||||||
|
OUT(quantity)
|
||||||
|
OUT(favor)
|
||||||
|
eq->unknown8 = 0;
|
||||||
|
eq->slot = ServerToUFSlot(emu->slot);
|
||||||
|
|
||||||
|
FINISH_ENCODE()
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_Illusion)
|
ENCODE(OP_Illusion)
|
||||||
@@ -1828,6 +1943,30 @@ namespace UF
|
|||||||
OUT(pvp);
|
OUT(pvp);
|
||||||
OUT(anon);
|
OUT(anon);
|
||||||
OUT(gm);
|
OUT(gm);
|
||||||
|
//Translate older ranks to new values* /
|
||||||
|
switch (emu->guildrank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
emu->guildrank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
emu->guildrank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
emu->guildrank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
emu->guildrank = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
OUT(guildrank);
|
OUT(guildrank);
|
||||||
OUT(guildbanker);
|
OUT(guildbanker);
|
||||||
// OUT(unknown13054[12]);
|
// OUT(unknown13054[12]);
|
||||||
@@ -1931,88 +2070,124 @@ namespace UF
|
|||||||
|
|
||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
*p = nullptr;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2027,6 +2202,9 @@ namespace UF
|
|||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->invslot = ServerToUFSlot(emu->invslot);
|
eq->invslot = ServerToUFSlot(emu->invslot);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@@ -2260,6 +2438,19 @@ namespace UF
|
|||||||
FINISH_ENCODE();
|
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)
|
ENCODE(OP_SomeItemPacketMaybe)
|
||||||
{
|
{
|
||||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||||
@@ -2292,29 +2483,88 @@ namespace UF
|
|||||||
|
|
||||||
ENCODE(OP_SpawnAppearance)
|
ENCODE(OP_SpawnAppearance)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *in = *p;
|
ENCODE_LENGTH_EXACT(SpawnAppearance_Struct);
|
||||||
*p = nullptr;
|
SETUP_DIRECT_ENCODE(SpawnAppearance_Struct, structs::SpawnAppearance_Struct);
|
||||||
|
|
||||||
unsigned char *emu_buffer = in->pBuffer;
|
OUT(spawn_id);
|
||||||
|
OUT(type);
|
||||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
OUT(parameter);
|
||||||
|
switch (emu->type) {
|
||||||
if (sas->type != AT_Size)
|
case AppearanceType::GuildRank: {
|
||||||
{
|
//Translate new ranks to old values* /
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
switch (emu->parameter) {
|
||||||
return;
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
eq->parameter = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
eq->parameter = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
eq->parameter = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
eq->parameter = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AppearanceType::GuildShow: {
|
||||||
|
FAIL_ENCODE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_ChangeSize, sizeof(ChangeSize_Struct));
|
FINISH_ENCODE();
|
||||||
ChangeSize_Struct *css = (ChangeSize_Struct *)outapp->pBuffer;
|
}
|
||||||
|
|
||||||
css->EntityID = sas->spawn_id;
|
ENCODE(OP_SetGuildRank)
|
||||||
css->Size = (float)sas->parameter;
|
{
|
||||||
css->Unknown08 = 0;
|
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
|
||||||
css->Unknown12 = 1.0f;
|
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
eq->unknown00 = 0;
|
||||||
delete in;
|
eq->unknown04 = 0;
|
||||||
|
|
||||||
|
switch (emu->rank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
emu->rank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
emu->rank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
emu->rank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
emu->rank = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(eq->member_name, emu->member_name, sizeof(eq->member_name));
|
||||||
|
OUT(banker);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_SpawnDoor)
|
ENCODE(OP_SpawnDoor)
|
||||||
@@ -2718,7 +2968,7 @@ namespace UF
|
|||||||
if (strlen(emu->suffix))
|
if (strlen(emu->suffix))
|
||||||
PacketSize += strlen(emu->suffix) + 1;
|
PacketSize += strlen(emu->suffix) + 1;
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
if (emu->DestructibleObject)
|
if (emu->DestructibleObject)
|
||||||
PacketSize = PacketSize - 4; // No bodytype
|
PacketSize = PacketSize - 4; // No bodytype
|
||||||
@@ -2739,8 +2989,8 @@ namespace UF
|
|||||||
}
|
}
|
||||||
|
|
||||||
float SpawnSize = emu->size;
|
float SpawnSize = emu->size;
|
||||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if (!((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQ::textures::materialCount);
|
PacketSize -= (sizeof(structs::Texture_Struct) * EQ::textures::materialCount);
|
||||||
@@ -2807,7 +3057,7 @@ namespace UF
|
|||||||
|
|
||||||
uint8 OtherData = 0;
|
uint8 OtherData = 0;
|
||||||
|
|
||||||
if (emu->class_ == LDON_TREASURE) //Ldon chest
|
if (emu->class_ == Class::LDoNTreasure) //Ldon chest
|
||||||
{
|
{
|
||||||
OtherData = OtherData | 0x01;
|
OtherData = OtherData | 0x01;
|
||||||
}
|
}
|
||||||
@@ -2833,7 +3083,7 @@ namespace UF
|
|||||||
}
|
}
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
||||||
@@ -2905,6 +3155,30 @@ namespace UF
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID);
|
||||||
|
//Translate older ranks to new values* /
|
||||||
|
switch (emu->guildrank) {
|
||||||
|
case GUILD_SENIOR_MEMBER:
|
||||||
|
case GUILD_MEMBER:
|
||||||
|
case GUILD_JUNIOR_MEMBER:
|
||||||
|
case GUILD_INITIATE:
|
||||||
|
case GUILD_RECRUIT: {
|
||||||
|
emu->guildrank = GUILD_MEMBER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_OFFICER:
|
||||||
|
case GUILD_SENIOR_OFFICER: {
|
||||||
|
emu->guildrank = GUILD_OFFICER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GUILD_LEADER: {
|
||||||
|
emu->guildrank = GUILD_LEADER_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
emu->guildrank = GUILD_RANK_NONE_TI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank);
|
||||||
}
|
}
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_);
|
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_);
|
||||||
@@ -2942,8 +3216,8 @@ namespace UF
|
|||||||
|
|
||||||
Buffer += sizeof(structs::Spawn_Struct_Position);
|
Buffer += sizeof(structs::Spawn_Struct_Position);
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||||
@@ -2978,8 +3252,8 @@ namespace UF
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||||
@@ -3105,6 +3379,17 @@ namespace UF
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@@ -3526,6 +3811,34 @@ namespace UF
|
|||||||
DECODE_FORWARD(OP_GroupInvite);
|
DECODE_FORWARD(OP_GroupInvite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_GuildDemote)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::GuildDemoteStruct);
|
||||||
|
SETUP_DIRECT_DECODE(GuildDemoteStruct, structs::GuildDemoteStruct);
|
||||||
|
|
||||||
|
memcpy(emu->name, eq->name, sizeof(emu->name));
|
||||||
|
memcpy(emu->target, eq->target, sizeof(emu->target));
|
||||||
|
emu->rank = GUILD_MEMBER;
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECODE(OP_GuildTributeDonateItem)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::GuildTributeDonateItemRequest_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(GuildTributeDonateItemRequest_Struct, structs::GuildTributeDonateItemRequest_Struct);
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::Netcode, "UF::DECODE(OP_GuildTributeDonateItem)");
|
||||||
|
|
||||||
|
IN(quantity);
|
||||||
|
IN(tribute_master_id);
|
||||||
|
IN(guild_id);
|
||||||
|
|
||||||
|
emu->slot = UFToServerSlot(eq->slot);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_InspectRequest)
|
DECODE(OP_InspectRequest)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::Inspect_Struct);
|
DECODE_LENGTH_EXACT(structs::Inspect_Struct);
|
||||||
@@ -3623,39 +3936,48 @@ namespace UF
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
|
||||||
// we don't have a nice macro for this
|
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
__eq_buffer->motd[1023] = '\0';
|
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
|
||||||
IN(general.action);
|
|
||||||
IN(general.parameter);
|
|
||||||
FINISH_DIRECT_DECODE();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 36: { // raidPlayerNote unhandled
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
|
||||||
IN(action);
|
|
||||||
IN(parameter);
|
|
||||||
FINISH_DIRECT_DECODE();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (rgs->action)
|
||||||
|
{
|
||||||
|
case raidSetMotd:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(motd);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODE(OP_ReadBook)
|
DECODE(OP_ReadBook)
|
||||||
@@ -3664,7 +3986,8 @@ namespace UF
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
emu->invslot = UFToServerSlot(eq->invslot);
|
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
@@ -3721,6 +4044,21 @@ namespace UF
|
|||||||
FINISH_DIRECT_DECODE();
|
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(OP_TraderBuy)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ namespace UF
|
|||||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||||
|
|
||||||
const size_t SAY_LINK_BODY_SIZE = 50;
|
const size_t SAY_LINK_BODY_SIZE = 50;
|
||||||
|
const uint32 MAX_GUILD_ID = 50000;
|
||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ E(OP_GroupInvite)
|
|||||||
E(OP_GroupUpdate)
|
E(OP_GroupUpdate)
|
||||||
E(OP_GuildMemberList)
|
E(OP_GuildMemberList)
|
||||||
E(OP_GuildsList)
|
E(OP_GuildsList)
|
||||||
|
E(OP_GuildMemberAdd)
|
||||||
|
E(OP_SendGuildTributes)
|
||||||
|
E(OP_GuildMemberRankAltBanker)
|
||||||
|
E(OP_GuildTributeDonateItem)
|
||||||
E(OP_Illusion)
|
E(OP_Illusion)
|
||||||
E(OP_InspectBuffs)
|
E(OP_InspectBuffs)
|
||||||
E(OP_InspectRequest)
|
E(OP_InspectRequest)
|
||||||
@@ -82,8 +86,10 @@ E(OP_RespondAA)
|
|||||||
E(OP_SendAATable)
|
E(OP_SendAATable)
|
||||||
E(OP_SendCharInfo)
|
E(OP_SendCharInfo)
|
||||||
E(OP_SendZonepoints)
|
E(OP_SendZonepoints)
|
||||||
|
E(OP_SetGuildRank)
|
||||||
E(OP_ShopPlayerBuy)
|
E(OP_ShopPlayerBuy)
|
||||||
E(OP_ShopPlayerSell)
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_ShopRequest)
|
||||||
E(OP_SomeItemPacketMaybe)
|
E(OP_SomeItemPacketMaybe)
|
||||||
E(OP_SpawnAppearance)
|
E(OP_SpawnAppearance)
|
||||||
E(OP_SpawnDoor)
|
E(OP_SpawnDoor)
|
||||||
@@ -110,6 +116,7 @@ D(OP_ApplyPoison)
|
|||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_BuffRemoveRequest)
|
D(OP_BuffRemoveRequest)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
@@ -137,6 +144,8 @@ D(OP_GroupFollow)
|
|||||||
D(OP_GroupFollow2)
|
D(OP_GroupFollow2)
|
||||||
D(OP_GroupInvite)
|
D(OP_GroupInvite)
|
||||||
D(OP_GroupInvite2)
|
D(OP_GroupInvite2)
|
||||||
|
D(OP_GuildDemote)
|
||||||
|
D(OP_GuildTributeDonateItem)
|
||||||
D(OP_InspectRequest)
|
D(OP_InspectRequest)
|
||||||
D(OP_ItemLinkClick)
|
D(OP_ItemLinkClick)
|
||||||
D(OP_ItemVerifyRequest)
|
D(OP_ItemVerifyRequest)
|
||||||
@@ -150,6 +159,7 @@ D(OP_Save)
|
|||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerBuy)
|
D(OP_ShopPlayerBuy)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_ShopRequest)
|
||||||
D(OP_TraderBuy)
|
D(OP_TraderBuy)
|
||||||
D(OP_TradeSkillCombine)
|
D(OP_TradeSkillCombine)
|
||||||
D(OP_TributeItem)
|
D(OP_TributeItem)
|
||||||
|
|||||||
+75
-14
@@ -1670,6 +1670,15 @@ struct Surname_Struct
|
|||||||
/*0100*/
|
/*0100*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GuildSetRank_Struct
|
||||||
|
{
|
||||||
|
/*00*/ uint32 unknown00;
|
||||||
|
/*04*/ uint32 unknown04;
|
||||||
|
/*08*/ uint32 rank;
|
||||||
|
/*72*/ char member_name[64];
|
||||||
|
/*76*/ uint32 banker;
|
||||||
|
};
|
||||||
|
|
||||||
struct GuildsListEntry_Struct {
|
struct GuildsListEntry_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
};
|
};
|
||||||
@@ -1685,6 +1694,27 @@ struct GuildUpdate_Struct {
|
|||||||
GuildsListEntry_Struct entry;
|
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
|
** Money Loot
|
||||||
** Length: 22 Bytes
|
** Length: 22 Bytes
|
||||||
@@ -1886,9 +1916,9 @@ struct TimeOfDay_Struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Darvik: shopkeeper structs
|
// Darvik: shopkeeper structs
|
||||||
struct Merchant_Click_Struct {
|
struct MerchantClick_Struct {
|
||||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||||
/*004*/ uint32 playerid;
|
/*004*/ uint32 player_id;
|
||||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||||
};
|
};
|
||||||
@@ -2400,12 +2430,21 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0012*/ uint32 unknown0012;
|
/*0012*/ uint32 target_id;
|
||||||
/*0016*/ uint16 unknown0016;
|
/*0016*/ uint8 can_cast;
|
||||||
/*0018*/ char txtfile[8194];
|
/*0017*/ uint8 can_scribe;
|
||||||
|
/*0018*/ char txtfile[8194];
|
||||||
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ int32 invslot;
|
||||||
|
/*0004*/ int32 target_id; // client's target when using the book
|
||||||
|
/*0008*/ int32 unused; // always 0 from button packets
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3058,6 +3097,23 @@ struct GuildMakeLeader{
|
|||||||
char target[64];
|
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
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@@ -3069,7 +3125,7 @@ struct Make_Pet_Struct { //Simple struct for getting pet info
|
|||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
};
|
};
|
||||||
struct Ground_Spawn{
|
struct GroundSpawn{
|
||||||
float max_x;
|
float max_x;
|
||||||
float max_y;
|
float max_y;
|
||||||
float min_x;
|
float min_x;
|
||||||
@@ -3081,8 +3137,8 @@ struct Ground_Spawn{
|
|||||||
uint32 max_allowed;
|
uint32 max_allowed;
|
||||||
uint32 respawntimer;
|
uint32 respawntimer;
|
||||||
};
|
};
|
||||||
struct Ground_Spawns {
|
struct GroundSpawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct GroundSpawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct PetitionBug_Struct{
|
//struct PetitionBug_Struct{
|
||||||
@@ -3638,9 +3694,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general;
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user