mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-23 09:02:29 +00:00
Compare commits
820 Commits
task_scheduler
...
shm
| Author | SHA1 | Date | |
|---|---|---|---|
| c90f42eb8b | |||
| 5ce1fef9ec | |||
| 874ca053f7 | |||
| b8e7e5bb0d | |||
| 15f3697df1 | |||
| 16cfad1966 | |||
| bffeee8d1a | |||
| d29c0fc332 | |||
| a031c20e7e | |||
| 67d3cab80b | |||
| b41f2dac66 | |||
| b5b473f25d | |||
| 0dc3e5ba35 | |||
| 499fe153ab | |||
| d1349e5ac9 | |||
| bd8e94ff17 | |||
| d89b2f11b5 | |||
| 88ff56b2f2 | |||
| 1728923bbb | |||
| cbd1f42a08 | |||
| f8735cf9ba | |||
| eb00667eab | |||
| cbc0ada454 | |||
| 54b33f959e | |||
| c6e4b5647f | |||
| 928070e994 | |||
| 40ef4c799b | |||
| 8ba7ddd054 | |||
| 973fd376e5 | |||
| b5575133cd | |||
| 6f846dc4ff | |||
| 0461fc1789 | |||
| aa6264266e | |||
| c3cbe90575 | |||
| c2c6282cc7 | |||
| fab071d9da | |||
| 358bd60716 | |||
| 03ca345b37 | |||
| 6ddcc2bb8a | |||
| 02cac686b6 | |||
| 4c348baabd | |||
| 035bac1044 | |||
| 5a8d467d25 | |||
| ae959be5ac | |||
| 4157a03f32 | |||
| 41d0b1a947 | |||
| 3c71e2c91d | |||
| 80d1601754 | |||
| cfcbfea3ab | |||
| 7aa8db76f4 | |||
| 561433902e | |||
| abeb93f1e6 | |||
| ef0b29dc8e | |||
| 42f959329d | |||
| a898a1d07b | |||
| 803c3aabe4 | |||
| 15dde4778a | |||
| f2b68e6783 | |||
| 8193b04627 | |||
| 47e56f9381 | |||
| 58b9b719f4 | |||
| a4bf484c74 | |||
| 4712b56078 | |||
| 9362890d26 | |||
| 6d3848b2c7 | |||
| 8974059577 | |||
| 963735e7dd | |||
| c94a2496ca | |||
| ceb8b31bc0 | |||
| 51b31b5e53 | |||
| 6fb6d8891d | |||
| d4ea9bbee0 | |||
| 3a7908b1de | |||
| 99c1c826a8 | |||
| 1b888784eb | |||
| 52a25c3b78 | |||
| 4b08ce1237 | |||
| b94fdda429 | |||
| a48153baa1 | |||
| e26b159efe | |||
| a2b381bc9e | |||
| 60e194e32b | |||
| 1cdf507b9f | |||
| 3e98e60877 | |||
| af5022b3db | |||
| 52d2469da2 | |||
| e431c56f7c | |||
| 0ab7291625 | |||
| e384cf6149 | |||
| 463c0d9e0e | |||
| 0f92287c02 | |||
| 6a61fd5df9 | |||
| dac7541d89 | |||
| e7266943e2 | |||
| 7f25f8a235 | |||
| 240d5c2a66 | |||
| 785804a936 | |||
| e451dad94e | |||
| 08414bda55 | |||
| c39978d3d8 | |||
| f3d8271066 | |||
| 431a325414 | |||
| c42d6dcd1b | |||
| fa12b146a3 | |||
| e7fab67d8a | |||
| 6438a37fb5 | |||
| 899e2d3397 | |||
| 53be04c39c | |||
| bfecd6ad14 | |||
| dd1470892d | |||
| d4a1ea82dc | |||
| 8d252dfd9a | |||
| 1577f2823b | |||
| cede38f562 | |||
| 201757567c | |||
| 2a9248697e | |||
| 3708efd8df | |||
| 1d907564e9 | |||
| 1b15ee141d | |||
| d838ac9582 | |||
| dce5dea609 | |||
| 581d5b1289 | |||
| 4915e86aba | |||
| 09e9c0b504 | |||
| a3eb74b855 | |||
| fb396e9f60 | |||
| d85469dff9 | |||
| 3f7ce5df72 | |||
| d5b3dc7c0a | |||
| ac3b4ade10 | |||
| 482584f95a | |||
| 57e7b4a2b8 | |||
| 7f6414d685 | |||
| 81e91d7956 | |||
| 3875485567 | |||
| eb104e40de | |||
| bec33e22da | |||
| ac104ed4e0 | |||
| 0ffb5c46a5 | |||
| 92638504db | |||
| 08002eacea | |||
| 79248cffec | |||
| 8787f51b58 | |||
| 69f4d90737 | |||
| 1371e1e7ed | |||
| 81ff7f5d57 | |||
| 8376ed5d3f | |||
| fe4a0cfdba | |||
| 0043f56984 | |||
| 6ddc5ea8e8 | |||
| be38a62d70 | |||
| fdc38315d3 | |||
| e7c000813f | |||
| 6fb0042e3f | |||
| 0a4429c0c0 | |||
| a63dc7d5e0 | |||
| 67449de27e | |||
| 10e5f0e949 | |||
| 141ecca2bc | |||
| bd4fa4fb6b | |||
| 5901df4485 | |||
| 8cda4257b4 | |||
| 709a25ba9e | |||
| ed09d4ae54 | |||
| 952fd43301 | |||
| 5f8d193d6a | |||
| a4a70cf225 | |||
| 29fccd9239 | |||
| cdc82f0ba7 | |||
| 78756f27b6 | |||
| 2f5909d4cb | |||
| 13c2df7eb1 | |||
| 16ac6f624b | |||
| 501204a4d2 | |||
| 8bcef6c2e7 | |||
| 2db47adf7b | |||
| 916c88939c | |||
| 1528e7cb09 | |||
| 8dacadb4f9 | |||
| e19db3b7f4 | |||
| e1adffc4be | |||
| 7eb71c5902 | |||
| da397606b6 | |||
| 6b27e88315 | |||
| 4accb4ea2a | |||
| c419df52ff | |||
| 46ff09f438 | |||
| b4f42c150f | |||
| 49134644bc | |||
| 861b879a94 | |||
| 929e4c1317 | |||
| 138cb80b19 | |||
| 86b6f543b9 | |||
| d7138e84c0 | |||
| 2d24cdf5e4 | |||
| 4416e774c2 | |||
| 342012c4f4 | |||
| 34005cd2ed | |||
| 6bc6b659d5 | |||
| ad1f18306b | |||
| 6a984a53b5 | |||
| f9b3b7aecf | |||
| 5fefdfcc17 | |||
| 00f118cfb4 | |||
| a7633f4ddf | |||
| f742d6427b | |||
| d65a97e556 | |||
| b8229c8459 | |||
| 424b669cbb | |||
| e09b0ae1e9 | |||
| c2300d514c | |||
| f195820854 | |||
| 59903313e4 | |||
| b351d3718a | |||
| ab3d65b2ea | |||
| b02e87cce7 | |||
| 50a39057e4 | |||
| c8e6d031cf | |||
| 158d8a011f | |||
| 14c070f845 | |||
| 6dee837f67 | |||
| 83ad9c86db | |||
| bcb08f99f0 | |||
| f968d0df4c | |||
| 712366293d | |||
| 9689787e56 | |||
| 92d32feb0d | |||
| 371265d143 | |||
| 43da07fb55 | |||
| f880663528 | |||
| 63b8df72b2 | |||
| c82d08cf11 | |||
| c6ba29f2e5 | |||
| 6514ccc41c | |||
| 2f49266d08 | |||
| ff897dc90a | |||
| f73f72b2b2 | |||
| c2b3e85272 | |||
| c590cf7c35 | |||
| 453bee511a | |||
| 1baeb01e65 | |||
| 8b37ef5e67 | |||
| caceae1028 | |||
| 8e6dd638ff | |||
| 51fb7d8b77 | |||
| f6ed4bb888 | |||
| 9cc73f2b4a | |||
| 6f73278cf8 | |||
| 6c91786cfb | |||
| 8eb60302a2 | |||
| 43df845233 | |||
| feefd7a23b | |||
| 5a1eac010b | |||
| d47bf6a73b | |||
| daa9c04e89 | |||
| a9ef2474d4 | |||
| e1408ede6b | |||
| 4241fba7e2 | |||
| 139b6c34e5 | |||
| baf4cc62eb | |||
| 14402c9c41 | |||
| e4c4e5edb2 | |||
| e6a14beb2e | |||
| 945ca1278c | |||
| a307747c29 | |||
| 099da513ff | |||
| 607379110b | |||
| 7ce88b30ad | |||
| 28b0526857 | |||
| d5067c4c3a | |||
| 79db824a3c | |||
| 331032f4f4 | |||
| 61790ef195 | |||
| 9bdb70b2f0 | |||
| c438819ed6 | |||
| 7a791dda3c | |||
| 6366a3fa38 | |||
| 306a08b9ac | |||
| 467f8d7867 | |||
| 6c2100a650 | |||
| 9dacd0bd7a | |||
| 3c6cdd0905 | |||
| d1fb74ff5f | |||
| f81b9d8244 | |||
| b9e87abb3c | |||
| 451b0180c9 | |||
| 77ae4f0c3f | |||
| 852d951b65 | |||
| 4e8aec136e | |||
| eed4a648b4 | |||
| 720d314bb8 | |||
| e5ec277b5e | |||
| 47aa23e21e | |||
| 8ad11d0f85 | |||
| 6243a31644 | |||
| 958a6d939e | |||
| e27c4f4f7c | |||
| 662048cedc | |||
| 9dda9098a0 | |||
| 3a10131a00 | |||
| a94072e3ea | |||
| 40595de46b | |||
| d6d361f5eb | |||
| c48e8d8823 | |||
| 61d1c2d75c | |||
| 69d887b421 | |||
| e7ad57a37e | |||
| d50e5855c4 | |||
| 689493610f | |||
| 406b193206 | |||
| 6e4d9a915d | |||
| 3e0ded6c39 | |||
| 9a08b1be93 | |||
| d71afda954 | |||
| a9e4d1212e | |||
| a7479a628c | |||
| 67562e3e42 | |||
| 53a289a6bc | |||
| a5d41b02b7 | |||
| 0232a8a188 | |||
| 78d63165cb | |||
| ccce630cb2 | |||
| 59b2d18a95 | |||
| 54f73d7420 | |||
| 0f9c34cf3c | |||
| e531e68b6d | |||
| 233f26996b | |||
| ec5faea9b1 | |||
| 6b465c576d | |||
| 9481e9eb2d | |||
| b11528fbcc | |||
| 2f564d9651 | |||
| 4b6a1242f5 | |||
| 5fee9b2b3e | |||
| f9e822072f | |||
| 0643df3dbe | |||
| 8cb51eb253 | |||
| 07fd803d41 | |||
| 255c755169 | |||
| 77feaa9ac1 | |||
| fe18033b5d | |||
| 995fb6914e | |||
| 6c35611cd0 | |||
| 8a038e17e5 | |||
| 7678a905c8 | |||
| 80d8736276 | |||
| 20538e91a1 | |||
| 72f4f10dbb | |||
| c173936e32 | |||
| 71a1142f6b | |||
| f542913041 | |||
| 4695aa30ad | |||
| b222a619d7 | |||
| d23dccec82 | |||
| 25bd285be5 | |||
| af80b51bd3 | |||
| 4fa14e44aa | |||
| 4b69f56a65 | |||
| 2ab0ce19a7 | |||
| 8ef6feac9f | |||
| bc4e09cea4 | |||
| 81acd797b4 | |||
| c87b4f2ad4 | |||
| e050534378 | |||
| 2c8b51fcda | |||
| 0cb425b6dd | |||
| bd6e06aadb | |||
| ed67b461ea | |||
| 4e6018e3e8 | |||
| 1196abfda8 | |||
| efd710855e | |||
| ab35c3ed90 | |||
| e306e9ad0c | |||
| 08b8deaa4b | |||
| 326e1be09f | |||
| 7e724568a6 | |||
| 9910b07a4e | |||
| 35fe27eb5d | |||
| 86593798a9 | |||
| b8623bf6df | |||
| c90326f585 | |||
| a0de61a781 | |||
| a325a9978b | |||
| 40747ae5a3 | |||
| 598204d75c | |||
| 5fbda48c54 | |||
| b56bc29388 | |||
| b567e57971 | |||
| 9ced3270a0 | |||
| 0fcaf82038 | |||
| 05b3c89729 | |||
| e46fcdd48a | |||
| ea414a279e | |||
| 1553e44efb | |||
| 4437eef957 | |||
| 6b201fcbef | |||
| 8f3689e023 | |||
| c646942ed1 | |||
| 7de655ba76 | |||
| 6f83a39765 | |||
| 0bbf9d518e | |||
| 06ca5b009d | |||
| e788779be0 | |||
| 5f3d3a3539 | |||
| f402e96b96 | |||
| f012d13f0c | |||
| 147be47088 | |||
| 397619e2f9 | |||
| cd7584f512 | |||
| ed7ce38fe0 | |||
| dff23793c6 | |||
| 10c383fd86 | |||
| 2a8ab28551 | |||
| 769df9ce7b | |||
| b1704377da | |||
| c90bed9f69 | |||
| 40c835c576 | |||
| 15609ab1e8 | |||
| 316507adaf | |||
| 384b1b89c7 | |||
| 01b3b41bae | |||
| e2630d2b20 | |||
| dadeb01045 | |||
| 31914eb0b6 | |||
| a7bcc12eb6 | |||
| 566e6ea307 | |||
| 96e5adc8de | |||
| 6609728188 | |||
| 74ca949a5b | |||
| 194c61a467 | |||
| 3e50332c23 | |||
| 454a5c4527 | |||
| 135eaae402 | |||
| 8f5bd52e24 | |||
| 62be0c475e | |||
| 1c6971da4a | |||
| ff59255e63 | |||
| 653801a54b | |||
| 6a393afdf3 | |||
| b0efe88a03 | |||
| 7eb2e834b1 | |||
| 754ed71f9a | |||
| 4f538fbdad | |||
| 99ee4e04d9 | |||
| 7989451c36 | |||
| 4c9c070d67 | |||
| 058a722569 | |||
| 1d460bd636 | |||
| 47ee5b5afb | |||
| 7edfdbd9db | |||
| b9f57f1f28 | |||
| 579471afcc | |||
| 04e7238a6e | |||
| 0e9fae3181 | |||
| 37d4371acd | |||
| bcf0af0a8d | |||
| f17779efeb | |||
| 3aed0e257a | |||
| a26227f258 | |||
| db085b7126 | |||
| bca567d2f5 | |||
| c62d9040cb | |||
| abb1086e52 | |||
| 1f04938535 | |||
| 12204dd927 | |||
| b118864920 | |||
| af749cf07a | |||
| bf45e8b491 | |||
| abd14f556a | |||
| 29b90fbeaf | |||
| 6cecc85d17 | |||
| f3c85dc585 | |||
| 2e4868d3eb | |||
| 0005df31f7 | |||
| 1f3287759a | |||
| 3c345b9a9c | |||
| 895c8626b6 | |||
| 2965ab28e2 | |||
| 259bce9509 | |||
| 316d645f33 | |||
| 135b4aac34 | |||
| 0b3c489028 | |||
| cda6a1465b | |||
| 9a4a49fc9e | |||
| 118c6b5636 | |||
| 161edef2a8 | |||
| 54053f7e24 | |||
| 8ae76bc217 | |||
| fdf2fe71e1 | |||
| 5a600cd7c0 | |||
| 91a7ebbdfb | |||
| 3dbb5fab50 | |||
| 9bc96432be | |||
| 48cb96214a | |||
| 084e588843 | |||
| 11fdbb6a49 | |||
| 96ef76847b | |||
| 9a7ecb4e8d | |||
| 578fafb485 | |||
| 4e2b2aca6a | |||
| ae0eebe043 | |||
| 4e129ca7b5 | |||
| 1521e3810f | |||
| 2a18d7cd80 | |||
| d0b505f32d | |||
| 9c95d1bfa2 | |||
| 70ad517c14 | |||
| 265458a6da | |||
| 8ab2b15768 | |||
| cf80e594bc | |||
| 3128453eb6 | |||
| 655cb798c3 | |||
| 499c0fdca5 | |||
| 28d5c8f301 | |||
| 7911225960 | |||
| 1990ae970a | |||
| b41ae05dc4 | |||
| 8bb76ae2fe | |||
| e846fc4eea | |||
| e9f5c03141 | |||
| 8a26eaabf3 | |||
| a73df6aa09 | |||
| 420667a35b | |||
| b63821bbae | |||
| 51995ca7f2 | |||
| edf93f20e5 | |||
| 1e6a67e1ad | |||
| 4f20236440 | |||
| 40696a132b | |||
| 34a4db6302 | |||
| b2526ff6d6 | |||
| 6fcb97e153 | |||
| 3177b6ac46 | |||
| 3230d81d2c | |||
| 89dbdff925 | |||
| 5206983513 | |||
| 1bfbe51d89 | |||
| 0041d3e0da | |||
| fec567c2f3 | |||
| 4b61d00dfe | |||
| 4cba9439b9 | |||
| dad1efbeaa | |||
| ae781ee962 | |||
| 67d8d6d67d | |||
| b69fee5619 | |||
| f698571f35 | |||
| 891944a1ba | |||
| cc377f2659 | |||
| 6222132625 | |||
| 9e3f9f9749 | |||
| b8216a5d40 | |||
| 7154873091 | |||
| 052583d170 | |||
| 463aeea5a3 | |||
| a624b85ea1 | |||
| 4b77f573c0 | |||
| 1f928cd161 | |||
| b97696a8c0 | |||
| a428eb61a1 | |||
| 1515785ada | |||
| 8673aec9fd | |||
| 534bed1483 | |||
| 45278f80ca | |||
| 1e1b21f2bf | |||
| fcaa685e77 | |||
| 96103b09e0 | |||
| de38440c4f | |||
| 512880e316 | |||
| bd64d8e6b3 | |||
| e4bfc547cb | |||
| afa6358838 | |||
| c53c769a7c | |||
| 4ef481dbc0 | |||
| c887b7eae3 | |||
| eefe0dfbb7 | |||
| 8e1b6a23eb | |||
| c1b48b9931 | |||
| fceca6e72f | |||
| eb4592c3ae | |||
| f9536f9621 | |||
| c89cd9d3c4 | |||
| 2e98de3923 | |||
| 26e14c02b6 | |||
| b45fd24f9d | |||
| acae5d81ab | |||
| 89bfbe6bd2 | |||
| 3e4587cd57 | |||
| 076d393f79 | |||
| 44e3f28cb0 | |||
| b4339691f9 | |||
| b738f8852d | |||
| 405ed5447d | |||
| 70ba7c9c85 | |||
| c3a94766ea | |||
| 698d6d4ed2 | |||
| af4c630ede | |||
| b83c0f8bf9 | |||
| 1acb76bc74 | |||
| ed4fc74bd4 | |||
| b402e8f33d | |||
| c8e673c6d4 | |||
| 674dfc5fac | |||
| 2970afff67 | |||
| 2b1950d2e2 | |||
| 31cebb5793 | |||
| ccbbadc5ee | |||
| bfd0752c4d | |||
| 00c40f5d9e | |||
| 859252a270 | |||
| 2eb14a5c8a | |||
| be291d58b0 | |||
| 678c25e02c | |||
| 98cbb7d781 | |||
| d3803045bc | |||
| db5e511af3 | |||
| 585c07210d | |||
| b8624d0488 | |||
| 206b769731 | |||
| 5381dcead1 | |||
| 5c14bc92bd | |||
| 898aea80c7 | |||
| 69a3432898 | |||
| 1acf78101f | |||
| 0d6d78ebda | |||
| a534ab83ec | |||
| 3092a8ba3b | |||
| d341a1b38f | |||
| 276804604c | |||
| 836f842f23 | |||
| 4fbce7d5d6 | |||
| 34cb51c449 | |||
| f837d423ef | |||
| 5ce71b7923 | |||
| 9520499103 | |||
| 7749f83134 | |||
| 5a852d4780 | |||
| 712e403528 | |||
| 581a0ec212 | |||
| bb02af2548 | |||
| 852cc9119e | |||
| 72a922f2ba | |||
| c0575892cb | |||
| 377c569635 | |||
| 5e60fcdc0c | |||
| 4d1d9df05d | |||
| c6c4480061 | |||
| c2794b244d | |||
| 83cae7aaf3 | |||
| 08d197fe15 | |||
| 5a0fcdfefd | |||
| 49094bcfbc | |||
| 6fb1d95518 | |||
| bf25937ee0 | |||
| 05e7c473df | |||
| c149e6ca5f | |||
| 537e3931ef | |||
| 9476f9e417 | |||
| 1f4753b719 | |||
| 65c05f227b | |||
| ef6b2976a3 | |||
| 7b4908957d | |||
| 963da70506 | |||
| 1ef577bc25 | |||
| a2364023c4 | |||
| 1c6a76246f | |||
| 8c17c42a10 | |||
| e9cb8781bf | |||
| 04a18786f9 | |||
| 20bd37dde7 | |||
| 665efe09f3 | |||
| a28ea6419f | |||
| 9f25c9070c | |||
| 57354579aa | |||
| 25a5310f49 | |||
| 66ee0dc9bd | |||
| f39684b7f7 | |||
| f06ff14f9e | |||
| 661ad09291 | |||
| 9708bd38c4 | |||
| 8a2fce83e0 | |||
| 2081b0e214 | |||
| eaf31fb14b | |||
| d2e7cf96bd | |||
| 24d2a5723b | |||
| 17c8af3814 | |||
| 69bad593cd | |||
| 0884c57928 | |||
| 461931f5bd | |||
| 0d76e224fd | |||
| ea15e9bc5f | |||
| 5fce042a31 | |||
| 6a64d845c2 | |||
| 19c92173d2 | |||
| 880de837d9 | |||
| 8df7bcc2c8 | |||
| d9eeb00dea | |||
| a6af014d5e | |||
| 758a1af6ae | |||
| f1ee042de6 | |||
| 2014b6c251 | |||
| 8fa76b9154 | |||
| 9f6976e852 | |||
| b117be29fb | |||
| d3641be6c0 | |||
| 06fbd7103e | |||
| acef4c0264 | |||
| b62944c5fb | |||
| 8065cdb89d | |||
| 20530ed3cf | |||
| 4aa8cecc55 | |||
| 4ec210c411 | |||
| 4de85ff836 | |||
| ba6009730b | |||
| b0d33f094d | |||
| 5ff0f4851e | |||
| 63e1599e9b | |||
| 4498819fad | |||
| e56edd9231 | |||
| b754ddbc67 | |||
| 3f2f7b3929 | |||
| 9297fc38f6 | |||
| 581cbccad5 | |||
| 4aca39ad9b | |||
| 5a7186305d | |||
| e92d130538 | |||
| 7c2ee06355 | |||
| f6259af22b | |||
| 25c119b843 | |||
| 6d9bcfe39f | |||
| ce09aad28a | |||
| 949e7adff8 | |||
| 7b808ee6e0 | |||
| 2a927c5c80 | |||
| 6e550ecc75 | |||
| 839baba553 | |||
| 5c2ac5ab24 | |||
| 553d9aca6f | |||
| 910dfaf082 | |||
| 9730917d73 | |||
| 32e8a0fa45 | |||
| 193dbe5938 | |||
| 86943ce6be | |||
| 739f54bbfb | |||
| b165760f18 | |||
| 1a577014d9 | |||
| 54ea7d7c4b | |||
| 0111e9a5d0 | |||
| 0c2d26579a | |||
| 8eaeda5ec5 | |||
| 8c75cf1ff5 | |||
| d8f34651de | |||
| c2917a9004 | |||
| 5473457c0c | |||
| 392b328a95 | |||
| 4bc6493718 | |||
| 78d8b909be | |||
| 7d71163fa0 | |||
| 0668f41de2 | |||
| a9969e500b | |||
| 3eb102a006 | |||
| 9d3ece8133 | |||
| b2ed5fe479 | |||
| 86f9a205e5 | |||
| f0937c3963 | |||
| ffd652a643 | |||
| feea52f79e | |||
| 2c922876a9 | |||
| b41e58fd10 | |||
| 8b582730a8 | |||
| d5eb015533 | |||
| 8ad4ef503b | |||
| a914e97c29 | |||
| 126d8edc57 | |||
| d17cfff8fe | |||
| 1a5ce7a9de | |||
| bd2836db61 | |||
| ff5783965a | |||
| 7fcf6b51d8 | |||
| eea3965d02 | |||
| d40b95f2e8 | |||
| dc9e4e8260 | |||
| 8c25486112 | |||
| 9613d128ae | |||
| 11bc21f99f | |||
| cdfd473476 | |||
| bb7cae46c5 | |||
| c7e196e26d | |||
| daec42c4d9 | |||
| b04d71ff45 | |||
| fbebec03ae | |||
| 217c9751a8 | |||
| 9e0f440106 | |||
| 6638b9ade5 | |||
| ea02042ace | |||
| 4e7bcd86ff | |||
| 682054970c | |||
| 8bb909090b | |||
| 1aab23098a | |||
| 6da0f84e18 | |||
| b2dd3df1e2 | |||
| 3ec500244e | |||
| 4425e3ab49 | |||
| 413c006785 | |||
| ae3052fbd1 | |||
| f6c8d9532e | |||
| 5f23a72a16 | |||
| 26eb4fb6e0 | |||
| 8be23a1214 | |||
| 44f85f140c | |||
| a73bf221ed | |||
| f16faae964 | |||
| e0391dfcb8 | |||
| cc0034fd3c | |||
| 3fdfc82ca0 | |||
| 0ec53eff52 | |||
| 7a778c549f | |||
| 3ee5730890 | |||
| 569a907e43 | |||
| 5bbeec626c | |||
| 6b70faf141 |
@@ -0,0 +1,21 @@
|
||||
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.101.1/containers/ubuntu-18.04-git
|
||||
{
|
||||
"name": "Ubuntu 18.04 EQEMU",
|
||||
// Moved from dockerfile to image so it builds faster
|
||||
"image": "eqemu/devcontainer:0.0.2",
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": ["ms-vscode.cpptools", "ms-azuretools.vscode-docker"],
|
||||
"mounts": ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"],
|
||||
"remoteEnv": {
|
||||
"HOST_PROJECT_PATH": "${localWorkspaceFolder}"
|
||||
}
|
||||
}
|
||||
+25
-1
@@ -17,6 +17,8 @@
|
||||
*.out
|
||||
*.app
|
||||
|
||||
.bash_history
|
||||
|
||||
# CMake
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
@@ -27,6 +29,28 @@ install_manifest.txt
|
||||
log/
|
||||
logs/
|
||||
vcpkg/
|
||||
perl/
|
||||
|
||||
.idea/*
|
||||
*cbp
|
||||
*cbp
|
||||
|
||||
submodules/*
|
||||
cmake-build-debug/
|
||||
|
||||
.nfs.*
|
||||
|
||||
# Visual Studio and CMAKE Generated Files
|
||||
/.vs/
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.cmake
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.dir/
|
||||
libs/
|
||||
bin/
|
||||
/Win32
|
||||
/x64
|
||||
/client_files/**/CMakeFiles/
|
||||
|
||||
@@ -16,3 +16,6 @@
|
||||
[submodule "submodules/recastnavigation"]
|
||||
path = submodules/recastnavigation
|
||||
url = https://github.com/EQEmu/recastnavigation.git
|
||||
[submodule "submodules/expected"]
|
||||
path = submodules/expected
|
||||
url = https://github.com/TartanLlama/expected.git
|
||||
|
||||
+11
-19
@@ -1,26 +1,18 @@
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
dist: trusty
|
||||
dist: bionic
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo apt-get update -qq
|
||||
- mkdir $HOME/usr
|
||||
- export PATH="$HOME/usr/bin:$PATH"
|
||||
- wget https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.sh
|
||||
- chmod +x cmake-3.11.2-Linux-x86_64.sh
|
||||
- ./cmake-3.11.2-Linux-x86_64.sh --prefix=$HOME/usr --exclude-subdir --skip-license
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libmysqlclient-dev
|
||||
- libperl-dev
|
||||
- libboost-dev
|
||||
- liblua5.1-0-dev
|
||||
- zlib1g-dev
|
||||
- uuid-dev
|
||||
- libssl-dev
|
||||
|
||||
install:
|
||||
- sudo apt-get install -qq g++-7
|
||||
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90
|
||||
- sudo apt-get install libmysqlclient-dev
|
||||
- sudo apt-get install libperl-dev
|
||||
- sudo apt-get install libboost-dev
|
||||
- sudo apt-get install liblua5.1-0-dev
|
||||
- sudo apt-get install zlib1g-dev
|
||||
- sudo apt-get install uuid-dev
|
||||
- sudo apt-get install libssl-dev
|
||||
script:
|
||||
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
||||
- make -j2
|
||||
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"/usr/include/mysql"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
+155
@@ -0,0 +1,155 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "make",
|
||||
"type": "shell",
|
||||
"command": "cd build && make",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "make clean",
|
||||
"type": "shell",
|
||||
"command": "cd build && make clean",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "cmake",
|
||||
"type": "shell",
|
||||
"command": "mkdir -p build && cd build && rm CMakeCache.txt && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' ..",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher":{
|
||||
"owner": "cpp",
|
||||
"fileLocation": "relative",
|
||||
"pattern":[
|
||||
{
|
||||
"regexp": "([\\w+|\\\\]*\\.\\w+)\\((\\d+)\\)\\: (warning|error) (.*)$",
|
||||
"file": 1,
|
||||
"location": 2,
|
||||
"severity": 3,
|
||||
"message": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "download maps",
|
||||
"type": "shell",
|
||||
"command": "mkdir -p build/bin && cd build/bin && wget https://codeload.github.com/Akkadius/EQEmuMaps/zip/master -O maps.zip && unzip -o maps.zip && rm ./maps -rf && mv EQEmuMaps-master maps && rm maps.zip",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "download quests",
|
||||
"type": "shell",
|
||||
"command": "mkdir -p build/bin && cd build/bin && cd server && git -C ./quests pull 2> /dev/null || git clone https://github.com/ProjectEQ/projecteqquests.git quests",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "download eqemu_config",
|
||||
"type": "shell",
|
||||
"command": "mkdir -p build/bin && cd build/bin && wget --no-check-certificate https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/eqemu_config_docker.json -O eqemu_config.json",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "rebuild database (mariadb must be started)",
|
||||
"type": "shell",
|
||||
"command": "mkdir -p build/bin && cd build/bin && docker run -i --rm --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --network=eqemu -it eqemu/server:0.0.3 bash -c './eqemu_server.pl source_peq_db && ./eqemu_server.pl check_db_updates && ./eqemu_server.pl linux_login_server_setup'",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "zone 7000",
|
||||
"type": "shell",
|
||||
"command": "docker stop zone7000 | true && docker network create eqemu | true && docker run -i --rm --name zone7000 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu -p 7000:7000/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7000:7000",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "zone 7001",
|
||||
"type": "shell",
|
||||
"command": "docker stop zone7001 | true && docker network create eqemu | true && docker run -i --rm --name zone7001 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu -p 7001:7001/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7001:7001",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "loginserver",
|
||||
"type": "shell",
|
||||
"command": "docker stop loginserver | true && docker network create eqemu | true && docker run -i --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu --name loginserver -p 5999:5999/udp -p 5998:5998/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./loginserver",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "shared_memory, world",
|
||||
"type": "shell",
|
||||
"command": "docker stop sharedmemory | true && docker stop world | true && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --network=eqemu --name sharedmemory eqemu/server:0.0.3 ./shared_memory && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name world -p 9000:9000 -p 9000:9000/udp -p 9001:9001 -p 9080:9080 eqemu/server:0.0.3 gdb -ex run ./world",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "queryserv",
|
||||
"type": "shell",
|
||||
"command": "docker stop queryserv | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name queryserv eqemu/server:0.0.3 gdb -ex run ./queryserv",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "mariadb",
|
||||
"type": "shell",
|
||||
"command": "docker stop mariadb | true && cd build/bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin/db:/bitnami/mariadb -p 3306:3306 -e MARIADB_DATABASE=peq -e MARIADB_USER=eqemu -e MARIADB_PASSWORD=eqemupass -e ALLOW_EMPTY_PASSWORD=yes --name mariadb --network=eqemu bitnami/mariadb:latest",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
# Guide To Building From Source Without Installer
|
||||
|
||||
This guide is far from exhaustive, you should expect to have some experience with building C++ code before considering compiling the code from scratch. You should instead consider using the installer scripts if you don't want to hack on the code directly.
|
||||
|
||||
### CMake
|
||||
|
||||
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source.
|
||||
|
||||
### Dependencies
|
||||
|
||||
The following libraries are required to build from source:
|
||||
- [boost](https://www.boost.org/ "boost")
|
||||
- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead)
|
||||
- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb")
|
||||
|
||||
The following libraries are not strictly required but in many cased recommended.
|
||||
- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client)
|
||||
- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver)
|
||||
- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting)
|
||||
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
|
||||
|
||||
##### Windows
|
||||
For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies.
|
||||
|
||||
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
|
||||
|
||||
You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake.
|
||||
|
||||
##### Linux
|
||||
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
|
||||
|
||||
sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev
|
||||
|
||||
### Running CMake
|
||||
|
||||
##### Windows
|
||||
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
|
||||
|
||||
Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
|
||||
|
||||
##### Linux
|
||||
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
||||
|
||||
### Building
|
||||
|
||||
##### Windows
|
||||
Inside the build directory a file EQEmu.sln should be produced by a successful run of the CMake command. You can either open this with Visual Studio or build it directly with MSBuild via the command line.
|
||||
|
||||
msbuild EQEmu.sln /p:Configuration=Release
|
||||
|
||||
##### Linux
|
||||
From the build directory you can simply call make to build.
|
||||
|
||||
For example.
|
||||
|
||||
make -j4
|
||||
+275
-306
@@ -1,128 +1,28 @@
|
||||
#EQEmu CMake
|
||||
#Variables used:
|
||||
#EQEMU_DISABLE_CRT_SECURE_WARNINGS
|
||||
#EQEMU_FAST_FLOATINGPOINT
|
||||
#EQEMU_ENABLE_CRASH_LOGGING
|
||||
#EQEMU_DISABLE_SAFESEH
|
||||
#EQEMU_BUILD_MSVC_MP
|
||||
#EQEMU_DEBUG_LEVEL
|
||||
#EQEMU_LOG_LEVEL_STATUS
|
||||
#EQEMU_LOG_LEVEL_NORMAL
|
||||
#EQEMU_LOG_LEVEL_ERROR
|
||||
#EQEMU_LOG_LEVEL_DEBUG
|
||||
#EQEMU_LOG_LEVEL_QUEST
|
||||
#EQEMU_LOG_LEVEL_COMMANDS
|
||||
#EQEMU_LOG_LEVEL_CRASH
|
||||
#EQEMU_DEPOP_INVALIDATES_CACHE
|
||||
#EQEMU_ENABLE_BOTS
|
||||
#EQEMU_DISABLE_LOGSYS
|
||||
#EQEMU_COMMANDS_LOGGING
|
||||
#EQEMU_BUILD_SERVER
|
||||
#EQEMU_BUILD_LOGIN
|
||||
#EQEMU_BUILD_TESTS
|
||||
#EQEMU_BUILD_PERL
|
||||
#EQEMU_BUILD_LUA
|
||||
#EQEMU_SANITIZE_LUA_LIBS
|
||||
#EQEMU_BUILD_CLIENT_FILES
|
||||
#EQEMU_USE_MAP_MMFS
|
||||
#EQEMU_MAP_DIR
|
||||
#EQEMU_ARCH
|
||||
#EQEMU_ARCH_ALT
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
IF(POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
ENDIF()
|
||||
|
||||
#FindMySQL is located here so lets make it so CMake can find it
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||
|
||||
#Our project name is EQEmu
|
||||
IF(POLICY CMP0074)
|
||||
CMAKE_POLICY(SET CMP0074 NEW)
|
||||
ENDIF()
|
||||
|
||||
PROJECT(EQEmu)
|
||||
|
||||
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}")
|
||||
|
||||
#Add our various windows definitions
|
||||
IF(MSVC OR MINGW)
|
||||
ADD_DEFINITIONS(-D_WINDOWS)
|
||||
IF(CMAKE_CL_64)
|
||||
ADD_DEFINITIONS(-DWIN64)
|
||||
ELSE(CMAKE_CL_64)
|
||||
ADD_DEFINITIONS(-DWIN32)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ENDIF(MSVC OR MINGW)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
IF(MSVC)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(EQEMU_ARCH "x64")
|
||||
SET(EQEMU_ARCH_ALT "x64")
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(EQEMU_ARCH "x86")
|
||||
SET(EQEMU_ARCH_ALT "Win32")
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_${EQEMU_ARCH}")
|
||||
|
||||
IF(VCPKG_TOOLCHAIN)
|
||||
IF(NOT MSVC_VERSION GREATER 1800)
|
||||
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
|
||||
ENDIF()
|
||||
ELSE(VCPKG_TOOLCHAIN)
|
||||
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_${EQEMU_ARCH}")
|
||||
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_${EQEMU_ARCH}")
|
||||
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_${EQEMU_ARCH}")
|
||||
|
||||
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
|
||||
ENDIF(VCPKG_TOOLCHAIN)
|
||||
|
||||
IF(SODIUM_INCLUDE_HINTS)
|
||||
IF(MSVC_VERSION GREATER 1800)
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v140/dynamic")
|
||||
ELSEIF(MSVC_VERSION EQUAL 1800)
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v120/dynamic")
|
||||
ELSE()
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v110/dynamic")
|
||||
ENDIF()
|
||||
ENDIF(SODIUM_INCLUDE_HINTS)
|
||||
|
||||
#disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere
|
||||
OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON)
|
||||
IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ENDIF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
|
||||
|
||||
#fast FP if you'd like it
|
||||
OPTION(EQEMU_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
|
||||
IF(EQEMU_FAST_FLOATINGPOINT)
|
||||
ADD_DEFINITIONS(/fp:fast)
|
||||
ENDIF(EQEMU_FAST_FLOATINGPOINT)
|
||||
|
||||
#crash logging currently only works on windows x86/x64
|
||||
OPTION(EQEMU_ENABLE_CRASH_LOGGING "Enable crash logging" ON)
|
||||
IF(EQEMU_ENABLE_CRASH_LOGGING)
|
||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||
ENDIF(EQEMU_ENABLE_CRASH_LOGGING)
|
||||
|
||||
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON)
|
||||
IF(EQEMU_BUILD_MSVC_MP)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
ENDIF(EQEMU_BUILD_MSVC_MP)
|
||||
|
||||
#We want to compile /MT not /MD so we change that
|
||||
FOREACH(flag_var CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
IF(${flag_var} MATCHES "/MD")
|
||||
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
ENDIF(${flag_var} MATCHES "/MD")
|
||||
ENDFOREACH(flag_var)
|
||||
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
ELSE(MSVC)
|
||||
#Normally set by perl but we don't use the perl flags anymore so we set it.
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
|
||||
@@ -139,197 +39,285 @@ IF(UNIX)
|
||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
ENDIF(UNIX)
|
||||
|
||||
#debug level, 5 is default. Most people wont ever change this but it's there if you want to
|
||||
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
|
||||
0 - Quiet mode Errors to file Status and Normal ignored
|
||||
1 - Status and Normal to console, Errors to logfile
|
||||
2 - Status, Normal, and Error to console and logfile
|
||||
3 - Light debug release errors and status
|
||||
4 - Moderate debug release errors and status
|
||||
5 - Maximum debug release errors and status
|
||||
10 - More errors than you ever wanted to see"
|
||||
)
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
||||
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_STATUS 2 CACHE STRING "EQEmu logging level for [Status]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
#MSVC can fetch dependencies automatically.
|
||||
IF(MSVC)
|
||||
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
|
||||
ENDIF()
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_NORMAL 3 CACHE STRING "EQEmu logging level for [Normal]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
#Find everything we need
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
FIND_PACKAGE(MySQL)
|
||||
FIND_PACKAGE(MariaDB)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
FIND_PACKAGE(Lua51)
|
||||
FIND_PACKAGE(PerlLibs)
|
||||
FIND_PACKAGE(Sodium)
|
||||
FIND_PACKAGE(mbedTLS)
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_ERROR 2 CACHE STRING "EQEmu logging level for [Error]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Library Detection *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
IF(MYSQL_FOUND)
|
||||
MESSAGE(STATUS "* MySQL: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* MySQL: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_QUEST 2 CACHE STRING "EQEmu logging level for [Quest]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
IF(MARIADB_FOUND)
|
||||
MESSAGE(STATUS "* MariaDB: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* MariaDB: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_COMMANDS 1 CACHE STRING "EQEmu logging level for [Commands]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
IF(ZLIB_FOUND)
|
||||
MESSAGE(STATUS "* ZLIB: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* ZLIB: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
IF(Lua51_FOUND)
|
||||
MESSAGE(STATUS "* Lua: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* Lua: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_STATUS EQEMU_LOG_LEVEL_NORMAL EQEMU_LOG_LEVEL_ERROR EQEMU_LOG_LEVEL_DEBUG EQEMU_LOG_LEVEL_QUEST EQEMU_LOG_LEVEL_COMMANDS EQEMU_LOG_LEVEL_CRASH)
|
||||
IF(PerlLibs_FOUND)
|
||||
MESSAGE(STATUS "* Perl: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* Perl: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
#NPC Types Cache Behavior
|
||||
IF(SODIUM_FOUND)
|
||||
MESSAGE(STATUS "* libsodium: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* libsodium: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
IF(OpenSSL_FOUND)
|
||||
MESSAGE(STATUS "* OpenSSL: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* OpenSSL: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
IF(MBEDTLS_FOUND)
|
||||
MESSAGE(STATUS "* mbedTLS: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#options
|
||||
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
|
||||
|
||||
#Bots are a compile time option so on/off
|
||||
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
|
||||
|
||||
#Disable entire _mlog system (excludes trade/command logs)
|
||||
OPTION(EQEMU_DISABLE_LOGSYS "Disable Logging INI System" ON)
|
||||
|
||||
#Enable GM Command log system
|
||||
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
|
||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
||||
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||
|
||||
IF(EQEMU_COMMANDS_LOGGING)
|
||||
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
||||
ENDIF(EQEMU_COMMANDS_LOGGING)
|
||||
|
||||
IF(EQEMU_DISABLE_LOGSYS)
|
||||
ADD_DEFINITIONS(-DDISABLE_LOGSYS)
|
||||
ENDIF(EQEMU_DISABLE_LOGSYS)
|
||||
|
||||
IF(EQEMU_ENABLE_BOTS)
|
||||
ADD_DEFINITIONS(-DBOTS)
|
||||
ENDIF(EQEMU_ENABLE_BOTS)
|
||||
|
||||
#What to build
|
||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
|
||||
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||
|
||||
#C++11 stuff
|
||||
IF(NOT MSVC)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
|
||||
#database
|
||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
||||
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use:
|
||||
MySQL
|
||||
MariaDB"
|
||||
)
|
||||
|
||||
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
|
||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
||||
ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB")
|
||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB")
|
||||
ENDIF()
|
||||
ENDIF(NOT MSVC)
|
||||
ELSEIF(MariaDB_FOUND)
|
||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
||||
ELSEIF(MySQL_FOUND)
|
||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.")
|
||||
ENDIF()
|
||||
|
||||
#Various definitions
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
ENDIF(EQEMU_BUILD_PERL)
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
#security
|
||||
#prefer openssl to mbedtls (arbitrary)
|
||||
IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
|
||||
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
|
||||
OpenSSL
|
||||
mbedTLS"
|
||||
)
|
||||
|
||||
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
|
||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
||||
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
|
||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS")
|
||||
ENDIF()
|
||||
ELSEIF(OpenSSL_FOUND)
|
||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
||||
ELSEIF(MBEDTLS_FOUND)
|
||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
||||
ELSE()
|
||||
SET(TLS_LIBRARY_TYPE "Disabled")
|
||||
SET(TLS_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
#Disabled until reevaluation performed
|
||||
#OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
|
||||
#IF(EQEMU_USE_MAP_MMFS)
|
||||
# ADD_DEFINITIONS(-DUSE_MAP_MMFS)
|
||||
#ENDIF(EQEMU_USE_MAP_MMFS)
|
||||
|
||||
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
|
||||
|
||||
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
||||
ADD_DEFINITIONS(-DINVERSEXY)
|
||||
ADD_DEFINITIONS(-DFIELD_ITEMS)
|
||||
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_STATUS=${EQEMU_LOG_LEVEL_STATUS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_NORMAL=${EQEMU_LOG_LEVEL_NORMAL})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_ERROR=${EQEMU_LOG_LEVEL_ERROR})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
||||
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
||||
|
||||
#Find everything we need
|
||||
FIND_PACKAGE(ZLIB)
|
||||
FIND_PACKAGE(MySQL REQUIRED)
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
FIND_PACKAGE(PerlLibs REQUIRED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}")
|
||||
ENDIF(EQEMU_BUILD_PERL)
|
||||
|
||||
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} uv_a fmt RecastNavigation::Detour)
|
||||
|
||||
FIND_PACKAGE(Sodium REQUIRED)
|
||||
IF(SODIUM_FOUND)
|
||||
OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON)
|
||||
IF(EQEMU_ENABLE_SECURITY)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}")
|
||||
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES})
|
||||
SET(SODIUM_LIBRARY_TYPE "Libsodium")
|
||||
SET(SODIUM_LIBRARY_ENABLED ON)
|
||||
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
|
||||
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
|
||||
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
||||
ELSE()
|
||||
SET(SODIUM_LIBRARY_TYPE " Disabled")
|
||||
SET(SODIUM_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(Lua51_FOUND)
|
||||
SET(LUA_LIBRARY_TYPE " Lua 5.1")
|
||||
SET(LUA_LIBRARY_ENABLED ON)
|
||||
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
|
||||
SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
||||
ELSE()
|
||||
SET(LUA_LIBRARY_TYPE "Disabled")
|
||||
SET(LUA_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(PerlLibs_FOUND)
|
||||
SET(PERL_LIBRARY_TYPE " Perl")
|
||||
SET(PERL_LIBRARY_ENABLED ON)
|
||||
SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY})
|
||||
SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH})
|
||||
ELSE()
|
||||
SET(PERL_LIBRARY_TYPE "Disabled")
|
||||
SET(PERL_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
#use zlib if exists
|
||||
IF(ZLIB_FOUND)
|
||||
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON)
|
||||
IF(EQEMU_BUILD_ZLIB)
|
||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
ELSE()
|
||||
SET(ZLIB_LIBRARY_TYPE " zlib")
|
||||
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
|
||||
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Library Usage *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#setup server libs and headers
|
||||
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/expected/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
||||
|
||||
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
|
||||
IF(EQEMU_BUILD_LOGGING)
|
||||
ADD_DEFINITIONS(-DBUILD_LOGGING)
|
||||
ENDIF()
|
||||
|
||||
IF(TLS_LIBRARY_ENABLED)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
|
||||
ENDIF()
|
||||
|
||||
IF(SODIUM_LIBRARY_ENABLED)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
|
||||
ENDIF()
|
||||
|
||||
IF(LUA_LIBRARY_ENABLED)
|
||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
|
||||
|
||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(ZLIB_FOUND)
|
||||
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." OFF)
|
||||
|
||||
IF(EQEMU_BUILD_ZLIB)
|
||||
INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic")
|
||||
ELSE()
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${ZLIB_LIBRARY})
|
||||
IF(PERL_LIBRARY_ENABLED)
|
||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.")
|
||||
SET(EQEMU_BUILD_ZLIB ON)
|
||||
INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic")
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
@@ -344,52 +332,32 @@ IF(UNIX)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
FIND_PACKAGE(EQLua51 REQUIRED)
|
||||
SET(Boost_USE_STATIC_LIBS OFF)
|
||||
SET(Boost_USE_MULTITHREADED ON)
|
||||
SET(Boost_USE_STATIC_RUNTIME OFF)
|
||||
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
|
||||
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
||||
|
||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
||||
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
||||
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||
ADD_SUBDIRECTORY(common)
|
||||
ADD_SUBDIRECTORY(libs)
|
||||
ADD_SUBDIRECTORY(submodules/fmt)
|
||||
ADD_SUBDIRECTORY(submodules/libuv)
|
||||
|
||||
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
|
||||
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
|
||||
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
|
||||
ADD_SUBDIRECTORY(submodules/recastnavigation)
|
||||
|
||||
IF(EQEMU_BUILD_ZLIB)
|
||||
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
|
||||
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
|
||||
ADD_SUBDIRECTORY(libs/zlibng)
|
||||
ENDIF()
|
||||
|
||||
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
|
||||
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
|
||||
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
|
||||
ADD_SUBDIRECTORY(submodules/recastnavigation)
|
||||
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||
|
||||
IF(EQEMU_BUILD_SERVER)
|
||||
ADD_SUBDIRECTORY(shared_memory)
|
||||
ADD_SUBDIRECTORY(world)
|
||||
@@ -398,6 +366,7 @@ IF(EQEMU_BUILD_SERVER)
|
||||
ADD_SUBDIRECTORY(queryserv)
|
||||
ADD_SUBDIRECTORY(eqlaunch)
|
||||
ENDIF(EQEMU_BUILD_SERVER)
|
||||
|
||||
IF(EQEMU_BUILD_LOGIN)
|
||||
ADD_SUBDIRECTORY(loginserver)
|
||||
ENDIF(EQEMU_BUILD_LOGIN)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# EQEmulator Core Server
|
||||
|Travis CI (Linux)|Appveyor w/ Bots (Windows) |Appveyor w/o Bots (Windows) |
|
||||
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
||||
|:---:|:---:|:---:|
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[](https://ci.appveyor.com/project/KimLS/server-w0pq2/branch/master) |
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
||||
|
||||
***
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|:---:|:---:|:---:|
|
||||
|**Install Count**|||
|
||||
### > Windows
|
||||
* [Install](https://github.com/EQEmu/Server/wiki/Windows-Server)
|
||||
* [Install](https://eqemu.gitbook.io/server/categories/how-to-guides/installation/server-installation-windows)
|
||||
|
||||
### > Debian/Ubuntu/CentOS/Fedora
|
||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
||||
@@ -52,7 +52,7 @@ forum, although pull requests will be much quicker and easier on all parties.
|
||||
|
||||
## Resources
|
||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
||||
- [EQEmulator Wiki](https://github.com/EQEmu/Server/wiki)
|
||||
- [EQEmulator Wiki](https://eqemu.gitbook.io/)
|
||||
|
||||
## Related Repositories
|
||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Security Policy - Reporting Vulnerabilities
|
||||
|
||||
When reporting active hacks, exploits and other vulnerabilities, please describe how to reproduce said report and if you can provide context into a possible solution
|
||||
+580
-551
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
add_subdirectory(import)
|
||||
add_subdirectory(export)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
SET(export_sources
|
||||
main.cpp
|
||||
|
||||
@@ -39,20 +39,19 @@ int main(int argc, char **argv) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
Log(Logs::General, Logs::Status, "Client Files Export Utility");
|
||||
LogInfo("Client Files Export Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
Log(Logs::General, Logs::Error, "Unable to load configuration file.");
|
||||
LogError("Unable to load configuration file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
|
||||
SharedDatabase database;
|
||||
Log(Logs::General, Logs::Status, "Connecting to database...");
|
||||
LogInfo("Connecting to database");
|
||||
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
||||
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
LogError("Unable to connect to the database, cannot continue without a database connection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -94,11 +93,11 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
void ExportSpells(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting Spells...");
|
||||
LogInfo("Exporting Spells");
|
||||
|
||||
FILE *f = fopen("export/spells_us.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping.");
|
||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -165,11 +164,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting Skill Caps...");
|
||||
LogInfo("Exporting Skill Caps");
|
||||
|
||||
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -194,11 +193,11 @@ void ExportSkillCaps(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ExportBaseData(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting Base Data...");
|
||||
LogInfo("Exporting Base Data");
|
||||
|
||||
FILE *f = fopen("export/BaseData.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping.");
|
||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -225,11 +224,11 @@ void ExportBaseData(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ExportDBStrings(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting DB Strings...");
|
||||
LogInfo("Exporting DB Strings");
|
||||
|
||||
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
SET(import_sources
|
||||
main.cpp
|
||||
|
||||
@@ -37,19 +37,19 @@ int main(int argc, char **argv) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
Log(Logs::General, Logs::Status, "Client Files Import Utility");
|
||||
LogInfo("Client Files Import Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
Log(Logs::General, Logs::Error, "Unable to load configuration file.");
|
||||
LogError("Unable to load configuration file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
|
||||
SharedDatabase database;
|
||||
Log(Logs::General, Logs::Status, "Connecting to database...");
|
||||
LogInfo("Connecting to database");
|
||||
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
||||
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
|
||||
LogError("Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
return 1;
|
||||
}
|
||||
@@ -97,10 +97,10 @@ bool IsStringField(int i) {
|
||||
}
|
||||
|
||||
void ImportSpells(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Importing Spells...");
|
||||
LogInfo("Importing Spells");
|
||||
FILE *f = fopen("import/spells_us.txt", "r");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping.");
|
||||
LogError("Unable to open import/spells_us.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -173,23 +173,23 @@ void ImportSpells(SharedDatabase *db) {
|
||||
|
||||
spells_imported++;
|
||||
if(spells_imported % 1000 == 0) {
|
||||
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
|
||||
LogInfo("[{}] spells imported", spells_imported);
|
||||
}
|
||||
}
|
||||
|
||||
if(spells_imported % 1000 != 0) {
|
||||
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
|
||||
LogInfo("[{}] spells imported", spells_imported);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ImportSkillCaps(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Importing Skill Caps...");
|
||||
LogInfo("Importing Skill Caps");
|
||||
|
||||
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping.");
|
||||
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,11 +220,11 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ImportBaseData(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Importing Base Data...");
|
||||
LogInfo("Importing Base Data");
|
||||
|
||||
FILE *f = fopen("import/BaseData.txt", "r");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping.");
|
||||
LogError("Unable to open import/BaseData.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -265,11 +265,11 @@ void ImportBaseData(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ImportDBStrings(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Importing DB Strings...");
|
||||
LogInfo("Importing DB Strings");
|
||||
|
||||
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
|
||||
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON)
|
||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON)
|
||||
|
||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
||||
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-x86")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-x64")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64")
|
||||
|
||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64})
|
||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64})
|
||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP})
|
||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR})
|
||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP})
|
||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR})
|
||||
ELSE()
|
||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86})
|
||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86})
|
||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP})
|
||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR})
|
||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP})
|
||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR})
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
||||
MESSAGE(STATUS "Resolving vcpkg dependencies...")
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
|
||||
|
||||
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
|
||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
||||
#Try to find perl first, (so you can use your active install first)
|
||||
FIND_PACKAGE(PerlLibs)
|
||||
|
||||
IF(NOT PerlLibs_FOUND)
|
||||
MESSAGE(STATUS "Resolving perl dependencies...")
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
|
||||
|
||||
MESSAGE(STATUS "Downloading portable perl...")
|
||||
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
|
||||
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
|
||||
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -1,124 +0,0 @@
|
||||
#CMake - Cross Platform Makefile Generator
|
||||
#Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
|
||||
#All rights reserved.
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions
|
||||
#are met:
|
||||
#
|
||||
#* Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#* Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# This module defines
|
||||
# LUA51_FOUND, if false, do not try to link to Lua
|
||||
# LUA_LIBRARIES
|
||||
# LUA_INCLUDE_DIR, where to find lua.h
|
||||
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
|
||||
IF(LUA_ROOT)
|
||||
FIND_PATH(LUA_INCLUDE_DIR
|
||||
NAMES lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
${LUA_ROOT}
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include src
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUA_LIBRARY
|
||||
NAMES lua51 lua5.1 lua-5.1 lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
${LUA_ROOT}
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES lib bin
|
||||
)
|
||||
ELSE(LUA_ROOT)
|
||||
FIND_PATH(LUA_INCLUDE_DIR
|
||||
NAMES lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUA_LIBRARY
|
||||
NAMES lua51 lua5.1 lua-5.1 lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES lib bin
|
||||
)
|
||||
ENDIF(LUA_ROOT)
|
||||
|
||||
IF(LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
IF(UNIX AND NOT APPLE)
|
||||
FIND_LIBRARY(LUA_MATH_LIBRARY m)
|
||||
SET(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
ELSE()
|
||||
SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||
|
||||
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||
UNSET(lua_version_str)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
# Modified from the FindLua51 that comes with CMake
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindLua51
|
||||
---------
|
||||
|
||||
|
||||
|
||||
Locate Lua51 library This module defines
|
||||
|
||||
::
|
||||
|
||||
LUA51_FOUND, if false, do not try to link to Lua
|
||||
LUA_LIBRARIES
|
||||
LUA_INCLUDE_DIR, where to find lua.h
|
||||
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
|
||||
|
||||
|
||||
Note that the expected include convention is
|
||||
|
||||
::
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
and not
|
||||
|
||||
::
|
||||
|
||||
#include <lua/lua.h>
|
||||
|
||||
This is because, the lua location is not standardized and may exist in
|
||||
locations other than lua/
|
||||
#]=======================================================================]
|
||||
|
||||
find_path(LUA_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include/luajit include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
find_library(LUA_LIBRARY
|
||||
NAMES lua51 lua5.1 lua-5.1 lua luajit
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
if(LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
|
||||
find_library(LUA_MATH_LIBRARY m)
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
else()
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||
|
||||
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||
unset(lua_version_str)
|
||||
endif()
|
||||
|
||||
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# - Find mariadbclient
|
||||
#
|
||||
# -*- cmake -*-
|
||||
#
|
||||
# Find the native MariaDB includes and library
|
||||
#
|
||||
# MariaDB_INCLUDE_DIR - where to find mysql.h, etc.
|
||||
# MariaDB_LIBRARIES - List of libraries when using MariaDB.
|
||||
# MariaDB_FOUND - True if MariaDB found.
|
||||
# The following can be used as a hint as to where to search:
|
||||
# MARIADB_ROOT
|
||||
|
||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
||||
# Already in cache, be silent
|
||||
SET(MariaDB_FIND_QUIETLY TRUE)
|
||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
||||
|
||||
# Include dir
|
||||
IF(MARIADB_ROOT)
|
||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
||||
NAMES mariadb_version.h
|
||||
PATHS ${MARIADB_ROOT}/include
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
NO_DEFAULT_PATH
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
||||
NAMES mariadb_version.h
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ELSE(MARIADB_ROOT)
|
||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
||||
NAMES mariadb_version.h
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ENDIF(MARIADB_ROOT)
|
||||
|
||||
# Library
|
||||
SET(MariaDB_NAMES libmariadb)
|
||||
IF(MARIADB_ROOT)
|
||||
FIND_LIBRARY(MariaDB_LIBRARY
|
||||
NAMES ${MariaDB_NAMES}
|
||||
PATHS ${MARIADB_ROOT}/lib
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
NO_DEFAULT_PATH
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
FIND_LIBRARY(MariaDB_LIBRARY
|
||||
NAMES ${MariaDB_NAMES}
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ELSE(MARIADB_ROOT)
|
||||
FIND_LIBRARY(MariaDB_LIBRARY
|
||||
NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient
|
||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ENDIF(MARIADB_ROOT)
|
||||
|
||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
||||
SET(MariaDB_FOUND TRUE)
|
||||
SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY})
|
||||
ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
||||
SET(MariaDB_FOUND FALSE)
|
||||
SET(MariaDB_LIBRARIES)
|
||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
||||
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR)
|
||||
|
||||
IF(MariaDB_FOUND)
|
||||
SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} )
|
||||
SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} )
|
||||
SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} )
|
||||
ELSE(MariaDB_FOUND)
|
||||
SET( MariaDB_LIBRARIES )
|
||||
ENDIF(MariaDB_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
MariaDB_LIBRARY_DEBUG
|
||||
MariaDB_LIBRARY_RELEASE
|
||||
MariaDB_INCLUDE_DIR
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
# - Try to find mbedTLS
|
||||
# Once done this will define
|
||||
#
|
||||
# Read-Only variables
|
||||
# MBEDTLS_FOUND - system has mbedTLS
|
||||
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
|
||||
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
|
||||
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
|
||||
# MBEDTLS_LIBRARY - path to mbedTLS library
|
||||
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
|
||||
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
|
||||
#
|
||||
# Hint
|
||||
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.
|
||||
|
||||
SET(_MBEDTLS_ROOT_HINTS
|
||||
${MBEDTLS_ROOT_DIR}
|
||||
ENV MBEDTLS_ROOT_DIR
|
||||
)
|
||||
|
||||
SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
PATHS ${_MBEDTLS_ROOT_PATHS}
|
||||
)
|
||||
|
||||
FIND_PATH(MBEDTLS_INCLUDE_DIR
|
||||
NAMES mbedtls/version.h
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
|
||||
# Already in cache, be silent
|
||||
SET(MBEDTLS_FIND_QUIETLY TRUE)
|
||||
ENDIF()
|
||||
|
||||
FIND_LIBRARY(MBEDTLS_LIBRARY
|
||||
NAMES mbedtls libmbedtls
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES library
|
||||
)
|
||||
FIND_LIBRARY(MBEDX509_LIBRARY
|
||||
NAMES mbedx509 libmbedx509
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES library
|
||||
)
|
||||
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
|
||||
NAMES mbedcrypto libmbedcrypto
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES library
|
||||
)
|
||||
|
||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
|
||||
SET(MBEDTLS_FOUND TRUE)
|
||||
ENDIF()
|
||||
|
||||
IF(MBEDTLS_FOUND)
|
||||
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
|
||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
|
||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
|
||||
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
|
||||
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
|
||||
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
|
||||
|
||||
IF(NOT MBEDTLS_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found mbedTLS:")
|
||||
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
|
||||
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
|
||||
IF (MBEDTLSMATCH)
|
||||
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
|
||||
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
|
||||
ENDIF(MBEDTLSMATCH)
|
||||
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
|
||||
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
|
||||
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
|
||||
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
|
||||
ELSE(MBEDTLS_FOUND)
|
||||
IF(MBEDTLS_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
|
||||
ENDIF(MBEDTLS_FIND_REQUIRED)
|
||||
ENDIF(MBEDTLS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
MBEDTLS_INCLUDE_DIR
|
||||
MBEDTLS_LIBRARY_DIR
|
||||
MBEDTLS_LIBRARIES
|
||||
MBEDTLS_LIBRARY
|
||||
MBEDX509_LIBRARY
|
||||
MBEDCRYPTO_LIBRARY
|
||||
)
|
||||
+35
-24
@@ -1,13 +1,15 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
SET(common_sources
|
||||
base_packet.cpp
|
||||
classes.cpp
|
||||
cli/eqemu_command_handler.cpp
|
||||
compression.cpp
|
||||
condition.cpp
|
||||
crash.cpp
|
||||
crc16.cpp
|
||||
crc32.cpp
|
||||
database/database_dump_service.cpp
|
||||
database.cpp
|
||||
database_conversions.cpp
|
||||
database_instances.cpp
|
||||
@@ -30,11 +32,13 @@ SET(common_sources
|
||||
event_sub.cpp
|
||||
extprofile.cpp
|
||||
faction.cpp
|
||||
file_util.cpp
|
||||
guild_base.cpp
|
||||
guilds.cpp
|
||||
inventory_profile.cpp
|
||||
inventory_slot.cpp
|
||||
ipc_mutex.cpp
|
||||
ip_util.cpp
|
||||
item_data.cpp
|
||||
item_instance.cpp
|
||||
json_config.cpp
|
||||
@@ -71,7 +75,6 @@ SET(common_sources
|
||||
textures.cpp
|
||||
timer.cpp
|
||||
unix.cpp
|
||||
xml_parser.cpp
|
||||
platform.cpp
|
||||
json/jsoncpp.cpp
|
||||
net/console_server.cpp
|
||||
@@ -102,13 +105,8 @@ SET(common_sources
|
||||
patches/uf.cpp
|
||||
patches/uf_limits.cpp
|
||||
StackWalker/StackWalker.cpp
|
||||
tinyxml/tinystr.cpp
|
||||
tinyxml/tinyxml.cpp
|
||||
tinyxml/tinyxmlerror.cpp
|
||||
tinyxml/tinyxmlparser.cpp
|
||||
util/directory.cpp
|
||||
util/uuid.cpp
|
||||
)
|
||||
util/uuid.cpp)
|
||||
|
||||
SET(common_headers
|
||||
any.h
|
||||
@@ -121,8 +119,13 @@ SET(common_headers
|
||||
crash.h
|
||||
crc16.h
|
||||
crc32.h
|
||||
cli/argh.h
|
||||
cli/eqemu_command_handler.h
|
||||
cli/terminal_color.hpp
|
||||
database/database_dump_service.h
|
||||
data_verification.h
|
||||
database.h
|
||||
database_schema.h
|
||||
dbcore.h
|
||||
deity.h
|
||||
emu_constants.h
|
||||
@@ -138,7 +141,7 @@ SET(common_headers
|
||||
eqemu_config.h
|
||||
eqemu_config_elements.h
|
||||
eqemu_logsys.h
|
||||
eqemu_logsys_fmt.h
|
||||
eqemu_logsys_log_aliases.h
|
||||
eq_limits.h
|
||||
eq_packet.h
|
||||
eq_stream_ident.h
|
||||
@@ -148,17 +151,21 @@ SET(common_headers
|
||||
eqtime.h
|
||||
errmsg.h
|
||||
event_sub.h
|
||||
expected.h
|
||||
extprofile.h
|
||||
faction.h
|
||||
file_util.h
|
||||
features.h
|
||||
fixed_memory_hash_set.h
|
||||
fixed_memory_variable_hash_set.h
|
||||
global_define.h
|
||||
guild_base.h
|
||||
guilds.h
|
||||
http/httplib.h
|
||||
inventory_profile.h
|
||||
inventory_slot.h
|
||||
ipc_mutex.h
|
||||
ip_util.h
|
||||
item_data.h
|
||||
item_fieldlist.h
|
||||
item_instance.h
|
||||
@@ -209,7 +216,6 @@ SET(common_headers
|
||||
unix.h
|
||||
useperl.h
|
||||
version.h
|
||||
xml_parser.h
|
||||
zone_numbers.h
|
||||
event/event_loop.h
|
||||
event/task.h
|
||||
@@ -262,13 +268,17 @@ SET(common_headers
|
||||
patches/uf_limits.h
|
||||
patches/uf_ops.h
|
||||
patches/uf_structs.h
|
||||
shared/shared_memory.h
|
||||
shared/shared_memory_error.h
|
||||
shared/shared_memory_handle.h
|
||||
shared/shared_memory_list.h
|
||||
shared/shared_memory_map.h
|
||||
shared/shared_memory_string.h
|
||||
shared/shared_memory_vector.h
|
||||
StackWalker/StackWalker.h
|
||||
tinyxml/tinystr.h
|
||||
tinyxml/tinyxml.h
|
||||
util/memory_stream.h
|
||||
util/directory.h
|
||||
util/uuid.h
|
||||
)
|
||||
util/uuid.h)
|
||||
|
||||
SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
@@ -363,20 +373,21 @@ SOURCE_GROUP(Patches FILES
|
||||
patches/uf_limits.cpp
|
||||
)
|
||||
|
||||
SOURCE_GROUP(shared FILES
|
||||
shared/shared_memory.h
|
||||
shared/shared_memory_error.h
|
||||
shared/shared_memory_handle.h
|
||||
shared/shared_memory_list.h
|
||||
shared/shared_memory_map.h
|
||||
shared/shared_memory_string.h
|
||||
shared/shared_memory_vector.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP(StackWalker FILES
|
||||
StackWalker/StackWalker.h
|
||||
StackWalker/StackWalker.cpp
|
||||
)
|
||||
|
||||
SOURCE_GROUP(TinyXML FILES
|
||||
tinyxml/tinystr.h
|
||||
tinyxml/tinyxml.h
|
||||
tinyxml/tinystr.cpp
|
||||
tinyxml/tinyxml.cpp
|
||||
tinyxml/tinyxmlerror.cpp
|
||||
tinyxml/tinyxmlparser.cpp
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Util FILES
|
||||
util/memory_stream.h
|
||||
util/directory.cpp
|
||||
@@ -385,7 +396,7 @@ SOURCE_GROUP(Util FILES
|
||||
util/uuid.h
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML)
|
||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||
|
||||
ADD_LIBRARY(common ${common_sources} ${common_headers})
|
||||
|
||||
|
||||
@@ -573,6 +573,20 @@ bool IsNonSpellFighterClass(uint8 class_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHybridClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case PALADIN:
|
||||
case RANGER:
|
||||
case SHADOWKNIGHT:
|
||||
case BARD:
|
||||
case BEASTLORD:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
|
||||
@@ -135,6 +135,7 @@ uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
||||
bool IsFighterClass(uint8 class_id);
|
||||
bool IsSpellFighterClass(uint8 class_id);
|
||||
bool IsNonSpellFighterClass(uint8 class_id);
|
||||
bool IsHybridClass(uint8 class_id);
|
||||
bool IsCasterClass(uint8 class_id);
|
||||
bool IsINTCasterClass(uint8 class_id);
|
||||
bool IsWISCasterClass(uint8 class_id);
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
namespace argh
|
||||
{
|
||||
// Terminology:
|
||||
// A command line is composed of 2 types of args:
|
||||
// 1. Positional args, i.e. free standing values
|
||||
// 2. Options: args beginning with '-'. We identify two kinds:
|
||||
// 2.1: Flags: boolean options => (exist ? true : false)
|
||||
// 2.2: Parameters: a name followed by a non-option value
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ >= 5)
|
||||
using string_stream = std::istringstream;
|
||||
#else
|
||||
// Until GCC 5, istringstream did not have a move constructor.
|
||||
// stringstream_proxy is used instead, as a workaround.
|
||||
class stringstream_proxy
|
||||
{
|
||||
public:
|
||||
stringstream_proxy() = default;
|
||||
|
||||
// Construct with a value.
|
||||
stringstream_proxy(std::string const& value) :
|
||||
stream_(value)
|
||||
{}
|
||||
|
||||
// Copy constructor.
|
||||
stringstream_proxy(const stringstream_proxy& other) :
|
||||
stream_(other.stream_.str())
|
||||
{
|
||||
stream_.setstate(other.stream_.rdstate());
|
||||
}
|
||||
|
||||
void setstate(std::ios_base::iostate state) { stream_.setstate(state); }
|
||||
|
||||
// Stream out the value of the parameter.
|
||||
// If the conversion was not possible, the stream will enter the fail state,
|
||||
// and operator bool will return false.
|
||||
template<typename T>
|
||||
stringstream_proxy& operator >> (T& thing)
|
||||
{
|
||||
stream_ >> thing;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Get the string value.
|
||||
std::string str() const { return stream_.str(); }
|
||||
|
||||
std::stringbuf* rdbuf() const { return stream_.rdbuf(); }
|
||||
|
||||
// Check the state of the stream.
|
||||
// False when the most recent stream operation failed
|
||||
operator bool() const { return !!stream_; }
|
||||
|
||||
~stringstream_proxy() = default;
|
||||
private:
|
||||
std::istringstream stream_;
|
||||
};
|
||||
using string_stream = stringstream_proxy;
|
||||
#endif
|
||||
|
||||
class parser
|
||||
{
|
||||
public:
|
||||
enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0,
|
||||
PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1,
|
||||
NO_SPLIT_ON_EQUALSIGN = 1 << 2,
|
||||
SINGLE_DASH_IS_MULTIFLAG = 1 << 3,
|
||||
};
|
||||
|
||||
parser() = default;
|
||||
|
||||
parser(std::initializer_list<char const* const> pre_reg_names)
|
||||
{ add_params(pre_reg_names); }
|
||||
|
||||
parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
|
||||
{ parse(argv, mode); }
|
||||
|
||||
parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
|
||||
{ parse(argc, argv, mode); }
|
||||
|
||||
void add_param(std::string const& name);
|
||||
void add_params(std::initializer_list<char const* const> init_list);
|
||||
|
||||
void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
|
||||
void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
|
||||
|
||||
std::multiset<std::string> const& flags() const { return flags_; }
|
||||
std::map<std::string, std::string> const& params() const { return params_; }
|
||||
std::vector<std::string> const& pos_args() const { return pos_args_; }
|
||||
|
||||
// begin() and end() for using range-for over positional args.
|
||||
std::vector<std::string>::const_iterator begin() const { return pos_args_.cbegin(); }
|
||||
std::vector<std::string>::const_iterator end() const { return pos_args_.cend(); }
|
||||
size_t size() const { return pos_args_.size(); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Accessors
|
||||
|
||||
// flag (boolean) accessors: return true if the flag appeared, otherwise false.
|
||||
bool operator[](std::string const& name) const;
|
||||
|
||||
// multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false.
|
||||
bool operator[](std::initializer_list<char const* const> init_list) const;
|
||||
|
||||
// returns positional arg string by order. Like argv[] but without the options
|
||||
std::string const& operator[](size_t ind) const;
|
||||
|
||||
// returns a std::istream that can be used to convert a positional arg to a typed value.
|
||||
string_stream operator()(size_t ind) const;
|
||||
|
||||
// same as above, but with a default value in case the arg is missing (index out of range).
|
||||
template<typename T>
|
||||
string_stream operator()(size_t ind, T&& def_val) const;
|
||||
|
||||
// parameter accessors, give a name get an std::istream that can be used to convert to a typed value.
|
||||
// call .str() on result to get as string
|
||||
string_stream operator()(std::string const& name) const;
|
||||
|
||||
// accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value.
|
||||
// call .str() on result to get as string
|
||||
// returns the first value in the list to be found.
|
||||
string_stream operator()(std::initializer_list<char const* const> init_list) const;
|
||||
|
||||
// same as above, but with a default value in case the param was missing.
|
||||
// Non-string def_val types must have an operator<<() (output stream operator)
|
||||
// If T only has an input stream operator, pass the string version of the type as in "3" instead of 3.
|
||||
template<typename T>
|
||||
string_stream operator()(std::string const& name, T&& def_val) const;
|
||||
|
||||
// same as above but for a list of names. returns the first value to be found.
|
||||
template<typename T>
|
||||
string_stream operator()(std::initializer_list<char const* const> init_list, T&& def_val) const;
|
||||
|
||||
private:
|
||||
string_stream bad_stream() const;
|
||||
std::string trim_leading_dashes(std::string const& name) const;
|
||||
bool is_number(std::string const& arg) const;
|
||||
bool is_option(std::string const& arg) const;
|
||||
bool got_flag(std::string const& name) const;
|
||||
bool is_param(std::string const& name) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> args_;
|
||||
std::map<std::string, std::string> params_;
|
||||
std::vector<std::string> pos_args_;
|
||||
std::multiset<std::string> flags_;
|
||||
std::set<std::string> registeredParams_;
|
||||
std::string empty_;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::parse(const char * const argv[], int mode)
|
||||
{
|
||||
int argc = 0;
|
||||
for (auto argvp = argv; *argvp; ++argc, ++argvp);
|
||||
parse(argc, argv, mode);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/)
|
||||
{
|
||||
// convert to strings
|
||||
args_.resize(argc);
|
||||
std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; });
|
||||
|
||||
// parse line
|
||||
for (auto i = 0u; i < args_.size(); ++i)
|
||||
{
|
||||
if (!is_option(args_[i]))
|
||||
{
|
||||
pos_args_.emplace_back(args_[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto name = trim_leading_dashes(args_[i]);
|
||||
|
||||
if (!(mode & NO_SPLIT_ON_EQUALSIGN))
|
||||
{
|
||||
auto equalPos = name.find('=');
|
||||
if (equalPos != std::string::npos)
|
||||
{
|
||||
params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if the option is unregistered and should be a multi-flag
|
||||
if (1 == (args_[i].size() - name.size()) && // single dash
|
||||
argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode
|
||||
!is_param(name)) // unregistered
|
||||
{
|
||||
std::string keep_param;
|
||||
|
||||
if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param
|
||||
{
|
||||
keep_param += name.back();
|
||||
name.resize(name.size() - 1);
|
||||
}
|
||||
|
||||
for (auto const& c : name)
|
||||
{
|
||||
flags_.emplace(std::string{ c });
|
||||
}
|
||||
|
||||
if (!keep_param.empty())
|
||||
{
|
||||
name = keep_param;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue; // do not consider other options for this arg
|
||||
}
|
||||
}
|
||||
|
||||
// any potential option will get as its value the next arg, unless that arg is an option too
|
||||
// in that case it will be determined a flag.
|
||||
if (i == args_.size() - 1 || is_option(args_[i + 1]))
|
||||
{
|
||||
flags_.emplace(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped
|
||||
// otherwise we have 2 modes:
|
||||
// PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag.
|
||||
// The following value (the next arg) will be a free parameter.
|
||||
//
|
||||
// PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg
|
||||
// will be the value of that option.
|
||||
|
||||
assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION)
|
||||
|| !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION));
|
||||
|
||||
bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION;
|
||||
|
||||
if (is_param(name) || preferParam)
|
||||
{
|
||||
params_.insert({ name, args_[i + 1] });
|
||||
++i; // skip next value, it is not a free parameter
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags_.emplace(name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::bad_stream() const
|
||||
{
|
||||
string_stream bad;
|
||||
bad.setstate(std::ios_base::failbit);
|
||||
return bad;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::is_number(std::string const& arg) const
|
||||
{
|
||||
// inefficient but simple way to determine if a string is a number (which can start with a '-')
|
||||
std::istringstream istr(arg);
|
||||
double number;
|
||||
istr >> number;
|
||||
return !(istr.fail() || istr.bad());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::is_option(std::string const& arg) const
|
||||
{
|
||||
assert(0 != arg.size());
|
||||
if (is_number(arg))
|
||||
return false;
|
||||
return '-' == arg[0];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::string parser::trim_leading_dashes(std::string const& name) const
|
||||
{
|
||||
auto pos = name.find_first_not_of('-');
|
||||
return std::string::npos != pos ? name.substr(pos) : name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool argh::parser::got_flag(std::string const& name) const
|
||||
{
|
||||
return flags_.end() != flags_.find(trim_leading_dashes(name));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool argh::parser::is_param(std::string const& name) const
|
||||
{
|
||||
return registeredParams_.count(name);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::operator[](std::string const& name) const
|
||||
{
|
||||
return got_flag(name);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::operator[](std::initializer_list<char const* const> init_list) const
|
||||
{
|
||||
return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); });
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::string const& parser::operator[](size_t ind) const
|
||||
{
|
||||
if (ind < pos_args_.size())
|
||||
return pos_args_[ind];
|
||||
return empty_;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::operator()(std::string const& name) const
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
return bad_stream();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::operator()(std::initializer_list<char const* const> init_list) const
|
||||
{
|
||||
for (auto& name : init_list)
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
}
|
||||
return bad_stream();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
string_stream parser::operator()(std::string const& name, T&& def_val) const
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
|
||||
std::ostringstream ostr;
|
||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
||||
ostr << def_val;
|
||||
return string_stream(ostr.str()); // use default
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// same as above but for a list of names. returns the first value to be found.
|
||||
template<typename T>
|
||||
string_stream parser::operator()(std::initializer_list<char const* const> init_list, T&& def_val) const
|
||||
{
|
||||
for (auto& name : init_list)
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
}
|
||||
std::ostringstream ostr;
|
||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
||||
ostr << def_val;
|
||||
return string_stream(ostr.str()); // use default
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::operator()(size_t ind) const
|
||||
{
|
||||
if (pos_args_.size() <= ind)
|
||||
return bad_stream();
|
||||
|
||||
return string_stream(pos_args_[ind]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
string_stream parser::operator()(size_t ind, T&& def_val) const
|
||||
{
|
||||
if (pos_args_.size() <= ind)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
||||
ostr << def_val;
|
||||
return string_stream(ostr.str());
|
||||
}
|
||||
|
||||
return string_stream(pos_args_[ind]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::add_param(std::string const& name)
|
||||
{
|
||||
registeredParams_.insert(trim_leading_dashes(name));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::add_params(std::initializer_list<char const* const> init_list)
|
||||
{
|
||||
for (auto& name : init_list)
|
||||
registeredParams_.insert(trim_leading_dashes(name));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* 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 <fmt/format.h>
|
||||
#include "eqemu_command_handler.h"
|
||||
#include "terminal_color.hpp"
|
||||
#include "../platform.h"
|
||||
|
||||
namespace EQEmuCommand {
|
||||
|
||||
std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> function_map;
|
||||
|
||||
/**
|
||||
* @param cmd
|
||||
*/
|
||||
void DisplayDebug(argh::parser &cmd)
|
||||
{
|
||||
if (cmd[{"-d", "--debug"}]) {
|
||||
std::cout << "Positional args:\n";
|
||||
for (auto &pos_arg : cmd.pos_args())
|
||||
std::cout << '\t' << pos_arg << std::endl;
|
||||
|
||||
std::cout << "\nFlags:\n";
|
||||
for (auto &flag : cmd.flags())
|
||||
std::cout << '\t' << flag << std::endl;
|
||||
|
||||
std::cout << "\nParameters:\n";
|
||||
for (auto ¶m : cmd.params())
|
||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arguments
|
||||
* @param options
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void ValidateCmdInput(
|
||||
std::vector<std::string> &arguments,
|
||||
std::vector<std::string> &options,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
bool arguments_filled = true;
|
||||
|
||||
int index = 2;
|
||||
for (auto &arg : arguments) {
|
||||
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
||||
arguments_filled = false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (!arguments_filled || argc == 2) {
|
||||
std::string arguments_string;
|
||||
for (auto &arg : arguments) {
|
||||
arguments_string += " " + arg;
|
||||
}
|
||||
|
||||
std::string options_string;
|
||||
for (auto &opt : options) {
|
||||
options_string += " " + opt + "\n";
|
||||
}
|
||||
|
||||
std::stringstream command_string;
|
||||
|
||||
command_string <<
|
||||
termcolor::colorize <<
|
||||
termcolor::yellow <<
|
||||
"\nCommand" <<
|
||||
termcolor::reset << "\n\n" <<
|
||||
termcolor::green << argv[1] << arguments_string << termcolor::reset << "\n" <<
|
||||
termcolor::yellow << (!options_string.empty() ? "\nOptions\n\n" : "") <<
|
||||
termcolor::reset << termcolor::cyan << options_string << termcolor::reset;
|
||||
|
||||
std::cout << command_string.str() << std::endl;
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in_function_map
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void HandleMenu(
|
||||
std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> &in_function_map,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
std::string description;
|
||||
bool ran_command = false;
|
||||
for (auto &it: in_function_map) {
|
||||
if (it.first == argv[1]) {
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
ran_command = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
std::cout << std::endl;
|
||||
std::cout <<
|
||||
"> " <<
|
||||
termcolor::yellow <<
|
||||
"EQEmulator [" + GetPlatformName() + "] CLI Menu" <<
|
||||
termcolor::reset
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
|
||||
/**
|
||||
* Get max command length for padding length
|
||||
*/
|
||||
int max_command_length = 0;
|
||||
|
||||
for (auto &it: in_function_map) {
|
||||
std::stringstream command;
|
||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||
if (command.str().length() > max_command_length) {
|
||||
max_command_length = command.str().length() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display command menu
|
||||
*/
|
||||
std::string command_section;
|
||||
for (auto &it: in_function_map) {
|
||||
description = "";
|
||||
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
|
||||
/**
|
||||
* Print section header
|
||||
*/
|
||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
||||
if (command_section != command_prefix) {
|
||||
command_section = command_prefix;
|
||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print commands
|
||||
*/
|
||||
std::stringstream command;
|
||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
if (ran_command) {
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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_EQEMU_COMMAND_HANDLER_H
|
||||
#define EQEMU_EQEMU_COMMAND_HANDLER_H
|
||||
|
||||
#include "argh.h"
|
||||
|
||||
namespace EQEmuCommand {
|
||||
|
||||
extern std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> function_map;
|
||||
|
||||
/**
|
||||
* @param arguments
|
||||
* @param options
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void ValidateCmdInput(
|
||||
std::vector<std::string> &arguments,
|
||||
std::vector<std::string> &options,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
);
|
||||
|
||||
/**
|
||||
* @param cmd
|
||||
*/
|
||||
void DisplayDebug(argh::parser &cmd);
|
||||
|
||||
/**
|
||||
* @param in_function_map
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void HandleMenu(
|
||||
std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> &in_function_map,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_EQEMU_COMMAND_HANDLER_H
|
||||
@@ -0,0 +1,557 @@
|
||||
//!
|
||||
//! termcolor
|
||||
//! ~~~~~~~~~
|
||||
//!
|
||||
//! termcolor is a header-only c++ library for printing colored messages
|
||||
//! to the terminal. Written just for fun with a help of the Force.
|
||||
//!
|
||||
//! :copyright: (c) 2013 by Ihor Kalnytskyi
|
||||
//! :license: BSD, see LICENSE for details
|
||||
//!
|
||||
|
||||
#ifndef TERMCOLOR_HPP_
|
||||
#define TERMCOLOR_HPP_
|
||||
|
||||
// the following snippet of code detects the current OS and
|
||||
// defines the appropriate macro that is used to wrap some
|
||||
// platform specific things
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define TERMCOLOR_OS_WINDOWS
|
||||
#elif defined(__APPLE__)
|
||||
# define TERMCOLOR_OS_MACOS
|
||||
#elif defined(__unix__) || defined(__unix)
|
||||
# define TERMCOLOR_OS_LINUX
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
|
||||
// This headers provides the `isatty()`/`fileno()` functions,
|
||||
// which are used for testing whether a standart stream refers
|
||||
// to the terminal. As for Windows, we also need WinApi funcs
|
||||
// for changing colors attributes of the terminal.
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
# include <unistd.h>
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
|
||||
namespace termcolor
|
||||
{
|
||||
// Forward declaration of the `_internal` namespace.
|
||||
// All comments are below.
|
||||
namespace _internal
|
||||
{
|
||||
// An index to be used to access a private storage of I/O streams. See
|
||||
// colorize / nocolorize I/O manipulators for details.
|
||||
static int colorize_index = std::ios_base::xalloc();
|
||||
|
||||
inline FILE* get_standard_stream(const std::ostream& stream);
|
||||
inline bool is_colorized(std::ostream& stream);
|
||||
inline bool is_atty(const std::ostream& stream);
|
||||
|
||||
#if defined(TERMCOLOR_OS_WINDOWS)
|
||||
inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& colorize(std::ostream& stream)
|
||||
{
|
||||
stream.iword(_internal::colorize_index) = 1L;
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& nocolorize(std::ostream& stream)
|
||||
{
|
||||
stream.iword(_internal::colorize_index) = 0L;
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& reset(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;00m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1, -1);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& bold(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;1m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& dark(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;2m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& underline(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;4m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& blink(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;5m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& reverse(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;7m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& concealed(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;8m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& grey(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;30m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
0 // grey (black)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& red(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;31m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& green(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;32m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_GREEN
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& yellow(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;33m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_GREEN | FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& blue(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;34m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& magenta(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;35m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE | FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& cyan(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;36m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE | FOREGROUND_GREEN
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& white(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;37m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& on_grey(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;40m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
0 // grey (black)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_red(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;41m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_green(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;42m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_yellow(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;43m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN | BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_blue(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;44m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_BLUE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_magenta(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;45m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_BLUE | BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_cyan(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;46m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN | BACKGROUND_BLUE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_white(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;47m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Since C++ hasn't a way to hide something in the header from
|
||||
//! the outer access, I have to introduce this namespace which
|
||||
//! is used for internal purpose and should't be access from
|
||||
//! the user code.
|
||||
namespace _internal
|
||||
{
|
||||
//! Since C++ hasn't a true way to extract stream handler
|
||||
//! from the a given `std::ostream` object, I have to write
|
||||
//! this kind of hack.
|
||||
inline
|
||||
FILE* get_standard_stream(const std::ostream& stream)
|
||||
{
|
||||
if (&stream == &std::cout)
|
||||
return stdout;
|
||||
else if ((&stream == &std::cerr) || (&stream == &std::clog))
|
||||
return stderr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Say whether a given stream should be colorized or not. It's always
|
||||
// true for ATTY streams and may be true for streams marked with
|
||||
// colorize flag.
|
||||
inline
|
||||
bool is_colorized(std::ostream& stream)
|
||||
{
|
||||
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index));
|
||||
}
|
||||
|
||||
//! Test whether a given `std::ostream` object refers to
|
||||
//! a terminal.
|
||||
inline
|
||||
bool is_atty(const std::ostream& stream)
|
||||
{
|
||||
FILE* std_stream = get_standard_stream(stream);
|
||||
|
||||
// Unfortunately, fileno() ends with segmentation fault
|
||||
// if invalid file descriptor is passed. So we need to
|
||||
// handle this case gracefully and assume it's not a tty
|
||||
// if standard stream is not detected, and 0 is returned.
|
||||
if (!std_stream)
|
||||
return false;
|
||||
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
return ::isatty(fileno(std_stream));
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
return ::_isatty(_fileno(std_stream));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(TERMCOLOR_OS_WINDOWS)
|
||||
//! Change Windows Terminal colors attribute. If some
|
||||
//! parameter is `-1` then attribute won't changed.
|
||||
inline void win_change_attributes(std::ostream& stream, int foreground, int background)
|
||||
{
|
||||
// yeah, i know.. it's ugly, it's windows.
|
||||
static WORD defaultAttributes = 0;
|
||||
|
||||
// Windows doesn't have ANSI escape sequences and so we use special
|
||||
// API to change Terminal output color. That means we can't
|
||||
// manipulate colors by means of "std::stringstream" and hence
|
||||
// should do nothing in this case.
|
||||
if (!_internal::is_atty(stream))
|
||||
return;
|
||||
|
||||
// get terminal handle
|
||||
HANDLE hTerminal = INVALID_HANDLE_VALUE;
|
||||
if (&stream == &std::cout)
|
||||
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
else if (&stream == &std::cerr)
|
||||
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
// save default terminal attributes if it unsaved
|
||||
if (!defaultAttributes)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
||||
return;
|
||||
defaultAttributes = info.wAttributes;
|
||||
}
|
||||
|
||||
// restore all default settings
|
||||
if (foreground == -1 && background == -1)
|
||||
{
|
||||
SetConsoleTextAttribute(hTerminal, defaultAttributes);
|
||||
return;
|
||||
}
|
||||
|
||||
// get current settings
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
||||
return;
|
||||
|
||||
if (foreground != -1)
|
||||
{
|
||||
info.wAttributes &= ~(info.wAttributes & 0x0F);
|
||||
info.wAttributes |= static_cast<WORD>(foreground);
|
||||
}
|
||||
|
||||
if (background != -1)
|
||||
{
|
||||
info.wAttributes &= ~(info.wAttributes & 0xF0);
|
||||
info.wAttributes |= static_cast<WORD>(background);
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hTerminal, info.wAttributes);
|
||||
}
|
||||
#endif // TERMCOLOR_OS_WINDOWS
|
||||
|
||||
} // namespace _internal
|
||||
|
||||
} // namespace termcolor
|
||||
|
||||
|
||||
#undef TERMCOLOR_OS_WINDOWS
|
||||
#undef TERMCOLOR_OS_MACOS
|
||||
#undef TERMCOLOR_OS_LINUX
|
||||
|
||||
#endif // TERMCOLOR_HPP_
|
||||
+54
-1
@@ -111,7 +111,60 @@ void set_exception_handler() {
|
||||
SetUnhandledExceptionFilter(windows_exception_handler);
|
||||
}
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
void print_trace()
|
||||
{
|
||||
auto uid = geteuid();
|
||||
|
||||
std::string temp_output_file = "/tmp/dump-output";
|
||||
|
||||
char pid_buf[30];
|
||||
sprintf(pid_buf, "%d", getpid());
|
||||
char name_buf[512];
|
||||
name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
|
||||
int child_pid = fork();
|
||||
if (!child_pid) {
|
||||
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
|
||||
dup2(fd, 1); // redirect output to stderr
|
||||
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
||||
if (uid == 0) {
|
||||
execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
|
||||
}
|
||||
else {
|
||||
execlp("sudo", "gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
abort(); /* If gdb failed to start */
|
||||
}
|
||||
else {
|
||||
waitpid(child_pid, NULL, 0);
|
||||
}
|
||||
|
||||
std::ifstream input(temp_output_file);
|
||||
for (std::string line; getline(input, line);) {
|
||||
LogCrash("{}", line);
|
||||
}
|
||||
|
||||
std::remove(temp_output_file.c_str());
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// crash is off or an unhandled platform
|
||||
void set_exception_handler() {
|
||||
void set_exception_handler()
|
||||
{
|
||||
signal(SIGABRT, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
signal(SIGSEGV, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
}
|
||||
#endif
|
||||
|
||||
+36
-32
@@ -1,53 +1,57 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
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
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
template <typename T>
|
||||
T Clamp(const T& value, const T& lower, const T& upper) {
|
||||
namespace EQEmu {
|
||||
template<typename T>
|
||||
T Clamp(const T &value, const T &lower, const T &upper)
|
||||
{
|
||||
return std::max(lower, std::min(value, upper));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ClampLower(const T& value, const T& lower) {
|
||||
template<typename T>
|
||||
T ClampLower(const T &value, const T &lower)
|
||||
{
|
||||
return std::max(lower, value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ClampUpper(const T& value, const T& upper) {
|
||||
template<typename T>
|
||||
T ClampUpper(const T &value, const T &upper)
|
||||
{
|
||||
return std::min(value, upper);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ValueWithin(const T& value, const T& lower, const T& upper) {
|
||||
template<typename T>
|
||||
bool ValueWithin(const T &value, const T &lower, const T &upper)
|
||||
{
|
||||
return value >= lower && value <= upper;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
bool ValueWithin(const T1& value, const T2& lower, const T3& upper) {
|
||||
return value >= (T1)lower && value <= (T1)upper;
|
||||
template<typename T1, typename T2, typename T3>
|
||||
bool ValueWithin(const T1 &value, const T2 &lower, const T3 &upper)
|
||||
{
|
||||
return value >= (T1) lower && value <= (T1) upper;
|
||||
}
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
|
||||
+350
-193
File diff suppressed because it is too large
Load Diff
+19
-13
@@ -94,6 +94,8 @@ class PTimerList;
|
||||
# define _ISNAN_(a) std::isnan(a)
|
||||
#endif
|
||||
|
||||
#define SQL(...) #__VA_ARGS__
|
||||
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
@@ -105,7 +107,7 @@ public:
|
||||
|
||||
bool AddToNameFilter(const char* name);
|
||||
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
|
||||
bool DeleteCharacter(char* name);
|
||||
bool DeleteCharacter(char* character_name);
|
||||
bool MoveCharacterToZone(const char* charname, const char* zonename);
|
||||
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
|
||||
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
|
||||
@@ -118,7 +120,7 @@ public:
|
||||
|
||||
/* General Information Queries */
|
||||
|
||||
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the Banned_IPs table.
|
||||
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
|
||||
bool AddGMIP(char* ip_address, char* name);
|
||||
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||
@@ -127,13 +129,17 @@ public:
|
||||
|
||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||
uint32 GetAccountIDByChar(uint32 char_id);
|
||||
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const char *name);
|
||||
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
const char *GetCharNameByID(uint32 char_id);
|
||||
const char *GetNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 AccountID, const char* LoginIP);
|
||||
|
||||
/* Instancing */
|
||||
@@ -174,35 +180,35 @@ public:
|
||||
|
||||
/* Account Related */
|
||||
|
||||
bool DeleteAccount(const char* name);
|
||||
bool DeleteAccount(const char *name, const char* loginserver);
|
||||
bool GetLiveChar(uint32 account_id, char* cname);
|
||||
bool SetAccountStatus(const char* name, int16 status);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 accid, const char* password);
|
||||
bool UpdateLiveChar(char* charname, uint32 lsaccount_id);
|
||||
bool UpdateLiveChar(char* charname, uint32 account_id);
|
||||
|
||||
int16 CheckStatus(uint32 account_id);
|
||||
|
||||
uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0);
|
||||
uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0);
|
||||
uint32 GetMiniLoginAccount(char* ip);
|
||||
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);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
|
||||
|
||||
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
|
||||
uint32 GetGroupID(const char* name);
|
||||
|
||||
|
||||
void ClearGroup(uint32 gid = 0);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
||||
|
||||
@@ -0,0 +1,569 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 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 <string>
|
||||
#include <cstdio>
|
||||
#include <iterator>
|
||||
#include "database_dump_service.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../string_util.h"
|
||||
#include "../eqemu_config.h"
|
||||
#include "../database_schema.h"
|
||||
#include "../file_util.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#endif
|
||||
|
||||
#define DATABASE_DUMP_PATH "backups/"
|
||||
|
||||
/**
|
||||
* @param cmd
|
||||
* @param return_result
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::execute(const std::string &cmd, bool return_result = true)
|
||||
{
|
||||
const char *file_name = "db-exec-result.txt";
|
||||
|
||||
if (return_result) {
|
||||
#ifdef _WINDOWS
|
||||
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||
#else
|
||||
std::system((cmd + " > " + file_name).c_str());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
std::system((cmd).c_str());
|
||||
}
|
||||
|
||||
std::string result;
|
||||
|
||||
if (return_result) {
|
||||
std::ifstream file(file_name);
|
||||
result = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
|
||||
std::remove(file_name);
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
bool DatabaseDumpService::IsMySQLInstalled()
|
||||
{
|
||||
std::string version_output = GetMySQLVersion();
|
||||
|
||||
return version_output.find("mysql") != std::string::npos && version_output.find("Ver") != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Linux
|
||||
* @return bool
|
||||
*/
|
||||
bool DatabaseDumpService::IsTarAvailable()
|
||||
{
|
||||
std::string version_output = execute("tar --version");
|
||||
|
||||
return version_output.find("GNU tar") != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows
|
||||
* @return bool
|
||||
*/
|
||||
bool DatabaseDumpService::Is7ZipAvailable()
|
||||
{
|
||||
std::string version_output = execute("7z --help");
|
||||
|
||||
return version_output.find("7-Zip") != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
bool DatabaseDumpService::HasCompressionBinary()
|
||||
{
|
||||
return IsTarAvailable() || Is7ZipAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetMySQLVersion()
|
||||
{
|
||||
std::string version_output = execute("mysql --version");
|
||||
|
||||
return trim(version_output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
||||
{
|
||||
auto config = EQEmuConfig::get();
|
||||
|
||||
return fmt::format(
|
||||
"mysqldump -u {} -p{} -h {} {}",
|
||||
config->DatabaseUsername,
|
||||
config->DatabasePassword,
|
||||
config->DatabaseHost,
|
||||
config->DatabaseDB
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetPlayerTablesList()
|
||||
{
|
||||
std::string tables_list;
|
||||
std::vector<std::string> tables = DatabaseSchema::GetPlayerTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
return trim(tables_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetLoginTableList()
|
||||
{
|
||||
std::string tables_list;
|
||||
std::vector<std::string> tables = DatabaseSchema::GetLoginTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
return trim(tables_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetQueryServTables()
|
||||
{
|
||||
std::string tables_list;
|
||||
std::vector<std::string> tables = DatabaseSchema::GetQueryServerTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
return trim(tables_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetSystemTablesList()
|
||||
{
|
||||
std::string tables_list;
|
||||
|
||||
std::vector<std::string> tables = DatabaseSchema::GetServerTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
tables = DatabaseSchema::GetVersionTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
return trim(tables_list);
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetStateTablesList()
|
||||
{
|
||||
std::string tables_list;
|
||||
|
||||
std::vector<std::string> tables = DatabaseSchema::GetStateTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
return trim(tables_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetContentTablesList()
|
||||
{
|
||||
std::string tables_list;
|
||||
|
||||
std::vector<std::string> tables = DatabaseSchema::GetContentTables();
|
||||
for (const auto &table : tables) {
|
||||
tables_list += table + " ";
|
||||
}
|
||||
|
||||
return trim(tables_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string GetDumpDate()
|
||||
{
|
||||
|
||||
time_t now = time(nullptr);
|
||||
struct tm time_struct{};
|
||||
char buf[80];
|
||||
time_struct = *localtime(&now);
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d", &time_struct);
|
||||
|
||||
std::string time = buf;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetSetDumpPath()
|
||||
{
|
||||
return !GetDumpPath().empty() ? GetDumpPath() : DATABASE_DUMP_PATH;
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetDumpFileNameWithPath()
|
||||
{
|
||||
return GetSetDumpPath() + GetDumpFileName();
|
||||
}
|
||||
|
||||
void DatabaseDumpService::Dump()
|
||||
{
|
||||
if (!IsMySQLInstalled()) {
|
||||
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsDumpDropTableSyntaxOnly()) {
|
||||
SetDumpOutputToConsole(true);
|
||||
}
|
||||
|
||||
if (IsDumpOutputToConsole()) {
|
||||
LogSys.SilenceConsoleLogging();
|
||||
}
|
||||
|
||||
LogInfo("MySQL installed [{}]", GetMySQLVersion());
|
||||
|
||||
SetDumpFileName(EQEmuConfig::get()->DatabaseDB + '-' + GetDumpDate());
|
||||
|
||||
auto config = EQEmuConfig::get();
|
||||
|
||||
LogInfo(
|
||||
"Database [{}] Host [{}] Username [{}]",
|
||||
config->DatabaseDB,
|
||||
config->DatabaseHost,
|
||||
config->DatabaseUsername
|
||||
);
|
||||
|
||||
std::string options = "--allow-keywords --extended-insert";
|
||||
|
||||
if (IsDumpWithNoData()) {
|
||||
options += " --no-data";
|
||||
}
|
||||
|
||||
if (!IsDumpTableLock()) {
|
||||
options += " --skip-lock-tables";
|
||||
}
|
||||
|
||||
std::string tables_to_dump;
|
||||
std::string dump_descriptor;
|
||||
|
||||
if (!IsDumpAllTables()) {
|
||||
if (IsDumpPlayerTables()) {
|
||||
tables_to_dump += GetPlayerTablesList() + " ";
|
||||
dump_descriptor += "-player";
|
||||
}
|
||||
|
||||
if (IsDumpSystemTables()) {
|
||||
tables_to_dump += GetSystemTablesList() + " ";
|
||||
dump_descriptor += "-system";
|
||||
}
|
||||
|
||||
if (IsDumpStateTables()) {
|
||||
tables_to_dump += GetStateTablesList() + " ";
|
||||
dump_descriptor += "-state";
|
||||
}
|
||||
|
||||
if (IsDumpContentTables()) {
|
||||
tables_to_dump += GetContentTablesList() + " ";
|
||||
dump_descriptor += "-content";
|
||||
}
|
||||
|
||||
if (IsDumpLoginServerTables()) {
|
||||
tables_to_dump += GetLoginTableList() + " ";
|
||||
dump_descriptor += "-login";
|
||||
}
|
||||
|
||||
if (IsDumpQueryServerTables()) {
|
||||
tables_to_dump += GetQueryServTables();
|
||||
dump_descriptor += "-queryserv";
|
||||
}
|
||||
}
|
||||
|
||||
if (!dump_descriptor.empty()) {
|
||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* If we are dumping to stdout then we don't generate a file
|
||||
*/
|
||||
std::string pipe_file;
|
||||
if (!IsDumpOutputToConsole()) {
|
||||
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
||||
}
|
||||
|
||||
std::string execute_command = fmt::format(
|
||||
"{} {} {} {}",
|
||||
GetBaseMySQLDumpCommand(),
|
||||
options,
|
||||
tables_to_dump,
|
||||
pipe_file
|
||||
);
|
||||
|
||||
if (!FileUtil::exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||
FileUtil::mkdir(GetSetDumpPath());
|
||||
}
|
||||
|
||||
if (IsDumpDropTableSyntaxOnly()) {
|
||||
std::vector<std::string> tables = SplitString(tables_to_dump, ' ');
|
||||
|
||||
for (auto &table : tables) {
|
||||
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
|
||||
}
|
||||
|
||||
if (tables_to_dump.empty()) {
|
||||
std::cerr << "No tables were specified" << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string execution_result = execute(execute_command, IsDumpOutputToConsole());
|
||||
if (!execution_result.empty()) {
|
||||
std::cout << execution_result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tables_to_dump.empty()) {
|
||||
LogInfo("Dumping Tables [{}]", tables_to_dump);
|
||||
}
|
||||
|
||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
||||
if (HasCompressionBinary()) {
|
||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsTarAvailable()) {
|
||||
execute(
|
||||
fmt::format(
|
||||
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
||||
GetDumpFileNameWithPath(),
|
||||
GetSetDumpPath(),
|
||||
GetDumpFileName()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
||||
}
|
||||
else if (Is7ZipAvailable()) {
|
||||
execute(
|
||||
fmt::format(
|
||||
"7z a -t7z {}.zip {}.sql",
|
||||
GetDumpFileNameWithPath(),
|
||||
GetDumpFileNameWithPath()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
||||
}
|
||||
else {
|
||||
LogInfo("Compression requested, but no available compression binary was found");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogWarning("Compression requested but binary not found... Skipping...");
|
||||
}
|
||||
}
|
||||
|
||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||
// LogDebug("[{}] query-serv", (IsDumpQueryServerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
|
||||
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
|
||||
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpSystemTables() const
|
||||
{
|
||||
return dump_system_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpSystemTables(bool dump_system_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_system_tables = dump_system_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpContentTables() const
|
||||
{
|
||||
return dump_content_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpContentTables(bool dump_content_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_content_tables = dump_content_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpPlayerTables() const
|
||||
{
|
||||
return dump_player_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpPlayerTables(bool dump_player_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_player_tables = dump_player_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpLoginServerTables() const
|
||||
{
|
||||
return dump_login_server_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpLoginServerTables(bool dump_login_server_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_login_server_tables = dump_login_server_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpWithNoData() const
|
||||
{
|
||||
return dump_with_no_data;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpWithNoData(bool dump_with_no_data)
|
||||
{
|
||||
DatabaseDumpService::dump_with_no_data = dump_with_no_data;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpAllTables() const
|
||||
{
|
||||
return dump_all_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpAllTables(bool dump_all_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_all_tables = dump_all_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpTableLock() const
|
||||
{
|
||||
return dump_table_lock;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpTableLock(bool dump_table_lock)
|
||||
{
|
||||
DatabaseDumpService::dump_table_lock = dump_table_lock;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpWithCompression() const
|
||||
{
|
||||
return dump_with_compression;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpWithCompression(bool dump_with_compression)
|
||||
{
|
||||
DatabaseDumpService::dump_with_compression = dump_with_compression;
|
||||
}
|
||||
|
||||
const std::string &DatabaseDumpService::GetDumpPath() const
|
||||
{
|
||||
return dump_path;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpPath(const std::string &dump_path)
|
||||
{
|
||||
DatabaseDumpService::dump_path = dump_path;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpFileName(const std::string &dump_file_name)
|
||||
{
|
||||
DatabaseDumpService::dump_file_name = dump_file_name;
|
||||
}
|
||||
|
||||
const std::string &DatabaseDumpService::GetDumpFileName() const
|
||||
{
|
||||
return dump_file_name;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpQueryServerTables() const
|
||||
{
|
||||
return dump_query_server_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpQueryServerTables(bool dump_query_server_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_query_server_tables = dump_query_server_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpOutputToConsole() const
|
||||
{
|
||||
return dump_output_to_console;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpOutputToConsole(bool dump_output_to_console)
|
||||
{
|
||||
DatabaseDumpService::dump_output_to_console = dump_output_to_console;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpDropTableSyntaxOnly() const
|
||||
{
|
||||
return dump_drop_table_syntax_only;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only)
|
||||
{
|
||||
DatabaseDumpService::dump_drop_table_syntax_only = dump_drop_table_syntax_only;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpStateTables() const
|
||||
{
|
||||
return dump_state_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_state_tables = dump_state_tables;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 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_DATABASE_DUMP_SERVICE_H
|
||||
#define EQEMU_DATABASE_DUMP_SERVICE_H
|
||||
|
||||
|
||||
class DatabaseDumpService {
|
||||
public:
|
||||
void Dump();
|
||||
bool IsDumpAllTables() const;
|
||||
void SetDumpAllTables(bool dump_all_tables);
|
||||
bool IsDumpWithNoData() const;
|
||||
void SetDumpWithNoData(bool dump_with_no_data);
|
||||
bool IsDumpSystemTables() const;
|
||||
void SetDumpSystemTables(bool dump_system_tables);
|
||||
bool IsDumpContentTables() const;
|
||||
void SetDumpContentTables(bool dump_content_tables);
|
||||
bool IsDumpPlayerTables() const;
|
||||
void SetDumpPlayerTables(bool dump_player_tables);
|
||||
bool IsDumpLoginServerTables() const;
|
||||
void SetDumpLoginServerTables(bool dump_login_server_tables);
|
||||
bool IsDumpTableLock() const;
|
||||
void SetDumpTableLock(bool dump_table_lock);
|
||||
bool IsDumpWithCompression() const;
|
||||
void SetDumpWithCompression(bool dump_with_compression);
|
||||
const std::string &GetDumpPath() const;
|
||||
void SetDumpPath(const std::string &dump_path);
|
||||
const std::string &GetDumpFileName() const;
|
||||
void SetDumpFileName(const std::string &dump_file_name);
|
||||
bool IsDumpQueryServerTables() const;
|
||||
void SetDumpQueryServerTables(bool dump_query_server_tables);
|
||||
bool IsDumpOutputToConsole() const;
|
||||
void SetDumpOutputToConsole(bool dump_output_to_console);
|
||||
bool IsDumpDropTableSyntaxOnly() const;
|
||||
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
||||
bool IsDumpStateTables() const;
|
||||
void SetDumpStateTables(bool dump_state_tables);
|
||||
|
||||
private:
|
||||
bool dump_all_tables = false;
|
||||
bool dump_state_tables = false;
|
||||
bool dump_system_tables = false;
|
||||
bool dump_content_tables = false;
|
||||
bool dump_player_tables = false;
|
||||
bool dump_query_server_tables = false;
|
||||
bool dump_login_server_tables = false;
|
||||
bool dump_with_no_data = false;
|
||||
bool dump_table_lock = false;
|
||||
bool dump_with_compression = false;
|
||||
bool dump_output_to_console = false;
|
||||
bool dump_drop_table_syntax_only = false;
|
||||
std::string dump_path;
|
||||
std::string dump_file_name;
|
||||
|
||||
std::string execute(const std::string &cmd, bool return_result);
|
||||
bool IsMySQLInstalled();
|
||||
std::string GetMySQLVersion();
|
||||
std::string GetBaseMySQLDumpCommand();
|
||||
std::string GetPlayerTablesList();
|
||||
std::string GetSystemTablesList();
|
||||
std::string GetStateTablesList();
|
||||
std::string GetContentTablesList();
|
||||
std::string GetLoginTableList();
|
||||
bool IsTarAvailable();
|
||||
bool Is7ZipAvailable();
|
||||
bool HasCompressionBinary();
|
||||
std::string GetDumpFileNameWithPath();
|
||||
std::string GetSetDumpPath();
|
||||
std::string GetQueryServTables();
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_DATABASE_DUMP_SERVICE_H
|
||||
@@ -476,7 +476,7 @@ bool Database::CheckDatabaseConversions() {
|
||||
CheckDatabaseConvertCorpseDeblob();
|
||||
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
system("perl eqemu_server.pl ran_from_world");
|
||||
if(system("perl eqemu_server.pl ran_from_world"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -97,42 +97,53 @@ bool Database::CheckInstanceExists(uint16 instance_id) {
|
||||
bool Database::CheckInstanceExpired(uint16 instance_id)
|
||||
{
|
||||
|
||||
int32 start_time = 0;
|
||||
int32 duration = 0;
|
||||
int32 start_time = 0;
|
||||
int32 duration = 0;
|
||||
uint32 never_expires = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
|
||||
std::string query = StringFormat(
|
||||
"SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u",
|
||||
instance_id
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
if (!results.Success()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
if (results.RowCount() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
start_time = atoi(row[0]);
|
||||
duration = atoi(row[1]);
|
||||
start_time = atoi(row[0]);
|
||||
duration = atoi(row[1]);
|
||||
never_expires = atoi(row[2]);
|
||||
|
||||
if (never_expires == 1)
|
||||
if (never_expires == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
timeval tv;
|
||||
timeval tv{};
|
||||
gettimeofday(&tv, nullptr);
|
||||
|
||||
if ((start_time + duration) <= tv.tv_sec)
|
||||
return true;
|
||||
return (start_time + duration) <= tv.tv_sec;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
||||
{
|
||||
std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||
" values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)",
|
||||
(unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration);
|
||||
std::string query = StringFormat(
|
||||
"INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||
" values (%u, %u, %u, UNIX_TIMESTAMP(), %u)",
|
||||
instance_id,
|
||||
zone_id,
|
||||
version,
|
||||
duration
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return results.Success();
|
||||
@@ -140,66 +151,84 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
||||
|
||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
{
|
||||
uint32 count = RuleI(Zone, ReservedInstances);
|
||||
uint32 max = 65535;
|
||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||
uint32 max = 32000;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u",
|
||||
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;
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (atoi(row[0]) <= max)
|
||||
{
|
||||
if (atoi(row[0]) <= max) {
|
||||
instance_id = atoi(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count);
|
||||
if (instance_id < max_reserved_instance_id) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", max_reserved_instance_id);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count++;
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
if (count < atoi(row[0]))
|
||||
{
|
||||
instance_id = count;
|
||||
max_reserved_instance_id++;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
if (max_reserved_instance_id < atoi(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count > max)
|
||||
{
|
||||
if (max_reserved_instance_id > max) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count++;
|
||||
max_reserved_instance_id++;
|
||||
}
|
||||
|
||||
instance_id = count;
|
||||
instance_id = max_reserved_instance_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -548,17 +577,36 @@ void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &ch
|
||||
|
||||
void Database::PurgeExpiredInstances()
|
||||
{
|
||||
std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0");
|
||||
|
||||
/**
|
||||
* Delay purging by a day so that we can continue using adjacent free instance id's
|
||||
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
||||
* has not been fully de-allocated
|
||||
*/
|
||||
std::string query =
|
||||
SQL(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
instance_list
|
||||
where
|
||||
(start_time + duration) <= (UNIX_TIMESTAMP() - 86400)
|
||||
and never_expires = 0
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
if (results.RowCount() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
DeleteInstance(atoi(row[0]));
|
||||
}
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
@@ -566,4 +614,4 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), "
|
||||
"duration=%u WHERE id=%u", new_duration, instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
/**
|
||||
* 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_DATABASE_SCHEMA_H
|
||||
#define EQEMU_DATABASE_SCHEMA_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace DatabaseSchema {
|
||||
|
||||
/**
|
||||
* Character-specific tables
|
||||
*
|
||||
* Does not included related meta-data tables such as 'guilds', 'accounts'
|
||||
* @return
|
||||
*/
|
||||
static std::map<std::string, std::string> GetCharacterTables()
|
||||
{
|
||||
return {
|
||||
{"adventure_stats", "player_id"},
|
||||
{"buyer", "charid"},
|
||||
{"char_recipe_list", "char_id"},
|
||||
{"character_activities", "charid"},
|
||||
{"character_alt_currency", "char_id"},
|
||||
{"character_alternate_abilities", "id"},
|
||||
{"character_auras", "id"},
|
||||
{"character_bandolier", "id"},
|
||||
{"character_bind", "id"},
|
||||
{"character_buffs", "character_id"},
|
||||
{"character_corpses", "id"},
|
||||
{"character_currency", "id"},
|
||||
{"character_data", "id"},
|
||||
{"character_disciplines", "id"},
|
||||
{"character_enabledtasks", "charid"},
|
||||
{"character_inspect_messages", "id"},
|
||||
{"character_item_recast", "id"},
|
||||
{"character_languages", "id"},
|
||||
{"character_leadership_abilities", "id"},
|
||||
{"character_material", "id"},
|
||||
{"character_memmed_spells", "id"},
|
||||
{"character_pet_buffs", "char_id"},
|
||||
{"character_pet_info", "char_id"},
|
||||
{"character_pet_inventory", "char_id"},
|
||||
{"character_potionbelt", "id"},
|
||||
{"character_skills", "id"},
|
||||
{"character_spells", "id"},
|
||||
{"character_tasks", "charid"},
|
||||
{"character_tribute", "id"},
|
||||
{"completed_tasks", "charid"},
|
||||
{"data_buckets", "id"},
|
||||
{"faction_values", "char_id"},
|
||||
{"friends", "charid"},
|
||||
{"guild_members", "char_id"},
|
||||
{"guilds", "id"},
|
||||
{"instance_list_player", "id"},
|
||||
{"inventory", "charid"},
|
||||
{"inventory_snapshots", "charid"},
|
||||
{"keyring", "char_id"},
|
||||
{"mail", "charid"},
|
||||
{"player_titlesets", "char_id"},
|
||||
{"quest_globals", "charid"},
|
||||
{"timers", "char_id"},
|
||||
{"titles", "char_id"},
|
||||
{"trader", "char_id"},
|
||||
{"zone_flags", "charID"}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Gets all player and meta-data tables
|
||||
* @note These tables have no content in the PEQ daily dump
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetPlayerTables()
|
||||
{
|
||||
return {
|
||||
"account",
|
||||
"account_ip",
|
||||
"account_flags",
|
||||
"account_rewards",
|
||||
"adventure_details",
|
||||
"adventure_stats",
|
||||
"buyer",
|
||||
"char_recipe_list",
|
||||
"character_activities",
|
||||
"character_alt_currency",
|
||||
"character_alternate_abilities",
|
||||
"character_auras",
|
||||
"character_bandolier",
|
||||
"character_bind",
|
||||
"character_buffs",
|
||||
"character_corpse_items",
|
||||
"character_corpses",
|
||||
"character_currency",
|
||||
"character_data",
|
||||
"character_disciplines",
|
||||
"character_enabledtasks",
|
||||
"character_inspect_messages",
|
||||
"character_item_recast",
|
||||
"character_languages",
|
||||
"character_leadership_abilities",
|
||||
"character_material",
|
||||
"character_memmed_spells",
|
||||
"character_pet_buffs",
|
||||
"character_pet_info",
|
||||
"character_pet_inventory",
|
||||
"character_potionbelt",
|
||||
"character_skills",
|
||||
"character_spells",
|
||||
"character_tasks",
|
||||
"character_tribute",
|
||||
"completed_tasks",
|
||||
"data_buckets",
|
||||
"discovered_items",
|
||||
"faction_values",
|
||||
"friends",
|
||||
"guild_bank",
|
||||
"guild_members",
|
||||
"guild_ranks",
|
||||
"guild_relations",
|
||||
"guilds",
|
||||
"instance_list_player",
|
||||
"inventory",
|
||||
"inventory_snapshots",
|
||||
"keyring",
|
||||
"mail",
|
||||
"petitions",
|
||||
"player_titlesets",
|
||||
"quest_globals",
|
||||
"sharedbank",
|
||||
"spell_buckets",
|
||||
"spell_globals",
|
||||
"timers",
|
||||
"titles",
|
||||
"trader",
|
||||
"trader_audit",
|
||||
"zone_flags"
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets content tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetContentTables()
|
||||
{
|
||||
return {
|
||||
"aa_ability",
|
||||
"aa_actions",
|
||||
"aa_effects",
|
||||
"aa_rank_effects",
|
||||
"aa_rank_prereqs",
|
||||
"aa_ranks",
|
||||
"aa_required_level_cost",
|
||||
"adventure_template",
|
||||
"adventure_template_entry",
|
||||
"adventure_template_entry_flavor",
|
||||
"altadv_vars",
|
||||
"alternate_currency",
|
||||
"auras",
|
||||
"base_data",
|
||||
"blocked_spells",
|
||||
"books",
|
||||
"char_create_combinations",
|
||||
"char_create_point_allocations",
|
||||
"class_skill",
|
||||
"damageshieldtypes",
|
||||
"doors",
|
||||
"faction_base_data",
|
||||
"faction_list",
|
||||
"faction_list_mod",
|
||||
"fear_hints",
|
||||
"fishing",
|
||||
"forage",
|
||||
"global_loot",
|
||||
"goallists",
|
||||
"graveyard",
|
||||
"grid",
|
||||
"grid_entries",
|
||||
"ground_spawns",
|
||||
"horses",
|
||||
"instance_list",
|
||||
"items",
|
||||
"ldon_trap_entries",
|
||||
"ldon_trap_templates",
|
||||
"lootdrop",
|
||||
"lootdrop_entries",
|
||||
"loottable",
|
||||
"loottable_entries",
|
||||
"merchantlist",
|
||||
"npc_emotes",
|
||||
"npc_faction",
|
||||
"npc_faction_entries",
|
||||
"npc_scale_global_base",
|
||||
"npc_spells",
|
||||
"npc_spells_effects",
|
||||
"npc_spells_effects_entries",
|
||||
"npc_spells_entries",
|
||||
"npc_types",
|
||||
"npc_types_metadata",
|
||||
"npc_types_tint",
|
||||
"object",
|
||||
"pets",
|
||||
"pets_equipmentset",
|
||||
"pets_equipmentset_entries",
|
||||
"proximities",
|
||||
"races",
|
||||
"skill_caps",
|
||||
"spawn2",
|
||||
"spawn_condition_values",
|
||||
"spawn_conditions",
|
||||
"spawn_events",
|
||||
"spawnentry",
|
||||
"spawngroup",
|
||||
"spells_new",
|
||||
"start_zones",
|
||||
"starting_items",
|
||||
"task_activities",
|
||||
"tasks",
|
||||
"tasksets",
|
||||
"tradeskill_recipe",
|
||||
"tradeskill_recipe_entries",
|
||||
"traps",
|
||||
"tribute_levels",
|
||||
"tributes",
|
||||
"veteran_reward_templates",
|
||||
"zone",
|
||||
"zone_points",
|
||||
"zone_server",
|
||||
"zoneserver_auth",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetServerTables()
|
||||
{
|
||||
return {
|
||||
"chatchannels",
|
||||
"command_settings",
|
||||
"db_str",
|
||||
"eqtime",
|
||||
"launcher",
|
||||
"launcher_zones",
|
||||
"level_exp_mods",
|
||||
"logsys_categories",
|
||||
"name_filter",
|
||||
"perl_event_export_settings",
|
||||
"profanity_list",
|
||||
"rule_sets",
|
||||
"rule_values",
|
||||
"variables",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets QueryServer tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetQueryServerTables()
|
||||
{
|
||||
return {
|
||||
"qs_merchant_transaction_record",
|
||||
"qs_merchant_transaction_record_entries",
|
||||
"qs_player_aa_rate_hourly",
|
||||
"qs_player_delete_record",
|
||||
"qs_player_delete_record_entries",
|
||||
"qs_player_events",
|
||||
"qs_player_handin_record",
|
||||
"qs_player_handin_record_entries",
|
||||
"qs_player_move_record",
|
||||
"qs_player_move_record_entries",
|
||||
"qs_player_npc_kill_record",
|
||||
"qs_player_npc_kill_record_entries",
|
||||
"qs_player_speech",
|
||||
"qs_player_trade_record",
|
||||
"qs_player_trade_record_entries",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets state tables
|
||||
* Tables that keep track of server state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetStateTables()
|
||||
{
|
||||
return {
|
||||
"adventure_members",
|
||||
"banned_ips",
|
||||
"bug_reports",
|
||||
"bugs",
|
||||
"eventlog",
|
||||
"gm_ips",
|
||||
"group_id",
|
||||
"group_leaders",
|
||||
"hackers",
|
||||
"ip_exemptions",
|
||||
"item_tick",
|
||||
"lfguild",
|
||||
"merchantlist_temp",
|
||||
"object_contents",
|
||||
"raid_details",
|
||||
"raid_leaders",
|
||||
"raid_members",
|
||||
"reports",
|
||||
"respawn_times",
|
||||
"saylink",
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets login tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetLoginTables()
|
||||
{
|
||||
return {
|
||||
"login_accounts",
|
||||
"login_api_tokens",
|
||||
"login_server_admins",
|
||||
"login_server_list_types",
|
||||
"login_world_servers",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets login tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetVersionTables()
|
||||
{
|
||||
return {
|
||||
"db_version",
|
||||
"inventory_versions",
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //EQEMU_DATABASE_SCHEMA_H
|
||||
+113
-65
@@ -2,8 +2,9 @@
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "misc_functions.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "dbcore.h"
|
||||
|
||||
@@ -14,33 +15,37 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#include <process.h>
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#include <process.h>
|
||||
#else
|
||||
#include "unix.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include "unix.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _EQDEBUG
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#else
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#endif
|
||||
|
||||
DBcore::DBcore() {
|
||||
DBcore::DBcore()
|
||||
{
|
||||
mysql_init(&mysql);
|
||||
pHost = 0;
|
||||
pUser = 0;
|
||||
pHost = 0;
|
||||
pUser = 0;
|
||||
pPassword = 0;
|
||||
pDatabase = 0;
|
||||
pCompress = false;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
}
|
||||
|
||||
DBcore::~DBcore() {
|
||||
DBcore::~DBcore()
|
||||
{
|
||||
mysql_close(&mysql);
|
||||
safe_delete_array(pHost);
|
||||
safe_delete_array(pUser);
|
||||
@@ -49,7 +54,8 @@ DBcore::~DBcore() {
|
||||
}
|
||||
|
||||
// Sends the MySQL server a keepalive
|
||||
void DBcore::ping() {
|
||||
void DBcore::ping()
|
||||
{
|
||||
if (!MDatabase.trylock()) {
|
||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||
return;
|
||||
@@ -63,34 +69,35 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO
|
||||
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||
}
|
||||
|
||||
MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce)
|
||||
MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce)
|
||||
{
|
||||
BenchTimer timer;
|
||||
timer.reset();
|
||||
|
||||
LockMutex lock(&MDatabase);
|
||||
|
||||
// Reconnect if we are not connected before hand.
|
||||
if (pStatus != Connected)
|
||||
if (pStatus != Connected) {
|
||||
Open();
|
||||
}
|
||||
|
||||
// request query. != 0 indicates some kind of error.
|
||||
if (mysql_real_query(&mysql, query, querylen) != 0)
|
||||
{
|
||||
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
||||
unsigned int errorNumber = mysql_errno(&mysql);
|
||||
|
||||
if (errorNumber == CR_SERVER_GONE_ERROR)
|
||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
||||
pStatus = Error;
|
||||
}
|
||||
|
||||
// error appears to be a disconnect error, may need to try again.
|
||||
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR)
|
||||
{
|
||||
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) {
|
||||
|
||||
if (retryOnFailureOnce)
|
||||
{
|
||||
std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl;
|
||||
if (retryOnFailureOnce) {
|
||||
LogInfo("Database Error: Lost connection, attempting to recover");
|
||||
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
|
||||
|
||||
if (requestResult.Success())
|
||||
{
|
||||
std::cout << "Reconnection to database successful." << std::endl;
|
||||
if (requestResult.Success()) {
|
||||
LogInfo("Reconnection to database successful");
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
@@ -102,109 +109,150 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
|
||||
|
||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer);
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
|
||||
}
|
||||
|
||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
|
||||
/* Implement Logging at the Root */
|
||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0){
|
||||
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)
|
||||
Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query);
|
||||
/**
|
||||
* Error logging
|
||||
*/
|
||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
||||
LogMySQLError("[{}] [{}]\n[{}]", 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);
|
||||
}
|
||||
|
||||
// successful query. get results.
|
||||
MYSQL_RES* res = mysql_store_result(&mysql);
|
||||
uint32 rowCount = 0;
|
||||
MYSQL_RES *res = mysql_store_result(&mysql);
|
||||
uint32 rowCount = 0;
|
||||
|
||||
if (res != nullptr)
|
||||
rowCount = (uint32)mysql_num_rows(res);
|
||||
if (res != nullptr) {
|
||||
rowCount = (uint32) mysql_num_rows(res);
|
||||
}
|
||||
|
||||
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
|
||||
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)
|
||||
{
|
||||
MySQLRequestResult requestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(&mysql),
|
||||
rowCount,
|
||||
(uint32) mysql_field_count(&mysql),
|
||||
(uint32) mysql_insert_id(&mysql)
|
||||
);
|
||||
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||
if ((strncasecmp(query, "select", 6) == 0)) {
|
||||
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s");
|
||||
LogMySQLQuery(
|
||||
"{0} ({1} row{2} returned) ({3}s)",
|
||||
query,
|
||||
requestResult.RowCount(),
|
||||
requestResult.RowCount() == 1 ? "" : "s",
|
||||
std::to_string(timer.elapsed())
|
||||
);
|
||||
}
|
||||
else {
|
||||
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s");
|
||||
LogMySQLQuery(
|
||||
"{0} ({1} row{2} affected) ({3}s)",
|
||||
query,
|
||||
requestResult.RowsAffected(),
|
||||
requestResult.RowsAffected() == 1 ? "" : "s",
|
||||
std::to_string(timer.elapsed())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
void DBcore::TransactionBegin() {
|
||||
void DBcore::TransactionBegin()
|
||||
{
|
||||
QueryDatabase("START TRANSACTION");
|
||||
}
|
||||
|
||||
void DBcore::TransactionCommit() {
|
||||
void DBcore::TransactionCommit()
|
||||
{
|
||||
QueryDatabase("COMMIT");
|
||||
}
|
||||
|
||||
void DBcore::TransactionRollback() {
|
||||
void DBcore::TransactionRollback()
|
||||
{
|
||||
QueryDatabase("ROLLBACK");
|
||||
}
|
||||
|
||||
uint32 DBcore::DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen) {
|
||||
uint32 DBcore::DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen)
|
||||
{
|
||||
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
||||
// LockMutex lock(&MDatabase);
|
||||
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
||||
}
|
||||
|
||||
bool DBcore::Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase,uint32 iPort, uint32* errnum, char* errbuf, bool iCompress, bool iSSL) {
|
||||
bool DBcore::Open(
|
||||
const char *iHost,
|
||||
const char *iUser,
|
||||
const char *iPassword,
|
||||
const char *iDatabase,
|
||||
uint32 iPort,
|
||||
uint32 *errnum,
|
||||
char *errbuf,
|
||||
bool iCompress,
|
||||
bool iSSL
|
||||
)
|
||||
{
|
||||
LockMutex lock(&MDatabase);
|
||||
safe_delete(pHost);
|
||||
safe_delete(pUser);
|
||||
safe_delete(pPassword);
|
||||
safe_delete(pDatabase);
|
||||
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
|
||||
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
|
||||
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
|
||||
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
|
||||
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
|
||||
pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase);
|
||||
pCompress = iCompress;
|
||||
pPort = iPort;
|
||||
pSSL = iSSL;
|
||||
pPort = iPort;
|
||||
pSSL = iSSL;
|
||||
return Open(errnum, errbuf);
|
||||
}
|
||||
|
||||
bool DBcore::Open(uint32* errnum, char* errbuf) {
|
||||
if (errbuf)
|
||||
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||
{
|
||||
if (errbuf) {
|
||||
errbuf[0] = 0;
|
||||
}
|
||||
LockMutex lock(&MDatabase);
|
||||
if (GetStatus() == Connected)
|
||||
if (GetStatus() == Connected) {
|
||||
return true;
|
||||
}
|
||||
if (GetStatus() == Error) {
|
||||
mysql_close(&mysql);
|
||||
mysql_init(&mysql); // Initialize structure again
|
||||
mysql_init(&mysql); // Initialize structure again
|
||||
}
|
||||
if (!pHost)
|
||||
if (!pHost) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
Added CLIENT_FOUND_ROWS flag to the connect
|
||||
otherwise DB update calls would say 0 rows affected when the value already equalled
|
||||
what the function was tring to set it to, therefore the function would think it failed
|
||||
*/
|
||||
uint32 flags = CLIENT_FOUND_ROWS;
|
||||
if (pCompress)
|
||||
if (pCompress) {
|
||||
flags |= CLIENT_COMPRESS;
|
||||
if (pSSL)
|
||||
}
|
||||
if (pSSL) {
|
||||
flags |= CLIENT_SSL;
|
||||
}
|
||||
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
||||
pStatus = Connected;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (errnum)
|
||||
if (errnum) {
|
||||
*errnum = mysql_errno(&mysql);
|
||||
if (errbuf)
|
||||
}
|
||||
if (errbuf) {
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
}
|
||||
pStatus = Error;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,10 @@ namespace EQEmu
|
||||
|
||||
} // namespace invtype
|
||||
|
||||
namespace DevTools {
|
||||
const int32 GM_ACCOUNT_STATUS_LEVEL = 150;
|
||||
}
|
||||
|
||||
namespace popupresponse {
|
||||
const int32 SERVER_INTERNAL_USE_BASE = 2000000000;
|
||||
const int32 MOB_INFO_DISMISS = 2000000001;
|
||||
@@ -313,6 +317,15 @@ namespace EQEmu
|
||||
QuestControlGrid = -1
|
||||
};
|
||||
|
||||
namespace consent {
|
||||
enum eConsentType : uint8 {
|
||||
Normal = 0,
|
||||
Group,
|
||||
Raid,
|
||||
Guild
|
||||
};
|
||||
}; // namespace consent
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
+113
-194
@@ -71,7 +71,7 @@
|
||||
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
||||
|
||||
// animations for AT_Anim
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_STAND 0x64
|
||||
#define ANIM_SIT 0x6e
|
||||
#define ANIM_CROUCH 0x6f
|
||||
@@ -87,200 +87,114 @@ typedef enum {
|
||||
_eaMaxAppearance
|
||||
} EmuAppearance;
|
||||
|
||||
#define MT_NPCQuestSay 10
|
||||
// msg_type's for custom usercolors
|
||||
#define MT_Say 256
|
||||
#define MT_Tell 257
|
||||
#define MT_Group 258
|
||||
#define MT_Guild 259
|
||||
#define MT_OOC 260
|
||||
#define MT_Auction 261
|
||||
#define MT_Shout 262
|
||||
#define MT_Emote 263
|
||||
#define MT_Spells 264
|
||||
#define MT_YouHitOther 265
|
||||
#define MT_OtherHitsYou 266
|
||||
#define MT_YouMissOther 267
|
||||
#define MT_OtherMissesYou 268
|
||||
#define MT_Broadcasts 269
|
||||
#define MT_Skills 270
|
||||
#define MT_Disciplines 271
|
||||
#define MT_Unused1 272
|
||||
#define MT_DefaultText 273
|
||||
#define MT_Unused2 274
|
||||
#define MT_MerchantOffer 275
|
||||
#define MT_MerchantBuySell 276
|
||||
#define MT_YourDeath 277
|
||||
#define MT_OtherDeath 278
|
||||
#define MT_OtherHits 279
|
||||
#define MT_OtherMisses 280
|
||||
#define MT_Who 281
|
||||
#define MT_YellForHelp 282
|
||||
#define MT_NonMelee 283
|
||||
#define MT_WornOff 284
|
||||
#define MT_MoneySplit 285
|
||||
#define MT_LootMessages 286
|
||||
#define MT_DiceRoll 287
|
||||
#define MT_OtherSpells 288
|
||||
#define MT_SpellFailure 289
|
||||
#define MT_Chat 290
|
||||
#define MT_Channel1 291
|
||||
#define MT_Channel2 292
|
||||
#define MT_Channel3 293
|
||||
#define MT_Channel4 294
|
||||
#define MT_Channel5 295
|
||||
#define MT_Channel6 296
|
||||
#define MT_Channel7 297
|
||||
#define MT_Channel8 298
|
||||
#define MT_Channel9 299
|
||||
#define MT_Channel10 300
|
||||
#define MT_CritMelee 301
|
||||
#define MT_SpellCrits 302
|
||||
#define MT_TooFarAway 303
|
||||
#define MT_NPCRampage 304
|
||||
#define MT_NPCFlurry 305
|
||||
#define MT_NPCEnrage 306
|
||||
#define MT_SayEcho 307
|
||||
#define MT_TellEcho 308
|
||||
#define MT_GroupEcho 309
|
||||
#define MT_GuildEcho 310
|
||||
#define MT_OOCEcho 311
|
||||
#define MT_AuctionEcho 312
|
||||
#define MT_ShoutECho 313
|
||||
#define MT_EmoteEcho 314
|
||||
#define MT_Chat1Echo 315
|
||||
#define MT_Chat2Echo 316
|
||||
#define MT_Chat3Echo 317
|
||||
#define MT_Chat4Echo 318
|
||||
#define MT_Chat5Echo 319
|
||||
#define MT_Chat6Echo 320
|
||||
#define MT_Chat7Echo 321
|
||||
#define MT_Chat8Echo 322
|
||||
#define MT_Chat9Echo 323
|
||||
#define MT_Chat10Echo 324
|
||||
#define MT_DoTDamage 325
|
||||
#define MT_ItemLink 326
|
||||
#define MT_RaidSay 327
|
||||
#define MT_MyPet 328
|
||||
#define MT_DS 329
|
||||
#define MT_Leadership 330
|
||||
#define MT_PetFlurry 331
|
||||
#define MT_PetCrit 332
|
||||
#define MT_FocusEffect 333
|
||||
#define MT_Experience 334
|
||||
#define MT_System 335
|
||||
#define MT_PetSpell 336
|
||||
#define MT_PetResponse 337
|
||||
#define MT_ItemSpeech 338
|
||||
#define MT_StrikeThrough 339
|
||||
#define MT_Stun 340
|
||||
namespace Chat {
|
||||
const uint16 White = 0;
|
||||
const uint16 DimGray = 1;
|
||||
const uint16 Default = 1;
|
||||
const uint16 Green = 2;
|
||||
const uint16 BrightBlue = 3;
|
||||
const uint16 LightBlue = 4;
|
||||
const uint16 Magenta = 5;
|
||||
const uint16 Gray = 6;
|
||||
const uint16 LightGray = 7;
|
||||
const uint16 NPCQuestSay = 10;
|
||||
const uint16 DarkGray = 12;
|
||||
const uint16 Red = 13;
|
||||
const uint16 Lime = 14;
|
||||
const uint16 Yellow = 15;
|
||||
const uint16 Blue = 16;
|
||||
const uint16 LightNavy = 17;
|
||||
const uint16 Cyan = 18;
|
||||
const uint16 Black = 20;
|
||||
|
||||
// TODO: Really should combine above and below into one
|
||||
|
||||
//from showeq
|
||||
enum ChatColor
|
||||
{
|
||||
/*
|
||||
CC_Default = 0,
|
||||
CC_DarkGrey = 1,
|
||||
CC_DarkGreen = 2,
|
||||
CC_DarkBlue = 3,
|
||||
CC_Purple = 5,
|
||||
CC_LightGrey = 6,
|
||||
*/
|
||||
|
||||
CC_WhiteSmoke = 0, // FF|F0F0F0
|
||||
CC_Green = 2, // FF|008000
|
||||
CC_BrightBlue = 3, // FF|0040FF
|
||||
CC_Magenta = 5, // FF|F000F0
|
||||
CC_Gray = 6, // FF|808080
|
||||
CC_LightGray = 7, // FF|E0E0E0
|
||||
//CC_WhiteSmoke2 = 10, // FF|F0F0F0
|
||||
CC_DarkGray = 12, // FF|A0A0A0
|
||||
CC_Red = 13, // FF|F00000
|
||||
CC_Lime = 14, // FF|00F000
|
||||
CC_Yellow = 15, // FF|F0F000
|
||||
CC_Blue = 16, // FF|0000F0
|
||||
CC_LightNavy = 17, // FF|0000AF
|
||||
CC_Cyan = 18, // FF|00F0F0
|
||||
CC_Black = 20, // FF|000000
|
||||
|
||||
// any index <= 255 that is not defined above
|
||||
CC_DimGray = 1, // FF|606060
|
||||
CC_Default = 1,
|
||||
|
||||
CC_User_Say = 256,
|
||||
CC_User_Tell = 257,
|
||||
CC_User_Group = 258,
|
||||
CC_User_Guild = 259,
|
||||
CC_User_OOC = 260,
|
||||
CC_User_Auction = 261,
|
||||
CC_User_Shout = 262,
|
||||
CC_User_Emote = 263,
|
||||
CC_User_Spells = 264,
|
||||
CC_User_YouHitOther = 265,
|
||||
CC_User_OtherHitYou = 266,
|
||||
CC_User_YouMissOther = 267,
|
||||
CC_User_OtherMissYou = 268,
|
||||
CC_User_Duels = 269,
|
||||
CC_User_Skills = 270,
|
||||
CC_User_Disciplines = 271,
|
||||
CC_User_Default = 273,
|
||||
CC_User_MerchantOffer = 275,
|
||||
CC_User_MerchantExchange = 276,
|
||||
CC_User_YourDeath = 277,
|
||||
CC_User_OtherDeath = 278,
|
||||
CC_User_OtherHitOther = 279,
|
||||
CC_User_OtherMissOther = 280,
|
||||
CC_User_Who = 281,
|
||||
CC_User_Yell = 282,
|
||||
CC_User_NonMelee = 283,
|
||||
CC_User_SpellWornOff = 284,
|
||||
CC_User_MoneySplit = 285,
|
||||
CC_User_Loot = 286,
|
||||
CC_User_Random = 287,
|
||||
CC_User_OtherSpells = 288,
|
||||
CC_User_SpellFailure = 289,
|
||||
CC_User_ChatChannel = 290,
|
||||
CC_User_Chat1 = 291,
|
||||
CC_User_Chat2 = 292,
|
||||
CC_User_Chat3 = 293,
|
||||
CC_User_Chat4 = 294,
|
||||
CC_User_Chat5 = 295,
|
||||
CC_User_Chat6 = 296,
|
||||
CC_User_Chat7 = 297,
|
||||
CC_User_Chat8 = 298,
|
||||
CC_User_Chat9 = 299,
|
||||
CC_User_Chat10 = 300,
|
||||
CC_User_MeleeCrit = 301,
|
||||
CC_User_SpellCrit = 302,
|
||||
CC_User_TooFarAway = 303,
|
||||
CC_User_NPCRampage = 304,
|
||||
CC_User_NPCFurry = 305,
|
||||
CC_User_NPCEnrage = 306,
|
||||
CC_User_EchoSay = 307,
|
||||
CC_User_EchoTell = 308,
|
||||
CC_User_EchoGroup = 309,
|
||||
CC_User_EchoGuild = 310,
|
||||
CC_User_EchoOOC = 311,
|
||||
CC_User_EchoAuction = 312,
|
||||
CC_User_EchoShout = 313,
|
||||
CC_User_EchoEmote = 314,
|
||||
CC_User_EchoChat1 = 315,
|
||||
CC_User_EchoChat2 = 316,
|
||||
CC_User_EchoChat3 = 317,
|
||||
CC_User_EchoChat4 = 318,
|
||||
CC_User_EchoChat5 = 319,
|
||||
CC_User_EchoChat6 = 320,
|
||||
CC_User_EchoChat7 = 321,
|
||||
CC_User_EchoChat8 = 322,
|
||||
CC_User_EchoChat9 = 323,
|
||||
CC_User_EchoChat10 = 324,
|
||||
CC_User_UnusedAtThisTime = 325,
|
||||
CC_User_ItemTags = 326,
|
||||
CC_User_RaidSay = 327,
|
||||
CC_User_MyPet = 328,
|
||||
CC_User_DamageShield = 329,
|
||||
/**
|
||||
* User colors
|
||||
*/
|
||||
const uint16 Say = 256;
|
||||
const uint16 Tell = 257;
|
||||
const uint16 Group = 258;
|
||||
const uint16 Guild = 259;
|
||||
const uint16 OOC = 260;
|
||||
const uint16 Auction = 261;
|
||||
const uint16 Shout = 262;
|
||||
const uint16 Emote = 263;
|
||||
const uint16 Spells = 264;
|
||||
const uint16 YouHitOther = 265;
|
||||
const uint16 OtherHitYou = 266;
|
||||
const uint16 YouMissOther = 267;
|
||||
const uint16 OtherMissYou = 268;
|
||||
const uint16 Broadcasts = 269;
|
||||
const uint16 Skills = 270;
|
||||
const uint16 Disciplines = 271;
|
||||
const uint16 Unused1 = 272;
|
||||
const uint16 DefaultText = 273;
|
||||
const uint16 Unused2 = 274;
|
||||
const uint16 MerchantOffer = 275;
|
||||
const uint16 MerchantExchange = 276;
|
||||
const uint16 YourDeath = 277;
|
||||
const uint16 OtherDeath = 278;
|
||||
const uint16 OtherHitOther = 279;
|
||||
const uint16 OtherMissOther = 280;
|
||||
const uint16 Who = 281;
|
||||
const uint16 YellForHelp = 282;
|
||||
const uint16 NonMelee = 283;
|
||||
const uint16 SpellWornOff = 284;
|
||||
const uint16 MoneySplit = 285;
|
||||
const uint16 Loot = 286;
|
||||
const uint16 DiceRoll = 287;
|
||||
const uint16 OtherSpells = 288;
|
||||
const uint16 SpellFailure = 289;
|
||||
const uint16 ChatChannel = 290;
|
||||
const uint16 Chat1 = 291;
|
||||
const uint16 Chat2 = 292;
|
||||
const uint16 Chat3 = 293;
|
||||
const uint16 Chat4 = 294;
|
||||
const uint16 Chat5 = 295;
|
||||
const uint16 Chat6 = 296;
|
||||
const uint16 Chat7 = 297;
|
||||
const uint16 Chat8 = 298;
|
||||
const uint16 Chat9 = 299;
|
||||
const uint16 Chat10 = 300;
|
||||
const uint16 MeleeCrit = 301;
|
||||
const uint16 SpellCrit = 302;
|
||||
const uint16 TooFarAway = 303;
|
||||
const uint16 NPCRampage = 304;
|
||||
const uint16 NPCFlurry = 305;
|
||||
const uint16 NPCEnrage = 306;
|
||||
const uint16 EchoSay = 307;
|
||||
const uint16 EchoTell = 308;
|
||||
const uint16 EchoGroup = 309;
|
||||
const uint16 EchoGuild = 310;
|
||||
const uint16 EchoOOC = 311;
|
||||
const uint16 EchoAuction = 312;
|
||||
const uint16 EchoShout = 313;
|
||||
const uint16 EchoEmote = 314;
|
||||
const uint16 EchoChat1 = 315;
|
||||
const uint16 EchoChat2 = 316;
|
||||
const uint16 EchoChat3 = 317;
|
||||
const uint16 EchoChat4 = 318;
|
||||
const uint16 EchoChat5 = 319;
|
||||
const uint16 EchoChat6 = 320;
|
||||
const uint16 EchoChat7 = 321;
|
||||
const uint16 EchoChat8 = 322;
|
||||
const uint16 EchoChat9 = 323;
|
||||
const uint16 EchoChat10 = 324;
|
||||
const uint16 DotDamage = 325;
|
||||
const uint16 ItemLink = 326;
|
||||
const uint16 RaidSay = 327;
|
||||
const uint16 MyPet = 328;
|
||||
const uint16 DamageShield = 329;
|
||||
const uint16 LeaderShip = 330;
|
||||
const uint16 PetFlurry = 331;
|
||||
const uint16 PetCritical = 332;
|
||||
const uint16 FocusEffect = 333;
|
||||
const uint16 Experience = 334;
|
||||
const uint16 System = 335;
|
||||
const uint16 PetSpell = 336;
|
||||
const uint16 PetResponse = 337;
|
||||
const uint16 ItemSpeech = 338;
|
||||
const uint16 StrikeThrough = 339;
|
||||
const uint16 Stun = 340;
|
||||
};
|
||||
|
||||
//ZoneChange_Struct->success values
|
||||
@@ -545,4 +459,9 @@ enum ChatChannelNames : uint16
|
||||
ChatChannel_Emotes = 22
|
||||
};
|
||||
|
||||
namespace ZoneBlockedSpellTypes {
|
||||
const uint8 ZoneWide = 1;
|
||||
const uint8 Region = 2;
|
||||
};
|
||||
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
+44
-38
@@ -35,6 +35,8 @@ static const uint32 MAX_MERC = 100;
|
||||
static const uint32 MAX_MERC_GRADES = 10;
|
||||
static const uint32 MAX_MERC_STANCES = 10;
|
||||
static const uint32 BLOCKED_BUFF_COUNT = 20;
|
||||
static const uint32 QUESTREWARD_COUNT = 8;
|
||||
static const uint32 ADVANCED_LORE_LENGTH = 8192;
|
||||
|
||||
|
||||
/*
|
||||
@@ -1358,21 +1360,24 @@ struct BecomeCorpse_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ int32 delta_heading:10, // change in heading
|
||||
x_pos:19, // x coord
|
||||
padding0002:3; // ***Placeholder
|
||||
/*0006*/ int32 y_pos:19, // y coord
|
||||
animation:10, // animation
|
||||
padding0006:3; // ***Placeholder
|
||||
/*0010*/ int32 z_pos:19, // z coord
|
||||
delta_y:13; // change in y
|
||||
/*0014*/ int32 delta_x:13, // change in x
|
||||
heading:12, // heading
|
||||
padding0014:7; // ***Placeholder
|
||||
/*0018*/ int32 delta_z:13, // change in z
|
||||
padding0018:19; // ***Placeholder
|
||||
/*0022*/
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 vehicle_id;
|
||||
/*0004*/ signed padding0004 : 12;
|
||||
signed y_pos : 19; // y coord
|
||||
unsigned padding : 1;
|
||||
/*0008*/ signed delta_z : 13; // change in z
|
||||
signed delta_x : 13; // change in x
|
||||
signed padding0008 : 6;
|
||||
/*0012*/ signed x_pos : 19; // x coord
|
||||
unsigned heading : 12; // heading
|
||||
signed padding0016 : 1;
|
||||
/*0016*/ signed delta_heading : 10; // change in heading
|
||||
signed z_pos : 19; // z coord
|
||||
signed padding0020 : 3;
|
||||
/*0020*/ signed animation : 10; // animation
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0024 : 9;
|
||||
/*0024*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1383,21 +1388,23 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 sequence; //increments one each packet
|
||||
/*0004*/ float y_pos; // y coord
|
||||
/*0008*/ float delta_z; // Change in z
|
||||
/*0012*/ float delta_x; // Change in x
|
||||
/*0016*/ float delta_y; // Change in y
|
||||
/*0020*/ int32 animation:10, // animation
|
||||
delta_heading:10, // change in heading
|
||||
padding0020:12; // ***Placeholder (mostly 1)
|
||||
/*0024*/ float x_pos; // x coord
|
||||
/*0028*/ float z_pos; // z coord
|
||||
/*0032*/ uint16 heading:12, // Directional heading
|
||||
padding0004:4; // ***Placeholder
|
||||
/*0034*/ uint8 unknown0006[2]; // ***Placeholder
|
||||
/*0036*/
|
||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0010*/ float delta_x; // Change in x
|
||||
/*0014*/ unsigned heading : 12; // Directional heading
|
||||
unsigned padding0040 : 20; // ***Placeholder
|
||||
/*0018*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0022*/ float delta_z; // Change in z
|
||||
/*0026*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0030*/ float y_pos; // y coord (1st loc value)
|
||||
/*0034*/ unsigned animation : 10; // ***Placeholder
|
||||
unsigned padding0024 : 22; // animation
|
||||
/*0038*/ float delta_y; // Change in y
|
||||
/*0042*/ signed delta_heading : 10; // change in heading
|
||||
unsigned padding0041 : 22; // ***Placeholder
|
||||
/*0046*/
|
||||
};
|
||||
|
||||
struct SpawnPositionUpdate_Struct
|
||||
@@ -2175,14 +2182,7 @@ struct QuestReward_Struct
|
||||
/*024*/ uint32 silver; // Gives silver to the client
|
||||
/*028*/ uint32 gold; // Gives gold to the client
|
||||
/*032*/ uint32 platinum; // Gives platinum to the client
|
||||
/*036*/ uint32 item_id;
|
||||
/*040*/ uint32 unknown040;
|
||||
/*044*/ uint32 unknown044;
|
||||
/*048*/ uint32 unknown048;
|
||||
/*052*/ uint32 unknown052;
|
||||
/*056*/ uint32 unknown056;
|
||||
/*060*/ uint32 unknown060;
|
||||
/*064*/ uint32 unknown064;
|
||||
/*036*/ int32 item_id[QUESTREWARD_COUNT]; // -1 for nothing
|
||||
/*068*/
|
||||
};
|
||||
|
||||
@@ -2967,6 +2967,12 @@ struct ItemViewRequest_Struct {
|
||||
/*046*/ char unknown046[2];
|
||||
};
|
||||
|
||||
struct ItemAdvancedLoreText_Struct {
|
||||
int32 item_id;
|
||||
char item_name[64];
|
||||
char advanced_lore[ADVANCED_LORE_LENGTH];
|
||||
};
|
||||
|
||||
struct LDONItemViewRequest_Struct {
|
||||
uint32 item_id;
|
||||
uint8 unknown004[4];
|
||||
|
||||
+104
-104
@@ -84,14 +84,14 @@ void EQStream::init(bool resetSession) {
|
||||
|
||||
OpMgr = nullptr;
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
LogNetcode(_L "init Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
}
|
||||
|
||||
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
||||
{
|
||||
EQRawApplicationPacket *ap=nullptr;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size);
|
||||
LogNetcode(_L "Creating new application packet, length [{}]" __L, p->size);
|
||||
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
|
||||
ap = p->MakeAppPacket();
|
||||
return ap;
|
||||
@@ -100,7 +100,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
||||
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
|
||||
{
|
||||
EQRawApplicationPacket *ap=nullptr;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len);
|
||||
LogNetcode(_L "Creating new application packet, length [{}]" __L, len);
|
||||
ap = new EQRawApplicationPacket(buf, len);
|
||||
return ap;
|
||||
}
|
||||
@@ -130,7 +130,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
}
|
||||
|
||||
if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L);
|
||||
LogNetcode(_L "Session not initialized, packet ignored" __L);
|
||||
// _raw(NET__DEBUG, 0xFFFF, p);
|
||||
return;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
while(processed < p->size) {
|
||||
subpacket_length=*(p->pBuffer+processed);
|
||||
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length);
|
||||
LogNetcode(_L "Extracting combined packet of length [{}]" __L, subpacket_length);
|
||||
// _raw(NET__NET_CREATE_HEX, 0xFFFF, subp);
|
||||
subp->copyInfo(p);
|
||||
ProcessPacket(subp);
|
||||
@@ -156,12 +156,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
while(processed<p->size) {
|
||||
EQRawApplicationPacket *ap=nullptr;
|
||||
if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
|
||||
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
|
||||
ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length);
|
||||
processed+=subpacket_length+1;
|
||||
} else {
|
||||
subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1));
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
|
||||
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
|
||||
ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length);
|
||||
processed+=subpacket_length+3;
|
||||
}
|
||||
@@ -176,29 +176,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_Packet: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_Packet that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
SeqOrder check=CompareSequence(NextInSeq,seq);
|
||||
if (check == SeqFuture) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
LogNetcode(_L "Future OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
|
||||
PacketQueue[seq]=p->Copy();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
||||
|
||||
//SendOutOfOrderAck(seq);
|
||||
|
||||
} else if (check == SeqPast) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
LogNetcode(_L "Duplicate OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
SendOutOfOrderAck(seq); //we already got this packet but it was out of order
|
||||
} else {
|
||||
// In case we did queue one before as well.
|
||||
EQProtocolPacket *qp=RemoveQueue(seq);
|
||||
if (qp) {
|
||||
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq);
|
||||
LogNetcode("[NET_TRACE] OP_Packet: Removing older queued packet with sequence [{}]", seq);
|
||||
delete qp;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
// Check for an embedded OP_AppCombinded (protocol level 0x19)
|
||||
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
||||
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size);
|
||||
LogNetcode(_L "seq [{}], Extracting combined packet of length [{}]" __L, seq, subp->size);
|
||||
// _raw(NET__NET_CREATE_HEX, seq, subp);
|
||||
subp->copyInfo(p);
|
||||
ProcessPacket(subp);
|
||||
@@ -226,29 +226,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_Fragment: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_Fragment that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
SeqOrder check=CompareSequence(NextInSeq,seq);
|
||||
if (check == SeqFuture) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
LogNetcode(_L "Future OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
|
||||
PacketQueue[seq]=p->Copy();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size());
|
||||
LogNetcode(_L "OP_Fragment Queue size=[{}]" __L, PacketQueue.size());
|
||||
|
||||
//SendOutOfOrderAck(seq);
|
||||
|
||||
} else if (check == SeqPast) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
LogNetcode(_L "Duplicate OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
SendOutOfOrderAck(seq);
|
||||
} else {
|
||||
// In case we did queue one before as well.
|
||||
EQProtocolPacket *qp=RemoveQueue(seq);
|
||||
if (qp) {
|
||||
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq);
|
||||
LogNetcode("[NET_TRACE] OP_Fragment: Removing older queued packet with sequence [{}]", seq);
|
||||
delete qp;
|
||||
}
|
||||
SetNextAckToSend(seq);
|
||||
@@ -256,18 +256,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
if (oversize_buffer) {
|
||||
memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2);
|
||||
oversize_offset+=p->size-2;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length);
|
||||
LogNetcode(_L "Fragment of oversized of length [{}], seq [{}]: now at [{}]/[{}]" __L, p->size-2, seq, oversize_offset, oversize_length);
|
||||
if (oversize_offset==oversize_length) {
|
||||
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
||||
EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size);
|
||||
LogNetcode(_L "seq [{}], Extracting combined oversize packet of length [{}]" __L, seq, subp->size);
|
||||
//// _raw(NET__NET_CREATE_HEX, subp);
|
||||
subp->copyInfo(p);
|
||||
ProcessPacket(subp);
|
||||
delete subp;
|
||||
} else {
|
||||
EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size);
|
||||
LogNetcode(_L "seq [{}], completed combined oversize packet of length [{}]" __L, seq, ap->size);
|
||||
if (ap) {
|
||||
ap->copyInfo(p);
|
||||
InboundQueuePush(ap);
|
||||
@@ -282,20 +282,20 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
oversize_buffer=new unsigned char[oversize_length];
|
||||
memcpy(oversize_buffer,p->pBuffer+6,p->size-6);
|
||||
oversize_offset=p->size-6;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length);
|
||||
LogNetcode(_L "First fragment of oversized of seq [{}]: now at [{}]/[{}]" __L, seq, oversize_offset, oversize_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_KeepAlive: {
|
||||
NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size));
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L);
|
||||
LogNetcode(_L "Received and queued reply to keep alive" __L);
|
||||
}
|
||||
break;
|
||||
case OP_Ack: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_Ack that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
@@ -309,11 +309,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_SessionRequest: {
|
||||
if(p->Size() < sizeof(SessionRequest))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_SessionRequest that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
if (GetState()==ESTABLISHED) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts);
|
||||
LogNetcode(_L "Received OP_SessionRequest in ESTABLISHED state ([{}]) streamactive ([{}]) attempt ([{}])" __L, GetState(),streamactive,sessionAttempts);
|
||||
|
||||
// client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case
|
||||
// streamactive means we identified the opcode for the stream, we cannot re-establish this connection
|
||||
@@ -331,7 +331,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
SessionRequest *Request=(SessionRequest *)p->pBuffer;
|
||||
Session=ntohl(Request->Session);
|
||||
SetMaxLen(ntohl(Request->MaxLength));
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen);
|
||||
LogNetcode(_L "Received OP_SessionRequest: session [{}], maxlen [{}]" __L, (unsigned long)Session, MaxLen);
|
||||
SetState(ESTABLISHED);
|
||||
Key=0x11223344;
|
||||
SendSessionResponse();
|
||||
@@ -340,7 +340,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_SessionResponse: {
|
||||
if(p->Size() < sizeof(SessionResponse))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_SessionResponse that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
compressed=(Response->Format&FLAG_COMPRESSED);
|
||||
encoded=(Response->Format&FLAG_ENCODED);
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
|
||||
LogNetcode(_L "Received OP_SessionResponse: session [{}], maxlen [{}], key [{}], compressed? [{}], encoded? [{}]" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
|
||||
|
||||
// Kinda kludgy, but trie for now
|
||||
if (StreamType==UnknownStream) {
|
||||
@@ -379,17 +379,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
EQStreamState state = GetState();
|
||||
if(state == ESTABLISHED) {
|
||||
//client initiated disconnect?
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L);
|
||||
LogNetcode(_L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect" __L);
|
||||
_SendDisconnect();
|
||||
SetState(CLOSED);
|
||||
} else if(state == CLOSING) {
|
||||
//we were waiting for this anyways, ignore pending messages, send the reply and be closed.
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L);
|
||||
LogNetcode(_L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though" __L);
|
||||
_SendDisconnect();
|
||||
SetState(CLOSED);
|
||||
} else {
|
||||
//we are expecting this (or have already gotten it, but dont care either way)
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L);
|
||||
LogNetcode(_L "Received expected OP_SessionDisconnect. Moving to closed state" __L);
|
||||
SetState(CLOSED);
|
||||
}
|
||||
}
|
||||
@@ -397,14 +397,14 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_OutOfOrderAck: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_OutOfOrderAck that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
MOutboundQueue.lock();
|
||||
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
|
||||
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
|
||||
@@ -414,7 +414,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
|
||||
uint16 sqsize = SequencedQueue.size();
|
||||
uint16 index = seq - SequencedBase;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize);
|
||||
LogNetcode(_L "OP_OutOfOrderAck marking packet acked in queue (queue index = [{}], queue size = [{}])" __L, index, sqsize);
|
||||
if (index < sqsize) {
|
||||
SequencedQueue[index]->acked = true;
|
||||
// flag packets for a resend
|
||||
@@ -423,7 +423,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) {
|
||||
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) {
|
||||
(*sitr)->sent_time = 0;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck Flagging packet %d for retransmission" __L, SequencedBase + count);
|
||||
LogNetcode(_L "OP_OutOfOrderAck Flagging packet [{}] for retransmission" __L, SequencedBase + count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -432,11 +432,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
retransmittimer = Timer::GetCurrentTime();
|
||||
}
|
||||
} else {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq);
|
||||
LogNetcode(_L "Received OP_OutOfOrderAck for out-of-window [{}]. Window ([{}]->[{}])" __L, seq, SequencedBase, NextOutSeq);
|
||||
}
|
||||
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
LogNetcode(_L "Post-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
|
||||
MOutboundQueue.unlock();
|
||||
@@ -445,7 +445,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_SessionStatRequest: {
|
||||
if(p->Size() < sizeof(ClientSessionStats))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
|
||||
LogNetcode(_L "Received OP_SessionStatRequest that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
|
||||
@@ -468,7 +468,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
retransmittimeout += 300;
|
||||
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
|
||||
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
|
||||
LogNetcode(_L "Retransmit timeout recalculated to [{}]ms" __L, retransmittimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,11 +485,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
}
|
||||
break;
|
||||
case OP_SessionStatResponse: {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L);
|
||||
LogNetcode(_L "Received OP_SessionStatResponse. Ignoring" __L);
|
||||
}
|
||||
break;
|
||||
case OP_OutOfSession: {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L);
|
||||
LogNetcode(_L "Received OP_OutOfSession. Ignoring" __L);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -520,7 +520,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
|
||||
return;
|
||||
|
||||
if(OpMgr == nullptr || *OpMgr == nullptr) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L);
|
||||
LogNetcode(_L "Packet enqueued into a stream with no opcode manager, dropping" __L);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
@@ -559,18 +559,18 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
||||
|
||||
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
|
||||
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
|
||||
LogNetcode(_L "Making oversized packet, len [{}]" __L, p->Size());
|
||||
|
||||
auto tmpbuff = new unsigned char[p->size + 3];
|
||||
length=p->serialize(opcode, tmpbuff);
|
||||
if (length != p->Size())
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
|
||||
LogNetcode(_L "Packet adjustment, len [{}] to [{}]" __L, p->Size(), length);
|
||||
|
||||
auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4);
|
||||
*(uint32 *)(out->pBuffer+2)=htonl(length);
|
||||
used=MaxLen-10;
|
||||
memcpy(out->pBuffer+6,tmpbuff,used);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
|
||||
LogNetcode(_L "First fragment: used [{}]/[{}]. Payload size [{}] in the packet" __L, used, length, p->size);
|
||||
SequencedPush(out);
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
||||
out->size=chunksize+2;
|
||||
SequencedPush(out);
|
||||
used+=chunksize;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
|
||||
LogNetcode(_L "Subsequent fragment: len [{}], used [{}]/[{}]" __L, chunksize, used, length);
|
||||
}
|
||||
delete p;
|
||||
delete[] tmpbuff;
|
||||
@@ -623,7 +623,7 @@ void EQStream::SequencedPush(EQProtocolPacket *p)
|
||||
void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
||||
{
|
||||
MOutboundQueue.lock();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size);
|
||||
LogNetcode(_L "Pushing non-sequenced packet of length [{}]" __L, p->size);
|
||||
NonSequencedQueue.push(p);
|
||||
MOutboundQueue.unlock();
|
||||
}
|
||||
@@ -631,14 +631,14 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
||||
void EQStream::SendAck(uint16 seq)
|
||||
{
|
||||
uint16 Seq=htons(seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq);
|
||||
LogNetcode(_L "Sending ack with sequence [{}]" __L, seq);
|
||||
SetLastAckSent(seq);
|
||||
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
|
||||
}
|
||||
|
||||
void EQStream::SendOutOfOrderAck(uint16 seq)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq);
|
||||
LogNetcode(_L "Sending out of order ack with sequence [{}]" __L, seq);
|
||||
uint16 Seq=htons(seq);
|
||||
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
|
||||
}
|
||||
@@ -688,24 +688,24 @@ void EQStream::Write(int eq_fd)
|
||||
// If we don't have a packet to try to combine into, use this one as the base
|
||||
// And remove it form the queue
|
||||
p = NonSequencedQueue.front();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size);
|
||||
LogNetcode(_L "Starting combined packet with non-seq packet of len [{}]" __L, p->size);
|
||||
NonSequencedQueue.pop();
|
||||
} else if (!p->combine(NonSequencedQueue.front())) {
|
||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||
// So just send the base packet (we'll try this packet again later)
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size);
|
||||
LogNetcode(_L "Combined packet full at len [{}], next non-seq packet is len [{}]" __L, p->size, (NonSequencedQueue.front())->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
p=nullptr;
|
||||
|
||||
if (BytesWritten > threshold) {
|
||||
// Sent enough this round, lets stop to be fair
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold);
|
||||
LogNetcode(_L "Exceeded write threshold in nonseq ([{}] > [{}])" __L, BytesWritten, threshold);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Combine worked, so just remove this packet and it's spot in the queue
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size);
|
||||
LogNetcode(_L "Combined non-seq packet of len [{}], yeilding [{}] combined" __L, (NonSequencedQueue.front())->size, p->size);
|
||||
delete NonSequencedQueue.front();
|
||||
NonSequencedQueue.pop();
|
||||
}
|
||||
@@ -718,7 +718,7 @@ void EQStream::Write(int eq_fd)
|
||||
uint16 seq_send = SequencedBase + count; //just for logging...
|
||||
|
||||
if(SequencedQueue.empty()) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq);
|
||||
LogNetcode(_L "Tried to write a packet with an empty queue ([{}] is past next out [{}])" __L, seq_send, NextOutSeq);
|
||||
SeqEmpty=true;
|
||||
continue;
|
||||
}
|
||||
@@ -728,35 +728,35 @@ void EQStream::Write(int eq_fd)
|
||||
++sitr;
|
||||
++count;
|
||||
if (p) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten += p->size;
|
||||
p = nullptr;
|
||||
}
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send);
|
||||
LogNetcode(_L "Not retransmitting seq packet [{}] because already marked as acked" __L, seq_send);
|
||||
} else if (!p) {
|
||||
// If we don't have a packet to try to combine into, use this one as the base
|
||||
// Copy it first as it will still live until it is acked
|
||||
p=(*sitr)->Copy();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
|
||||
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
++sitr;
|
||||
++count;
|
||||
} else if (!p->combine(*sitr)) {
|
||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||
// So just send the base packet (we'll try this packet again later)
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send + 1, (*sitr)->size);
|
||||
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send + 1, (*sitr)->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
p=nullptr;
|
||||
if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) {
|
||||
// Sent enough this round, lets stop to be fair
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
|
||||
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Combine worked
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size);
|
||||
LogNetcode(_L "Combined seq packet [{}] of len [{}], yeilding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
++sitr;
|
||||
++count;
|
||||
@@ -766,7 +766,7 @@ void EQStream::Write(int eq_fd)
|
||||
++sitr;
|
||||
++count;
|
||||
if (p) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten += p->size;
|
||||
p = nullptr;
|
||||
@@ -776,25 +776,25 @@ void EQStream::Write(int eq_fd)
|
||||
// Copy it first as it will still live until it is acked
|
||||
p=(*sitr)->Copy();
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
|
||||
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
|
||||
++sitr;
|
||||
++count;
|
||||
} else if (!p->combine(*sitr)) {
|
||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||
// So just send the base packet (we'll try this packet again later)
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size);
|
||||
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send, (*sitr)->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
p=nullptr;
|
||||
|
||||
if (BytesWritten > threshold) {
|
||||
// Sent enough this round, lets stop to be fair
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
|
||||
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Combine worked
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yielding %d combined." __L, seq_send, (*sitr)->size, p->size);
|
||||
LogNetcode(_L "Combined seq packet [{}] of len [{}], yielding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
++sitr;
|
||||
++count;
|
||||
@@ -802,7 +802,7 @@ void EQStream::Write(int eq_fd)
|
||||
}
|
||||
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
LogNetcode(_L "Post send Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
} else {
|
||||
// No more sequenced packets
|
||||
@@ -814,7 +814,7 @@ void EQStream::Write(int eq_fd)
|
||||
|
||||
// We have a packet still, must have run out of both seq and non-seq, so send it
|
||||
if (p) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
}
|
||||
@@ -831,7 +831,7 @@ void EQStream::Write(int eq_fd)
|
||||
if(SeqEmpty && NonSeqEmpty) {
|
||||
//no more data to send
|
||||
if(CheckState(CLOSING)) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L );
|
||||
LogNetcode(_L "All outgoing data flushed, closing stream" __L );
|
||||
//we are waiting for the queues to empty, now we can do our disconnect.
|
||||
//this packet will not actually go out until the next call to Write().
|
||||
_SendDisconnect();
|
||||
@@ -910,7 +910,7 @@ void EQStream::SendSessionRequest()
|
||||
Request->Session=htonl(time(nullptr));
|
||||
Request->MaxLength=htonl(512);
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
|
||||
LogNetcode(_L "Sending OP_SessionRequest: session [{}], maxlen=[{}]" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
|
||||
|
||||
NonSequencedPush(out);
|
||||
}
|
||||
@@ -924,7 +924,7 @@ void EQStream::_SendDisconnect()
|
||||
*(uint32 *)out->pBuffer=htonl(Session);
|
||||
NonSequencedPush(out);
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session);
|
||||
LogNetcode(_L "Sending OP_SessionDisconnect: session [{}]" __L, (unsigned long)Session);
|
||||
}
|
||||
|
||||
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
|
||||
@@ -976,7 +976,7 @@ EQRawApplicationPacket *p=nullptr;
|
||||
if(OpMgr != nullptr && *OpMgr != nullptr) {
|
||||
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
|
||||
if(emu_op == OP_Unknown) {
|
||||
Log(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode);
|
||||
LogNetcode("Unable to convert EQ opcode {:#04x} to an Application opcode", p->opcode);
|
||||
}
|
||||
|
||||
p->SetOpcode(emu_op);
|
||||
@@ -1004,7 +1004,7 @@ void EQStream::InboundQueueClear()
|
||||
{
|
||||
EQApplicationPacket *p=nullptr;
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L);
|
||||
LogNetcode(_L "Clearing inbound queue" __L);
|
||||
|
||||
MInboundQueue.lock();
|
||||
if (!InboundQueue.empty()) {
|
||||
@@ -1047,7 +1047,7 @@ void EQStream::OutboundQueueClear()
|
||||
{
|
||||
EQProtocolPacket *p=nullptr;
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L);
|
||||
LogNetcode(_L "Clearing outbound queue" __L);
|
||||
|
||||
MOutboundQueue.lock();
|
||||
while(!NonSequencedQueue.empty()) {
|
||||
@@ -1069,7 +1069,7 @@ void EQStream::PacketQueueClear()
|
||||
{
|
||||
EQProtocolPacket *p=nullptr;
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L);
|
||||
LogNetcode(_L "Clearing future packet queue" __L);
|
||||
|
||||
if(!PacketQueue.empty()) {
|
||||
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
|
||||
@@ -1101,7 +1101,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
|
||||
delete p;
|
||||
ProcessQueue();
|
||||
} else {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L);
|
||||
LogNetcode(_L "Incoming packet failed checksum" __L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,23 +1132,23 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
||||
SeqOrder ord = CompareSequence(SequencedBase, seq);
|
||||
if(ord == SeqInOrder) {
|
||||
//they are not acking anything new...
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq);
|
||||
LogNetcode(_L "Received an ack with no window advancement (seq [{}])" __L, seq);
|
||||
} else if(ord == SeqPast) {
|
||||
//they are nacking blocks going back before our buffer, wtf?
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase);
|
||||
LogNetcode(_L "Received an ack with backward window advancement (they gave [{}], our window starts at [{}]). This is bad" __L, seq, SequencedBase);
|
||||
} else {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase);
|
||||
LogNetcode(_L "Received an ack up through sequence [{}]. Our base is [{}]" __L, seq, SequencedBase);
|
||||
|
||||
|
||||
//this is a good ack, we get to ack some blocks.
|
||||
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
|
||||
while(SequencedBase != seq) {
|
||||
if(SequencedQueue.empty()) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, SequencedQueue.size());
|
||||
LogNetcode(_L "OUT OF PACKETS acked packet with sequence [{}]. Next send is [{}] before this" __L, (unsigned long)SequencedBase, SequencedQueue.size());
|
||||
SequencedBase = NextOutSeq;
|
||||
break;
|
||||
}
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu." __L, (unsigned long)SequencedBase);
|
||||
LogNetcode(_L "Removing acked packet with sequence [{}]" __L, (unsigned long)SequencedBase);
|
||||
//clean out the acked packet
|
||||
delete SequencedQueue.front();
|
||||
SequencedQueue.pop_front();
|
||||
@@ -1156,7 +1156,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
||||
SequencedBase++;
|
||||
}
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
LogNetcode(_L "Post-Ack on [{}] Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
||||
void EQStream::SetNextAckToSend(uint32 seq)
|
||||
{
|
||||
MAcks.lock();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq);
|
||||
LogNetcode(_L "Set Next Ack To Send to [{}]" __L, (unsigned long)seq);
|
||||
NextAckToSend=seq;
|
||||
MAcks.unlock();
|
||||
}
|
||||
@@ -1174,7 +1174,7 @@ void EQStream::SetNextAckToSend(uint32 seq)
|
||||
void EQStream::SetLastAckSent(uint32 seq)
|
||||
{
|
||||
MAcks.lock();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq);
|
||||
LogNetcode(_L "Set Last Ack Sent to [{}]" __L, (unsigned long)seq);
|
||||
LastAckSent=seq;
|
||||
MAcks.unlock();
|
||||
}
|
||||
@@ -1187,10 +1187,10 @@ void EQStream::ProcessQueue()
|
||||
|
||||
EQProtocolPacket *qp=nullptr;
|
||||
while((qp=RemoveQueue(NextInSeq))!=nullptr) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq);
|
||||
LogNetcode(_L "Processing Queued Packet: Seq=[{}]" __L, NextInSeq);
|
||||
ProcessPacket(qp);
|
||||
delete qp;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1201,21 +1201,21 @@ EQProtocolPacket *qp=nullptr;
|
||||
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
|
||||
qp=itr->second;
|
||||
PacketQueue.erase(itr);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
||||
}
|
||||
return qp;
|
||||
}
|
||||
|
||||
void EQStream::SetStreamType(EQStreamType type)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type));
|
||||
LogNetcode(_L "Changing stream type from [{}] to [{}]" __L, StreamTypeString(StreamType), StreamTypeString(type));
|
||||
StreamType=type;
|
||||
switch (StreamType) {
|
||||
case LoginStream:
|
||||
app_opcode_size=1;
|
||||
compressed=false;
|
||||
encoded=false;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size);
|
||||
LogNetcode(_L "Login stream has app opcode size [{}], is not compressed or encoded" __L, app_opcode_size);
|
||||
break;
|
||||
case ChatOrMailStream:
|
||||
case ChatStream:
|
||||
@@ -1223,7 +1223,7 @@ void EQStream::SetStreamType(EQStreamType type)
|
||||
app_opcode_size=1;
|
||||
compressed=false;
|
||||
encoded=true;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size);
|
||||
LogNetcode(_L "Chat/Mail stream has app opcode size [{}], is not compressed, and is encoded" __L, app_opcode_size);
|
||||
break;
|
||||
case ZoneStream:
|
||||
case WorldStream:
|
||||
@@ -1231,7 +1231,7 @@ void EQStream::SetStreamType(EQStreamType type)
|
||||
app_opcode_size=2;
|
||||
compressed=true;
|
||||
encoded=false;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size);
|
||||
LogNetcode(_L "World/Zone stream has app opcode size [{}], is compressed, and is not encoded" __L, app_opcode_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1281,7 +1281,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
|
||||
|
||||
void EQStream::SetState(EQStreamState state) {
|
||||
MState.lock();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state);
|
||||
LogNetcode(_L "Changing state from [{}] to [{}]" __L, State, state);
|
||||
State=state;
|
||||
MState.unlock();
|
||||
}
|
||||
@@ -1293,29 +1293,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
|
||||
|
||||
EQStreamState orig_state = GetState();
|
||||
if (orig_state == CLOSING && !outgoing_data) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L);
|
||||
LogNetcode(_L "Out of data in closing state, disconnecting" __L);
|
||||
_SendDisconnect();
|
||||
SetState(DISCONNECTING);
|
||||
} else if (LastPacket && (now-LastPacket) > timeout) {
|
||||
switch(orig_state) {
|
||||
case CLOSING:
|
||||
//if we time out in the closing state, they are not acking us, just give up
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L);
|
||||
LogNetcode(_L "Timeout expired in closing state. Moving to closed state" __L);
|
||||
_SendDisconnect();
|
||||
SetState(CLOSED);
|
||||
break;
|
||||
case DISCONNECTING:
|
||||
//we timed out waiting for them to send us the disconnect reply, just give up.
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L);
|
||||
LogNetcode(_L "Timeout expired in disconnecting state. Moving to closed state" __L);
|
||||
SetState(CLOSED);
|
||||
break;
|
||||
case CLOSED:
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L);
|
||||
LogNetcode(_L "Timeout expired in closed state??" __L);
|
||||
break;
|
||||
case ESTABLISHED:
|
||||
//we timed out during normal operation. Try to be nice about it.
|
||||
//we will almost certainly time out again waiting for the disconnect reply, but oh well.
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L);
|
||||
LogNetcode(_L "Timeout expired in established state. Closing connection" __L);
|
||||
_SendDisconnect();
|
||||
SetState(DISCONNECTING);
|
||||
break;
|
||||
@@ -1342,7 +1342,7 @@ void EQStream::Decay()
|
||||
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) {
|
||||
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) {
|
||||
(*sitr)->sent_time = 0;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout exceeded for seq %d. Flagging packet for retransmission" __L, SequencedBase + count);
|
||||
LogNetcode(_L "Timeout exceeded for seq [{}]. Flagging packet for retransmission" __L, SequencedBase + count);
|
||||
}
|
||||
}
|
||||
MOutboundQueue.unlock();
|
||||
@@ -1384,12 +1384,12 @@ void EQStream::AdjustRates(uint32 average_delta)
|
||||
void EQStream::Close() {
|
||||
if(HasOutgoingData()) {
|
||||
//there is pending data, wait for it to go out.
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
|
||||
LogNetcode(_L "Stream requested to Close(), but there is pending data, waiting for it" __L);
|
||||
SetState(CLOSING);
|
||||
} else {
|
||||
//otherwise, we are done, we can drop immediately.
|
||||
_SendDisconnect();
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L);
|
||||
LogNetcode(_L "Stream closing immediate due to Close()" __L);
|
||||
SetState(DISCONNECTING);
|
||||
}
|
||||
}
|
||||
@@ -1417,19 +1417,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
|
||||
} else if(p->opcode == sig->first_eq_opcode) {
|
||||
//opcode matches, check length..
|
||||
if(p->size == sig->first_length) {
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length matched [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
res = MatchSuccessful;
|
||||
} else if(sig->first_length == 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length ([{}]) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
res = MatchSuccessful;
|
||||
} else {
|
||||
//opcode matched but length did not.
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x}, but length [{}] did not match expected [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
|
||||
res = MatchFailed;
|
||||
}
|
||||
} else {
|
||||
//first opcode did not match..
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode {:#04x} did not match expected {:#04x}", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
|
||||
res = MatchFailed;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -46,7 +46,7 @@ void EQStreamIdentifier::Process() {
|
||||
|
||||
//first see if this stream has expired
|
||||
if(r.expire.Check(false)) {
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before timeout", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
r.stream->Close();
|
||||
|
||||
cur = m_streams.erase(cur);
|
||||
@@ -62,23 +62,23 @@ void EQStreamIdentifier::Process() {
|
||||
}
|
||||
if(r.stream->GetState() != ESTABLISHED) {
|
||||
//the stream closed before it was identified.
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before it closed", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
switch(r.stream->GetState())
|
||||
{
|
||||
case ESTABLISHED:
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established");
|
||||
LogNetcode("[StreamIdentify] Stream state was Established");
|
||||
break;
|
||||
case CLOSING:
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing");
|
||||
LogNetcode("[StreamIdentify] Stream state was Closing");
|
||||
break;
|
||||
case DISCONNECTING:
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting");
|
||||
LogNetcode("[StreamIdentify] Stream state was Disconnecting");
|
||||
break;
|
||||
case CLOSED:
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed");
|
||||
LogNetcode("[StreamIdentify] Stream state was Closed");
|
||||
break;
|
||||
default:
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown");
|
||||
LogNetcode("[StreamIdentify] Stream state was Unestablished or unknown");
|
||||
break;
|
||||
}
|
||||
r.stream->ReleaseFromUse();
|
||||
@@ -102,13 +102,13 @@ void EQStreamIdentifier::Process() {
|
||||
switch(res) {
|
||||
case EQStreamInterface::MatchNotReady:
|
||||
//the stream has not received enough packets to compare with this signature
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[StreamIdentify] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
all_ready = false;
|
||||
break;
|
||||
case EQStreamInterface::MatchSuccessful: {
|
||||
//yay, a match.
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
LogNetcode("[StreamIdentify] Identified stream [{}:{}] with signature [{}]", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
|
||||
// before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further
|
||||
r.stream->SetActive(true);
|
||||
@@ -122,7 +122,7 @@ void EQStreamIdentifier::Process() {
|
||||
}
|
||||
case EQStreamInterface::MatchFailed:
|
||||
//do nothing...
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
LogNetcode("[StreamIdentify] [{}:{}] Tried patch [{}] and it did not match", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ void EQStreamIdentifier::Process() {
|
||||
//if we checked all patches and did not find a match.
|
||||
if(all_ready && !found_one) {
|
||||
//the stream cannot be identified.
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}], no match found", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
r.stream->ReleaseFromUse();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||
return;
|
||||
|
||||
if (p->GetOpcode() != OP_SpecialMesg) {
|
||||
Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||
}
|
||||
|
||||
EQApplicationPacket *newp = p->Copy();
|
||||
|
||||
@@ -165,7 +165,7 @@ class EQEmuConfig
|
||||
fconfig >> _config->_root;
|
||||
_config->parse_config();
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
+153
-59
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "eqemu_logsys.h"
|
||||
#include "rulesys.h"
|
||||
#include "platform.h"
|
||||
#include "string_util.h"
|
||||
#include "database.h"
|
||||
@@ -81,31 +82,19 @@ namespace Console {
|
||||
};
|
||||
}
|
||||
|
||||
enum GameChatColor {
|
||||
yellow = 15,
|
||||
red = 13,
|
||||
light_green = 14,
|
||||
light_cyan = 258,
|
||||
light_purple = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* EQEmuLogSys Constructor
|
||||
*/
|
||||
EQEmuLogSys::EQEmuLogSys()
|
||||
{
|
||||
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
|
||||
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
|
||||
bool file_logs_enabled = false;
|
||||
int log_platform = 0;
|
||||
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
|
||||
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
|
||||
}
|
||||
|
||||
/**
|
||||
* EQEmuLogSys Deconstructor
|
||||
*/
|
||||
EQEmuLogSys::~EQEmuLogSys()
|
||||
{
|
||||
}
|
||||
EQEmuLogSys::~EQEmuLogSys() = default;
|
||||
|
||||
void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
{
|
||||
@@ -113,7 +102,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
* Get Executable platform currently running this code (Zone/World/etc)
|
||||
*/
|
||||
log_platform = GetExecutablePlatformInt();
|
||||
|
||||
|
||||
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
|
||||
log_settings[log_category_id].log_to_console = 0;
|
||||
log_settings[log_category_id].log_to_file = 0;
|
||||
@@ -126,15 +115,28 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
/**
|
||||
* Set Defaults
|
||||
*/
|
||||
log_settings[Logs::World_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::QS_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::Crash].log_to_console = Logs::General;
|
||||
log_settings[Logs::MySQLError].log_to_console = Logs::General;
|
||||
log_settings[Logs::Login_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::Headless_Client].log_to_console = Logs::General;
|
||||
log_settings[Logs::NPCScaling].log_to_gmsay = Logs::General;
|
||||
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* RFC 5424
|
||||
*/
|
||||
log_settings[Logs::Emergency].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Alert].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Critical].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Notice].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* Set Category enabled status on defaults
|
||||
@@ -175,20 +177,41 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_category
|
||||
* @return
|
||||
*/
|
||||
bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
|
||||
{
|
||||
return (
|
||||
log_category == Logs::Emergency ||
|
||||
log_category == Logs::Alert ||
|
||||
log_category == Logs::Critical ||
|
||||
log_category == Logs::Error ||
|
||||
log_category == Logs::Warning ||
|
||||
log_category == Logs::Notice ||
|
||||
log_category == Logs::Info ||
|
||||
log_category == Logs::Debug
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_category
|
||||
* @param in_message
|
||||
* @return
|
||||
*/
|
||||
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
|
||||
std::string EQEmuLogSys::FormatOutMessageString(
|
||||
uint16 log_category,
|
||||
const std::string &in_message
|
||||
)
|
||||
{
|
||||
std::string ret;
|
||||
ret.push_back('[');
|
||||
ret.append(Logs::LogCategoryName[log_category]);
|
||||
ret.push_back(']');
|
||||
ret.push_back(' ');
|
||||
ret.append(in_message);
|
||||
return ret;
|
||||
std::string return_string;
|
||||
|
||||
if (IsRfc5424LogCategory(log_category)) {
|
||||
return_string = "[" + GetPlatformName() + "] ";
|
||||
}
|
||||
|
||||
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +219,11 @@ std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
void EQEmuLogSys::ProcessGMSay(
|
||||
uint16 debug_level,
|
||||
uint16 log_category,
|
||||
const std::string &message
|
||||
)
|
||||
{
|
||||
/**
|
||||
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
|
||||
@@ -218,7 +245,11 @@ void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const st
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
void EQEmuLogSys::ProcessLogWrite(
|
||||
uint16 debug_level,
|
||||
uint16 log_category,
|
||||
const std::string &message
|
||||
)
|
||||
{
|
||||
if (log_category == Logs::Crash) {
|
||||
char time_stamp[80];
|
||||
@@ -280,6 +311,8 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
|
||||
case Logs::Normal:
|
||||
return LC_YELLOW;
|
||||
case Logs::MySQLError:
|
||||
case Logs::Warning:
|
||||
case Logs::Critical:
|
||||
case Logs::Error:
|
||||
return LC_RED;
|
||||
case Logs::MySQLQuery:
|
||||
@@ -306,22 +339,22 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
return GameChatColor::yellow;
|
||||
return Chat::Yellow;
|
||||
case Logs::MySQLError:
|
||||
case Logs::Error:
|
||||
return GameChatColor::red;
|
||||
return Chat::Red;
|
||||
case Logs::MySQLQuery:
|
||||
case Logs::Debug:
|
||||
return GameChatColor::light_green;
|
||||
return Chat::Lime;
|
||||
case Logs::Quests:
|
||||
return GameChatColor::light_cyan;
|
||||
return Chat::Group;
|
||||
case Logs::Commands:
|
||||
case Logs::Mercenaries:
|
||||
return GameChatColor::light_purple;
|
||||
return Chat::Magenta;
|
||||
case Logs::Crash:
|
||||
return GameChatColor::red;
|
||||
return Chat::Red;
|
||||
default:
|
||||
return GameChatColor::yellow;
|
||||
return Chat::Yellow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,6 +384,42 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
|
||||
on_log_console_hook(debug_level, log_category, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
constexpr const char *str_end(const char *str)
|
||||
{
|
||||
return *str ? str_end(str + 1) : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
constexpr bool str_slant(const char *str)
|
||||
{
|
||||
return *str == '/' ? true : (*str ? str_slant(str + 1) : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
constexpr const char *r_slant(const char *str)
|
||||
{
|
||||
return *str == '/' ? (str + 1) : r_slant(str - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
constexpr const char *base_file_name(const char *str)
|
||||
{
|
||||
return str_slant(str) ? r_slant(str_end(str)) : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core logging function
|
||||
*
|
||||
@@ -359,7 +428,15 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
|
||||
* @param message
|
||||
* @param ...
|
||||
*/
|
||||
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
|
||||
void EQEmuLogSys::Out(
|
||||
Logs::DebugLevel debug_level,
|
||||
uint16 log_category,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *message,
|
||||
...
|
||||
)
|
||||
{
|
||||
bool log_to_console = true;
|
||||
if (log_settings[log_category].log_to_console < debug_level) {
|
||||
@@ -381,12 +458,18 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prefix;
|
||||
|
||||
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
||||
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
std::string output_message = vStringFormat(message.c_str(), args);
|
||||
std::string output_message = vStringFormat(message, args);
|
||||
va_end(args);
|
||||
|
||||
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message);
|
||||
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
|
||||
|
||||
if (log_to_console) {
|
||||
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
|
||||
@@ -422,7 +505,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
|
||||
return;
|
||||
_mkdir(directory_name.c_str());
|
||||
#else
|
||||
struct stat st;
|
||||
struct stat st{};
|
||||
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||
return;
|
||||
}
|
||||
@@ -463,12 +546,7 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuLogSys::Out(
|
||||
Logs::General,
|
||||
Logs::Status,
|
||||
"Starting File Log 'logs/%s_%i.log'",
|
||||
platform_file_name.c_str(),
|
||||
getpid());
|
||||
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
|
||||
|
||||
/**
|
||||
* Make directory if not exists
|
||||
@@ -488,17 +566,11 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
/**
|
||||
* All other processes
|
||||
*/
|
||||
|
||||
if (platform_file_name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EQEmuLogSys::Out(
|
||||
Logs::General,
|
||||
Logs::Status,
|
||||
"Starting File Log 'logs/%s_%i.log'",
|
||||
platform_file_name.c_str(),
|
||||
getpid());
|
||||
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
|
||||
|
||||
/**
|
||||
* Open file pointer
|
||||
@@ -509,3 +581,25 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Silence console logging
|
||||
*/
|
||||
void EQEmuLogSys::SilenceConsoleLogging()
|
||||
{
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = 0;
|
||||
log_settings[log_index].is_category_enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables console logging
|
||||
*/
|
||||
void EQEmuLogSys::EnableConsoleLogging()
|
||||
{
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = Logs::General;
|
||||
log_settings[log_index].is_category_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
+138
-29
@@ -25,6 +25,14 @@
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <functional>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef utf16_to_utf8
|
||||
#undef utf16_to_utf8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "types.h"
|
||||
|
||||
namespace Logs {
|
||||
@@ -45,7 +53,7 @@ namespace Logs {
|
||||
AI,
|
||||
Aggro,
|
||||
Attack,
|
||||
Client_Server_Packet,
|
||||
PacketClientServer,
|
||||
Combat,
|
||||
Commands,
|
||||
Crash,
|
||||
@@ -59,40 +67,54 @@ namespace Logs {
|
||||
Normal,
|
||||
Object,
|
||||
Pathing,
|
||||
QS_Server,
|
||||
QSServer,
|
||||
Quests,
|
||||
Rules,
|
||||
Skills,
|
||||
Spawns,
|
||||
Spells,
|
||||
Status,
|
||||
TCP_Connection,
|
||||
TCPConnection,
|
||||
Tasks,
|
||||
Tradeskills,
|
||||
Trading,
|
||||
Tribute,
|
||||
UCS_Server,
|
||||
WebInterface_Server,
|
||||
World_Server,
|
||||
Zone_Server,
|
||||
UCSServer,
|
||||
WebInterfaceServer,
|
||||
WorldServer,
|
||||
ZoneServer,
|
||||
MySQLError,
|
||||
MySQLQuery,
|
||||
Mercenaries,
|
||||
QuestDebug,
|
||||
Server_Client_Packet,
|
||||
Client_Server_Packet_Unhandled,
|
||||
Server_Client_Packet_With_Dump,
|
||||
Client_Server_Packet_With_Dump,
|
||||
Login_Server,
|
||||
Client_Login,
|
||||
Headless_Client,
|
||||
HP_Update,
|
||||
PacketServerClient,
|
||||
PacketClientServerUnhandled,
|
||||
PacketServerClientWithDump,
|
||||
PacketClientServerWithDump,
|
||||
Loginserver,
|
||||
ClientLogin,
|
||||
HeadlessClient,
|
||||
HPUpdate,
|
||||
FixZ,
|
||||
Food,
|
||||
Traps,
|
||||
NPCRoamBox,
|
||||
NPCScaling,
|
||||
MobAppearance,
|
||||
Info,
|
||||
Warning,
|
||||
Critical,
|
||||
Emergency,
|
||||
Alert,
|
||||
Notice,
|
||||
AIScanClose,
|
||||
AIYellForHelp,
|
||||
AICastBeneficialClose,
|
||||
AoeCast,
|
||||
EntityManagement,
|
||||
Flee,
|
||||
Aura,
|
||||
HotReload,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -152,19 +174,25 @@ namespace Logs {
|
||||
"Traps",
|
||||
"NPC Roam Box",
|
||||
"NPC Scaling",
|
||||
"Mob Appearance"
|
||||
"Mob Appearance",
|
||||
"Info",
|
||||
"Warning",
|
||||
"Critical",
|
||||
"Emergency",
|
||||
"Alert",
|
||||
"Notice",
|
||||
"AI Scan Close",
|
||||
"AI Yell For Help",
|
||||
"AI Cast Beneficial Close",
|
||||
"AOE Cast",
|
||||
"Entity Management",
|
||||
"Flee",
|
||||
"Aura",
|
||||
"HotReload",
|
||||
};
|
||||
}
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogF(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
OutF(LogSys, debug_level, log_category, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
|
||||
class EQEmuLogSys {
|
||||
public:
|
||||
@@ -177,6 +205,10 @@ public:
|
||||
*/
|
||||
void CloseFileLogs();
|
||||
void LoadLogSettingsDefaults();
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void MakeDirectory(const std::string &directory_name);
|
||||
|
||||
/**
|
||||
@@ -188,12 +220,25 @@ public:
|
||||
* - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
|
||||
* be checked against to see if that piped output is set to actually process it for the category and debug level
|
||||
*/
|
||||
void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...);
|
||||
void Out(
|
||||
Logs::DebugLevel debug_level,
|
||||
uint16 log_category,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *message,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
* Used in file logs to prepend a timestamp entry for logs
|
||||
* @param time_stamp
|
||||
*/
|
||||
void SetCurrentTimeStamp(char* time_stamp);
|
||||
|
||||
/**
|
||||
* @param log_name
|
||||
*/
|
||||
void StartFileLogs(const std::string &log_name = "");
|
||||
|
||||
/**
|
||||
@@ -218,14 +263,14 @@ public:
|
||||
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
||||
* Database loaded via Database::LoadLogSettings(log_settings)
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID];
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
bool file_logs_enabled;
|
||||
bool file_logs_enabled = false;
|
||||
|
||||
/**
|
||||
* Sets Executable platform (Zone/World/UCS) etc.
|
||||
*/
|
||||
int log_platform;
|
||||
int log_platform = 0;
|
||||
|
||||
/**
|
||||
* File name used in writing logs
|
||||
@@ -240,9 +285,26 @@ public:
|
||||
*/
|
||||
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
||||
|
||||
/**
|
||||
* @param f
|
||||
*/
|
||||
void SetGMSayHandler(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
|
||||
|
||||
/**
|
||||
* @param f
|
||||
*/
|
||||
void SetConsoleHandler(std::function<void(uint16 debug_level, uint16 log_type, const std::string&)> f) { on_log_console_hook = f; }
|
||||
|
||||
/**
|
||||
* Silence console logging
|
||||
*/
|
||||
void SilenceConsoleLogging();
|
||||
|
||||
/**
|
||||
* Turn on all console logging
|
||||
*/
|
||||
void EnableConsoleLogging();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -258,6 +320,7 @@ private:
|
||||
|
||||
/**
|
||||
* Linux console color messages mapped by category
|
||||
*
|
||||
* @param log_category
|
||||
* @return
|
||||
*/
|
||||
@@ -268,11 +331,57 @@ private:
|
||||
*/
|
||||
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||
|
||||
/**
|
||||
* @param log_category
|
||||
* @return
|
||||
*/
|
||||
bool IsRfc5424LogCategory(uint16 log_category);
|
||||
};
|
||||
|
||||
extern EQEmuLogSys LogSys;
|
||||
|
||||
/**
|
||||
template<typename... Args>
|
||||
void OutF(
|
||||
EQEmuLogSys &ls,
|
||||
Logs::DebugLevel debug_level,
|
||||
uint16 log_category,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *fmt,
|
||||
const Args &... args
|
||||
)
|
||||
{
|
||||
std::string log_str = fmt::format(fmt, args...);
|
||||
ls.Out(debug_level, log_category, file, func, line, log_str.c_str());
|
||||
}
|
||||
**/
|
||||
|
||||
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
|
||||
do { \
|
||||
ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,920 @@
|
||||
/**
|
||||
* 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_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
|
||||
#ifdef BUILD_LOGGING
|
||||
|
||||
/**
|
||||
* RFC 5424
|
||||
*/
|
||||
|
||||
#define LogEmergency(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Emergency].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Emergency, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAlert(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Alert].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Alert, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCritical(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Critical].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Critical, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogError(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Error].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogWarning(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Warning].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNotice(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Notice].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Notice, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInfo(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Info].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDebug(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Debug].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Category
|
||||
*/
|
||||
|
||||
#define LogAA(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AA].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAADetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AA].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAI(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AI].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AI].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAggro(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Aggro].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAggroDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Aggro].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAttack(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Attack].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAttackDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Attack].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketClientServer(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketClientServerDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCombat(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Combat].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Combat].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCommands(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Commands].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCommandsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Commands].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCrash(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Crash].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCrashDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Crash].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDoors(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Doors].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDoorsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Doors].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogGuilds(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Guilds].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogGuildsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Guilds].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInventory(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Inventory].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInventoryDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Inventory].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLauncher(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Launcher].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLauncherDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Launcher].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNetcode(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Netcode].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNetcodeDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Netcode].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNormal(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Normal].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNormalDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Normal].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogObject(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Object].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogObjectDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Object].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPathing(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Pathing].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPathingDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Pathing].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQSServer(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::QSServer].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQSServerDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::QSServer].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuests(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Quests].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Quests].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogRules(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Rules].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogRulesDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Rules].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSkills(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Skills].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSkillsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Skills].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpawns(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Spawns].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpawnsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Spawns].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpells(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Spells].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpellsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Spells].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTCPConnection(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::TCPConnection].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTCPConnectionDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::TCPConnection].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTasks(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Tasks].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTasksDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Tasks].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTradeskills(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Tradeskills].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTradeskillsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Tradeskills].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTrading(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Trading].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTradingDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Trading].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTribute(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Tribute].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTributeDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Tribute].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLError(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLErrorDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLQuery(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLQueryDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMercenaries(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Mercenaries].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMercenariesDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Mercenaries].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestDebug(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::QuestDebug].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestDebugDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::QuestDebug].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLoginserver(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Loginserver].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLoginserverDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Loginserver].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogClientLogin(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::ClientLogin].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogClientLoginDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::ClientLogin].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHeadlessClient(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::HeadlessClient].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHeadlessClientDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::HeadlessClient].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHPUpdate(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::HPUpdate].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHPUpdateDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::HPUpdate].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFixZ(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::FixZ].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFixZDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::FixZ].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFood(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Food].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFoodDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Food].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTraps(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Traps].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTrapsDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Traps].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCRoamBox(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::NPCRoamBox].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCRoamBoxDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::NPCRoamBox].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCScaling(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::NPCScaling].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCScalingDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::NPCScaling].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMobAppearance(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::MobAppearance].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMobAppearanceDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::MobAppearance].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogStatus(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogStatusDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIScanClose(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AIScanClose].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIScanCloseDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AIScanClose].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIYellForHelp(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AIYellForHelp].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIYellForHelpDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AIYellForHelp].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAICastBeneficialClose(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AICastBeneficialClose].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAICastBeneficialCloseDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AICastBeneficialClose].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAoeCast(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAoeCastDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEntityManagement(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEntityManagementDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFlee(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Flee].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFleeDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Flee].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAura(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Aura].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Aura, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAuraDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Aura].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Aura, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHotReload(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::HotReload].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::HotReload, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHotReloadDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::HotReload].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::HotReload, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogF(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define LogEmergency(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAlert(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCritical(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogError(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogWarning(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNotice(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogInfo(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogDebug(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Category
|
||||
*/
|
||||
|
||||
#define LogAA(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAADetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAI(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAIDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAggro(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAggroDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAttack(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAttackDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketClientServer(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketClientServerDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCombat(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCommands(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCommandsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCrash(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogCrashDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogDoors(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogDoorsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogGuilds(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogGuildsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogInventory(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogInventoryDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogLauncher(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogLauncherDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNetcode(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNetcodeDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNormal(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNormalDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogObject(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogObjectDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogPathing(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogPathingDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogQSServer(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogQSServerDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogQuests(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogRules(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogRulesDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogSkills(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogSkillsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogSpawns(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogSpawnsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogSpells(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogSpellsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTCPConnection(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTCPConnectionDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTasks(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTasksDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTradeskills(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTradeskillsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTrading(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTradingDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTribute(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTributeDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLError(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLErrorDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLQuery(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLQueryDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMercenaries(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMercenariesDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestDebug(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestDebugDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogLoginserver(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogLoginserverDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogClientLogin(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogClientLoginDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogHeadlessClient(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogHeadlessClientDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogHPUpdate(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogHPUpdateDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogFixZ(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogFixZDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogFood(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogFoodDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTraps(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogTrapsDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCRoamBox(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCRoamBoxDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCScaling(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCScalingDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMobAppearance(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogMobAppearanceDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogStatus(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogStatusDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAIScanClose(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAIScanCloseDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAIYellForHelp(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAIYellForHelpDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAICastBeneficialClose(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAICastBeneficialCloseDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAoeCast(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAoeCastDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogEntityManagement(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogEntityManagementDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogFlee(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogFleeDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAura(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogAuraDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogHotReload(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogHotReloadDetail(message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
} while (0)
|
||||
|
||||
#define LogF(debug_level, log_category, message, ...) do {\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
@@ -21,6 +21,14 @@ namespace EQ
|
||||
uv_run(&m_loop, UV_RUN_NOWAIT);
|
||||
}
|
||||
|
||||
void Run() {
|
||||
uv_run(&m_loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
uv_stop(&m_loop);
|
||||
}
|
||||
|
||||
uv_loop_t* Handle() { return &m_loop; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <future>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Event
|
||||
{
|
||||
class TaskScheduler
|
||||
{
|
||||
public:
|
||||
static const int DefaultThreadCount = 4;
|
||||
|
||||
TaskScheduler() : _running(false)
|
||||
{
|
||||
Start(DefaultThreadCount);
|
||||
}
|
||||
|
||||
TaskScheduler(size_t threads) : _running(false)
|
||||
{
|
||||
Start(threads);
|
||||
}
|
||||
|
||||
~TaskScheduler() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
void Start(size_t threads) {
|
||||
if (true == _running) {
|
||||
return;
|
||||
}
|
||||
|
||||
_running = true;
|
||||
|
||||
for (size_t i = 0; i < threads; ++i) {
|
||||
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
||||
}
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
if (false == _running) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
_running = false;
|
||||
}
|
||||
|
||||
_cv.notify_all();
|
||||
|
||||
for (auto &t : _threads) {
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Fn, typename... Args>
|
||||
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::result_of<Fn(Args...)>::type> {
|
||||
using return_type = typename std::result_of<Fn(Args...)>::type;
|
||||
|
||||
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
||||
);
|
||||
|
||||
std::future<return_type> res = task->get_future();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
|
||||
if (false == _running) {
|
||||
throw std::runtime_error("Enqueue on stopped scheduler.");
|
||||
}
|
||||
|
||||
_tasks.emplace([task]() { (*task)(); });
|
||||
}
|
||||
|
||||
_cv.notify_one();
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
void ProcessWork() {
|
||||
for (;;) {
|
||||
std::function<void()> work;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
_cv.wait(lock, [this] { return !_running || !_tasks.empty(); });
|
||||
|
||||
if (false == _running) {
|
||||
return;
|
||||
}
|
||||
|
||||
work = std::move(_tasks.front());
|
||||
_tasks.pop();
|
||||
}
|
||||
|
||||
work();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool _running = true;
|
||||
std::vector<std::thread> _threads;
|
||||
std::mutex _lock;
|
||||
std::condition_variable _cv;
|
||||
std::queue<std::function<void()>> _tasks;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2004 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 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
|
||||
@@ -13,10 +13,15 @@
|
||||
|
||||
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
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
|
||||
*/
|
||||
#ifndef OLDCODE_H
|
||||
#define OLDCODE_H
|
||||
|
||||
#endif
|
||||
#pragma once
|
||||
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
namespace eq
|
||||
{
|
||||
using tl::expected;
|
||||
using tl::make_unexpected;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 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 <fstream>
|
||||
#include "file_util.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <direct.h>
|
||||
#include <conio.h>
|
||||
#include <iostream>
|
||||
#include <dos.h>
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
bool FileUtil::exists(const std::string &name)
|
||||
{
|
||||
std::ifstream f(name.c_str());
|
||||
|
||||
return f.good();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void FileUtil::mkdir(const std::string& directory_name)
|
||||
{
|
||||
|
||||
#ifdef _WINDOWS
|
||||
struct _stat st;
|
||||
if (_stat(directory_name.c_str(), &st) == 0) // exists
|
||||
return;
|
||||
_mkdir(directory_name.c_str());
|
||||
#else
|
||||
struct stat st{};
|
||||
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||
return;
|
||||
}
|
||||
::mkdir(directory_name.c_str(), 0755);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 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_FILE_UTIL_H
|
||||
#define EQEMU_FILE_UTIL_H
|
||||
|
||||
|
||||
class FileUtil {
|
||||
public:
|
||||
static bool exists(const std::string &name);
|
||||
static void mkdir(const std::string& directory_name);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_FILE_UTIL_H
|
||||
+47
-47
@@ -46,7 +46,7 @@ bool BaseGuildManager::LoadGuilds() {
|
||||
ClearGuilds();
|
||||
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to load guilds when we have no database object.");
|
||||
LogGuilds("Requested to load guilds when we have no database object");
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -77,13 +77,13 @@ bool BaseGuildManager::LoadGuilds() {
|
||||
uint8 rankn = atoi(row[1]);
|
||||
|
||||
if(rankn > GUILD_MAX_RANK) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Found invalid (too high) rank %d for guild %d, skipping.", rankn, guild_id);
|
||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
res = m_guilds.find(guild_id);
|
||||
if(res == m_guilds.end()) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Found rank %d for non-existent guild %d, skipping.", rankn, guild_id);
|
||||
LogGuilds("Found rank [{}] for non-existent guild [{}], skipping", rankn, guild_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ bool BaseGuildManager::LoadGuilds() {
|
||||
|
||||
bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to refresh guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to refresh guild [{}] when we have no database object", guild_id);
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Guilds, "Unable to find guild %d in the database.", guild_id);
|
||||
LogGuilds("Unable to find guild [{}] in the database", guild_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||
uint8 rankn = atoi(row[1]);
|
||||
|
||||
if(rankn > GUILD_MAX_RANK) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Found invalid (too high) rank %d for guild %d, skipping.", rankn, guild_id);
|
||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||
rank.permissions[GUILD_WARPEACE] = (row[10][0] == '1') ? true: false;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Successfully refreshed guild %d from the database.", guild_id);
|
||||
LogGuilds("Successfully refreshed guild [{}] from the database", guild_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -214,14 +214,14 @@ BaseGuildManager::GuildInfo *BaseGuildManager::_CreateGuild(uint32 guild_id, con
|
||||
|
||||
bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to store guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to store guild [{}] when we have no database object", guild_id);
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||
res = m_guilds.find(guild_id);
|
||||
if(res == m_guilds.end()) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to store non-existent guild %d", guild_id);
|
||||
LogGuilds("Requested to store non-existent guild [{}]", guild_id);
|
||||
return(false);
|
||||
}
|
||||
GuildInfo *info = res->second;
|
||||
@@ -289,14 +289,14 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
||||
safe_delete_array(title_esc);
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Stored guild %d in the database", guild_id);
|
||||
LogGuilds("Stored guild [{}] in the database", guild_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 BaseGuildManager::_GetFreeGuildID() {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested find a free guild ID when we have no database object.");
|
||||
LogGuilds("Requested find a free guild ID when we have no database object");
|
||||
return(GUILD_NONE);
|
||||
}
|
||||
|
||||
@@ -330,12 +330,12 @@ uint32 BaseGuildManager::_GetFreeGuildID() {
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Guilds, "Located free guild ID %d in the database", index);
|
||||
LogGuilds("Located free guild ID [{}] in the database", index);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Unable to find a free guild ID when requested.");
|
||||
LogGuilds("Unable to find a free guild ID when requested");
|
||||
return GUILD_NONE;
|
||||
}
|
||||
|
||||
@@ -505,11 +505,11 @@ uint32 BaseGuildManager::DBCreateGuild(const char* name, uint32 leader) {
|
||||
|
||||
//now store the resulting guild setup into the DB.
|
||||
if(!_StoreGuildDB(new_id)) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Error storing new guild. It may have been partially created which may need manual removal.");
|
||||
LogGuilds("Error storing new guild. It may have been partially created which may need manual removal");
|
||||
return(GUILD_NONE);
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Created guild %d in the database.", new_id);
|
||||
LogGuilds("Created guild [{}] in the database", new_id);
|
||||
|
||||
return(new_id);
|
||||
}
|
||||
@@ -525,7 +525,7 @@ bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
|
||||
}
|
||||
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to delete guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to delete guild [{}] when we have no database object", guild_id);
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -545,14 +545,14 @@ bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
|
||||
query = StringFormat("DELETE FROM guild_bank WHERE guildid=%lu", (unsigned long)guild_id);
|
||||
QueryWithLogging(query, "deleting guild bank");
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Deleted guild %d from the database.", guild_id);
|
||||
LogGuilds("Deleted guild [{}] from the database", guild_id);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to rename guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to rename guild [{}] when we have no database object", guild_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -573,13 +573,13 @@ bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
Log(Logs::Detail, Logs::Guilds, "Error renaming guild %d '%s': %s", guild_id, query.c_str(), results.Success());
|
||||
LogGuilds("Error renaming guild [{}] [{}]: [{}]", guild_id, query.c_str(), results.Success());
|
||||
safe_delete_array(esc);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(esc);
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Renamed guild %s (%d) to %s in database.", info->name.c_str(), guild_id, name);
|
||||
LogGuilds("Renamed guild [{}] ([{}]) to [{}] in database", info->name.c_str(), guild_id, name);
|
||||
|
||||
info->name = name; //update our local record.
|
||||
|
||||
@@ -588,7 +588,7 @@ bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
||||
|
||||
bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to set the leader for guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to set the leader for guild [{}] when we have no database object", guild_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -614,7 +614,7 @@ bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
||||
if(!DBSetGuildRank(leader, GUILD_LEADER))
|
||||
return false;
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Set guild leader for guild %d to %d in the database", guild_id, leader);
|
||||
LogGuilds("Set guild leader for guild [{}] to [{}] in the database", guild_id, leader);
|
||||
|
||||
info->leader_char_id = leader; //update our local record.
|
||||
|
||||
@@ -623,7 +623,7 @@ bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
||||
|
||||
bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to set the MOTD for guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to set the MOTD for guild [{}] when we have no database object", guild_id);
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -654,7 +654,7 @@ bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const c
|
||||
safe_delete_array(esc);
|
||||
safe_delete_array(esc_set);
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Set MOTD for guild %d in the database", guild_id);
|
||||
LogGuilds("Set MOTD for guild [{}] in the database", guild_id);
|
||||
|
||||
info->motd = motd; //update our local record.
|
||||
info->motd_setter = setter; //update our local record.
|
||||
@@ -688,7 +688,7 @@ bool BaseGuildManager::DBSetGuildURL(uint32 GuildID, const char* URL)
|
||||
}
|
||||
safe_delete_array(esc);
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Set URL for guild %d in the database", GuildID);
|
||||
LogGuilds("Set URL for guild [{}] in the database", GuildID);
|
||||
|
||||
info->url = URL; //update our local record.
|
||||
|
||||
@@ -722,7 +722,7 @@ bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
|
||||
}
|
||||
safe_delete_array(esc);
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Set Channel for guild %d in the database", GuildID);
|
||||
LogGuilds("Set Channel for guild [{}] in the database", GuildID);
|
||||
|
||||
info->channel = Channel; //update our local record.
|
||||
|
||||
@@ -731,7 +731,7 @@ bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
|
||||
|
||||
bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested to set char to guild %d when we have no database object.", guild_id);
|
||||
LogGuilds("Requested to set char to guild [{}] when we have no database object", guild_id);
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -753,7 +753,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Log(Logs::Detail, Logs::Guilds, "Set char %d to guild %d and rank %d in the database.", charid, guild_id, rank);
|
||||
LogGuilds("Set char [{}] to guild [{}] and rank [{}] in the database", charid, guild_id, rank);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ bool BaseGuildManager::DBSetPublicNote(uint32 charid, const char* note) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Set public not for char %d", charid);
|
||||
LogGuilds("Set public not for char [{}]", charid);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -912,7 +912,7 @@ bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo
|
||||
return(false);
|
||||
|
||||
//load up the rank info for each guild.
|
||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE g.guild_id=%d", guild_id);
|
||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE g.guild_id=%d AND c.deleted_at IS NULL", guild_id);
|
||||
auto results = m_db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
@@ -924,14 +924,14 @@ bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo
|
||||
members.push_back(ci);
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Retreived entire guild member list for guild %d from the database", guild_id);
|
||||
LogGuilds("Retreived entire guild member list for guild [{}] from the database", guild_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested char info on %s when we have no database object.", char_name);
|
||||
LogGuilds("Requested char info on [{}] when we have no database object", char_name);
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -941,7 +941,7 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
||||
m_db->DoEscapeString(esc, char_name, nl);
|
||||
|
||||
//load up the rank info for each guild.
|
||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.name='%s'", esc);
|
||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.name='%s' AND c.deleted_at IS NULL", esc);
|
||||
safe_delete_array(esc);
|
||||
auto results = m_db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
@@ -953,7 +953,7 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
||||
|
||||
auto row = results.begin();
|
||||
ProcessGuildMember(row, into);
|
||||
Log(Logs::Detail, Logs::Guilds, "Retreived guild member info for char %s from the database", char_name);
|
||||
LogGuilds("Retreived guild member info for char [{}] from the database", char_name);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -962,16 +962,16 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
||||
|
||||
bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
||||
if(m_db == nullptr) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Requested char info on %d when we have no database object.", char_id);
|
||||
LogGuilds("Requested char info on [{}] when we have no database object", char_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
//load up the rank info for each guild.
|
||||
std::string query;
|
||||
#ifdef BOTS
|
||||
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C'", char_id);
|
||||
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C' AND c.deleted_at IS NULL", char_id);
|
||||
#else
|
||||
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d", char_id);
|
||||
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
|
||||
#endif
|
||||
auto results = m_db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
@@ -983,7 +983,7 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
||||
|
||||
auto row = results.begin();
|
||||
ProcessGuildMember(row, into);
|
||||
Log(Logs::Detail, Logs::Guilds, "Retreived guild member info for char %d", char_id);
|
||||
LogGuilds("Retreived guild member info for char [{}]", char_id);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1098,16 +1098,16 @@ bool BaseGuildManager::GuildExists(uint32 guild_id) const {
|
||||
|
||||
bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
|
||||
if(guild_id == GUILD_NONE) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Check leader for char %d: not a guild.", char_id);
|
||||
LogGuilds("Check leader for char [{}]: not a guild", char_id);
|
||||
return(false);
|
||||
}
|
||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||
res = m_guilds.find(guild_id);
|
||||
if(res == m_guilds.end()) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Check leader for char %d: invalid guild.", char_id);
|
||||
LogGuilds("Check leader for char [{}]: invalid guild", char_id);
|
||||
return(false); //invalid guild
|
||||
}
|
||||
Log(Logs::Detail, Logs::Guilds, "Check leader for guild %d, char %d: leader id=%d", guild_id, char_id, res->second->leader_char_id);
|
||||
LogGuilds("Check leader for guild [{}], char [{}]: leader id=[{}]", guild_id, char_id, res->second->leader_char_id);
|
||||
return(char_id == res->second->leader_char_id);
|
||||
}
|
||||
|
||||
@@ -1137,20 +1137,20 @@ uint8 BaseGuildManager::GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 cha
|
||||
|
||||
bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
|
||||
if(status >= 250) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d with user status %d > 250, granted.", guild_id, status);
|
||||
LogGuilds("Check permission on guild [{}] with user status [{}] > 250, granted", guild_id, status);
|
||||
return(true); //250+ as allowed anything
|
||||
}
|
||||
|
||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||
res = m_guilds.find(guild_id);
|
||||
if(res == m_guilds.end()) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d with user status %d, no such guild, denied.", guild_id, status);
|
||||
LogGuilds("Check permission on guild [{}] with user status [{}], no such guild, denied", guild_id, status);
|
||||
return(false); //invalid guild
|
||||
}
|
||||
|
||||
bool granted = (res->second->minstatus <= status);
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %s (%d) with user status %d. Min status %d: %s",
|
||||
LogGuilds("Check permission on guild [{}] ([{}]) with user status [{}]. Min status [{}]: [{}]",
|
||||
res->second->name.c_str(), guild_id, status, res->second->minstatus, granted?"granted":"denied");
|
||||
|
||||
return(granted);
|
||||
@@ -1158,21 +1158,21 @@ bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
|
||||
|
||||
bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const {
|
||||
if(rank > GUILD_MAX_RANK) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d and rank %d for action %s (%d): Invalid rank, denied.",
|
||||
LogGuilds("Check permission on guild [{}] and rank [{}] for action [{}] ([{}]): Invalid rank, denied",
|
||||
guild_id, rank, GuildActionNames[act], act);
|
||||
return(false); //invalid rank
|
||||
}
|
||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||
res = m_guilds.find(guild_id);
|
||||
if(res == m_guilds.end()) {
|
||||
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d and rank %d for action %s (%d): Invalid guild, denied.",
|
||||
LogGuilds("Check permission on guild [{}] and rank [{}] for action [{}] ([{}]): Invalid guild, denied",
|
||||
guild_id, rank, GuildActionNames[act], act);
|
||||
return(false); //invalid guild
|
||||
}
|
||||
|
||||
bool granted = res->second->ranks[rank].permissions[act];
|
||||
|
||||
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %s (%d) and rank %s (%d) for action %s (%d): %s",
|
||||
LogGuilds("Check permission on guild [{}] ([{}]) and rank [{}] ([{}]) for action [{}] ([{}]): [{}]",
|
||||
res->second->name.c_str(), guild_id,
|
||||
res->second->ranks[rank].name.c_str(), rank,
|
||||
GuildActionNames[act], act,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1381,7 +1381,7 @@ int16 EQEmu::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
||||
}
|
||||
|
||||
if (result == INVALID_INDEX) {
|
||||
Log(Logs::General, Logs::Error, "InventoryProfile::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot);
|
||||
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
||||
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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 "ip_util.h"
|
||||
|
||||
/**
|
||||
* @param ip
|
||||
* @return
|
||||
*/
|
||||
uint32_t IpUtil::IPToUInt(const std::string &ip)
|
||||
{
|
||||
int a, b, c, d;
|
||||
uint32_t addr = 0;
|
||||
|
||||
if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr = a << 24;
|
||||
addr |= b << 16;
|
||||
addr |= c << 8;
|
||||
addr |= d;
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ip
|
||||
* @param network
|
||||
* @param mask
|
||||
* @return
|
||||
*/
|
||||
bool IpUtil::IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask)
|
||||
{
|
||||
uint32_t ip_addr = IpUtil::IPToUInt(ip);
|
||||
uint32_t network_addr = IpUtil::IPToUInt(network);
|
||||
uint32_t mask_addr = IpUtil::IPToUInt(mask);
|
||||
|
||||
uint32_t net_lower = (network_addr & mask_addr);
|
||||
uint32_t net_upper = (net_lower | (~mask_addr));
|
||||
|
||||
return ip_addr >= net_lower && ip_addr <= net_upper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ip
|
||||
* @return
|
||||
*/
|
||||
bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
||||
{
|
||||
return (
|
||||
IpUtil::IsIpInRange(ip, "10.0.0.0", "255.0.0.0") ||
|
||||
IpUtil::IsIpInRange(ip, "172.16.0.0", "255.240.0.0") ||
|
||||
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
|
||||
);
|
||||
}
|
||||
@@ -16,15 +16,21 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef EQEMU_IP_UTIL_H
|
||||
#define EQEMU_IP_UTIL_H
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "types.h"
|
||||
#include "iostream"
|
||||
|
||||
template <typename... Args>
|
||||
void OutF(EQEmuLogSys &ls, Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args)
|
||||
{
|
||||
std::string log_str = fmt::format(fmt, args...);
|
||||
ls.Out(debug_level, log_category, log_str);
|
||||
}
|
||||
class IpUtil {
|
||||
public:
|
||||
|
||||
static uint32_t IPToUInt(const std::string &ip);
|
||||
static bool IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask);
|
||||
static bool IsIpInPrivateRfc1918(const std::string &ip);
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_IP_UTIL_H
|
||||
+1
-1
@@ -413,7 +413,7 @@ namespace EQEmu
|
||||
int32 SkillModMax; // Max skill point modification
|
||||
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
||||
uint32 BaneDmgRace; // Bane Damage Race
|
||||
int8 BaneDmgAmt; // Bane Damage Body Amount
|
||||
int32 BaneDmgAmt; // Bane Damage Body Amount
|
||||
uint32 BaneDmgBody; // Bane Damage Body
|
||||
bool Magic; // True=Magic Item, False=not
|
||||
int32 CastTime_;
|
||||
|
||||
@@ -5277,7 +5277,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
|
||||
{
|
||||
//! [StreamWriterBuilderDefaults]
|
||||
(*settings)["commentStyle"] = "All";
|
||||
(*settings)["indentation"] = "\t";
|
||||
(*settings)["indentation"] = " ";
|
||||
(*settings)["enableYAMLCompatibility"] = false;
|
||||
(*settings)["dropNullPlaceholders"] = false;
|
||||
(*settings)["useSpecialFloats"] = false;
|
||||
|
||||
+89
-17
@@ -1,26 +1,29 @@
|
||||
#include "json_config.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
EQ::JsonConfigFile::JsonConfigFile()
|
||||
{
|
||||
}
|
||||
EQ::JsonConfigFile::JsonConfigFile() = default;
|
||||
|
||||
EQ::JsonConfigFile::JsonConfigFile(const Json::Value &value)
|
||||
{
|
||||
m_root = value;
|
||||
}
|
||||
|
||||
EQ::JsonConfigFile::~JsonConfigFile()
|
||||
{
|
||||
}
|
||||
EQ::JsonConfigFile::~JsonConfigFile() = default;
|
||||
|
||||
EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename)
|
||||
/**
|
||||
* @param file_name
|
||||
* @return
|
||||
*/
|
||||
EQ::JsonConfigFile EQ::JsonConfigFile::Load(
|
||||
const std::string &file_name
|
||||
)
|
||||
{
|
||||
JsonConfigFile ret;
|
||||
ret.m_root = Json::Value();
|
||||
|
||||
std::ifstream ifs;
|
||||
ifs.open(filename, std::ifstream::in);
|
||||
ifs.open(file_name, std::ifstream::in);
|
||||
|
||||
if (!ifs.good()) {
|
||||
return ret;
|
||||
@@ -29,59 +32,128 @@ EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename)
|
||||
try {
|
||||
ifs >> ret.m_root;
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string EQ::JsonConfigFile::GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value) {
|
||||
/**
|
||||
* @param file_name
|
||||
* @return
|
||||
*/
|
||||
void EQ::JsonConfigFile::Save(
|
||||
const std::string &file_name
|
||||
)
|
||||
{
|
||||
std::ofstream opened_config_file;
|
||||
opened_config_file.open(file_name);
|
||||
|
||||
/**
|
||||
* Grab and build config contents
|
||||
*/
|
||||
Json::StreamWriterBuilder write_builder;
|
||||
write_builder["indentation"] = " ";
|
||||
std::string document = Json::writeString(write_builder, m_root);
|
||||
|
||||
/**
|
||||
* Write current contents and close
|
||||
*/
|
||||
opened_config_file << document;
|
||||
opened_config_file.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param title
|
||||
* @param parameter
|
||||
* @param default_value
|
||||
* @return
|
||||
*/
|
||||
std::string EQ::JsonConfigFile::GetVariableString(
|
||||
const std::string &title,
|
||||
const std::string ¶meter,
|
||||
const std::string &default_value
|
||||
)
|
||||
{
|
||||
try {
|
||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||
return m_root[title][parameter].asString();
|
||||
}
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
return default_value;
|
||||
}
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
int EQ::JsonConfigFile::GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value) {
|
||||
/**
|
||||
* @param title
|
||||
* @param parameter
|
||||
* @param default_value
|
||||
* @return
|
||||
*/
|
||||
int EQ::JsonConfigFile::GetVariableInt(
|
||||
const std::string &title,
|
||||
const std::string ¶meter,
|
||||
const int default_value
|
||||
)
|
||||
{
|
||||
try {
|
||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||
return m_root[title][parameter].asInt();
|
||||
}
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
return default_value;
|
||||
}
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
bool EQ::JsonConfigFile::GetVariableBool(const std::string &title, const std::string ¶meter, const bool default_value) {
|
||||
/**
|
||||
* @param title
|
||||
* @param parameter
|
||||
* @param default_value
|
||||
* @return
|
||||
*/
|
||||
bool EQ::JsonConfigFile::GetVariableBool(
|
||||
const std::string &title,
|
||||
const std::string ¶meter,
|
||||
const bool default_value
|
||||
)
|
||||
{
|
||||
try {
|
||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||
return m_root[title][parameter].asBool();
|
||||
}
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
return default_value;
|
||||
}
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
double EQ::JsonConfigFile::GetVariableDouble(const std::string &title, const std::string ¶meter, const double default_value) {
|
||||
/**
|
||||
* @param title
|
||||
* @param parameter
|
||||
* @param default_value
|
||||
* @return
|
||||
*/
|
||||
double EQ::JsonConfigFile::GetVariableDouble(
|
||||
const std::string &title,
|
||||
const std::string ¶meter,
|
||||
const double default_value
|
||||
)
|
||||
{
|
||||
try {
|
||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||
return m_root[title][parameter].asDouble();
|
||||
}
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
return default_value;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,12 @@ namespace EQ
|
||||
class JsonConfigFile
|
||||
{
|
||||
public:
|
||||
JsonConfigFile();
|
||||
JsonConfigFile(const Json::Value &value);
|
||||
~JsonConfigFile();
|
||||
|
||||
static JsonConfigFile Load(const std::string &filename);
|
||||
static JsonConfigFile Load(const std::string &file_name);
|
||||
void Save(const std::string &file_name);
|
||||
|
||||
std::string GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value);
|
||||
int GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value);
|
||||
@@ -19,7 +21,6 @@ namespace EQ
|
||||
|
||||
Json::Value& RawHandle() { return m_root; }
|
||||
private:
|
||||
JsonConfigFile();
|
||||
Json::Value m_root;
|
||||
};
|
||||
|
||||
|
||||
@@ -278,12 +278,6 @@ void LinkedListIterator<TYPE>::Replace(const TYPE& new_data)
|
||||
template<class TYPE>
|
||||
void LinkedListIterator<TYPE>::Reset()
|
||||
{
|
||||
if (!(&list))
|
||||
{
|
||||
current_element=0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dir == FORWARD)
|
||||
{
|
||||
current_element = list.first;
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
#include "types.h"
|
||||
#include <cstring>
|
||||
|
||||
#define ENC(c) (((c) & 0x3f) + ' ')
|
||||
#define DEC(c) (((c) - ' ') & 0x3f)
|
||||
|
||||
std::map<int,std::string> DBFieldNames;
|
||||
|
||||
#ifndef WIN32
|
||||
@@ -333,64 +330,6 @@ void LoadItemDBFieldNames() {
|
||||
DBFieldNames[113]="unknown115"; // ? (end quote)
|
||||
}
|
||||
|
||||
void encode_length(unsigned long length, char *out)
|
||||
{
|
||||
char buf[4];
|
||||
memcpy(buf,&length,sizeof(unsigned long));
|
||||
encode_chunk(buf,3,out);
|
||||
}
|
||||
|
||||
unsigned long encode(char *in, unsigned long length, char *out)
|
||||
{
|
||||
unsigned long used=0,len=0;
|
||||
while(used<length) {
|
||||
encode_chunk(in+used,length-used,out+len);
|
||||
used+=3;
|
||||
len+=4;
|
||||
}
|
||||
*(out+len)=0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned long decode_length(char *in)
|
||||
{
|
||||
int length;
|
||||
char buf[4];
|
||||
decode_chunk(in,&buf[0]);
|
||||
buf[3]=0;
|
||||
memcpy(&length,buf,sizeof(unsigned long));
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void decode(char *in, char *out)
|
||||
{
|
||||
char *ptr=in;
|
||||
char *outptr=out;
|
||||
while(*ptr) {
|
||||
decode_chunk(ptr,outptr);
|
||||
ptr+=4;
|
||||
outptr+=3;
|
||||
}
|
||||
*outptr=0;
|
||||
}
|
||||
|
||||
void encode_chunk(char *in, int len, char *out)
|
||||
{
|
||||
*out=ENC(in[0] >> 2);
|
||||
*(out+1)=ENC((in[0] << 4)|(((len<2 ? 0 : in[1]) >> 4) & 0xF));
|
||||
*(out+2)=ENC(((len<2 ? 0 : in[1]) << 2)|(((len<3 ? 0 : in[2]) >> 6) & 0x3));
|
||||
*(out+3)=ENC((len<3 ? 0 : in[2]));
|
||||
}
|
||||
|
||||
void decode_chunk(char *in, char *out)
|
||||
{
|
||||
*out = DEC(*in) << 2 | DEC(in[1]) >> 4;
|
||||
*(out+1) = DEC(in[1]) << 4 | DEC(in[2]) >> 2;
|
||||
*(out+2) = DEC(in[2]) << 6 | DEC(in[3]);
|
||||
}
|
||||
|
||||
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
||||
{
|
||||
unsigned long i,j;
|
||||
|
||||
@@ -17,13 +17,6 @@ int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
||||
|
||||
void LoadItemDBFieldNames();
|
||||
|
||||
void encode_length(unsigned long length, char *out);
|
||||
unsigned long decode_length(char *in);
|
||||
unsigned long encode(char *in, unsigned long length, char *out);
|
||||
void decode(char *in, char *out);
|
||||
void encode_chunk(char *in, int len, char *out);
|
||||
void decode_chunk(char *in, char *out);
|
||||
|
||||
#ifndef WIN32
|
||||
int print_stacktrace();
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define VERIFY_PACKET_LENGTH(OPCode, Packet, StructName) \
|
||||
if(Packet->size != sizeof(StructName)) \
|
||||
{ \
|
||||
Log(Logs::Detail, Logs::Netcode, "Size mismatch in " #OPCode " expected %i got %i", sizeof(StructName), Packet->size); \
|
||||
LogNetcode("Size mismatch in " #OPCode " expected [{}] got [{}]", sizeof(StructName), Packet->size); \
|
||||
DumpPacket(Packet); \
|
||||
return; \
|
||||
}
|
||||
|
||||
@@ -116,17 +116,21 @@ bool EQ::Net::ConsoleServerConnection::SendChannelMessage(const ServerChannelMes
|
||||
}
|
||||
|
||||
switch (scm->chan_num) {
|
||||
if (RuleB(Chat, ServerWideAuction)) {
|
||||
case 4: {
|
||||
case 4: {
|
||||
if (RuleB(Chat, ServerWideAuction)) {
|
||||
QueueMessage(fmt::format("{0} auctions, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
} else { // I think we want default action in this case?
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (RuleB(Chat, ServerWideOOC)) {
|
||||
case 5: {
|
||||
case 5: {
|
||||
if (RuleB(Chat, ServerWideOOC)) {
|
||||
QueueMessage(fmt::format("{0} says ooc, '{1}'", scm->from, scm->message));
|
||||
break;
|
||||
} else { // I think we want default action in this case?
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -399,7 +399,7 @@ void EQ::Net::DaybreakConnection::Process()
|
||||
|
||||
ProcessQueue();
|
||||
}
|
||||
catch (std::exception ex) {
|
||||
catch (std::exception &ex) {
|
||||
if (m_owner->m_on_error_message) {
|
||||
m_owner->m_on_error_message(fmt::format("Error processing connection: {0}", ex.what()));
|
||||
}
|
||||
@@ -1047,12 +1047,14 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
|
||||
uint8_t new_buffer[2048] = { 0 };
|
||||
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
||||
uint32_t new_length = 0;
|
||||
bool send_uncompressed = true;
|
||||
|
||||
if (length > 30) {
|
||||
new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048) + 1;
|
||||
new_buffer[0] = 0x5a;
|
||||
send_uncompressed = (new_length > length);
|
||||
}
|
||||
else {
|
||||
if (send_uncompressed) {
|
||||
memcpy(new_buffer + 1, buffer, length);
|
||||
new_buffer[0] = 0xa5;
|
||||
new_length = length + 1;
|
||||
@@ -1380,7 +1382,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
|
||||
auto stream = &m_streams[stream_id];
|
||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size();
|
||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
|
||||
size_t length = p.Length();
|
||||
if (length > max_raw_size) {
|
||||
DaybreakReliableFragmentHeader first_header;
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace EQ
|
||||
resend_delay_min = 150;
|
||||
resend_delay_max = 5000;
|
||||
connect_delay_ms = 500;
|
||||
stale_connection_ms = 30000;
|
||||
stale_connection_ms = 60000;
|
||||
connect_stale_ms = 5000;
|
||||
crc_length = 2;
|
||||
max_packet_size = 512;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "eqstream.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../eqemu_logsys_fmt.h"
|
||||
|
||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
|
||||
{
|
||||
@@ -185,23 +184,23 @@ EQStreamInterface::MatchState EQ::Net::EQStream::CheckSignature(const Signature
|
||||
|
||||
if (opcode == sig->first_eq_opcode) {
|
||||
if (length == sig->first_length) {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length matched {3}",
|
||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode matched {2:#x} and length matched {3}",
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length);
|
||||
return MatchSuccessful;
|
||||
}
|
||||
else if (length == 0) {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length is ignored.",
|
||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode matched {2:#x} and length is ignored.",
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode);
|
||||
return MatchSuccessful;
|
||||
}
|
||||
else {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} but length {3} did not match expected {4}",
|
||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode matched {2:#x} but length {3} did not match expected {4}",
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length, sig->first_length);
|
||||
return MatchFailed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode {1:#x} did not match expected {2:#x}",
|
||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode {1:#x} did not match expected {2:#x}",
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), opcode, sig->first_eq_opcode);
|
||||
return MatchFailed;
|
||||
}
|
||||
|
||||
+4
-4
@@ -89,9 +89,9 @@ namespace EQ {
|
||||
public:
|
||||
StaticPacket(void *data, size_t size) { m_data = data; m_data_length = size; m_max_data_length = size; }
|
||||
virtual ~StaticPacket() { }
|
||||
StaticPacket(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; }
|
||||
StaticPacket(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; m_max_data_length = o.m_max_data_length; }
|
||||
StaticPacket& operator=(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
|
||||
StaticPacket(StaticPacket &&o) { m_data = o.m_data; m_data_length = o.m_data_length; }
|
||||
StaticPacket(StaticPacket &&o) noexcept { m_data = o.m_data; m_data_length = o.m_data_length; }
|
||||
|
||||
virtual const void *Data() const { return m_data; }
|
||||
virtual void *Data() { return m_data; }
|
||||
@@ -112,7 +112,7 @@ namespace EQ {
|
||||
public:
|
||||
DynamicPacket() { }
|
||||
virtual ~DynamicPacket() { }
|
||||
DynamicPacket(DynamicPacket &&o) { m_data = std::move(o.m_data); }
|
||||
DynamicPacket(DynamicPacket &&o) noexcept { m_data = std::move(o.m_data); }
|
||||
DynamicPacket(const DynamicPacket &o) { m_data = o.m_data; }
|
||||
DynamicPacket& operator=(const DynamicPacket &o) { m_data = o.m_data; return *this; }
|
||||
|
||||
@@ -127,4 +127,4 @@ namespace EQ {
|
||||
std::vector<char> m_data;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "servertalk_client_connection.h"
|
||||
#include "dns.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../eqemu_logsys_fmt.h"
|
||||
|
||||
EQ::Net::ServertalkClient::ServertalkClient(const std::string &addr, int port, bool ipv6, const std::string &identifier, const std::string &credentials)
|
||||
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkClient::Connect, this))))
|
||||
@@ -79,15 +78,15 @@ void EQ::Net::ServertalkClient::Connect()
|
||||
m_connecting = true;
|
||||
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
||||
if (connection == nullptr) {
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
LogF(Logs::General, Logs::TCPConnection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
m_connecting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Connected to {0}:{1}", m_addr, m_port);
|
||||
LogF(Logs::General, Logs::TCPConnection, "Connected to {0}:{1}", m_addr, m_port);
|
||||
m_connection = connection;
|
||||
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
LogF(Logs::General, Logs::TCPConnection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
m_encrypted = false;
|
||||
m_connection.reset();
|
||||
});
|
||||
@@ -214,7 +213,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p)
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogF(Logs::General, Logs::Error, "Could not process hello, size != {0}", 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
||||
LogError("Could not process hello, size != {0}", 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -226,7 +225,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p)
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing hello from server: {0}", ex.what());
|
||||
LogError("Error parsing hello from server: {0}", ex.what());
|
||||
m_connection->Disconnect();
|
||||
|
||||
if (m_on_connect_cb) {
|
||||
@@ -253,7 +252,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p)
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing hello from server: {0}", ex.what());
|
||||
LogError("Error parsing hello from server: {0}", ex.what());
|
||||
m_connection->Disconnect();
|
||||
|
||||
if (m_on_connect_cb) {
|
||||
@@ -276,7 +275,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
|
||||
std::unique_ptr<unsigned char[]> decrypted_text(new unsigned char[message_len]);
|
||||
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key))
|
||||
{
|
||||
LogF(Logs::General, Logs::Error, "Error decrypting message from server");
|
||||
LogError("Error decrypting message from server");
|
||||
(*(uint64_t*)&m_nonce_theirs[0])++;
|
||||
return;
|
||||
}
|
||||
@@ -324,7 +323,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing message from server: {0}", ex.what());
|
||||
LogError("Error parsing message from server: {0}", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "servertalk_legacy_client_connection.h"
|
||||
#include "dns.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../eqemu_logsys_fmt.h"
|
||||
|
||||
EQ::Net::ServertalkLegacyClient::ServertalkLegacyClient(const std::string &addr, int port, bool ipv6)
|
||||
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkLegacyClient::Connect, this))))
|
||||
@@ -59,15 +58,15 @@ void EQ::Net::ServertalkLegacyClient::Connect()
|
||||
m_connecting = true;
|
||||
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
||||
if (connection == nullptr) {
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
LogF(Logs::General, Logs::TCPConnection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
m_connecting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Connected to {0}:{1}", m_addr, m_port);
|
||||
LogF(Logs::General, Logs::TCPConnection, "Connected to {0}:{1}", m_addr, m_port);
|
||||
m_connection = connection;
|
||||
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
LogF(Logs::General, Logs::TCPConnection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||
m_connection.reset();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "servertalk_server_connection.h"
|
||||
#include "servertalk_server.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../eqemu_logsys_fmt.h"
|
||||
#include "../util/uuid.h"
|
||||
|
||||
EQ::Net::ServertalkServerConnection::ServertalkServerConnection(std::shared_ptr<EQ::Net::TCPConnection> c, EQ::Net::ServertalkServer *parent, bool encrypted, bool allow_downgrade)
|
||||
@@ -202,8 +201,8 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
{
|
||||
#ifdef ENABLE_SECURITY
|
||||
if (downgrade_security && m_allow_downgrade && m_encrypted) {
|
||||
LogF(Logs::General, Logs::TCP_Connection, "Downgraded encrypted connection to plaintext because otherside didn't support encryption {0}:{1}",
|
||||
m_connection->RemoteIP(), m_connection->RemotePort());
|
||||
LogF(Logs::General, Logs::TCPConnection, "Downgraded encrypted connection to plaintext because otherside didn't support encryption {0}:{1}",
|
||||
m_connection->RemoteIP(), m_connection->RemotePort());
|
||||
m_encrypted = false;
|
||||
}
|
||||
|
||||
@@ -221,7 +220,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
|
||||
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)p.Data() + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, cipher_len, m_nonce_theirs, m_shared_key))
|
||||
{
|
||||
LogF(Logs::General, Logs::Error, "Error decrypting handshake from client, dropping connection.");
|
||||
LogError("Error decrypting handshake from client, dropping connection.");
|
||||
m_connection->Disconnect();
|
||||
return;
|
||||
}
|
||||
@@ -230,7 +229,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
std::string credentials = (const char*)&decrypted_text[0] + (m_identifier.length() + 1);
|
||||
|
||||
if (!m_parent->CheckCredentials(credentials)) {
|
||||
LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||
LogError("Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||
m_connection->Disconnect();
|
||||
return;
|
||||
}
|
||||
@@ -240,7 +239,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what());
|
||||
LogError("Error parsing handshake from client: {0}", ex.what());
|
||||
m_connection->Disconnect();
|
||||
}
|
||||
}
|
||||
@@ -250,7 +249,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
auto credentials = p.GetCString(m_identifier.length() + 1);
|
||||
|
||||
if (!m_parent->CheckCredentials(credentials)) {
|
||||
LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||
LogError("Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||
m_connection->Disconnect();
|
||||
return;
|
||||
}
|
||||
@@ -258,7 +257,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
m_parent->ConnectionIdentified(this);
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what());
|
||||
LogError("Error parsing handshake from client: {0}", ex.what());
|
||||
m_connection->Disconnect();
|
||||
}
|
||||
}
|
||||
@@ -268,7 +267,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
auto credentials = p.GetCString(m_identifier.length() + 1);
|
||||
|
||||
if (!m_parent->CheckCredentials(credentials)) {
|
||||
LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||
LogError("Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||
m_connection->Disconnect();
|
||||
return;
|
||||
}
|
||||
@@ -276,7 +275,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
||||
m_parent->ConnectionIdentified(this);
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what());
|
||||
LogError("Error parsing handshake from client: {0}", ex.what());
|
||||
m_connection->Disconnect();
|
||||
}
|
||||
#endif
|
||||
@@ -296,7 +295,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
||||
|
||||
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key))
|
||||
{
|
||||
LogF(Logs::General, Logs::Error, "Error decrypting message from client");
|
||||
LogError("Error decrypting message from client");
|
||||
(*(uint64_t*)&m_nonce_theirs[0])++;
|
||||
return;
|
||||
}
|
||||
@@ -344,6 +343,6 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
LogF(Logs::General, Logs::Error, "Error parsing message from client: {0}", ex.what());
|
||||
LogError("Error parsing message from client: {0}", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,10 @@ int EQ::Net::TCPConnection::LocalPort() const
|
||||
|
||||
std::string EQ::Net::TCPConnection::RemoteIP() const
|
||||
{
|
||||
if (!m_socket) {
|
||||
return "";
|
||||
}
|
||||
|
||||
sockaddr_storage addr;
|
||||
int addr_len = sizeof(addr);
|
||||
uv_tcp_getpeername(m_socket, (sockaddr*)&addr, &addr_len);
|
||||
@@ -220,6 +224,10 @@ std::string EQ::Net::TCPConnection::RemoteIP() const
|
||||
|
||||
int EQ::Net::TCPConnection::RemotePort() const
|
||||
{
|
||||
if (!m_socket) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sockaddr_storage addr;
|
||||
int addr_len = sizeof(addr);
|
||||
uv_tcp_getpeername(m_socket, (sockaddr*)&addr, &addr_len);
|
||||
@@ -236,3 +244,11 @@ int EQ::Net::TCPConnection::RemotePort() const
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
bool EQ::Net::TCPConnection::IsConnected() const
|
||||
{
|
||||
return m_socket != nullptr;
|
||||
}
|
||||
|
||||
@@ -24,10 +24,12 @@ namespace EQ
|
||||
void Read(const char *data, size_t count);
|
||||
void Write(const char *data, size_t count);
|
||||
|
||||
bool IsConnected() const;
|
||||
std::string LocalIP() const;
|
||||
int LocalPort() const;
|
||||
std::string RemoteIP() const;
|
||||
int RemotePort() const;
|
||||
|
||||
private:
|
||||
TCPConnection();
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ EQ::Net::WebsocketServer::WebsocketServer(const std::string &addr, int port)
|
||||
auto &connection = iter->second;
|
||||
connection->GetWebsocketConnection()->ping("keepalive");
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
iter->second->GetTCPConnection()->Disconnect();
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ void EQ::Net::WebsocketServer::DispatchEvent(WebsocketSubscriptionEvent evt, Jso
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ Json::Value EQ::Net::WebsocketServer::Login(WebsocketServerConnection *connectio
|
||||
|
||||
return ret;
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
throw WebsocketException("Unable to process login request");
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ Json::Value EQ::Net::WebsocketServer::Subscribe(WebsocketServerConnection *conne
|
||||
catch (WebsocketException &ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
throw WebsocketException("Unable to process unsubscribe request");
|
||||
}
|
||||
}
|
||||
@@ -234,7 +234,7 @@ Json::Value EQ::Net::WebsocketServer::Unsubscribe(WebsocketServerConnection *con
|
||||
catch (WebsocketException &ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (std::exception) {
|
||||
catch (std::exception &) {
|
||||
throw WebsocketException("Unable to process unsubscribe request");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ OpcodeManager::OpcodeManager() {
|
||||
bool OpcodeManager::LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors) {
|
||||
FILE *opf = fopen(filename, "r");
|
||||
if(opf == nullptr) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open opcodes file '%s'", filename);
|
||||
LogError("Unable to open opcodes file [{}]", filename);
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
+15
-13
@@ -85,7 +85,7 @@ namespace RoF
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ namespace RoF
|
||||
signature.first_length = sizeof(structs::ClientZoneEntry_Struct);
|
||||
signature.first_eq_opcode = opcodes->EmuToEQ(OP_ZoneEntry);
|
||||
into.RegisterPatch(signature, pname.c_str(), &opcodes, &struct_strategy);
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
||||
}
|
||||
|
||||
void Reload()
|
||||
@@ -125,10 +125,10 @@ namespace RoF
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ namespace RoF
|
||||
|
||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -589,7 +589,7 @@ namespace RoF
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Netcode, "RoF::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
LogNetcode("RoF::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
@@ -624,6 +624,7 @@ namespace RoF
|
||||
SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct);
|
||||
|
||||
OUT(spawn_id);
|
||||
OUT(vehicle_id);
|
||||
OUT(x_pos);
|
||||
OUT(delta_x);
|
||||
OUT(delta_y);
|
||||
@@ -1521,7 +1522,7 @@ namespace RoF
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log(Logs::General, Logs::Netcode, "RoF::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
LogNetcode("RoF::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2602,7 +2603,7 @@ namespace RoF
|
||||
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Player Profile Packet is %i bytes", outapp->GetWritePosition());
|
||||
LogNetcode("[STRUCTS] Player Profile Packet is [{}] bytes", outapp->GetWritePosition());
|
||||
|
||||
auto NewBuffer = new unsigned char[outapp->GetWritePosition()];
|
||||
memcpy(NewBuffer, outapp->pBuffer, outapp->GetWritePosition());
|
||||
@@ -3453,7 +3454,7 @@ namespace RoF
|
||||
|
||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -3804,7 +3805,7 @@ namespace RoF
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -4052,7 +4053,7 @@ namespace RoF
|
||||
Buffer += 29;
|
||||
if (Buffer != (BufferStart + PacketSize))
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now %i from end", Buffer - (BufferStart + PacketSize));
|
||||
LogNetcode("[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now [{}] from end", Buffer - (BufferStart + PacketSize));
|
||||
}
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending zone spawn for %s packet is %i bytes", emu->name, outapp->size);
|
||||
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
||||
@@ -4314,6 +4315,7 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct);
|
||||
|
||||
IN(spawn_id);
|
||||
IN(vehicle_id);
|
||||
IN(sequence);
|
||||
IN(x_pos);
|
||||
IN(y_pos);
|
||||
@@ -4621,7 +4623,7 @@ namespace RoF
|
||||
return;
|
||||
}
|
||||
default:
|
||||
Log(Logs::Detail, Logs::Netcode, "Unhandled OP_GuildBank action");
|
||||
LogNetcode("Unhandled OP_GuildBank action");
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
||||
return;
|
||||
}
|
||||
@@ -5678,7 +5680,7 @@ namespace RoF
|
||||
RoFSlot = server_corpse_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to RoF Corpse Main Slot %i", server_corpse_slot, RoFSlot);
|
||||
LogNetcode("Convert Server Corpse Slot [{}] to RoF Corpse Main Slot [{}]", server_corpse_slot, RoFSlot);
|
||||
|
||||
return RoFSlot;
|
||||
}
|
||||
|
||||
+27
-66
@@ -37,6 +37,7 @@
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
|
||||
|
||||
namespace RoF2
|
||||
@@ -85,7 +86,7 @@ namespace RoF2
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -111,7 +112,7 @@ namespace RoF2
|
||||
|
||||
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
||||
}
|
||||
|
||||
void Reload()
|
||||
@@ -128,10 +129,10 @@ namespace RoF2
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ namespace RoF2
|
||||
|
||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -657,7 +658,7 @@ namespace RoF2
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Netcode, "RoF2::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
LogNetcode("RoF2::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
@@ -686,25 +687,6 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ClientUpdate)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(PlayerPositionUpdateServer_Struct);
|
||||
SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct);
|
||||
|
||||
OUT(spawn_id);
|
||||
OUT(x_pos);
|
||||
OUT(delta_x);
|
||||
OUT(delta_y);
|
||||
OUT(z_pos);
|
||||
OUT(delta_heading);
|
||||
OUT(y_pos);
|
||||
OUT(delta_z);
|
||||
OUT(animation);
|
||||
OUT(heading);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_Consider)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Consider_Struct);
|
||||
@@ -1589,7 +1571,7 @@ namespace RoF2
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log(Logs::General, Logs::Netcode, "RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
LogNetcode("RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2688,7 +2670,7 @@ namespace RoF2
|
||||
// Think we need 1 byte of padding at the end
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Player Profile Packet is %i bytes", outapp->GetWritePosition());
|
||||
LogNetcode("[STRUCTS] Player Profile Packet is [{}] bytes", outapp->GetWritePosition());
|
||||
|
||||
auto NewBuffer = new unsigned char[outapp->GetWritePosition()];
|
||||
memcpy(NewBuffer, outapp->pBuffer, outapp->GetWritePosition());
|
||||
@@ -3520,7 +3502,7 @@ namespace RoF2
|
||||
|
||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -3567,7 +3549,7 @@ namespace RoF2
|
||||
{
|
||||
eq->items[i].Unknown18 = 0;
|
||||
if (i < 80) {
|
||||
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016d", emu->SerialNumber[i]);
|
||||
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016" PRId64, emu->SerialNumber[i]);
|
||||
eq->ItemCost[i] = emu->ItemCost[i];
|
||||
}
|
||||
else {
|
||||
@@ -3630,7 +3612,7 @@ namespace RoF2
|
||||
|
||||
OUT(TraderID);
|
||||
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
||||
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderDelItem): TraderID %d, SerialNumber: %d", emu->TraderID, emu->ItemID);
|
||||
LogTrading("ENCODE(OP_TraderDelItem): TraderID [{}], SerialNumber: [{}]", emu->TraderID, emu->ItemID);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -3661,7 +3643,7 @@ namespace RoF2
|
||||
eq->Traders2 = emu->Traders;
|
||||
eq->Items2 = emu->Items;
|
||||
|
||||
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): BazaarWelcome_Struct Code %d, Traders %d, Items %d",
|
||||
LogTrading("ENCODE(OP_TraderShop): BazaarWelcome_Struct Code [{}], Traders [{}], Items [{}]",
|
||||
eq->Code, eq->Traders, eq->Items);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -3684,14 +3666,14 @@ namespace RoF2
|
||||
OUT(Quantity);
|
||||
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
||||
|
||||
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||
LogTrading("ENCODE(OP_TraderShop): Buy Action [{}], Price [{}], Trader [{}], ItemID [{}], Quantity [{}], ItemName, [{}]",
|
||||
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, emu->ItemName);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): Encode Size Unknown (%d)", psize);
|
||||
LogTrading("ENCODE(OP_TraderShop): Encode Size Unknown ([{}])", psize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3946,7 +3928,7 @@ namespace RoF2
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -4278,7 +4260,7 @@ namespace RoF2
|
||||
Buffer += 29;
|
||||
if (Buffer != (BufferStart + PacketSize))
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now %i from end", Buffer - (BufferStart + PacketSize));
|
||||
LogNetcode("[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now [{}] from end", Buffer - (BufferStart + PacketSize));
|
||||
}
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending zone spawn for %s packet is %i bytes", emu->name, outapp->size);
|
||||
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
||||
@@ -4545,27 +4527,6 @@ namespace RoF2
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ClientUpdate)
|
||||
{
|
||||
// for some odd reason, there is an extra byte on the end of this on occasion..
|
||||
DECODE_LENGTH_ATLEAST(structs::PlayerPositionUpdateClient_Struct);
|
||||
SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct);
|
||||
|
||||
IN(spawn_id);
|
||||
IN(sequence);
|
||||
IN(x_pos);
|
||||
IN(y_pos);
|
||||
IN(z_pos);
|
||||
IN(heading);
|
||||
IN(delta_x);
|
||||
IN(delta_y);
|
||||
IN(delta_z);
|
||||
IN(delta_heading);
|
||||
IN(animation);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Consider)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Consider_Struct);
|
||||
@@ -4859,7 +4820,7 @@ namespace RoF2
|
||||
return;
|
||||
}
|
||||
default:
|
||||
Log(Logs::Detail, Logs::Netcode, "Unhandled OP_GuildBank action");
|
||||
LogNetcode("Unhandled OP_GuildBank action");
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
||||
return;
|
||||
}
|
||||
@@ -5012,7 +4973,7 @@ namespace RoF2
|
||||
emu->to_slot = RoF2ToServerSlot(eq->to_slot);
|
||||
IN(number_in_stack);
|
||||
|
||||
//Log(Logs::General, Logs::Netcode, "[RoF2] MoveItem Slot from %u to %u, Number %u", emu->from_slot, emu->to_slot, emu->number_in_stack);
|
||||
//LogNetcode("[RoF2] MoveItem Slot from [{}] to [{}], Number [{}]", emu->from_slot, emu->to_slot, emu->number_in_stack);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -5245,7 +5206,7 @@ namespace RoF2
|
||||
IN(Code);
|
||||
IN(TraderID);
|
||||
IN(Approval);
|
||||
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderClick_Struct Code %d, TraderID %d, Approval %d",
|
||||
LogTrading("DECODE(OP_TraderShop): TraderClick_Struct Code [{}], TraderID [{}], Approval [{}]",
|
||||
eq->Code, eq->TraderID, eq->Approval);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -5259,7 +5220,7 @@ namespace RoF2
|
||||
emu->Beginning.Action = eq->Code;
|
||||
IN(Traders);
|
||||
IN(Items);
|
||||
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): BazaarWelcome_Struct Code %d, Traders %d, Items %d",
|
||||
LogTrading("DECODE(OP_TraderShop): BazaarWelcome_Struct Code [{}], Traders [{}], Items [{}]",
|
||||
eq->Code, eq->Traders, eq->Items);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -5276,20 +5237,20 @@ namespace RoF2
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderBuy_Struct (Unknowns) Unknown004 %d, Unknown008 %d, Unknown012 %d, Unknown076 %d, Unknown276 %d",
|
||||
LogTrading("DECODE(OP_TraderShop): TraderBuy_Struct (Unknowns) Unknown004 [{}], Unknown008 [{}], Unknown012 [{}], Unknown076 [{}], Unknown276 [{}]",
|
||||
eq->Unknown004, eq->Unknown008, eq->Unknown012, eq->Unknown076, eq->Unknown276);
|
||||
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderBuy_Struct Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||
LogTrading("DECODE(OP_TraderShop): TraderBuy_Struct Buy Action [{}], Price [{}], Trader [{}], ItemID [{}], Quantity [{}], ItemName, [{}]",
|
||||
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, eq->ItemName);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
else if (psize == 4)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Forwarding packet as-is with size 4");
|
||||
LogTrading("DECODE(OP_TraderShop): Forwarding packet as-is with size 4");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Decode Size Unknown (%d)", psize);
|
||||
LogTrading("DECODE(OP_TraderShop): Decode Size Unknown ([{}])", psize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5966,7 +5927,7 @@ namespace RoF2
|
||||
RoF2Slot = server_corpse_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to RoF2 Corpse Main Slot %i", server_corpse_slot, RoF2Slot);
|
||||
LogNetcode("Convert Server Corpse Slot [{}] to RoF2 Corpse Main Slot [{}]", server_corpse_slot, RoF2Slot);
|
||||
|
||||
return RoF2Slot;
|
||||
}
|
||||
@@ -6149,7 +6110,7 @@ namespace RoF2
|
||||
ServerSlot = rof2_corpse_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert RoF2 Corpse Main Slot %i to Server Corpse Slot %i", rof2_corpse_slot, ServerSlot);
|
||||
LogNetcode("Convert RoF2 Corpse Main Slot [{}] to Server Corpse Slot [{}]", rof2_corpse_slot, ServerSlot);
|
||||
|
||||
return ServerSlot;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ E(OP_CastSpell)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClickObjectAction)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
E(OP_Damage)
|
||||
E(OP_DeleteCharge)
|
||||
@@ -155,7 +154,6 @@ D(OP_BuffRemoveRequest)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consume)
|
||||
|
||||
@@ -1620,24 +1620,24 @@ struct RespawnWindow_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 spawnId2;
|
||||
/*0004*/ signed padding0004 : 12;
|
||||
signed y_pos : 19; // y coord
|
||||
unsigned padding : 1;
|
||||
/*0008*/ signed delta_z : 13; // change in z
|
||||
signed delta_x : 13; // change in x
|
||||
signed padding0008 : 6;
|
||||
/*0012*/ signed x_pos : 19; // x coord
|
||||
unsigned heading : 12; // heading
|
||||
signed padding0016 : 1;
|
||||
/*0016*/ signed delta_heading : 10; // change in heading
|
||||
signed z_pos : 19; // z coord
|
||||
signed padding0020 : 3;
|
||||
/*0020*/ signed animation : 10; // animation
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0024 : 9;
|
||||
/*0024*/
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 vehicle_id;
|
||||
/*0004*/ signed padding0004 : 12;
|
||||
signed y_pos : 19; // y coord
|
||||
unsigned padding : 1;
|
||||
/*0008*/ signed delta_z : 13; // change in z
|
||||
signed delta_x : 13; // change in x
|
||||
signed padding0008 : 6;
|
||||
/*0012*/ signed x_pos : 19; // x coord
|
||||
unsigned heading : 12; // heading
|
||||
signed padding0016 : 1;
|
||||
/*0016*/ signed delta_heading : 10; // change in heading
|
||||
signed z_pos : 19; // z coord
|
||||
signed padding0020 : 3;
|
||||
/*0020*/ signed animation : 10; // animation
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0024 : 9;
|
||||
/*0024*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1648,22 +1648,23 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0004*/ uint8 unknown0004[6]; // ***Placeholder
|
||||
/*0010*/ float delta_x; // Change in x
|
||||
/*0014*/ unsigned heading : 12; // Directional heading
|
||||
unsigned padding0040 : 20; // ***Placeholder
|
||||
/*0018*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0022*/ float delta_z; // Change in z
|
||||
/*0026*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0030*/ float y_pos; // y coord (1st loc value)
|
||||
/*0034*/ unsigned animation : 10; // ***Placeholder
|
||||
unsigned padding0024 : 22; // animation
|
||||
/*0038*/ float delta_y; // Change in y
|
||||
/*0042*/ signed delta_heading : 10; // change in heading
|
||||
unsigned padding0041 : 22; // ***Placeholder
|
||||
/*0046*/
|
||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0010*/ float delta_x; // Change in x
|
||||
/*0014*/ unsigned heading : 12; // Directional heading
|
||||
unsigned padding0040 : 20; // ***Placeholder
|
||||
/*0018*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0022*/ float delta_z; // Change in z
|
||||
/*0026*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0030*/ float y_pos; // y coord (1st loc value)
|
||||
/*0034*/ unsigned animation : 10; // ***Placeholder
|
||||
unsigned padding0024 : 22; // animation
|
||||
/*0038*/ float delta_y; // Change in y
|
||||
/*0042*/ signed delta_heading : 10; // change in heading
|
||||
unsigned padding0041 : 22; // ***Placeholder
|
||||
/*0046*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -4400,7 +4401,7 @@ struct SendAA_Struct {
|
||||
/*0104*/ uint32 special_category;
|
||||
/*0108*/ uint8 shroud;
|
||||
/*0109*/ uint8 unknown109;
|
||||
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||
/*0110*/ uint8 reset_on_death; // timer is reset on death
|
||||
/*0111*/ uint8 unknown111;
|
||||
/*0112*/ uint32 total_abilities;
|
||||
/*0116*/ AA_Ability abilities[0];
|
||||
|
||||
@@ -1608,22 +1608,22 @@ struct RespawnWindow_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 spawnId2;
|
||||
/*0004*/ signed padding0004:12;
|
||||
signed y_pos:19; // y coord
|
||||
unsigned padding:1;
|
||||
/*0008*/ signed delta_x:13; // change in x
|
||||
signed delta_heading:10;// change in heading
|
||||
signed padding0008:9;
|
||||
/*0012*/ signed delta_y:13; // change in y
|
||||
signed z_pos:19; // z coord
|
||||
/*0016*/ signed x_pos:19; // x coord
|
||||
signed animation:10; // animation
|
||||
signed padding0016:3;
|
||||
/*0020*/ unsigned heading:12; // heading
|
||||
signed delta_z:13; // change in z
|
||||
signed padding0020:7;
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 vehicle_id;
|
||||
/*0004*/ signed padding0004 : 12;
|
||||
signed y_pos : 19; // y coord
|
||||
unsigned padding : 1;
|
||||
/*0008*/ signed delta_x : 13; // change in x
|
||||
signed delta_heading : 10; // change in heading
|
||||
signed padding0008 : 9;
|
||||
/*0012*/ signed delta_y : 13; // change in y
|
||||
signed z_pos : 19; // z coord
|
||||
/*0016*/ signed x_pos : 19; // x coord
|
||||
signed animation : 10; // animation
|
||||
signed padding0016 : 3;
|
||||
/*0020*/ unsigned heading : 12; // heading
|
||||
signed delta_z : 13; // change in z
|
||||
signed padding0020 : 7;
|
||||
/*0024*/
|
||||
};
|
||||
|
||||
@@ -1636,21 +1636,22 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0004*/ uint8 unknown0004[6]; // ***Placeholder
|
||||
/*0010*/ float delta_y; // Change in y
|
||||
/*0014*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0018*/ float y_pos; // y coord (1st loc value)
|
||||
/*0022*/ signed delta_heading:10; // change in heading
|
||||
unsigned animation:10; // ***Placeholder
|
||||
unsigned padding0024:12; // animation
|
||||
/*0026*/ float delta_z; // Change in z
|
||||
/*0030*/ float delta_x; // Change in x
|
||||
/*0034*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0038*/ unsigned heading:12; // Directional heading
|
||||
unsigned padding0040:10; // ***Placeholder
|
||||
unsigned padding0041:10; // ***Placeholder
|
||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0010*/ float delta_y; // Change in y
|
||||
/*0014*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0018*/ float y_pos; // y coord (1st loc value)
|
||||
/*0022*/ signed delta_heading : 10; // change in heading
|
||||
unsigned animation : 10; // ***Placeholder
|
||||
unsigned padding0024 : 12; // animation
|
||||
/*0026*/ float delta_z; // Change in z
|
||||
/*0030*/ float delta_x; // Change in x
|
||||
/*0034*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0038*/ unsigned heading : 12; // Directional heading
|
||||
unsigned padding0040 : 10; // ***Placeholder
|
||||
unsigned padding0041 : 10; // ***Placeholder
|
||||
/*0042*/
|
||||
};
|
||||
|
||||
@@ -4340,7 +4341,7 @@ struct SendAA_Struct {
|
||||
/*0104*/ uint32 special_category;
|
||||
/*0108*/ uint8 shroud;
|
||||
/*0109*/ uint8 unknown109;
|
||||
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||
/*0110*/ uint8 reset_on_death; // timer is reset on death
|
||||
/*0111*/ uint8 unknown111;
|
||||
/*0112*/ uint32 total_abilities;
|
||||
/*0116*/ AA_Ability abilities[0];
|
||||
|
||||
+14
-13
@@ -79,7 +79,7 @@ namespace SoD
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace SoD
|
||||
|
||||
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
||||
}
|
||||
|
||||
void Reload()
|
||||
@@ -122,10 +122,10 @@ namespace SoD
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace SoD
|
||||
|
||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -400,7 +400,7 @@ namespace SoD
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Netcode, "SoD::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
LogNetcode("SoD::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
@@ -1069,7 +1069,7 @@ namespace SoD
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log(Logs::General, Logs::Netcode, "SoD::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
LogNetcode("SoD::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2198,7 +2198,7 @@ namespace SoD
|
||||
|
||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2435,7 +2435,7 @@ namespace SoD
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2926,6 +2926,7 @@ namespace SoD
|
||||
IN(delta_z);
|
||||
IN(delta_heading);
|
||||
IN(animation);
|
||||
emu->vehicle_id = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -3848,7 +3849,7 @@ namespace SoD
|
||||
SoDSlot = serverSlot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to SoD Slot %i", serverSlot, SoDSlot);
|
||||
LogNetcode("Convert Server Slot [{}] to SoD Slot [{}]", serverSlot, SoDSlot);
|
||||
|
||||
return SoDSlot;
|
||||
}
|
||||
@@ -3865,7 +3866,7 @@ namespace SoD
|
||||
SoDSlot = server_corpse_slot - 2;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to SoD Corpse Slot %i", server_corpse_slot, SoDSlot);
|
||||
LogNetcode("Convert Server Corpse Slot [{}] to SoD Corpse Slot [{}]", server_corpse_slot, SoDSlot);
|
||||
|
||||
return SoDSlot;
|
||||
}
|
||||
@@ -3930,7 +3931,7 @@ namespace SoD
|
||||
server_slot = sod_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert SoD Slot %i to Server Slot %i", sod_slot, server_slot);
|
||||
LogNetcode("Convert SoD Slot [{}] to Server Slot [{}]", sod_slot, server_slot);
|
||||
|
||||
return server_slot;
|
||||
}
|
||||
@@ -3947,7 +3948,7 @@ namespace SoD
|
||||
server_slot = sod_corpse_slot + 2;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert SoD Corpse Slot %i to Server Corpse Slot %i", sod_corpse_slot, server_slot);
|
||||
LogNetcode("Convert SoD Corpse Slot [{}] to Server Corpse Slot [{}]", sod_corpse_slot, server_slot);
|
||||
|
||||
return server_slot;
|
||||
}
|
||||
|
||||
@@ -1372,21 +1372,21 @@ struct RespawnWindow_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ signed padding0000:12; // ***Placeholder
|
||||
signed delta_x:13; // change in x
|
||||
signed padding0005:7; // ***Placeholder
|
||||
/*0006*/ signed delta_heading:10;// change in heading
|
||||
signed delta_y:13; // change in y
|
||||
signed padding0006:9; // ***Placeholder
|
||||
/*0010*/ signed y_pos:19; // y coord
|
||||
signed animation:10; // animation
|
||||
signed padding0010:3; // ***Placeholder
|
||||
/*0014*/ unsigned heading:12; // heading
|
||||
signed x_pos:19; // x coord
|
||||
signed padding0014:1; // ***Placeholder
|
||||
/*0018*/ signed z_pos:19; // z coord
|
||||
signed delta_z:13; // change in z
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ signed padding0000 : 12; // ***Placeholder
|
||||
signed delta_x : 13; // change in x
|
||||
signed padding0005 : 7; // ***Placeholder
|
||||
/*0006*/ signed delta_heading : 10; // change in heading
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0006 : 9; // ***Placeholder
|
||||
/*0010*/ signed y_pos : 19; // y coord
|
||||
signed animation : 10; // animation
|
||||
signed padding0010 : 3; // ***Placeholder
|
||||
/*0014*/ unsigned heading : 12; // heading
|
||||
signed x_pos : 19; // x coord
|
||||
signed padding0014 : 1; // ***Placeholder
|
||||
/*0018*/ signed z_pos : 19; // z coord
|
||||
signed delta_z : 13; // change in z
|
||||
/*0022*/
|
||||
};
|
||||
|
||||
@@ -1399,21 +1399,21 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0002*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0008*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0012*/ float y_pos; // y coord (1st loc value)
|
||||
/*0016*/ signed delta_heading:10; // change in heading
|
||||
unsigned padding0036:10; // animation
|
||||
unsigned padding0016:12; // ***Placeholder
|
||||
/*0020*/ float delta_x; // Change in x
|
||||
/*0024*/ float delta_y; // Change in y
|
||||
/*0028*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0032*/ float delta_z; // Change in z
|
||||
/*0036*/ unsigned animation:10; // ***Placeholder
|
||||
unsigned heading:12; // Directional heading
|
||||
unsigned padding0037:10; // ***Placeholder
|
||||
/*0000*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0002*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0008*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0012*/ float y_pos; // y coord (1st loc value)
|
||||
/*0016*/ signed delta_heading : 10; // change in heading
|
||||
unsigned padding0036 : 10; // animation
|
||||
unsigned padding0016 : 12; // ***Placeholder
|
||||
/*0020*/ float delta_x; // Change in x
|
||||
/*0024*/ float delta_y; // Change in y
|
||||
/*0028*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0032*/ float delta_z; // Change in z
|
||||
/*0036*/ unsigned animation : 10; // ***Placeholder
|
||||
unsigned heading : 12; // Directional heading
|
||||
unsigned padding0037 : 10; // ***Placeholder
|
||||
/*0040*/
|
||||
};
|
||||
|
||||
@@ -3780,7 +3780,7 @@ struct SendAA_Struct {
|
||||
/*0092*/ uint32 special_category;
|
||||
/*0096*/ uint8 shroud;
|
||||
/*0097*/ uint8 unknown97;
|
||||
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||
/*0098*/ uint8 reset_on_death; // timer is reset on death
|
||||
/*0099*/ uint8 unknown99;
|
||||
/*0100*/ uint32 total_abilities;
|
||||
/*0104*/ AA_Ability abilities[0];
|
||||
|
||||
+17
-10
@@ -79,7 +79,7 @@ namespace SoF
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ namespace SoF
|
||||
signature.first_eq_opcode = opcodes->EmuToEQ(OP_ZoneEntry);
|
||||
into.RegisterPatch(signature, pname.c_str(), &opcodes, &struct_strategy);
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
||||
}
|
||||
|
||||
void Reload()
|
||||
@@ -120,10 +120,10 @@ namespace SoF
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ namespace SoF
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Netcode, "SoF::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
LogNetcode("SoF::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
@@ -864,7 +864,7 @@ namespace SoF
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log(Logs::General, Logs::Netcode, "SoF::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
LogNetcode("SoF::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -1116,7 +1116,10 @@ namespace SoF
|
||||
}
|
||||
OUT(deity);
|
||||
OUT(intoxication);
|
||||
|
||||
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
|
||||
eq->spellSlotRefresh[9] = 0; // 10th slot is not valid in this release
|
||||
|
||||
OUT(abilitySlotRefresh);
|
||||
OUT(points); // Relocation Test
|
||||
// OUT(unknown0166[4]);
|
||||
@@ -1177,7 +1180,10 @@ namespace SoF
|
||||
}
|
||||
|
||||
// OUT(unknown4184[128]);
|
||||
|
||||
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||
eq->mem_spells[9] = 0xFFFFFFFFU; // 10th slot is not valid in this release
|
||||
|
||||
// OUT(unknown04396[32]);
|
||||
OUT(platinum);
|
||||
OUT(gold);
|
||||
@@ -1821,7 +1827,7 @@ namespace SoF
|
||||
|
||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -1983,7 +1989,7 @@ namespace SoF
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2381,6 +2387,7 @@ namespace SoF
|
||||
IN(delta_z);
|
||||
IN(delta_heading);
|
||||
IN(animation);
|
||||
emu->vehicle_id = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -3238,7 +3245,7 @@ namespace SoF
|
||||
sof_slot = server_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to SoF Slot %i", server_slot, sof_slot);
|
||||
LogNetcode("Convert Server Slot [{}] to SoF Slot [{}]", server_slot, sof_slot);
|
||||
|
||||
return sof_slot;
|
||||
}
|
||||
@@ -3324,7 +3331,7 @@ namespace SoF
|
||||
server_slot = sof_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert SoF Slot %i to Server Slot %i", sof_slot, server_slot);
|
||||
LogNetcode("Convert SoF Slot [{}] to Server Slot [{}]", sof_slot, server_slot);
|
||||
|
||||
return server_slot;
|
||||
}
|
||||
|
||||
@@ -328,7 +328,11 @@ namespace SoF
|
||||
|
||||
const int SPELL_ID_MAX = 15999;
|
||||
const int SPELLBOOK_SIZE = 480;
|
||||
// Be careful not to confuse these two..SoF disc release has a special requirement...
|
||||
// - The number of available spell gems HAS NOT increased from 9 at this point
|
||||
// - The profile allocation HAS increased to 10 at this point
|
||||
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
|
||||
const int SPELL_GEM_PROFILE_SIZE = 10; // special case declaration
|
||||
|
||||
const int LONG_BUFFS = 25;
|
||||
const int SHORT_BUFFS = 15;
|
||||
|
||||
@@ -885,7 +885,7 @@ struct PlayerProfile_Struct //23576 Octets
|
||||
/*00060*/ BindStruct binds[5]; // Bind points (primary is first)
|
||||
/*00160*/ uint32 deity; // deity
|
||||
/*00164*/ uint32 intoxication; // Alcohol level (in ticks till sober?)
|
||||
/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_COUNT]; // Refresh time (millis) - 4 Octets Each
|
||||
/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_PROFILE_SIZE]; // Refresh time (millis) - 4 Octets Each
|
||||
/*00208*/ uint32 abilitySlotRefresh;
|
||||
/*00212*/ uint8 haircolor; // Player hair color
|
||||
/*00213*/ uint8 beardcolor; // Player beard color
|
||||
@@ -912,7 +912,7 @@ struct PlayerProfile_Struct //23576 Octets
|
||||
/*04173*/ uint8 unknown02264[147]; // was [139]
|
||||
/*04312*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 480 = 60 pages
|
||||
/*06232*/ uint8 unknown4184[128]; // was [136]
|
||||
/*06396*/ uint32 mem_spells[spells::SPELL_GEM_COUNT]; // List of spells memorized
|
||||
/*06396*/ uint32 mem_spells[spells::SPELL_GEM_PROFILE_SIZE]; // List of spells memorized
|
||||
/*06436*/ uint8 unknown04396[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
|
||||
/*06464*/ uint32 platinum; // Platinum Pieces on player
|
||||
/*06468*/ uint32 gold; // Gold Pieces on player
|
||||
@@ -1373,21 +1373,21 @@ struct RespawnWindow_Struct {
|
||||
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id; // Entity ID of the Spawn/Player
|
||||
/*0002*/ signed padding0000:12; // ***Placeholder
|
||||
signed x_pos:19; // x coord
|
||||
signed padding0290:1; // ***Placeholder
|
||||
/*0006*/ signed delta_x:13; // change in x
|
||||
signed delta_y:13; // change in y
|
||||
signed padding0294:6; // ***Placeholder
|
||||
/*0010*/ signed z_pos:19; // z coord
|
||||
signed delta_heading:10; // change in heading
|
||||
signed padding0298:3; // ***Placeholder
|
||||
/*0014*/ signed y_pos:19; // y coord
|
||||
signed delta_z:13; // change in z
|
||||
/*0022*/ signed animation:10; // animation
|
||||
unsigned heading:12; // heading
|
||||
signed padding0302:10; // ***Placeholder
|
||||
/*0000*/ uint16 spawn_id; // Entity ID of the Spawn/Player
|
||||
/*0002*/ signed padding0000 : 12; // ***Placeholder
|
||||
signed x_pos : 19; // x coord
|
||||
signed padding0290 : 1; // ***Placeholder
|
||||
/*0006*/ signed delta_x : 13; // change in x
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0294 : 6; // ***Placeholder
|
||||
/*0010*/ signed z_pos : 19; // z coord
|
||||
signed delta_heading : 10; // change in heading
|
||||
signed padding0298 : 3; // ***Placeholder
|
||||
/*0014*/ signed y_pos : 19; // y coord
|
||||
signed delta_z : 13; // change in z
|
||||
/*0022*/ signed animation : 10; // animation
|
||||
unsigned heading : 12; // heading
|
||||
signed padding0302 : 10; // ***Placeholder
|
||||
/*0026*/
|
||||
};
|
||||
|
||||
@@ -1399,20 +1399,20 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id; // Player's Entity ID - Verified
|
||||
/*0002*/ uint16 sequence; //increments one each packet - Verified
|
||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0008*/ float delta_z; // Change in z
|
||||
/*0012*/ float x_pos; // x coord - Verified
|
||||
/*0016*/ signed delta_heading:10; // Change in heading
|
||||
signed animation:10; // Animation
|
||||
unsigned padding0028:12; // Seems to always be 0
|
||||
/*0020*/ float y_pos; // y coord - Verified
|
||||
/*0024*/ float delta_x; // Change in x
|
||||
/*0028*/ unsigned heading:12; // Directional heading - Verified
|
||||
unsigned padding0032:20; // ***Placeholder - Some Static Number
|
||||
/*0032*/ float delta_y; // Change in y
|
||||
/*0036*/ float z_pos; // z coord - Verified
|
||||
/*0000*/ uint16 spawn_id; // Player's Entity ID - Verified
|
||||
/*0002*/ uint16 sequence; //increments one each packet - Verified
|
||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0008*/ float delta_z; // Change in z
|
||||
/*0012*/ float x_pos; // x coord - Verified
|
||||
/*0016*/ signed delta_heading : 10; // Change in heading
|
||||
signed animation : 10; // Animation
|
||||
unsigned padding0028 : 12; // Seems to always be 0
|
||||
/*0020*/ float y_pos; // y coord - Verified
|
||||
/*0024*/ float delta_x; // Change in x
|
||||
/*0028*/ unsigned heading : 12; // Directional heading - Verified
|
||||
unsigned padding0032 : 20; // ***Placeholder - Some Static Number
|
||||
/*0032*/ float delta_y; // Change in y
|
||||
/*0036*/ float z_pos; // z coord - Verified
|
||||
/*0040*/
|
||||
};
|
||||
|
||||
@@ -3704,7 +3704,7 @@ struct SendAA_Struct {
|
||||
/*0088*/ uint32 aa_expansion;
|
||||
/*0092*/ uint32 special_category;
|
||||
/*0096*/ uint8 shroud;
|
||||
/*0097*/ uint8 unknown97;
|
||||
/*0097*/ uint8 reset_on_death; // timer is reset on death -- guess
|
||||
/*0098*/ uint32 total_abilities;
|
||||
/*0102*/ AA_Ability abilities[0];
|
||||
};
|
||||
@@ -3768,7 +3768,7 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
};
|
||||
|
||||
struct LoadSpellSet_Struct {
|
||||
uint32 spell[spells::SPELL_GEM_COUNT];
|
||||
uint32 spell[spells::SPELL_GEM_PROFILE_SIZE];
|
||||
uint32 unknown;
|
||||
};
|
||||
|
||||
|
||||
@@ -87,14 +87,14 @@
|
||||
//check length of packet before decoding. Call before setup.
|
||||
#define ENCODE_LENGTH_EXACT(struct_) \
|
||||
if((*p)->size != sizeof(struct_)) { \
|
||||
Log(Logs::Detail, Logs::Netcode, "Wrong size on outbound %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName((*p)->GetOpcode()), (*p)->size, sizeof(struct_)); \
|
||||
LogNetcode("Wrong size on outbound [{}] (" #struct_ "): Got [{}], expected [{}]", opcodes->EmuToName((*p)->GetOpcode()), (*p)->size, sizeof(struct_)); \
|
||||
delete *p; \
|
||||
*p = nullptr; \
|
||||
return; \
|
||||
}
|
||||
#define ENCODE_LENGTH_ATLEAST(struct_) \
|
||||
if((*p)->size < sizeof(struct_)) { \
|
||||
Log(Logs::Detail, Logs::Netcode, "Wrong size on outbound %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName((*p)->GetOpcode()), (*p)->size, sizeof(struct_)); \
|
||||
LogNetcode("Wrong size on outbound [{}] (" #struct_ "): Got [{}], expected at least [{}]", opcodes->EmuToName((*p)->GetOpcode()), (*p)->size, sizeof(struct_)); \
|
||||
delete *p; \
|
||||
*p = nullptr; \
|
||||
return; \
|
||||
@@ -153,13 +153,13 @@
|
||||
//check length of packet before decoding. Call before setup.
|
||||
#define DECODE_LENGTH_EXACT(struct_) \
|
||||
if(__packet->size != sizeof(struct_)) { \
|
||||
Log(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
LogNetcode("Wrong size on incoming [{}] (" #struct_ "): Got [{}], expected [{}]", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
return; \
|
||||
}
|
||||
#define DECODE_LENGTH_ATLEAST(struct_) \
|
||||
if(__packet->size < sizeof(struct_)) { \
|
||||
Log(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
LogNetcode("Wrong size on incoming [{}] (" #struct_ "): Got [{}], expected at least [{}]", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
return; \
|
||||
}
|
||||
|
||||
+56
-12
@@ -78,7 +78,7 @@ namespace Titanium
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace Titanium
|
||||
|
||||
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
||||
}
|
||||
|
||||
void Reload()
|
||||
@@ -121,10 +121,10 @@ namespace Titanium
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace Titanium
|
||||
for (int r = 0; r < itemcount; r++, eq++) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, ServerToTitaniumSlot(eq->slot_id), 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Netcode, "Titanium::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
LogNetcode("Titanium::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
@@ -350,6 +350,25 @@ namespace Titanium
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_ClientUpdate)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(PlayerPositionUpdateServer_Struct);
|
||||
SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct);
|
||||
|
||||
OUT(spawn_id);
|
||||
OUT(x_pos);
|
||||
OUT(delta_x);
|
||||
OUT(delta_y);
|
||||
OUT(z_pos);
|
||||
OUT(delta_heading);
|
||||
OUT(y_pos);
|
||||
OUT(delta_z);
|
||||
OUT(animation);
|
||||
OUT(heading);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_Damage)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CombatDamage_Struct);
|
||||
@@ -822,7 +841,7 @@ namespace Titanium
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, ServerToTitaniumSlot(int_struct->slot_id), 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log(Logs::General, Logs::Netcode, "Titanium::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
LogNetcode("Titanium::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -1510,7 +1529,7 @@ namespace Titanium
|
||||
|
||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -1628,7 +1647,7 @@ namespace Titanium
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -1878,6 +1897,28 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ClientUpdate)
|
||||
{
|
||||
// for some odd reason, there is an extra byte on the end of this on occasion.. (copied from SoF..not sure if applies to Ti - TODO: check)
|
||||
DECODE_LENGTH_ATLEAST(structs::PlayerPositionUpdateClient_Struct);
|
||||
SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct);
|
||||
|
||||
IN(spawn_id);
|
||||
IN(sequence);
|
||||
IN(x_pos);
|
||||
IN(y_pos);
|
||||
IN(z_pos);
|
||||
IN(heading);
|
||||
IN(delta_x);
|
||||
IN(delta_y);
|
||||
IN(delta_z);
|
||||
IN(delta_heading);
|
||||
IN(animation);
|
||||
emu->vehicle_id = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Consume)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Consume_Struct);
|
||||
@@ -2303,7 +2344,10 @@ namespace Titanium
|
||||
ob << '|' << itoa(item->SkillModType);
|
||||
|
||||
ob << '|' << itoa(item->BaneDmgRace);
|
||||
ob << '|' << itoa(item->BaneDmgAmt);
|
||||
if (item->BaneDmgAmt > 255)
|
||||
ob << '|' << "255";
|
||||
else
|
||||
ob << '|' << itoa(item->BaneDmgAmt);
|
||||
ob << '|' << itoa(item->BaneDmgBody);
|
||||
|
||||
ob << '|' << itoa(item->Magic);
|
||||
@@ -2537,7 +2581,7 @@ namespace Titanium
|
||||
titanium_slot = server_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to Titanium Slot %i", server_slot, titanium_slot);
|
||||
LogNetcode("Convert Server Slot [{}] to Titanium Slot [{}]", server_slot, titanium_slot);
|
||||
|
||||
return titanium_slot;
|
||||
}
|
||||
@@ -2624,7 +2668,7 @@ namespace Titanium
|
||||
server_slot = titanium_slot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Titanium Slot %i to Server Slot %i", titanium_slot, server_slot);
|
||||
LogNetcode("Convert Titanium Slot [{}] to Server Slot [{}]", titanium_slot, server_slot);
|
||||
|
||||
return server_slot;
|
||||
}
|
||||
@@ -2645,7 +2689,7 @@ namespace Titanium
|
||||
server_slot = titanium_corpse_slot + 4;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Titanium Corpse Slot %i to Server Corpse Slot %i", titanium_corpse_slot, server_slot);
|
||||
LogNetcode("Convert Titanium Corpse Slot [{}] to Server Corpse Slot [{}]", titanium_corpse_slot, server_slot);
|
||||
|
||||
return server_slot;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ E(OP_BecomeTrader)
|
||||
E(OP_Buff)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Damage)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
@@ -82,6 +83,7 @@ D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_Emote)
|
||||
|
||||
@@ -1197,20 +1197,20 @@ struct BecomeCorpse_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ int32 delta_heading:10, // change in heading
|
||||
x_pos:19, // x coord
|
||||
padding0002:3; // ***Placeholder
|
||||
/*0006*/ int32 y_pos:19, // y coord
|
||||
animation:10, // animation
|
||||
padding0006:3; // ***Placeholder
|
||||
/*0010*/ int32 z_pos:19, // z coord
|
||||
delta_y:13; // change in y
|
||||
/*0014*/ int32 delta_x:13, // change in x
|
||||
heading:12, // heading
|
||||
padding0014:7; // ***Placeholder
|
||||
/*0018*/ int32 delta_z:13, // change in z
|
||||
padding0018:19; // ***Placeholder
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ int32 delta_heading : 10, // change in heading
|
||||
x_pos : 19, // x coord
|
||||
padding0002 : 3; // ***Placeholder
|
||||
/*0006*/ int32 y_pos : 19, // y coord
|
||||
animation : 10, // animation
|
||||
padding0006 : 3; // ***Placeholder
|
||||
/*0010*/ int32 z_pos : 19, // z coord
|
||||
delta_y : 13; // change in y
|
||||
/*0014*/ int32 delta_x : 13, // change in x
|
||||
heading : 12, // heading
|
||||
padding0014 : 7; // ***Placeholder
|
||||
/*0018*/ int32 delta_z : 13, // change in z
|
||||
padding0018 : 19; // ***Placeholder
|
||||
/*0022*/
|
||||
};
|
||||
|
||||
@@ -1222,20 +1222,20 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0022*/ uint16 sequence; //increments one each packet
|
||||
/*0004*/ float y_pos; // y coord
|
||||
/*0008*/ float delta_z; // Change in z
|
||||
/*0016*/ float delta_x; // Change in x
|
||||
/*0012*/ float delta_y; // Change in y
|
||||
/*0020*/ int32 animation:10, // animation
|
||||
delta_heading:10, // change in heading
|
||||
padding0020:12; // ***Placeholder (mostly 1)
|
||||
/*0024*/ float x_pos; // x coord
|
||||
/*0028*/ float z_pos; // z coord
|
||||
/*0034*/ uint16 heading:12, // Directional heading
|
||||
padding0004:4; // ***Placeholder
|
||||
/*0032*/ uint8 unknown0006[2]; // ***Placeholder
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0022*/ uint16 sequence; // increments one each packet
|
||||
/*0004*/ float y_pos; // y coord
|
||||
/*0008*/ float delta_z; // Change in z
|
||||
/*0016*/ float delta_x; // Change in x
|
||||
/*0012*/ float delta_y; // Change in y
|
||||
/*0020*/ int32 animation : 10, // animation
|
||||
delta_heading : 10, // change in heading
|
||||
padding0020 : 12; // ***Placeholder (mostly 1)
|
||||
/*0024*/ float x_pos; // x coord
|
||||
/*0028*/ float z_pos; // z coord
|
||||
/*0034*/ uint16 heading : 12, // Directional heading
|
||||
padding0004 : 4; // ***Placeholder
|
||||
/*0032*/ uint8 unknown0006[2]; // ***Placeholder
|
||||
/*0036*/
|
||||
};
|
||||
|
||||
|
||||
+14
-13
@@ -79,7 +79,7 @@ namespace UF
|
||||
//TODO: figure out how to support shared memory with multiple patches...
|
||||
opcodes = new RegularOpcodeManager();
|
||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace UF
|
||||
|
||||
|
||||
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
||||
}
|
||||
|
||||
void Reload()
|
||||
@@ -122,10 +122,10 @@ namespace UF
|
||||
opfile += name;
|
||||
opfile += ".conf";
|
||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||
return;
|
||||
}
|
||||
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ namespace UF
|
||||
|
||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -520,7 +520,7 @@ namespace UF
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Netcode, "UF::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
LogNetcode("UF::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
@@ -1277,7 +1277,7 @@ namespace UF
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log(Logs::General, Logs::Netcode, "UF::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
LogNetcode("UF::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2472,7 +2472,7 @@ namespace UF
|
||||
|
||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||
{
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -2704,7 +2704,7 @@ namespace UF
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
@@ -3252,6 +3252,7 @@ namespace UF
|
||||
IN(delta_z);
|
||||
IN(delta_heading);
|
||||
IN(animation);
|
||||
emu->vehicle_id = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -4206,7 +4207,7 @@ namespace UF
|
||||
UFSlot = serverSlot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to UF Slot %i", serverSlot, UFSlot);
|
||||
LogNetcode("Convert Server Slot [{}] to UF Slot [{}]", serverSlot, UFSlot);
|
||||
|
||||
return UFSlot;
|
||||
}
|
||||
@@ -4223,7 +4224,7 @@ namespace UF
|
||||
UFSlot = serverCorpseSlot - 2;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to UF Corpse Slot %i", serverCorpseSlot, UFSlot);
|
||||
LogNetcode("Convert Server Corpse Slot [{}] to UF Corpse Slot [{}]", serverCorpseSlot, UFSlot);
|
||||
|
||||
return UFSlot;
|
||||
}
|
||||
@@ -4288,7 +4289,7 @@ namespace UF
|
||||
ServerSlot = ufSlot;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert UF Slot %i to Server Slot %i", ufSlot, ServerSlot);
|
||||
LogNetcode("Convert UF Slot [{}] to Server Slot [{}]", ufSlot, ServerSlot);
|
||||
|
||||
return ServerSlot;
|
||||
}
|
||||
@@ -4305,7 +4306,7 @@ namespace UF
|
||||
ServerSlot = ufCorpseSlot + 2;
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Netcode, "Convert UF Corpse Slot %i to Server Corpse Slot %i", ufCorpseSlot, ServerSlot);
|
||||
LogNetcode("Convert UF Corpse Slot [{}] to Server Corpse Slot [{}]", ufCorpseSlot, ServerSlot);
|
||||
|
||||
return ServerSlot;
|
||||
}
|
||||
|
||||
+31
-31
@@ -1413,21 +1413,21 @@ struct RespawnWindow_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ signed padding0000:12; // ***Placeholder
|
||||
signed delta_x:13; // change in x
|
||||
signed padding0005:7; // ***Placeholder
|
||||
/*0006*/ signed delta_heading:10;// change in heading
|
||||
signed delta_y:13; // change in y
|
||||
signed padding0006:9; // ***Placeholder
|
||||
/*0010*/ signed y_pos:19; // y coord
|
||||
signed animation:10; // animation
|
||||
signed padding0010:3; // ***Placeholder
|
||||
/*0014*/ unsigned heading:12; // heading
|
||||
signed x_pos:19; // x coord
|
||||
signed padding0014:1; // ***Placeholder
|
||||
/*0018*/ signed z_pos:19; // z coord
|
||||
signed delta_z:13; // change in z
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ signed padding0000 : 12; // ***Placeholder
|
||||
signed delta_x : 13; // change in x
|
||||
signed padding0005 : 7; // ***Placeholder
|
||||
/*0006*/ signed delta_heading : 10; // change in heading
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0006 : 9; // ***Placeholder
|
||||
/*0010*/ signed y_pos : 19; // y coord
|
||||
signed animation : 10; // animation
|
||||
signed padding0010 : 3; // ***Placeholder
|
||||
/*0014*/ unsigned heading : 12; // heading
|
||||
signed x_pos : 19; // x coord
|
||||
signed padding0014 : 1; // ***Placeholder
|
||||
/*0018*/ signed z_pos : 19; // z coord
|
||||
signed delta_z : 13; // change in z
|
||||
/*0022*/
|
||||
};
|
||||
|
||||
@@ -1440,21 +1440,21 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0002*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0008*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0012*/ float y_pos; // y coord (1st loc value)
|
||||
/*0016*/ signed delta_heading:10; // change in heading
|
||||
unsigned padding0036:10; // animation
|
||||
unsigned padding0016:12; // ***Placeholder
|
||||
/*0020*/ float delta_x; // Change in x
|
||||
/*0024*/ float delta_y; // Change in y
|
||||
/*0028*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0032*/ float delta_z; // Change in z
|
||||
/*0036*/ unsigned animation:10; // ***Placeholder
|
||||
unsigned heading:12; // Directional heading
|
||||
unsigned padding0037:10; // ***Placeholder
|
||||
/*0000*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0002*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0008*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0012*/ float y_pos; // y coord (1st loc value)
|
||||
/*0016*/ signed delta_heading : 10; // change in heading
|
||||
unsigned padding0036 : 10; // animation
|
||||
unsigned padding0016 : 12; // ***Placeholder
|
||||
/*0020*/ float delta_x; // Change in x
|
||||
/*0024*/ float delta_y; // Change in y
|
||||
/*0028*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0032*/ float delta_z; // Change in z
|
||||
/*0036*/ unsigned animation : 10; // ***Placeholder
|
||||
unsigned heading : 12; // Directional heading
|
||||
unsigned padding0037 : 10; // ***Placeholder
|
||||
/*0040*/
|
||||
};
|
||||
|
||||
@@ -3835,7 +3835,7 @@ struct SendAA_Struct {
|
||||
/*0092*/ uint32 special_category;
|
||||
/*0096*/ uint8 shroud;
|
||||
/*0097*/ uint8 unknown97;
|
||||
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||
/*0098*/ uint8 reset_on_death; // timer is reset on death
|
||||
/*0099*/ uint8 unknown99;
|
||||
/*0100*/ uint32 total_abilities;
|
||||
/*0104*/ AA_Ability abilities[0];
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/**
|
||||
* 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 "platform.h"
|
||||
|
||||
EQEmuExePlatform exe_platform = ExePlatformNone;
|
||||
@@ -10,6 +30,44 @@ const EQEmuExePlatform& GetExecutablePlatform() {
|
||||
return exe_platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
int GetExecutablePlatformInt(){
|
||||
return exe_platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns platform name by string
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
std::string GetPlatformName()
|
||||
{
|
||||
switch (GetExecutablePlatformInt()) {
|
||||
case EQEmuExePlatform::ExePlatformWorld:
|
||||
return "WorldServer";
|
||||
case EQEmuExePlatform::ExePlatformQueryServ:
|
||||
return "QueryServer";
|
||||
case EQEmuExePlatform::ExePlatformZone:
|
||||
return "ZoneServer";
|
||||
case EQEmuExePlatform::ExePlatformUCS:
|
||||
return "UCS";
|
||||
case EQEmuExePlatform::ExePlatformLogin:
|
||||
return "LoginServer";
|
||||
case EQEmuExePlatform::ExePlatformSocket_Server:
|
||||
return "SocketServer";
|
||||
case EQEmuExePlatform::ExePlatformSharedMemory:
|
||||
return "SharedMemory";
|
||||
case EQEmuExePlatform::ExePlatformClientImport:
|
||||
return "ClientImport";
|
||||
case EQEmuExePlatform::ExePlatformClientExport:
|
||||
return "ClientExport";
|
||||
case EQEmuExePlatform::ExePlatformLaunch:
|
||||
return "Launch";
|
||||
case EQEmuExePlatform::ExePlatformHC:
|
||||
return "HC";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,28 @@
|
||||
/**
|
||||
* 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_PLATFORM_H
|
||||
#define EQEMU_PLATFORM_H
|
||||
|
||||
#include "iostream"
|
||||
|
||||
enum EQEmuExePlatform
|
||||
{
|
||||
ExePlatformNone = 0,
|
||||
@@ -20,5 +42,6 @@ enum EQEmuExePlatform
|
||||
void RegisterExecutablePlatform(EQEmuExePlatform p);
|
||||
const EQEmuExePlatform& GetExecutablePlatform();
|
||||
int GetExecutablePlatformInt();
|
||||
std::string GetPlatformName();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -134,7 +134,6 @@ bool PersistentTimer::Load(Database *db) {
|
||||
(unsigned long)_char_id, _type);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
Log(Logs::General, Logs::Error, "Error in PersistentTimer::Load, error: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -165,9 +164,6 @@ bool PersistentTimer::Store(Database *db) {
|
||||
#endif
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
Log(Logs::General, Logs::Error, "Error in PersistentTimer::Store, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -185,9 +181,6 @@ bool PersistentTimer::Clear(Database *db) {
|
||||
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
Log(Logs::General, Logs::Error, "Error in PersistentTimer::Clear, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -197,10 +190,6 @@ bool PersistentTimer::Clear(Database *db) {
|
||||
|
||||
/* This function checks if the timer triggered */
|
||||
bool PersistentTimer::Expired(Database *db, bool iReset) {
|
||||
if (this == nullptr) {
|
||||
Log(Logs::General, Logs::Error, "Null timer during ->Check()!?\n");
|
||||
return(true);
|
||||
}
|
||||
uint32 current_time = get_current_time();
|
||||
if (current_time-start_time >= timer_time) {
|
||||
if (enabled && iReset) {
|
||||
@@ -289,9 +278,6 @@ bool PTimerList::Load(Database *db) {
|
||||
(unsigned long)_char_id);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
Log(Logs::General, Logs::Error, "Error in PersistentTimer::Load, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -348,9 +334,6 @@ bool PTimerList::Clear(Database *db) {
|
||||
#endif
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
Log(Logs::General, Logs::Error, "Error in PersistentTimer::Clear, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -440,9 +423,6 @@ bool PTimerList::ClearOffline(Database *db, uint32 char_id, pTimerType type) {
|
||||
#endif
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
#if EQDEBUG > 5
|
||||
Log(Logs::General, Logs::Error, "Error in PTimerList::ClearOffline, error: %s", results.ErrorMessage().c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+331
-74
@@ -21,6 +21,7 @@
|
||||
#include "string_util.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fmt/format.h>
|
||||
|
||||
/*
|
||||
Commands:
|
||||
@@ -45,14 +46,14 @@ const char *RuleManager::s_categoryNames[_CatCount+1] = {
|
||||
|
||||
const RuleManager::RuleInfo RuleManager::s_RuleInfo[_IntRuleCount+_RealRuleCount+_BoolRuleCount+1] = {
|
||||
/* this is done in three steps so we can reliably get to them by index*/
|
||||
#define RULE_INT(cat, rule, default_value) \
|
||||
{ #cat ":" #rule, Category__##cat, IntRule, Int__##rule },
|
||||
#define RULE_INT(cat, rule, default_value, notes) \
|
||||
{ #cat ":" #rule, Category__##cat, IntRule, Int__##rule, notes },
|
||||
#include "ruletypes.h"
|
||||
#define RULE_REAL(cat, rule, default_value) \
|
||||
{ #cat ":" #rule, Category__##cat, RealRule, Real__##rule },
|
||||
#define RULE_REAL(cat, rule, default_value, notes) \
|
||||
{ #cat ":" #rule, Category__##cat, RealRule, Real__##rule, notes },
|
||||
#include "ruletypes.h"
|
||||
#define RULE_BOOL(cat, rule, default_value) \
|
||||
{ #cat ":" #rule, Category__##cat, BoolRule, Bool__##rule },
|
||||
#define RULE_BOOL(cat, rule, default_value, notes) \
|
||||
{ #cat ":" #rule, Category__##cat, BoolRule, Bool__##rule, notes },
|
||||
#include "ruletypes.h"
|
||||
{ "Invalid Rule", _CatCount, IntRule }
|
||||
};
|
||||
@@ -145,11 +146,11 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas
|
||||
switch(type) {
|
||||
case IntRule:
|
||||
m_RuleIntValues[index] = atoi(rule_value);
|
||||
Log(Logs::Detail, Logs::Rules, "Set rule %s to value %d", rule_name, m_RuleIntValues[index]);
|
||||
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
|
||||
break;
|
||||
case RealRule:
|
||||
m_RuleRealValues[index] = atof(rule_value);
|
||||
Log(Logs::Detail, Logs::Rules, "Set rule %s to value %.13f", rule_name, m_RuleRealValues[index]);
|
||||
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleRealValues[index]);
|
||||
break;
|
||||
case BoolRule:
|
||||
uint32 val = 0;
|
||||
@@ -157,7 +158,7 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas
|
||||
val = 1;
|
||||
|
||||
m_RuleBoolValues[index] = val;
|
||||
Log(Logs::Detail, Logs::Rules, "Set rule %s to value %s", rule_name, m_RuleBoolValues[index] == 1 ? "true" : "false");
|
||||
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleBoolValues[index] == 1 ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -178,11 +179,11 @@ void RuleManager::ResetRules(bool reload) {
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Rules, "Resetting running rules to default values");
|
||||
#define RULE_INT(cat, rule, default_value) \
|
||||
#define RULE_INT(cat, rule, default_value, notes) \
|
||||
m_RuleIntValues[ Int__##rule ] = default_value;
|
||||
#define RULE_REAL(cat, rule, default_value) \
|
||||
#define RULE_REAL(cat, rule, default_value, notes) \
|
||||
m_RuleRealValues[ Real__##rule ] = default_value;
|
||||
#define RULE_BOOL(cat, rule, default_value) \
|
||||
#define RULE_BOOL(cat, rule, default_value, notes) \
|
||||
m_RuleBoolValues[ Bool__##rule ] = default_value;
|
||||
#include "ruletypes.h"
|
||||
|
||||
@@ -214,19 +215,101 @@ bool RuleManager::_FindRule(const char *rule_name, RuleType &type_into, uint16 &
|
||||
//assumes index is valid!
|
||||
const char *RuleManager::_GetRuleName(RuleType type, uint16 index) {
|
||||
switch (type) {
|
||||
case IntRule:
|
||||
return(s_RuleInfo[index].name);
|
||||
case RealRule:
|
||||
return(s_RuleInfo[index + _IntRuleCount].name);
|
||||
case BoolRule:
|
||||
return(s_RuleInfo[index + _IntRuleCount + _RealRuleCount].name);
|
||||
case IntRule:
|
||||
return(s_RuleInfo[index].name);
|
||||
case RealRule:
|
||||
return(s_RuleInfo[index+_IntRuleCount].name);
|
||||
case BoolRule:
|
||||
return(s_RuleInfo[index+_IntRuleCount+_RealRuleCount].name);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//should never happen
|
||||
return("InvalidRule??");
|
||||
return(s_RuleInfo[_IntRuleCount+_RealRuleCount+_BoolRuleCount].name); // no need to create a string when one already exists...
|
||||
}
|
||||
|
||||
//assumes index is valid!
|
||||
const std::string &RuleManager::_GetRuleNotes(RuleType type, uint16 index) {
|
||||
switch (type) {
|
||||
case IntRule:
|
||||
return(s_RuleInfo[index].notes);
|
||||
case RealRule:
|
||||
return(s_RuleInfo[index+_IntRuleCount].notes);
|
||||
case BoolRule:
|
||||
return(s_RuleInfo[index+_IntRuleCount+_RealRuleCount].notes);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//should never happen
|
||||
return(s_RuleInfo[_IntRuleCount+_RealRuleCount+_BoolRuleCount].notes);
|
||||
}
|
||||
|
||||
bool RuleManager::LoadRules(Database *database, const char *ruleset_name, bool reload) {
|
||||
|
||||
int ruleset_id = this->GetRulesetID(database, ruleset_name);
|
||||
if (ruleset_id < 0) {
|
||||
Log(Logs::Detail, Logs::Rules, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset_name);
|
||||
return (false);
|
||||
}
|
||||
|
||||
m_activeRuleset = ruleset_id;
|
||||
m_activeName = ruleset_name;
|
||||
|
||||
/* Load default ruleset values first if we're loading something other than default */
|
||||
if (strcasecmp(ruleset_name, "default") != 0) {
|
||||
|
||||
std::string default_ruleset_name = "default";
|
||||
int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str());
|
||||
|
||||
if (default_ruleset_id < 0) {
|
||||
Log(Logs::Detail,
|
||||
Logs::Rules,
|
||||
"Failed to find default ruleset '%s' for load operation. Canceling.",
|
||||
default_ruleset_name.c_str()
|
||||
);
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Rules, "Processing rule set '%s' (%d) load...", default_ruleset_name.c_str(), default_ruleset_id);
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT `rule_name`, `rule_value` FROM `rule_values` WHERE `ruleset_id` = '%d'",
|
||||
default_ruleset_id
|
||||
);
|
||||
|
||||
auto results = database->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
if (!SetRule(row[0], row[1], nullptr, false, reload)) {
|
||||
Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for '%s'", row[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Rules, "Processing rule set '%s' (%d) load...", ruleset_name, ruleset_id);
|
||||
|
||||
std::string query = StringFormat("SELECT `rule_name`, `rule_value` FROM `rule_values` WHERE `ruleset_id` = '%d'", ruleset_id);
|
||||
|
||||
auto results = database->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
if (!SetRule(row[0], row[1], nullptr, false, reload)) {
|
||||
Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for '%s'", row[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuleManager::SaveRules(Database *database, const char *ruleset_name) {
|
||||
|
||||
|
||||
if (ruleset_name != nullptr) {
|
||||
//saving to a specific name
|
||||
if (m_activeName != ruleset_name) {
|
||||
@@ -257,56 +340,6 @@ void RuleManager::SaveRules(Database *database, const char *ruleset_name) {
|
||||
}
|
||||
}
|
||||
|
||||
bool RuleManager::LoadRules(Database *database, const char *ruleset_name, bool reload) {
|
||||
|
||||
int ruleset_id = this->GetRulesetID(database, ruleset_name);
|
||||
if (ruleset_id < 0) {
|
||||
Log(Logs::Detail, Logs::Rules, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset_name);
|
||||
return (false);
|
||||
}
|
||||
|
||||
Log(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", ruleset_name, ruleset_id);
|
||||
|
||||
m_activeRuleset = ruleset_id;
|
||||
m_activeName = ruleset_name;
|
||||
|
||||
/* Load default ruleset values first if we're loading something other than default */
|
||||
if (strcasecmp(ruleset_name, "default") != 0) {
|
||||
std::string default_ruleset_name = "default";
|
||||
int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str());
|
||||
if (default_ruleset_id < 0) {
|
||||
Log(Logs::Detail, Logs::Rules, "Failed to find default ruleset '%s' for load operation. Canceling.",
|
||||
default_ruleset_name.c_str());
|
||||
return (false);
|
||||
}
|
||||
Log(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", default_ruleset_name.c_str(), default_ruleset_id);
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id = %d",
|
||||
default_ruleset_id
|
||||
);
|
||||
|
||||
auto results = database->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
if (!SetRule(row[0], row[1], nullptr, false, reload))
|
||||
Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
|
||||
}
|
||||
|
||||
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id);
|
||||
auto results = database->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
if (!SetRule(row[0], row[1], nullptr, false, reload))
|
||||
Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) {
|
||||
char value_string[100];
|
||||
|
||||
@@ -328,17 +361,241 @@ void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) {
|
||||
}
|
||||
|
||||
std::string query = StringFormat(
|
||||
"REPLACE INTO rule_values "
|
||||
"(ruleset_id, rule_name, rule_value) "
|
||||
" VALUES(%d, '%s', '%s')",
|
||||
"REPLACE INTO `rule_values`"
|
||||
"(`ruleset_id`, `rule_name`, `rule_value`, `notes`)"
|
||||
" VALUES('%d', '%s', '%s', '%s')",
|
||||
m_activeRuleset,
|
||||
_GetRuleName(type, index),
|
||||
value_string
|
||||
value_string,
|
||||
EscapeString(_GetRuleNotes(type, index)).c_str()
|
||||
);
|
||||
|
||||
database->QueryDatabase(query);
|
||||
}
|
||||
|
||||
bool RuleManager::UpdateInjectedRules(Database *db, const char *ruleset_name, bool quiet_update)
|
||||
{
|
||||
std::vector<std::string> database_data;
|
||||
std::map<std::string, std::pair<std::string, const std::string *>> rule_data;
|
||||
std::vector<std::tuple<int, std::string, std::string, std::string>> injected_rule_entries;
|
||||
|
||||
if (ruleset_name == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ruleset_id = GetRulesetID(db, ruleset_name);
|
||||
if (ruleset_id < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// load database rule names
|
||||
std::string query(StringFormat("SELECT `rule_name` FROM `rule_values` WHERE `ruleset_id` = '%i'", ruleset_id));
|
||||
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// build database data entries
|
||||
for (auto row : results) {
|
||||
database_data.push_back(std::string(row[0]));
|
||||
}
|
||||
|
||||
// build rule data entries
|
||||
for (const auto &ri_iter : s_RuleInfo) {
|
||||
if (strcasecmp(ri_iter.name, "Invalid Rule") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char buffer[100];
|
||||
|
||||
switch (ri_iter.type) {
|
||||
case IntRule:
|
||||
sprintf(buffer, "%d", m_RuleIntValues[ri_iter.rule_index]);
|
||||
rule_data[ri_iter.name].first = buffer;
|
||||
rule_data[ri_iter.name].second = &ri_iter.notes;
|
||||
break;
|
||||
case RealRule:
|
||||
sprintf(buffer, "%.13f", m_RuleRealValues[ri_iter.rule_index]);
|
||||
rule_data[ri_iter.name].first = buffer;
|
||||
rule_data[ri_iter.name].second = &ri_iter.notes;
|
||||
break;
|
||||
case BoolRule:
|
||||
sprintf(buffer, "%s", (m_RuleBoolValues[ri_iter.rule_index] ? "true" : "false"));
|
||||
rule_data[ri_iter.name].first = buffer;
|
||||
rule_data[ri_iter.name].second = &ri_iter.notes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// build injected entries
|
||||
for (const auto &rd_iter : rule_data) {
|
||||
|
||||
const auto &dd_iter = std::find(database_data.begin(), database_data.end(), rd_iter.first);
|
||||
if (dd_iter == database_data.end()) {
|
||||
|
||||
injected_rule_entries.push_back(
|
||||
std::tuple<int, std::string, std::string, std::string>(
|
||||
ruleset_id, // `ruleset_id`
|
||||
rd_iter.first, // `rule_name`
|
||||
rd_iter.second.first, // `rule_value`
|
||||
EscapeString(*rd_iter.second.second) // `notes`
|
||||
)
|
||||
);
|
||||
|
||||
if (!quiet_update) {
|
||||
LogInfo(
|
||||
"Adding new rule [{}] ruleset [{}] ({}) value [{}]",
|
||||
rd_iter.first.c_str(),
|
||||
ruleset_name,
|
||||
ruleset_id,
|
||||
rd_iter.second.first.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (injected_rule_entries.size()) {
|
||||
|
||||
std::string query(
|
||||
fmt::format(
|
||||
"REPLACE INTO `rule_values`(`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES {}",
|
||||
implode(
|
||||
",",
|
||||
std::pair<char, char>('(', ')'),
|
||||
join_tuple(",", std::pair<char, char>('\'', '\''), injected_rule_entries)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (!db->QueryDatabase(query).Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"[{}] New rule(s) added to ruleset [{}] [{}]",
|
||||
injected_rule_entries.size(),
|
||||
ruleset_name,
|
||||
ruleset_id
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RuleManager::UpdateOrphanedRules(Database *db, bool quiet_update)
|
||||
{
|
||||
std::vector<std::string> rule_data;
|
||||
std::vector<std::string> orphaned_rule_entries;
|
||||
|
||||
// load database rule names
|
||||
std::string query("SELECT `rule_name` FROM `rule_values` GROUP BY `rule_name`");
|
||||
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// build rule data entries
|
||||
for (const auto &ri_iter : s_RuleInfo) {
|
||||
if (strcasecmp(ri_iter.name, "Invalid Rule") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rule_data.push_back(ri_iter.name);
|
||||
}
|
||||
|
||||
// build orphaned entries
|
||||
for (auto row : results) {
|
||||
|
||||
const auto &rd_iter = std::find(rule_data.begin(), rule_data.end(), row[0]);
|
||||
if (rd_iter == rule_data.end()) {
|
||||
|
||||
orphaned_rule_entries.push_back(std::string(row[0]));
|
||||
|
||||
if (!quiet_update) {
|
||||
LogInfo(
|
||||
"Rule [{}] no longer exists... Deleting orphaned entry from `rule_values` table...",
|
||||
row[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (orphaned_rule_entries.size()) {
|
||||
|
||||
std::string query (
|
||||
fmt::format(
|
||||
"DELETE FROM `rule_values` WHERE `rule_name` IN ({})",
|
||||
implode(",", std::pair<char, char>('\'', '\''), orphaned_rule_entries)
|
||||
)
|
||||
);
|
||||
|
||||
if (!db->QueryDatabase(query).Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogInfo("[{}] Orphaned Rule(s) Deleted from [All Rulesets] (-1)", orphaned_rule_entries.size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RuleManager::RestoreRuleNotes(Database *db)
|
||||
{
|
||||
std::string query("SELECT `ruleset_id`, `rule_name`, `notes` FROM `rule_values`");
|
||||
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int update_count = 0;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
|
||||
auto rule = [](const char *rule_name) {
|
||||
|
||||
for (auto rule_iter : s_RuleInfo) {
|
||||
if (strcasecmp(rule_iter.name, rule_name) == 0) {
|
||||
return rule_iter;
|
||||
}
|
||||
}
|
||||
|
||||
return s_RuleInfo[_IntRuleCount+_RealRuleCount+_BoolRuleCount];
|
||||
}(row[1]);
|
||||
|
||||
if (strcasecmp(rule.name, row[1]) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (row[2] != nullptr && rule.notes.compare(row[2]) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string query(
|
||||
fmt::format(
|
||||
"UPDATE `rule_values` SET `notes` = '{}' WHERE `ruleset_id` = '{}' AND `rule_name` = '{}'",
|
||||
EscapeString(rule.notes),
|
||||
row[0],
|
||||
row[1]
|
||||
)
|
||||
);
|
||||
|
||||
if (!db->QueryDatabase(query).Success()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
++update_count;
|
||||
}
|
||||
|
||||
if (update_count > 0) {
|
||||
LogInfo("[{}] Rule Note [{}] Restored", update_count, (update_count == 1 ? "" : "s"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int RuleManager::GetRulesetID(Database *database, const char *ruleset_name) {
|
||||
|
||||
|
||||
+12
-4
@@ -49,21 +49,21 @@ class RuleManager {
|
||||
public:
|
||||
//generate our rule enums:
|
||||
typedef enum {
|
||||
#define RULE_INT(cat, rule, default_value) \
|
||||
#define RULE_INT(cat, rule, default_value, notes) \
|
||||
Int__##rule,
|
||||
#include "ruletypes.h"
|
||||
_IntRuleCount
|
||||
} IntType;
|
||||
|
||||
typedef enum {
|
||||
#define RULE_REAL(cat, rule, default_value) \
|
||||
#define RULE_REAL(cat, rule, default_value, notes) \
|
||||
Real__##rule,
|
||||
#include "ruletypes.h"
|
||||
_RealRuleCount
|
||||
} RealType;
|
||||
|
||||
typedef enum {
|
||||
#define RULE_BOOL(cat, rule, default_value) \
|
||||
#define RULE_BOOL(cat, rule, default_value, notes) \
|
||||
Bool__##rule,
|
||||
#include "ruletypes.h"
|
||||
_BoolRuleCount
|
||||
@@ -97,6 +97,9 @@ public:
|
||||
static const char *GetRuleName(IntType t) { return(s_RuleInfo[t].name); }
|
||||
static const char *GetRuleName(RealType t) { return(s_RuleInfo[t+_IntRuleCount].name); }
|
||||
static const char *GetRuleName(BoolType t) { return(s_RuleInfo[t+_IntRuleCount+_RealRuleCount].name); }
|
||||
static const std::string &GetRuleNotes(IntType t) { return(s_RuleInfo[t].notes); }
|
||||
static const std::string &GetRuleNotes(RealType t) { return(s_RuleInfo[t+_IntRuleCount].notes); }
|
||||
static const std::string &GetRuleNotes(BoolType t) { return(s_RuleInfo[t+_IntRuleCount+_RealRuleCount].notes); }
|
||||
static uint32 CountRules() { return(_RulesCount); }
|
||||
static CategoryType FindCategory(const char *catname);
|
||||
bool ListRules(const char *catname, std::vector<const char *> &into);
|
||||
@@ -113,6 +116,9 @@ public:
|
||||
void ResetRules(bool reload = false);
|
||||
bool LoadRules(Database *db, const char *ruleset = nullptr, bool reload = false);
|
||||
void SaveRules(Database *db, const char *ruleset = nullptr);
|
||||
bool UpdateInjectedRules(Database *db, const char *ruleset_name, bool quiet_update = false);
|
||||
bool UpdateOrphanedRules(Database *db, bool quiet_update = false);
|
||||
bool RestoreRuleNotes(Database *db);
|
||||
|
||||
private:
|
||||
RuleManager();
|
||||
@@ -137,15 +143,17 @@ private:
|
||||
|
||||
static bool _FindRule(const char *rule_name, RuleType &type_into, uint16 &index_into);
|
||||
static const char *_GetRuleName(RuleType type, uint16 index);
|
||||
static const std::string &_GetRuleNotes(RuleType type, uint16 index);
|
||||
static int _FindOrCreateRuleset(Database *db, const char *ruleset);
|
||||
void _SaveRule(Database *db, RuleType type, uint16 index);
|
||||
|
||||
|
||||
static const char *s_categoryNames[];
|
||||
typedef struct {
|
||||
const char *name;
|
||||
CategoryType category;
|
||||
RuleType type;
|
||||
uint16 rule_index; //index into its 'type' array
|
||||
const std::string notes;
|
||||
} RuleInfo;
|
||||
static const RuleInfo s_RuleInfo[];
|
||||
|
||||
|
||||
+645
-611
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user