mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-17 12:04:27 -06:00
Compare commits
856 Commits
v1.0
...
visual-deb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4adba09b4 | ||
|
|
fc0961ed76 | ||
|
|
b28b93b3f0 | ||
|
|
f3ace4e7ed | ||
| 14d4bf3cc5 | |||
| 26f2eb409f | |||
| 1af3e59348 | |||
|
|
e3077aa410 | ||
| 3b75ecc0b4 | |||
| b70e7334e8 | |||
| 500b7885e2 | |||
|
|
bc132487e9 | ||
| 47f0830483 | |||
| e707207ffa | |||
|
|
ceb374591f | ||
|
|
c05562a227 | ||
| f8c1e2fb52 | |||
| e4a15a0f2e | |||
|
|
dd8091f60e | ||
|
|
50b3946548 | ||
| 976bd3c41b | |||
|
|
3b7f1dad54 | ||
|
|
54021458bd | ||
|
|
1e1b6aaa0b | ||
|
|
008f953003 | ||
|
|
dc960cb99c | ||
| 2d0faae759 | |||
| 932d8030f0 | |||
|
|
7f5ab8b9fa | ||
|
|
6c97ea8208 | ||
| 72477e01e2 | |||
|
|
ea86988521 | ||
| d626ac1ed4 | |||
| 168f837b94 | |||
| 9e4ce24fd2 | |||
|
|
4112a85906 | ||
|
|
408163ed35 | ||
|
|
4556f13474 | ||
|
|
88f316bf93 | ||
|
|
e6c7f744b5 | ||
|
|
d2b05a1ac5 | ||
|
|
a429489846 | ||
|
|
9ee219ea42 | ||
| a0aa8b2854 | |||
|
|
c11a4a67d1 | ||
|
|
c69d01d77b | ||
|
|
50cb9346b8 | ||
|
|
17d77db1c6 | ||
|
|
e97dc6fbff | ||
|
|
7ec458421f | ||
| 0b9e97625e | |||
|
|
d64fa1680d | ||
|
|
f80a26a944 | ||
|
|
26ddeaa429 | ||
| 8b386ae6c5 | |||
| f284e5a6e1 | |||
| 1b01abd7d9 | |||
| 0e46b875a5 | |||
| 19e77a38d8 | |||
|
|
adb6a2c609 | ||
| 4f7aa11067 | |||
|
|
ffd4477081 | ||
| a632ef8ccd | |||
|
|
9e08bb20d2 | ||
|
|
9813c3ed2c | ||
| e97ae92624 | |||
| a7fb6eb3f3 | |||
| 9ed4a4f47f | |||
| b57cacc676 | |||
| f2d1c5d26d | |||
|
|
ef0a3c6d0b | ||
|
|
6a38b67ed5 | ||
| 5523b6aafc | |||
|
|
40a9aefb5b | ||
|
|
91f2cebcc7 | ||
|
|
45a7dbdadd | ||
|
|
74bca38253 | ||
|
|
082a2a418f | ||
|
|
835cf2b794 | ||
|
|
74343be871 | ||
|
|
ed5ced0bed | ||
| 3dfe363a6b | |||
|
|
8e5da2cf1f | ||
|
|
ec4ed8fa7e | ||
|
|
b55606d41e | ||
|
|
69a0d5a50b | ||
|
|
945e572493 | ||
| ef8c2a40f3 | |||
|
|
fab8a1e982 | ||
|
|
0d4f86b20b | ||
|
|
c689b3d3d1 | ||
|
|
77d35019cc | ||
| 9287e5bc4b | |||
|
|
f5ae5aa13e | ||
|
|
df0f11c95b | ||
|
|
9c0819de4f | ||
|
|
3d46d703b2 | ||
|
|
9ba297dd2e | ||
|
|
ccb9f7c499 | ||
|
|
24dbd3944d | ||
|
|
5888c9f468 | ||
|
|
c9cd7a200a | ||
|
|
b7497a47e4 | ||
|
|
bfa1f57158 | ||
|
|
d642de9462 | ||
|
|
06217ad5e3 | ||
|
|
325dc5a571 | ||
|
|
66edf57b02 | ||
|
|
485de6173a | ||
| dddc33607b | |||
| 3865a186a7 | |||
|
|
22b2516107 | ||
|
|
0734760d42 | ||
|
|
138fffda2c | ||
|
|
de5d9182eb | ||
|
|
3cf243b1d7 | ||
|
|
8cdb388915 | ||
|
|
cc25ec0151 | ||
|
|
8a54e7ccd2 | ||
|
|
6e2936504c | ||
|
|
eaa962f265 | ||
| 1497d9b35a | |||
|
|
a55162775e | ||
|
|
670a2de95b | ||
| 94e161df55 | |||
|
|
06dc18fb49 | ||
|
|
00f7a5c4d6 | ||
| 5dd4086bd5 | |||
| 1b222a64c3 | |||
|
|
6a7c6da01a | ||
|
|
9bfff533c3 | ||
|
|
8e9c48cce0 | ||
|
|
fb81c0c9a2 | ||
|
|
c0d05b00df | ||
|
|
ef0873075f | ||
|
|
c89f420204 | ||
|
|
ea94de16cd | ||
|
|
c5f2f4b708 | ||
|
|
cb6d91cfb2 | ||
|
|
e24ad43dc5 | ||
|
|
09d50faf79 | ||
|
|
6b30292efd | ||
|
|
5f34b7150a | ||
|
|
43377caa3b | ||
| 29199f4755 | |||
|
|
f4b89a8925 | ||
|
|
968114199b | ||
|
|
c871aeef56 | ||
|
|
9cf534dc0a | ||
|
|
de47210f15 | ||
|
|
ba5037300f | ||
|
|
2e224cb151 | ||
|
|
2a0616d0e9 | ||
|
|
0774ab930d | ||
|
|
e415d96a9d | ||
|
|
35ea3d35ae | ||
|
|
e28b084395 | ||
|
|
136937184e | ||
|
|
2403a7fe45 | ||
|
|
531c4a594c | ||
|
|
1fe6c32933 | ||
|
|
4a39221dd0 | ||
|
|
09c459a083 | ||
|
|
7dfcd22a2e | ||
|
|
8bdd5b6e2c | ||
|
|
4556faf833 | ||
|
|
1179f5a2fe | ||
|
|
a61c6e5e41 | ||
|
|
1f62f169c8 | ||
|
|
842cb80137 | ||
|
|
2868465e89 | ||
|
|
ef8ea13d99 | ||
|
|
df9f9f08b6 | ||
|
|
50fd27b973 | ||
|
|
81431cfcbd | ||
|
|
7af248feeb | ||
|
|
fbf0b59ff1 | ||
|
|
c5dff54e01 | ||
|
|
30c8326c3e | ||
|
|
d8cde40b49 | ||
|
|
db773e9778 | ||
|
|
33cc3a3dd9 | ||
| 66215da37a | |||
|
|
73bbe641c6 | ||
| c6f871d42b | |||
|
|
445c01d485 | ||
|
|
915b779f03 | ||
|
|
731c25741c | ||
|
|
f8d73ccbc5 | ||
|
|
f5caa1f00d | ||
|
|
769f789a43 | ||
| e3422ac0c5 | |||
|
|
cdb2cf0344 | ||
|
|
44e17eabca | ||
| 06df15717c | |||
| 813aca9d20 | |||
|
|
a363d0734c | ||
|
|
667677dcdd | ||
| 9169d844e2 | |||
| 03a5aa4da0 | |||
| 729e79eadb | |||
| ca55fccb27 | |||
| 81af1f382e | |||
|
|
cc23538244 | ||
| 20b45bc27f | |||
|
|
85cd8c8833 | ||
|
|
d6aece44aa | ||
| aba349301f | |||
| 875827d688 | |||
| d7eb8783a8 | |||
|
|
d39df2e5a1 | ||
| 4c7034648b | |||
| ec207838d4 | |||
|
|
24745c2e7a | ||
|
|
8601976498 | ||
|
|
ca042bd415 | ||
| 06a1949eaa | |||
| b11b516641 | |||
| ad5c679d2d | |||
| e81acb4c67 | |||
| aa212ae6d8 | |||
| bd3e8aee51 | |||
|
|
a1a345326a | ||
|
|
6b409303af | ||
|
|
427c4a8c33 | ||
| 763a1f4a61 | |||
|
|
12ae6a5525 | ||
|
|
2435870ec5 | ||
|
|
59be7d8635 | ||
|
|
bbedf5d174 | ||
|
|
2f598dad09 | ||
|
|
16b108f69c | ||
|
|
94c00417ff | ||
|
|
b713b94841 | ||
|
|
843a5b39c0 | ||
|
|
fa7c4d9c27 | ||
|
|
cacf4fcd97 | ||
|
|
5afeb265cd | ||
|
|
aca2bb1090 | ||
|
|
2bd90ce353 | ||
|
|
27edf5da1d | ||
|
|
7d233a04c0 | ||
|
|
c2c8cf9767 | ||
|
|
4117ceb6c1 | ||
|
|
58d2cee984 | ||
|
|
4fd1467cbf | ||
|
|
7b32d2f609 | ||
|
|
2e29dce77c | ||
|
|
e56732184f | ||
|
|
dc770299d1 | ||
|
|
18fc01cd49 | ||
|
|
c6480192f8 | ||
|
|
7a051afd97 | ||
|
|
ceab229a63 | ||
|
|
8e10f090fd | ||
|
|
a4d934913c | ||
|
|
0eece14b68 | ||
|
|
d0233a2cd0 | ||
|
|
834b53b4ec | ||
|
|
2e61839d93 | ||
|
|
e85cf466d4 | ||
| d42cbb2473 | |||
| d4adb0e6e5 | |||
| 4cf9865431 | |||
|
|
6f9caaa8c1 | ||
|
|
c489132f59 | ||
| c845055e6b | |||
|
|
a3331d009d | ||
|
|
80a09881c0 | ||
| 263b019262 | |||
| 6933b2c301 | |||
| 8db7dfef75 | |||
| f3dd71ccb1 | |||
| 8fe5c00984 | |||
| d05601ce64 | |||
|
|
1defc22caf | ||
|
|
5691df9009 | ||
| 2122448284 | |||
| 263eaf03b0 | |||
| 6cef7a437a | |||
| 0778b4f81c | |||
| 235934714f | |||
| a343ed9493 | |||
| cc68b0768b | |||
| e696d26941 | |||
| a8fcb4c153 | |||
| 1e85ae2035 | |||
| 67615d5688 | |||
| 23677b4bd3 | |||
| 5b0f917485 | |||
| b3695c42b2 | |||
| 0e5a1c9721 | |||
| b4acf329b4 | |||
|
|
8f50e4ff56 | ||
|
|
a3e2aa2a97 | ||
| 3d6d5e58a7 | |||
| cdbb42badf | |||
| 1d1f479387 | |||
|
|
a32c5a2f3c | ||
| 59ec28a5a4 | |||
| 959c90985c | |||
| 4a98c46fb9 | |||
| 40d396c7e2 | |||
| 6b44936c68 | |||
|
|
e92cdc4f14 | ||
|
|
0f738c8d9c | ||
|
|
7a354b3545 | ||
|
|
f45cb380e0 | ||
|
|
f01c2e1bd3 | ||
|
|
30c7b65150 | ||
|
|
1e514a8b61 | ||
|
|
c08557f37d | ||
|
|
6927bc614e | ||
|
|
ae61b23896 | ||
|
|
aee3290248 | ||
|
|
1efbe2d2c0 | ||
|
|
d085c0cf10 | ||
|
|
3e60b9db4a | ||
|
|
fd13770e87 | ||
|
|
5ef1848474 | ||
|
|
77c6350f03 | ||
|
|
f17e6d6a4a | ||
|
|
53823a0be5 | ||
|
|
3900267fed | ||
|
|
0a494422b7 | ||
|
|
96f1c0a709 | ||
|
|
39089284ff | ||
|
|
5a76cb3b44 | ||
|
|
92d36496df | ||
|
|
9b6caef6b5 | ||
|
|
7030d937b1 | ||
|
|
e73793c1a3 | ||
|
|
5eb801eb12 | ||
|
|
4b0ab2380c | ||
|
|
bd0926e0a5 | ||
|
|
9d79fc3d2e | ||
|
|
a0a9936e47 | ||
|
|
5e5fefb501 | ||
|
|
395d607632 | ||
|
|
db0f363967 | ||
|
|
ec463dd4c8 | ||
|
|
acbd46afcb | ||
|
|
8379fba079 | ||
|
|
4bc5c8194f | ||
|
|
ba33c15b2d | ||
|
|
0bf2d398ea | ||
|
|
ece83db6ed | ||
|
|
8ae7bc0f92 | ||
|
|
ccff6746ce | ||
|
|
450bebc8a2 | ||
|
|
cf70881370 | ||
|
|
4724e0ebc1 | ||
|
|
95010e791f | ||
|
|
33b16a56e3 | ||
|
|
cc9b6c05f6 | ||
|
|
9169acad47 | ||
|
|
aed0ecc9fc | ||
|
|
0561f60031 | ||
|
|
e66421d34f | ||
|
|
8462068a05 | ||
|
|
8a8b5b4f44 | ||
|
|
bc7c543530 | ||
|
|
f22dab0f72 | ||
|
|
002025231e | ||
|
|
061d2b394c | ||
|
|
d3f954bdac | ||
|
|
c80a90e81e | ||
|
|
b903c81a0a | ||
|
|
f72c2dcaa5 | ||
|
|
6b759ff54e | ||
|
|
041dc8256f | ||
|
|
b79ebf1d40 | ||
|
|
0bf2f0e92a | ||
|
|
04852ac1d9 | ||
|
|
5fa0a16302 | ||
|
|
4edb428954 | ||
|
|
ff9d736073 | ||
|
|
b2890262fb | ||
|
|
0a6b8f139e | ||
|
|
529b40b66c | ||
|
|
2a2fa94b03 | ||
|
|
58c6429209 | ||
|
|
5c16dd11f4 | ||
|
|
bd6bdddcde | ||
|
|
fe334d8739 | ||
|
|
69cc265fea | ||
|
|
17e9fb0d3c | ||
|
|
b676343b02 | ||
|
|
c838f4f422 | ||
|
|
e244fbccc2 | ||
|
|
36edbf393b | ||
|
|
258174d4e1 | ||
|
|
fdd3e15b2f | ||
|
|
94e0ef77a9 | ||
|
|
06671b8d66 | ||
|
|
1783904cb6 | ||
|
|
9f16284595 | ||
|
|
af15cc60eb | ||
|
|
e79d4e66f3 | ||
|
|
82ebdccdb2 | ||
| 75fd425ef6 | |||
|
|
ec9749ab85 | ||
|
|
9385c33729 | ||
|
|
7b536ee079 | ||
|
|
0c41026df0 | ||
|
|
b0d4993344 | ||
|
|
35e576a839 | ||
|
|
69ec1216dc | ||
|
|
19e82a5150 | ||
|
|
965d4c7af0 | ||
|
|
17b0de8062 | ||
|
|
895bbec277 | ||
|
|
17f773c6cb | ||
|
|
dc74b46e11 | ||
|
|
148c177d27 | ||
|
|
c94f0918c9 | ||
|
|
54de6c6878 | ||
|
|
acb7ad78e8 | ||
|
|
0a453e9dca | ||
|
|
0a7fd6f79a | ||
|
|
a7cd2f4d9b | ||
|
|
e43517efe6 | ||
|
|
b459790b2f | ||
|
|
66b7c6522e | ||
|
|
3a959778fe | ||
|
|
db3cd33bca | ||
|
|
6499139a49 | ||
|
|
f83ad8bbe4 | ||
|
|
819c58df7c | ||
|
|
4e2c352ab9 | ||
|
|
b2c88bb6a7 | ||
|
|
e2bfdcd174 | ||
|
|
22a00de8cd | ||
|
|
68c600facc | ||
|
|
a49f9dc586 | ||
|
|
6be274b259 | ||
|
|
24d443537a | ||
|
|
3d1283675f | ||
|
|
ad52facef7 | ||
|
|
55def02c8f | ||
|
|
6905120ac6 | ||
|
|
5ffb57d92c | ||
|
|
87d3ac15bd | ||
|
|
1c116fb0c4 | ||
|
|
1c43d7f38c | ||
|
|
78fbe3c7fe | ||
|
|
4ef5508347 | ||
|
|
afa38ae890 | ||
|
|
352f654ede | ||
|
|
2bc9f8f66d | ||
|
|
5fbb1e9cc2 | ||
|
|
7c80c12b90 | ||
|
|
9021c5209f | ||
|
|
6c5c6b7b8e | ||
|
|
a60738f78f | ||
|
|
b077bd937d | ||
|
|
1607b506c8 | ||
|
|
42f6f2f10b | ||
|
|
788cd3f807 | ||
|
|
d5a18af0e8 | ||
|
|
cabd220a66 | ||
|
|
e397ed310e | ||
|
|
1122f50c7c | ||
|
|
d9874b452e | ||
|
|
0253a1fcb4 | ||
|
|
a22e1bd53d | ||
|
|
56765d355b | ||
|
|
417a1a7485 | ||
|
|
204f03fd2a | ||
|
|
b297d21a8d | ||
|
|
f41e8292e8 | ||
|
|
3de2c3bfc6 | ||
|
|
a6ed435038 | ||
|
|
679f077772 | ||
|
|
9cfb9a0de6 | ||
|
|
56521d35d0 | ||
|
|
72b3812716 | ||
|
|
b7d7146821 | ||
|
|
6ac90f98d1 | ||
|
|
42e20d6db5 | ||
|
|
b8c1f7629e | ||
|
|
448e888d69 | ||
|
|
ae6980966d | ||
|
|
579cf590b4 | ||
|
|
f7009b499b | ||
|
|
84cf79906b | ||
|
|
933cdee414 | ||
|
|
77459af1d3 | ||
|
|
828c457614 | ||
|
|
6ba9eea993 | ||
|
|
fe178bf745 | ||
|
|
c6f220ee31 | ||
|
|
dc2bd76aba | ||
|
|
f0a4324bd4 | ||
|
|
0d0949f5f0 | ||
|
|
13980c4133 | ||
|
|
dac8ec621c | ||
| 026654b0d0 | |||
|
|
59afc63a2f | ||
|
|
344af924fe | ||
|
|
676611ed6f | ||
|
|
4cd38f1174 | ||
|
|
910448b0e7 | ||
|
|
477b629faf | ||
| f6558aa31e | |||
|
|
4f1df372a2 | ||
|
|
1e01423a93 | ||
|
|
20037d12f7 | ||
|
|
f605451693 | ||
|
|
fa747a27db | ||
|
|
02bf5937dc | ||
|
|
ef194f8796 | ||
|
|
20789bab7f | ||
|
|
e248b74ee6 | ||
|
|
e11260a2fe | ||
|
|
24f8ea21db | ||
|
|
6fc0683ce9 | ||
|
|
15831e8d6c | ||
|
|
2a5f3b8072 | ||
|
|
850ae40f05 | ||
|
|
3bb1491f09 | ||
|
|
a9389fcabf | ||
|
|
7cf458cff2 | ||
|
|
2bfff2933a | ||
|
|
46f375a58e | ||
|
|
097af41392 | ||
|
|
67d5061416 | ||
|
|
d69a4ffaf0 | ||
|
|
84a376b425 | ||
|
|
179d44fdd3 | ||
|
|
2f2e670ef3 | ||
|
|
01ed5106b9 | ||
|
|
60ba78d639 | ||
|
|
3ede7006f9 | ||
|
|
df77997b0b | ||
|
|
7dd7fdaf71 | ||
|
|
789c0890ca | ||
|
|
d883536ebd | ||
|
|
fa714aa843 | ||
|
|
9dfa401b27 | ||
|
|
4ff84e0730 | ||
|
|
70af1f9314 | ||
|
|
24aaa04954 | ||
|
|
ae06188871 | ||
|
|
3eb319af5b | ||
|
|
3de3932503 | ||
|
|
470bc65239 | ||
|
|
304b03b1d1 | ||
|
|
d9d27a88fc | ||
|
|
3fb61f068b | ||
|
|
2221945dc8 | ||
|
|
03fd073e76 | ||
|
|
0415ada289 | ||
|
|
b7b182c57c | ||
|
|
150dec1cc2 | ||
|
|
01230e2575 | ||
|
|
03e2a855b1 | ||
|
|
77826c8691 | ||
|
|
b529b7d3a0 | ||
|
|
e5f7d164cb | ||
|
|
c1903ca12d | ||
|
|
4796b551ad | ||
|
|
590ccc78aa | ||
|
|
eef2ed0b4c | ||
|
|
9a7654806f | ||
|
|
72e2d24c67 | ||
|
|
dc39acaa75 | ||
|
|
f914799b62 | ||
|
|
0f3fafde4b | ||
|
|
852ec4d990 | ||
|
|
30fa4c2aa9 | ||
|
|
b21a88d1b0 | ||
|
|
5e7566c89a | ||
|
|
adab6cf96f | ||
|
|
f7b3a1ef10 | ||
|
|
a19454f7ae | ||
|
|
8ed7690b96 | ||
|
|
4d19459015 | ||
|
|
a9c0cfd9c8 | ||
|
|
227b82c446 | ||
|
|
cca5b79e91 | ||
|
|
329d3d66b3 | ||
|
|
cb9ce85bda | ||
|
|
7aed5f0500 | ||
|
|
a92e05c640 | ||
|
|
f1525028da | ||
|
|
f2b3b0bf66 | ||
|
|
64a78532ed | ||
|
|
a9da275673 | ||
|
|
f74cc9cb10 | ||
|
|
975654f8e2 | ||
|
|
73718fe9af | ||
|
|
a06fa39a5d | ||
|
|
03d4d84eeb | ||
|
|
eb18115c99 | ||
|
|
1100c57e2d | ||
|
|
a591dbfe9c | ||
|
|
74013e07a8 | ||
|
|
d78b2404e2 | ||
|
|
9f895205d4 | ||
|
|
1ddf7d1f94 | ||
|
|
4d6991ea4b | ||
|
|
15e8343e75 | ||
|
|
4198379aa8 | ||
|
|
df369612be | ||
|
|
f02165b912 | ||
|
|
203e75ef3d | ||
|
|
14fc049ea0 | ||
|
|
83107d413d | ||
|
|
a15f9f38d8 | ||
|
|
00e841587d | ||
|
|
2d5d5b273a | ||
|
|
84b3386eab | ||
|
|
824ab7c0c2 | ||
|
|
d501a85c51 | ||
|
|
f53a43631c | ||
|
|
9c10a7adef | ||
|
|
bb1c7095d7 | ||
|
|
0bf03cb66e | ||
|
|
f15b716ea7 | ||
|
|
7c1f392fdf | ||
|
|
0a737eaa0d | ||
|
|
64edb88d36 | ||
|
|
1e7a2febea | ||
|
|
da0be9f226 | ||
|
|
8af1c92eff | ||
|
|
be008ca439 | ||
|
|
6e6eee71b3 | ||
|
|
2ac2dbd650 | ||
|
|
ff8d68f45c | ||
|
|
0a7d9c46eb | ||
|
|
b6fc49f057 | ||
|
|
57e28d4619 | ||
|
|
8ba3fe33f3 | ||
|
|
76c9d057cf | ||
|
|
5e605b30de | ||
|
|
e95af79c8a | ||
|
|
e84811bdce | ||
|
|
6aad799f95 | ||
|
|
6ff5ae78aa | ||
|
|
7d40585211 | ||
|
|
9440af0d67 | ||
|
|
0afba0d1d3 | ||
|
|
271e14e2f1 | ||
|
|
ac01edd440 | ||
|
|
f772fedf19 | ||
|
|
29cf7f8998 | ||
|
|
97f8e9e9fc | ||
|
|
c575294587 | ||
|
|
23e269940b | ||
|
|
7b18c81608 | ||
|
|
eae1a38705 | ||
|
|
3cb16ddb5f | ||
|
|
dcbca46e75 | ||
|
|
65b7f49c9b | ||
|
|
1006bd17e3 | ||
|
|
0700b9647b | ||
|
|
aad4ed6a83 | ||
|
|
185bed2048 | ||
|
|
9d52ee7120 | ||
|
|
0531365cb5 | ||
| f7858ab183 | |||
|
|
dfb41c7c40 | ||
|
|
c8177563e9 | ||
|
|
6f6be5ec47 | ||
|
|
54501bce2a | ||
|
|
46149b19f1 | ||
|
|
35e8a374df | ||
|
|
88af3c7681 | ||
|
|
93ddd50f76 | ||
|
|
3793b1f00b | ||
|
|
8dd376ae1e | ||
|
|
f816ce4beb | ||
|
|
6f932fe2cb | ||
|
|
49aba62dbb | ||
|
|
630d34f51c | ||
|
|
8846524541 | ||
|
|
279fa076d6 | ||
|
|
3cad0214d1 | ||
|
|
9c570b8121 | ||
|
|
2a00d50672 | ||
|
|
b05c41fe8f | ||
|
|
52fa7aaeae | ||
|
|
9f761a9ea5 | ||
|
|
337383b6fd | ||
|
|
c4dd85be53 | ||
|
|
de202ac6cc | ||
|
|
34050f641d | ||
|
|
fb18225f46 | ||
|
|
a5d527d0cf | ||
| 58229a922e | |||
| a2ed772417 | |||
|
|
e58af90c8b | ||
|
|
0d88357c85 | ||
|
|
ff2f5cb2ce | ||
|
|
0f7986ff36 | ||
|
|
f96a5e2b1a | ||
|
|
2b92bbc45f | ||
|
|
5ab326142f | ||
|
|
023b7f85fb | ||
|
|
79bcf811d6 | ||
|
|
543b231a80 | ||
|
|
c060b01037 | ||
|
|
f6a401ac6b | ||
|
|
ca8f0059a3 | ||
|
|
995042f130 | ||
|
|
259c236b72 | ||
|
|
81d25dd574 | ||
|
|
ff3e10d076 | ||
|
|
9b1fbe6c2c | ||
|
|
ed151e6d45 | ||
|
|
932128a084 | ||
|
|
8c6ef98b22 | ||
|
|
9e032223eb | ||
|
|
830cf22beb | ||
|
|
d7294bda55 | ||
|
|
49c1cb3aff | ||
|
|
834b87f4b2 | ||
|
|
180db5dea5 | ||
|
|
95d1c65011 | ||
|
|
bb508e91c1 | ||
|
|
94e32a5773 | ||
|
|
6427b097ab | ||
|
|
22de531ab3 | ||
|
|
b6453376e4 | ||
|
|
74742771c4 | ||
|
|
833ed8a40d | ||
|
|
c8991666d2 | ||
|
|
e31dc35733 | ||
|
|
5767ebea38 | ||
|
|
6500b62c52 | ||
|
|
4a1928ba92 | ||
|
|
6350d8e135 | ||
|
|
1dd5ac0ecb | ||
|
|
b42c4db400 | ||
|
|
dca1361bac | ||
|
|
f7cf0010db | ||
|
|
1073a2e2d1 | ||
|
|
b6648ff596 | ||
|
|
3a7db82004 | ||
|
|
cd3540b085 | ||
|
|
c7c1500c5e | ||
|
|
0316b2189d | ||
|
|
67ca452993 | ||
|
|
0bad9d7186 | ||
|
|
960b090702 | ||
|
|
ecbf886e52 | ||
|
|
da5b290809 | ||
|
|
d1e0a73f36 | ||
|
|
a9dc0e0dac | ||
|
|
22e6caa0e6 | ||
|
|
11ade05510 | ||
|
|
ef7dd0f069 | ||
|
|
417ff818d3 | ||
|
|
82a1c8a765 | ||
|
|
1f083cb168 | ||
|
|
51600a5329 | ||
|
|
140c736bef | ||
|
|
9b085faf07 | ||
|
|
619eec8335 | ||
|
|
e4de42659e | ||
|
|
bd609dfc90 | ||
|
|
50512cdef8 | ||
|
|
56f860676d | ||
|
|
3b90669d03 | ||
|
|
ecd717702d | ||
|
|
18d797150e | ||
|
|
8c16127115 | ||
|
|
f22bf24663 | ||
|
|
fdd4e3cc80 | ||
|
|
e91222b504 | ||
|
|
72ffe50ca6 | ||
|
|
7f1e392be2 | ||
|
|
51a9f61e88 | ||
|
|
293aaff2a5 | ||
|
|
f185c8b5db | ||
|
|
a38765d02d | ||
|
|
59f053433c | ||
| a923a2baa7 | |||
| f68f683e22 | |||
|
|
0dfc962df5 | ||
|
|
cf6f69ba93 | ||
|
|
4a3d341c9a | ||
|
|
78a04c90e6 | ||
|
|
9b0ba22ef9 | ||
|
|
0d910e3307 | ||
|
|
b1e700e2a2 | ||
|
|
a6190fe29d | ||
|
|
cf79175500 | ||
|
|
a1f003edd9 | ||
|
|
0780824e31 | ||
|
|
4cf2f4e7c7 | ||
|
|
53c9467bec | ||
|
|
157977e267 | ||
|
|
e714cacc58 | ||
|
|
ac20be8744 | ||
|
|
2681ab3828 | ||
|
|
7a55db3f21 | ||
|
|
5281253f66 | ||
|
|
7bead89e39 | ||
|
|
002f3b6c0e | ||
|
|
a873de5e9e | ||
|
|
73ef2e6c59 | ||
|
|
b46f833e23 | ||
|
|
e01a7be08e | ||
|
|
b35a367ed1 | ||
|
|
e967bf2398 | ||
|
|
9387e88dc0 | ||
|
|
eede772b53 | ||
|
|
bcb0454916 | ||
|
|
d2fe15679c | ||
|
|
c48f4b08a2 | ||
|
|
bfcce19649 | ||
| 0db954fa72 | |||
|
|
6e33f5e545 | ||
|
|
eab32c68f3 | ||
|
|
fe5814d5ba | ||
|
|
50221fbd65 | ||
|
|
6f2e306c7e | ||
|
|
a59ea5e245 | ||
|
|
0add6853bf | ||
|
|
393cce885b | ||
|
|
b580f19825 | ||
| 17e4f2536b | |||
| 595afc4a93 | |||
|
|
ca287db536 | ||
|
|
994382b801 | ||
|
|
d9348054f1 | ||
|
|
713cb6c6e5 | ||
|
|
d7b443d51b | ||
|
|
af05371c09 | ||
|
|
9dc38e87cd | ||
|
|
932bf7ca60 | ||
|
|
2dd96198af | ||
|
|
7dadc4ce77 | ||
|
|
34f1d4002b | ||
|
|
3845dc77f9 | ||
|
|
3163c91a4a | ||
| 7e4be6fdb6 | |||
| 4b8712b0f5 | |||
| 2f064f0145 | |||
| 0a9d4d0d66 | |||
| bcfa1fb906 | |||
| 3c3a3dba8f | |||
|
|
f760ef456c | ||
|
|
1ba48ecd64 | ||
|
|
57ba0cde37 | ||
|
|
a409132f69 | ||
|
|
0c006b4007 | ||
|
|
498a9c0be4 | ||
|
|
26dd78fff7 | ||
|
|
54810fd5ef | ||
|
|
27dace206b | ||
|
|
a54687671a | ||
|
|
e0ef02bfdb | ||
|
|
18d33933d4 |
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
||||
.git
|
||||
Dockerfile
|
||||
*.md
|
||||
logo.png
|
||||
versions.txt
|
||||
build.sh
|
||||
docker-compose.yml
|
||||
.env
|
||||
docker/__pycache__
|
||||
.env.example
|
||||
76
.editorconfig
Normal file
76
.editorconfig
Normal file
@@ -0,0 +1,76 @@
|
||||
# top-most EditorConfig file
|
||||
root=true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
indent_style=tab
|
||||
tab_width=4
|
||||
charset=utf-8
|
||||
trim_trailing_whitespace=true
|
||||
end_of_line=lf
|
||||
insert_final_newline=true
|
||||
|
||||
[*.{c++,cc,cpp,cxx,h,h++,hh,hpp,hxx,inl,ipp,tlh,tli}]
|
||||
|
||||
vc_generate_documentation_comments=doxygen_slash_star
|
||||
|
||||
cpp_indent_braces=false
|
||||
cpp_alignment_tab_fill_style=use_spaces
|
||||
cpp_indent_multi_line_relative_to=innermost_parenthesis
|
||||
cpp_indent_within_parentheses=indent
|
||||
cpp_indent_preserve_within_parentheses=false
|
||||
cpp_indent_case_labels=false
|
||||
cpp_indent_case_contents=true
|
||||
cpp_indent_case_contents_when_block=false
|
||||
cpp_indent_lambda_braces_when_parameter=true
|
||||
cpp_indent_goto_labels=one_left
|
||||
cpp_indent_preprocessor=leftmost_column
|
||||
cpp_indent_access_specifiers=false
|
||||
cpp_indent_namespace_contents=true
|
||||
cpp_indent_preserve_comments=false
|
||||
cpp_new_line_before_open_brace_namespace=same_line
|
||||
cpp_new_line_before_open_brace_type=same_line
|
||||
cpp_new_line_before_open_brace_function=same_line
|
||||
cpp_new_line_before_open_brace_block=same_line
|
||||
cpp_new_line_before_open_brace_lambda=same_line
|
||||
cpp_new_line_scope_braces_on_separate_lines=false
|
||||
cpp_new_line_close_brace_same_line_empty_type=false
|
||||
cpp_new_line_close_brace_same_line_empty_function=false
|
||||
cpp_new_line_before_catch=false
|
||||
cpp_new_line_before_else=false
|
||||
cpp_new_line_before_while_in_do_while=false
|
||||
cpp_space_before_function_open_parenthesis=remove
|
||||
cpp_space_within_parameter_list_parentheses=false
|
||||
cpp_space_between_empty_parameter_list_parentheses=false
|
||||
cpp_space_after_keywords_in_control_flow_statements=true
|
||||
cpp_space_within_control_flow_statement_parentheses=false
|
||||
cpp_space_before_lambda_open_parenthesis=false
|
||||
cpp_space_within_cast_parentheses=false
|
||||
cpp_space_after_cast_close_parenthesis=false
|
||||
cpp_space_within_expression_parentheses=false
|
||||
cpp_space_before_block_open_brace=true
|
||||
cpp_space_between_empty_braces=false
|
||||
cpp_space_before_initializer_list_open_brace=false
|
||||
cpp_space_within_initializer_list_braces=true
|
||||
cpp_space_preserve_in_initializer_list=true
|
||||
cpp_space_before_open_square_bracket=false
|
||||
cpp_space_within_square_brackets=false
|
||||
cpp_space_before_empty_square_brackets=false
|
||||
cpp_space_between_empty_square_brackets=false
|
||||
cpp_space_group_square_brackets=true
|
||||
cpp_space_within_lambda_brackets=false
|
||||
cpp_space_between_empty_lambda_brackets=false
|
||||
cpp_space_before_comma=false
|
||||
cpp_space_after_comma=true
|
||||
cpp_space_remove_around_member_operators=true
|
||||
cpp_space_before_inheritance_colon=true
|
||||
cpp_space_before_constructor_colon=true
|
||||
cpp_space_remove_before_semicolon=true
|
||||
cpp_space_after_semicolon=false
|
||||
cpp_space_remove_around_unary_operator=true
|
||||
cpp_space_around_binary_operator=insert
|
||||
cpp_space_around_assignment_operator=insert
|
||||
cpp_space_pointer_reference_alignment=left
|
||||
cpp_space_around_ternary_operator=insert
|
||||
cpp_wrap_preserve_blocks=one_liners
|
||||
cpp_indent_comment=fasle
|
||||
17
.env.example
Normal file
17
.env.example
Normal file
@@ -0,0 +1,17 @@
|
||||
# Full path to the LEGO Universe client
|
||||
CLIENT_PATH=/Users/someuser/LEGO Universe
|
||||
# Can improve build time
|
||||
BUILD_THREADS=1
|
||||
# Updates NET_VERSION in CMakeVariables.txt
|
||||
BUILD_VERSION=171022
|
||||
# make sure this is a long random string
|
||||
# grab a "SHA 256-bit Key" from here: https://keygen.io/
|
||||
ACCOUNT_MANAGER_SECRET=
|
||||
# Should be the externally facing IP of your server host
|
||||
EXTERNAL_IP=localhost
|
||||
# Database values
|
||||
# Be careful with special characters here. It is more safe to use normal characters and/or numbers.
|
||||
MARIADB_USER=darkflame
|
||||
MARIADB_PASSWORD=SECRET_VALUE_CHANGE_ME
|
||||
MARIADB_ROOT_PASSWORD=SECRET_VALUE_CHANGE_ME
|
||||
MARIADB_DATABASE=darkflame
|
||||
8
.git-blame-ignore-revs
Normal file
8
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,8 @@
|
||||
# format codebase
|
||||
19e77a38d837ce781ba0ca6ea8e78b67a6e3b5a5
|
||||
|
||||
# add semi-colons to macros consistently
|
||||
9e4ce24fd2851e65df776dd9c57bcb0d45f4453a
|
||||
|
||||
# convert to unix line endings
|
||||
72477e01e2711e0f61cdb192ee266e5e21b8846f
|
||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
60
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
60
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: Bug Report
|
||||
description: Report incorrect behavior in DarkflameServer
|
||||
title: "BUG: "
|
||||
labels: ["bug", "triage"]
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: "Make sure you've done the following:"
|
||||
options:
|
||||
- label: >
|
||||
I have checked that this issue has not already been reported.
|
||||
required: true
|
||||
- label: >
|
||||
I have validated that this issue is not a syntax error of either MySQL or SQLite.
|
||||
required: true
|
||||
- label: >
|
||||
I have pulled the latest version of the main branch of DarkflameServer and have confirmed that the issue exists there.
|
||||
required: true
|
||||
- type: input
|
||||
id: server-version
|
||||
attributes:
|
||||
label: DarkflameServer Version
|
||||
description: >
|
||||
DarkflameServer version or commit SHA (can be obtained with `git rev-parse --short HEAD`)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Issue Description
|
||||
description: >
|
||||
Please provide a description of the issue. If this is an in-game bug, please also include pictures that showcase the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: >
|
||||
Please provide a concise list of steps needed to reproduce this issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: >
|
||||
Please describe what you expected to happen instead of the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: >
|
||||
Please include the environment you're running DarkflameServer on (for example: Windows, macOS, Ubuntu, WSL, etc).
|
||||
validations:
|
||||
required: true
|
||||
44
.github/ISSUE_TEMPLATE/documentation_improvement.yaml
vendored
Normal file
44
.github/ISSUE_TEMPLATE/documentation_improvement.yaml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Documentation Improvement
|
||||
description: Report wrong or missing documentation
|
||||
title: "DOC: "
|
||||
labels: ["docs", "triage"]
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: "Make sure you've done the following:"
|
||||
options:
|
||||
- label: >
|
||||
I have checked that this issue has not already been reported.
|
||||
required: true
|
||||
- label: >
|
||||
I have validated that the documentation is wrong or missing on the latest version of the main branch of DarkflameServer
|
||||
required: true
|
||||
- type: textarea
|
||||
id: location
|
||||
attributes:
|
||||
label: Location of the documentation
|
||||
description: >
|
||||
Please provide the location of the documentation, e.g. "Entity.cpp" or the
|
||||
URL of the documentation, e.g.
|
||||
"https://github.com/DarkflameUniverse/DarkflameServer/blob/main/README.md"
|
||||
placeholder: https://github.com/DarkflameUniverse/DarkflameServer/blob/main/README.md
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Documentation problem
|
||||
description: >
|
||||
Please provide a description of what documentation you believe needs to be fixed/improved
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: suggested-fix
|
||||
attributes:
|
||||
label: Suggested fix for documentation
|
||||
description: >
|
||||
Please explain the suggested fix and **why** it's better than the existing documentation
|
||||
validations:
|
||||
required: true
|
||||
40
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
40
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for DarkflameServer
|
||||
title: "ENH: "
|
||||
labels: ["enhancement", "triage"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Is your feature request related to a problem?
|
||||
description: >
|
||||
Please provide a description of what the problem is, e.g. "I wish I could use DarkflameServer to do [...]"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: >
|
||||
Please provide a description of the feature request, e.g. "`SlashCommandHandler.cpp` should get a new command `/unlimited-coins` that [...]", try to write a docstring for the desired feature
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: implications
|
||||
attributes:
|
||||
label: Repository breaking implications
|
||||
description: >
|
||||
Please provide a description of how this feature will affect the DarkflameServer repository
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: >
|
||||
Please provide a description of any alternative solutions or features you've considered
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: >
|
||||
Please add any other context, code examples, or references to existing implementations about the feature request here
|
||||
62
.github/ISSUE_TEMPLATE/installation_issue.yaml
vendored
Normal file
62
.github/ISSUE_TEMPLATE/installation_issue.yaml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Installation Issue
|
||||
description: Report issues installing the DarkflameServer on your system
|
||||
title: "BUILD: "
|
||||
labels: ["build", "triage"]
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: "Make sure you've done the following:"
|
||||
options:
|
||||
- label: >
|
||||
I have read the [installation guide](https://github.com/DarkflameUniverse/DarkflameServer/blob/main/README.md).
|
||||
required: true
|
||||
- type: input
|
||||
id: server-version
|
||||
attributes:
|
||||
label: DarkflameServer Version
|
||||
description: >
|
||||
DarkflameServer version or commit SHA (can be obtained with `git rev-parse --short HEAD`)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform
|
||||
description: >
|
||||
Please provide on which platform you've tried to install DarkflameServer
|
||||
options:
|
||||
- Windows
|
||||
- WSL1
|
||||
- WSL2
|
||||
- macOS
|
||||
- Ubuntu
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: architecture
|
||||
attributes:
|
||||
label: Architecture
|
||||
description: >
|
||||
Please provide on which architecture you've tried to install DarkflameServer
|
||||
options:
|
||||
- x86
|
||||
- ARM
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Error Logs
|
||||
description: >
|
||||
If possible, please copy and paste the error logs when attempting to install DarkflameServer.
|
||||
value: >
|
||||
<details>
|
||||
|
||||
|
||||
Replace this line with the error logs.
|
||||
|
||||
|
||||
</details>
|
||||
50
.github/ISSUE_TEMPLATE/performance_issue.yaml
vendored
Normal file
50
.github/ISSUE_TEMPLATE/performance_issue.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Performance Issue
|
||||
description: Report slow performance or memory issues when running DarkflameServer
|
||||
title: "PERF: "
|
||||
labels: ["performance", "triage"]
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: "Make sure you've done the following:"
|
||||
options:
|
||||
- label: >
|
||||
I have checked that this issue has not already been reported.
|
||||
required: true
|
||||
- label: >
|
||||
I have pulled the latest version of the main branch of DarkflameServer and have confirmed that the issue exists there.
|
||||
required: true
|
||||
- type: input
|
||||
id: server-version
|
||||
attributes:
|
||||
label: DarkflameServer Version
|
||||
description: >
|
||||
DarkflameServer version or commit SHA (can be obtained with `git rev-parse --short HEAD`)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: >
|
||||
Please include the environment you're running DarkflameServer on (for example: Windows, macOS, Ubuntu, WSL, etc), available memory, number of CPU cores.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: Reproducible Example
|
||||
description: >
|
||||
Please provide a minimal, example that quantifies slow runtime or memory issues.
|
||||
Ideally include screenshots of CPU usage or memory usage. And if possible point
|
||||
to the code that you may suspect to cause the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: prior-performance
|
||||
attributes:
|
||||
label: Prior Performance
|
||||
description: >
|
||||
If applicable, please provide the prior version of DarkflameServer and output
|
||||
of the same reproducible example where the performance issue did not exist.
|
||||
56
.github/workflows/build-and-test.yml
vendored
Normal file
56
.github/workflows/build-and-test.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
name: Build & Test (${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ windows-2022, ubuntu-20.04, macos-11 ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Add msbuild to PATH (Windows only)
|
||||
if: ${{ matrix.os == 'windows-2022' }}
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
with:
|
||||
vs-version: '[17,18)'
|
||||
msbuild-architecture: x64
|
||||
- name: Install libssl (Mac Only)
|
||||
if: ${{ matrix.os == 'macos-11' }}
|
||||
run: brew install openssl@3
|
||||
- name: cmake
|
||||
uses: lukka/run-cmake@v10
|
||||
with:
|
||||
configurePreset: "ci-${{matrix.os}}"
|
||||
buildPreset: "ci-${{matrix.os}}"
|
||||
testPreset: "ci-${{matrix.os}}"
|
||||
- name: artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
if: ${{ github.ref == 'ref/head/main' }}
|
||||
with:
|
||||
name: build-${{matrix.os}}
|
||||
path: |
|
||||
build
|
||||
!build/tests
|
||||
!build/Testing
|
||||
!build/CMakeFiles
|
||||
!build/DartConfiguration.tcl
|
||||
!build/CTestTestfile.cmake
|
||||
!build/CMakeCache.txt
|
||||
!build/build.ninja
|
||||
!build/_deps
|
||||
!build/cmake_install.cmake
|
||||
!build/*.a
|
||||
!build/*.lib
|
||||
!build/*.dir
|
||||
!build/*.vcxproj
|
||||
!build/*.vcxproj.filters
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
temp/
|
||||
cmake-build-debug/
|
||||
RelWithDebInfo/
|
||||
docker/configs
|
||||
|
||||
# Third party libraries
|
||||
thirdparty/mysql/
|
||||
@@ -114,3 +115,10 @@ CMakeFiles/TargetDirectories.txt
|
||||
# clangd
|
||||
.cache
|
||||
thirdparty/zlib-1.2.11/
|
||||
|
||||
.env
|
||||
docker/__pycache__
|
||||
|
||||
docker-compose.override.yml
|
||||
|
||||
!/tests/TestBitStreams/*.bin
|
||||
|
||||
16
.gitmodules
vendored
16
.gitmodules
vendored
@@ -10,3 +10,19 @@
|
||||
[submodule "thirdparty/libbcrypt"]
|
||||
path = thirdparty/libbcrypt
|
||||
url = https://github.com/trusch/libbcrypt.git
|
||||
[submodule "thirdparty/mariadb-connector-cpp"]
|
||||
path = thirdparty/mariadb-connector-cpp
|
||||
url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git
|
||||
ignore = dirty
|
||||
[submodule "thirdparty/docker-utils"]
|
||||
path = thirdparty/docker-utils
|
||||
url = https://github.com/lcdr/utils.git
|
||||
[submodule "thirdparty/LUnpack"]
|
||||
path = thirdparty/LUnpack
|
||||
url = https://github.com/Xiphoseer/LUnpack.git
|
||||
[submodule "thirdparty/AccountManager"]
|
||||
path = thirdparty/AccountManager
|
||||
url = https://github.com/DarkflameUniverse/AccountManager
|
||||
[submodule "thirdparty/raylib"]
|
||||
path = thirdparty/raylib
|
||||
url = https://github.com/raysan5/raylib
|
||||
|
||||
628
CMakeLists.txt
628
CMakeLists.txt
@@ -1,5 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(Darkflame)
|
||||
include(CTest)
|
||||
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Read variables from file
|
||||
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
|
||||
@@ -9,113 +12,76 @@ string(REPLACE "\n" ";" variables ${variables})
|
||||
|
||||
# Set the cmake variables, formatted as "VARIABLE #" in variables
|
||||
foreach(variable ${variables})
|
||||
# If the string contains a #, skip it
|
||||
if("${variable}" MATCHES "#")
|
||||
continue()
|
||||
endif()
|
||||
# If the string contains a #, skip it
|
||||
if(NOT "${variable}" MATCHES "#")
|
||||
|
||||
# Split the variable into name and value
|
||||
string(REPLACE "=" ";" variable ${variable})
|
||||
# Split the variable into name and value
|
||||
string(REPLACE "=" ";" variable ${variable})
|
||||
|
||||
# Check that the length of the variable is 2 (name and value)
|
||||
list(LENGTH variable length)
|
||||
if(NOT ${length} EQUAL 2)
|
||||
continue()
|
||||
endif()
|
||||
# Check that the length of the variable is 2 (name and value)
|
||||
list(LENGTH variable length)
|
||||
if(${length} EQUAL 2)
|
||||
|
||||
list(GET variable 0 variable_name)
|
||||
list(GET variable 1 variable_value)
|
||||
list(GET variable 0 variable_name)
|
||||
list(GET variable 1 variable_value)
|
||||
|
||||
# Set the variable
|
||||
set(${variable_name} ${variable_value})
|
||||
# Set the variable
|
||||
set(${variable_name} ${variable_value})
|
||||
|
||||
# Add compiler definition
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}")
|
||||
# Add compiler definition
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${variable_name}=${variable_value}")
|
||||
|
||||
message(STATUS "Variable: ${variable_name} = ${variable_value}")
|
||||
message(STATUS "Variable: ${variable_name} = ${variable_value}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# On windows it's better to build this from source, as there's no way FindZLIB is gonna find it
|
||||
if(NOT WIN32)
|
||||
find_package(ZLIB REQUIRED)
|
||||
endif()
|
||||
|
||||
# Fetch External (Non-Submodule) Libraries
|
||||
if(WIN32)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
mysql
|
||||
URL https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-8.0.27-winx64.zip
|
||||
URL_HASH MD5=e3c53f6e4d0a72fde2713f7597bf9468
|
||||
)
|
||||
|
||||
FetchContent_Declare(
|
||||
zlib
|
||||
URL http://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
|
||||
URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(zlib)
|
||||
FetchContent_MakeAvailable(mysql)
|
||||
|
||||
set(ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR})
|
||||
set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") # Why?
|
||||
add_library(ZLIB::ZLIB ALIAS zlib) # You're welcome
|
||||
|
||||
endif(WIN32)
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
else()
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
mysql
|
||||
URL https://dev.mysql.com/get/Downloads/Connector-C++/mysql-connector-c++-8.0.27-linux-glibc2.12-x86-64bit.tar.gz
|
||||
URL_HASH MD5=12f086b76c11022cc7139b41a36cdf9e
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(mysql)
|
||||
|
||||
if (__include_backtrace__ AND __compile_backtrace__)
|
||||
FetchContent_Declare(
|
||||
backtrace
|
||||
GIT_REPOSITORY https://github.com/ianlancetaylor/libbacktrace.git
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(backtrace)
|
||||
|
||||
if (NOT EXISTS ${backtrace_SOURCE_DIR}/.libs)
|
||||
set(backtrace_make_cmd "${backtrace_SOURCE_DIR}/configure --prefix=\"/usr\" --enable-shared --with-system-libunwind")
|
||||
|
||||
execute_process(
|
||||
COMMAND bash -c "cd ${backtrace_SOURCE_DIR} && ${backtrace_make_cmd} && make && cd ${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
link_directories(${backtrace_SOURCE_DIR}/.libs/)
|
||||
include_directories(${backtrace_SOURCE_DIR})
|
||||
endif(__include_backtrace__)
|
||||
|
||||
endif()
|
||||
endif(UNIX)
|
||||
|
||||
# Set the version
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}")
|
||||
# Set our compile options
|
||||
option(BUILD_VISUAL_DEBUGGER "Toggle for building visual debugger (default off)" OFF)
|
||||
|
||||
# Echo the version
|
||||
message(STATUS "Version: ${PROJECT_VERSION}")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
# Disable demo, tests and examples for recastNavigation. Turn these to ON if you want to use them
|
||||
# This has to be done here to prevent a rare build error due to missing dependencies on the initial generations.
|
||||
set(RECASTNAVIGATION_DEMO OFF CACHE BOOL "" FORCE)
|
||||
set(RECASTNAVIGATION_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
|
||||
if(WIN32)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
endif(WIN32)
|
||||
# Compiler flags:
|
||||
# Disabled deprecated warnings as the MySQL includes have deprecated code in them.
|
||||
# Disabled misleading indentation as DL_LinkedList from RakNet has a weird indent.
|
||||
# Disabled no-register
|
||||
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROJECT_VERSION=${PROJECT_VERSION}")
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC")
|
||||
endif()
|
||||
if (__dynamic AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
|
||||
endif()
|
||||
if (__ggdb)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC")
|
||||
elseif(MSVC)
|
||||
# Skip warning for invalid conversion from size_t to uint32_t for all targets below for now
|
||||
add_compile_options("/wd4267" "/utf-8")
|
||||
elseif(WIN32)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Our output dir
|
||||
set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# Create a /res directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/res)
|
||||
@@ -123,364 +89,184 @@ make_directory(${CMAKE_BINARY_DIR}/res)
|
||||
# Create a /locale directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/locale)
|
||||
|
||||
# Copy ini files on first build
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/authconfig.ini)
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/resources/authconfig.ini ${PROJECT_BINARY_DIR}/authconfig.ini
|
||||
COPYONLY
|
||||
)
|
||||
endif()
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/chatconfig.ini)
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/resources/chatconfig.ini ${PROJECT_BINARY_DIR}/chatconfig.ini
|
||||
COPYONLY
|
||||
)
|
||||
endif()
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/worldconfig.ini)
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/resources/worldconfig.ini ${PROJECT_BINARY_DIR}/worldconfig.ini
|
||||
COPYONLY
|
||||
)
|
||||
endif()
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/masterconfig.ini)
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/resources/masterconfig.ini ${PROJECT_BINARY_DIR}/masterconfig.ini
|
||||
COPYONLY
|
||||
)
|
||||
# Create a /logs directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/logs)
|
||||
|
||||
# Copy resource files on first build
|
||||
set(RESOURCE_FILES "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blacklist.dcf")
|
||||
foreach(resource_file ${RESOURCE_FILES})
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/${resource_file})
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file}
|
||||
COPYONLY
|
||||
)
|
||||
message("Moved ${resource_file} to project binary directory")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Copy vanity files on first build
|
||||
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml")
|
||||
foreach(file ${VANITY_FILES})
|
||||
configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY)
|
||||
endforeach()
|
||||
|
||||
# Move our migrations for MasterServer to run
|
||||
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/migrations/)
|
||||
file(GLOB SQL_FILES ${CMAKE_SOURCE_DIR}/migrations/dlu/*.sql)
|
||||
foreach(file ${SQL_FILES})
|
||||
get_filename_component(file ${file} NAME)
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/migrations/${file})
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/migrations/dlu/${file} ${PROJECT_BINARY_DIR}/migrations/${file}
|
||||
COPYONLY
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Create our list of include directories
|
||||
set(INCLUDED_DIRECTORIES
|
||||
"dCommon"
|
||||
"dChatFilter"
|
||||
"dGame"
|
||||
"dGame/dBehaviors"
|
||||
"dGame/dComponents"
|
||||
"dGame/dGameMessages"
|
||||
"dGame/dInventory"
|
||||
"dGame/dMission"
|
||||
"dGame/dEntity"
|
||||
"dGame/dUtilities"
|
||||
"dPhysics"
|
||||
"dNavigation"
|
||||
"dNavigation/dTerrain"
|
||||
"dZoneManager"
|
||||
"dDatabase"
|
||||
"dDatabase/Tables"
|
||||
"dNet"
|
||||
"dScripts"
|
||||
"dWorldServer"
|
||||
|
||||
"thirdparty/raknet/Source"
|
||||
"thirdparty/tinyxml2"
|
||||
"thirdparty/recastnavigation"
|
||||
"thirdparty/SQLite"
|
||||
"thirdparty/cpplinq"
|
||||
)
|
||||
|
||||
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
|
||||
if (APPLE)
|
||||
include_directories("/usr/local/include/")
|
||||
endif()
|
||||
|
||||
# Copy files to output
|
||||
configure_file("${CMAKE_SOURCE_DIR}/vanity/CREDITS.md" "${CMAKE_BINARY_DIR}/vanity/CREDITS.md" COPYONLY)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/vanity/INFO.md" "${CMAKE_BINARY_DIR}/vanity/INFO.md" COPYONLY)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/vanity/TESTAMENT.md" "${CMAKE_BINARY_DIR}/vanity/TESTAMENT.md" COPYONLY)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/vanity/NPC.xml" "${CMAKE_BINARY_DIR}/vanity/NPC.xml" COPYONLY)
|
||||
if (WIN32)
|
||||
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include")
|
||||
elseif (UNIX)
|
||||
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt")
|
||||
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include/bcrypt")
|
||||
endif()
|
||||
|
||||
# 3rdparty includes
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/)
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
include_directories(/usr/local/include/)
|
||||
include_directories(/usr/local/mysql-connector-c++/include/jdbc/)
|
||||
include_directories(/usr/local/mysql-connector-c++/include/jdbc/cppconn/)
|
||||
else()
|
||||
include_directories(${mysql_SOURCE_DIR}/include/jdbc/)
|
||||
include_directories(${mysql_SOURCE_DIR}/include/jdbc/cppconn/)
|
||||
endif(APPLE)
|
||||
endif(UNIX)
|
||||
if(WIN32)
|
||||
include_directories(${mysql_SOURCE_DIR}/include/jdbc)
|
||||
include_directories(${mysql_SOURCE_DIR}/include/jdbc/cppconn)
|
||||
endif(WIN32)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include)
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
# Bcrypt
|
||||
if (NOT WIN32)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include/bcrypt)
|
||||
else ()
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include)
|
||||
endif ()
|
||||
|
||||
# Our includes
|
||||
# Add binary directory as an include directory
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dChatFilter/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dCommon/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dBehaviors)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dComponents)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dGameMessages)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dInventory)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dMission)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dEntity)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dGame/dUtilities)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dPhysics/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dZoneManager/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dDatabase/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dDatabase/Tables/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/SQLite/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/cpplinq/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dNet/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dScripts/)
|
||||
|
||||
# Default to linking to libmysql
|
||||
set(MYSQL_LIB mysql)
|
||||
if(WIN32)
|
||||
set(MYSQL_LIB mysqlcppconn)
|
||||
endif(WIN32)
|
||||
# Actually include the directories from our list
|
||||
foreach (dir ${INCLUDED_DIRECTORIES})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/${dir})
|
||||
endforeach()
|
||||
|
||||
# Lib folders:
|
||||
# Add linking directories:
|
||||
link_directories(${PROJECT_BINARY_DIR})
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
link_directories(/usr/local/mysql-connector-c++/lib64/)
|
||||
else()
|
||||
link_directories(${mysql_SOURCE_DIR}/lib64/)
|
||||
|
||||
# Link to libmysqlcppconn on Linux
|
||||
set(MYSQL_LIB mysqlcppconn)
|
||||
endif(APPLE)
|
||||
endif(UNIX)
|
||||
if(WIN32)
|
||||
link_directories(${mysql_SOURCE_DIR}/lib64/vs14)
|
||||
endif(WIN32)
|
||||
# Load all of our third party directories
|
||||
add_subdirectory(thirdparty)
|
||||
|
||||
# Source Code
|
||||
# Glob together all headers that need to be precompiled
|
||||
file(
|
||||
GLOB SOURCES
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dWorldServer/*.cpp
|
||||
GLOB HEADERS_DDATABASE
|
||||
LIST_DIRECTORIES false
|
||||
${PROJECT_SOURCE_DIR}/dDatabase/*.h
|
||||
${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.h
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h
|
||||
)
|
||||
|
||||
# Source Code for AuthServer
|
||||
file(
|
||||
GLOB SOURCES_AUTH
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dAuthServer/*.cpp
|
||||
GLOB HEADERS_DZONEMANAGER
|
||||
LIST_DIRECTORIES false
|
||||
${PROJECT_SOURCE_DIR}/dZoneManager/*.h
|
||||
)
|
||||
|
||||
# Source Code for MasterServer
|
||||
file(
|
||||
GLOB SOURCES_MASTER
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dMasterServer/*.cpp
|
||||
GLOB HEADERS_DCOMMON
|
||||
LIST_DIRECTORIES false
|
||||
${PROJECT_SOURCE_DIR}/dCommon/*.h
|
||||
)
|
||||
|
||||
# Source Code for ChatServer
|
||||
file(
|
||||
GLOB SOURCES_CHAT
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dChatServer/*.cpp
|
||||
GLOB HEADERS_DGAME
|
||||
LIST_DIRECTORIES false
|
||||
${PROJECT_SOURCE_DIR}/dGame/Entity.h
|
||||
${PROJECT_SOURCE_DIR}/dGame/dGameMessages/GameMessages.h
|
||||
${PROJECT_SOURCE_DIR}/dGame/EntityManager.h
|
||||
${PROJECT_SOURCE_DIR}/dScripts/CppScripts.h
|
||||
)
|
||||
|
||||
# Source Code for raknet
|
||||
file(
|
||||
GLOB SOURCES_RAKNET
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/raknet/Source/*.cpp
|
||||
)
|
||||
# Add our library subdirectories for creation of the library object
|
||||
add_subdirectory(dCommon)
|
||||
add_subdirectory(dDatabase)
|
||||
add_subdirectory(dChatFilter)
|
||||
add_subdirectory(dNet)
|
||||
add_subdirectory(dScripts) # Add for dGame to use
|
||||
add_subdirectory(dGame)
|
||||
add_subdirectory(dZoneManager)
|
||||
add_subdirectory(dNavigation)
|
||||
add_subdirectory(dPhysics)
|
||||
|
||||
# Source Code for recast
|
||||
file(
|
||||
GLOB SOURCES_RECAST
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Source/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for detour
|
||||
file(
|
||||
GLOB SOURCES_DETOUR
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Source/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for tinyxml2
|
||||
file(
|
||||
GLOB SOURCES_TINYXML2
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.cpp
|
||||
)
|
||||
|
||||
# Source Code for libbcrypt
|
||||
file(
|
||||
GLOB SOURCES_LIBBCRYPT
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/*.c
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/src/*.c
|
||||
)
|
||||
|
||||
# Source Code for dCommon
|
||||
file(
|
||||
GLOB SOURCES_DCOMMON
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dCommon/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for dChatFilter
|
||||
file(
|
||||
GLOB SOURCES_DCHATFILTER
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dChatFilter/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for dDatabase
|
||||
file(
|
||||
GLOB SOURCES_DDATABASE
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dDatabase/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dDatabase/Tables/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.c
|
||||
)
|
||||
|
||||
# Source Code for dNet
|
||||
file(
|
||||
GLOB SOURCES_DNET
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dNet/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for dGame
|
||||
file(
|
||||
GLOB SOURCES_DGAME
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dGame/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dBehaviors/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dComponents/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dGameMessages/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dInventory/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dMission/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dEntity/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dGame/dUtilities/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/dScripts/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for dZoneManager
|
||||
file(
|
||||
GLOB SOURCES_DZM
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dZoneManager/*.cpp
|
||||
)
|
||||
|
||||
# Source Code for dPhysics
|
||||
file(
|
||||
GLOB SOURCES_DPHYSICS
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${PROJECT_SOURCE_DIR}/dPhysics/*.cpp
|
||||
)
|
||||
|
||||
# 3rdparty static libraries:
|
||||
#add_library(zlib ${SOURCES_ZLIB})
|
||||
add_library(raknet ${SOURCES_RAKNET})
|
||||
add_library(tinyxml2 ${SOURCES_TINYXML2})
|
||||
add_library(detour ${SOURCES_DETOUR})
|
||||
add_library(recast ${SOURCES_RECAST})
|
||||
add_library(libbcrypt ${SOURCES_LIBBCRYPT})
|
||||
|
||||
# Our static libraries:
|
||||
add_library(dCommon ${SOURCES_DCOMMON})
|
||||
add_library(dChatFilter ${SOURCES_DCHATFILTER})
|
||||
add_library(dDatabase ${SOURCES_DDATABASE})
|
||||
add_library(dNet ${SOURCES_DNET})
|
||||
add_library(dGame ${SOURCES_DGAME})
|
||||
add_library(dZoneManager ${SOURCES_DZM})
|
||||
add_library(dPhysics ${SOURCES_DPHYSICS})
|
||||
target_link_libraries(dNet dCommon) #Needed because otherwise linker errors occur.
|
||||
target_link_libraries(dCommon ZLIB::ZLIB)
|
||||
target_link_libraries(dCommon libbcrypt)
|
||||
|
||||
# Our executables:
|
||||
add_executable(WorldServer ${SOURCES})
|
||||
add_executable(AuthServer ${SOURCES_AUTH})
|
||||
add_executable(MasterServer ${SOURCES_MASTER})
|
||||
add_executable(ChatServer ${SOURCES_CHAT})
|
||||
|
||||
# Target libraries to link to:
|
||||
target_link_libraries(WorldServer dCommon)
|
||||
target_link_libraries(WorldServer dChatFilter)
|
||||
target_link_libraries(WorldServer dDatabase)
|
||||
target_link_libraries(WorldServer dNet)
|
||||
target_link_libraries(WorldServer dGame)
|
||||
target_link_libraries(WorldServer dZoneManager)
|
||||
target_link_libraries(WorldServer dPhysics)
|
||||
target_link_libraries(WorldServer detour)
|
||||
target_link_libraries(WorldServer recast)
|
||||
target_link_libraries(WorldServer raknet)
|
||||
target_link_libraries(WorldServer ${MYSQL_LIB})
|
||||
if(UNIX)
|
||||
target_link_libraries(WorldServer pthread)
|
||||
target_link_libraries(WorldServer dl)
|
||||
|
||||
if(NOT APPLE AND __include_backtrace__)
|
||||
target_link_libraries(WorldServer backtrace)
|
||||
target_link_libraries(MasterServer backtrace)
|
||||
target_link_libraries(AuthServer backtrace)
|
||||
target_link_libraries(ChatServer backtrace)
|
||||
if (BUILD_VISUAL_DEBUGGER)
|
||||
add_subdirectory(dVisualDebugger)
|
||||
endif()
|
||||
|
||||
endif(UNIX)
|
||||
if(WIN32)
|
||||
target_link_libraries(WorldServer ws2_32)
|
||||
endif(WIN32)
|
||||
target_link_libraries(WorldServer tinyxml2)
|
||||
# Create a list of common libraries shared between all binaries
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp")
|
||||
|
||||
# Target libraries for Auth:
|
||||
target_link_libraries(AuthServer dCommon)
|
||||
target_link_libraries(AuthServer dDatabase)
|
||||
target_link_libraries(AuthServer dNet)
|
||||
target_link_libraries(AuthServer raknet)
|
||||
target_link_libraries(AuthServer ${MYSQL_LIB})
|
||||
if(UNIX)
|
||||
target_link_libraries(AuthServer pthread)
|
||||
target_link_libraries(AuthServer dl)
|
||||
endif(UNIX)
|
||||
if(WIN32)
|
||||
target_link_libraries(AuthServer ws2_32)
|
||||
endif(WIN32)
|
||||
# Add platform specific common libraries
|
||||
if (UNIX)
|
||||
set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "dl" "pthread")
|
||||
|
||||
# Target libraries for Master:
|
||||
target_link_libraries(MasterServer dCommon)
|
||||
target_link_libraries(MasterServer dDatabase)
|
||||
target_link_libraries(MasterServer dNet)
|
||||
target_link_libraries(MasterServer raknet)
|
||||
target_link_libraries(MasterServer ${MYSQL_LIB})
|
||||
if(UNIX)
|
||||
target_link_libraries(MasterServer pthread)
|
||||
target_link_libraries(MasterServer dl)
|
||||
endif(UNIX)
|
||||
if(WIN32)
|
||||
target_link_libraries(MasterServer ws2_32)
|
||||
endif(WIN32)
|
||||
if (NOT APPLE AND __include_backtrace__)
|
||||
set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "backtrace")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Target libraries for Chat:
|
||||
target_link_libraries(ChatServer dCommon)
|
||||
target_link_libraries(ChatServer dChatFilter)
|
||||
target_link_libraries(ChatServer dDatabase)
|
||||
target_link_libraries(ChatServer dNet)
|
||||
target_link_libraries(ChatServer raknet)
|
||||
target_link_libraries(ChatServer ${MYSQL_LIB})
|
||||
if(UNIX)
|
||||
target_link_libraries(ChatServer pthread)
|
||||
target_link_libraries(ChatServer dl)
|
||||
endif(UNIX)
|
||||
if(WIN32)
|
||||
target_link_libraries(ChatServer ws2_32)
|
||||
endif(WIN32)
|
||||
add_subdirectory(tests)
|
||||
|
||||
# Compiler flags:
|
||||
# Disabled deprecated warnings as the MySQL includes have deprecated code in them.
|
||||
# Disabled misleading indentation as DL_LinkedList from RakNet has a weird indent.
|
||||
# Disabled no-register
|
||||
# Disabled unknown pragmas because Linux doesn't understand Windows pragmas.
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -Wno-unused-result -Wno-unknown-pragmas -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -fPIC")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17 -O2 -Wuninitialized -Wno-unused-result -Wno-unknown-pragmas -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -D_GLIBCXX_USE_CXX17_ABI=0 -static-libgcc -fPIC")
|
||||
endif()
|
||||
if (__dynamic)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
|
||||
endif()
|
||||
if (__ggdb)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fPIC")
|
||||
endif(UNIX)
|
||||
# Include all of our binary directories
|
||||
add_subdirectory(dWorldServer)
|
||||
add_subdirectory(dAuthServer)
|
||||
add_subdirectory(dChatServer)
|
||||
add_subdirectory(dMasterServer) # Add MasterServer last so it can rely on the other binaries
|
||||
|
||||
# Add our precompiled headers
|
||||
target_precompile_headers(
|
||||
dGame PRIVATE
|
||||
${HEADERS_DGAME}
|
||||
)
|
||||
|
||||
target_precompile_headers(
|
||||
dZoneManager PRIVATE
|
||||
${HEADERS_DZONEMANAGER}
|
||||
)
|
||||
|
||||
# Need to specify to use the CXX compiler language here or else we get errors including <string>.
|
||||
target_precompile_headers(
|
||||
dDatabase PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>"
|
||||
)
|
||||
|
||||
target_precompile_headers(
|
||||
dCommon PRIVATE
|
||||
${HEADERS_DCOMMON}
|
||||
)
|
||||
|
||||
target_precompile_headers(
|
||||
tinyxml2 PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>"
|
||||
)
|
||||
|
||||
126
CMakePresets.json
Normal file
126
CMakePresets.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 14,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "Default configure step",
|
||||
"description": "Use 'build' dir and Unix makefiles",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"generator": "Unix Makefiles"
|
||||
},
|
||||
{
|
||||
"name": "ci-ubuntu-20.04",
|
||||
"displayName": "CI configure step for Ubuntu",
|
||||
"description": "Same as default, Used in GitHub actions workflow",
|
||||
"inherits": "default"
|
||||
},
|
||||
{
|
||||
"name": "ci-macos-11",
|
||||
"displayName": "CI configure step for MacOS",
|
||||
"description": "Same as default, Used in GitHub actions workflow",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"OPENSSL_ROOT_DIR": "/usr/local/Cellar/openssl@3/3.0.5/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-windows-2022",
|
||||
"displayName": "CI configure step for Windows",
|
||||
"description": "Set architecture to 64-bit (b/c RakNet)",
|
||||
"inherits": "default",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"architecture": {
|
||||
"value": "x64"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-default",
|
||||
"inherits": "ci-windows-2022",
|
||||
"displayName": "Windows only Configure Settings",
|
||||
"description": "Sets build and install directories",
|
||||
"generator": "Ninja",
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"configurePreset": "default",
|
||||
"displayName": "Default Build",
|
||||
"description": "Default Build",
|
||||
"jobs": 2
|
||||
},
|
||||
{
|
||||
"name": "ci-windows-2022",
|
||||
"configurePreset": "ci-windows-2022",
|
||||
"displayName": "Windows CI Build",
|
||||
"description": "This preset is used by the CI build on windows",
|
||||
"configuration": "RelWithDebInfo",
|
||||
"jobs": 2
|
||||
},
|
||||
{
|
||||
"name": "ci-ubuntu-20.04",
|
||||
"configurePreset": "ci-ubuntu-20.04",
|
||||
"displayName": "Linux CI Build",
|
||||
"description": "This preset is used by the CI build on linux",
|
||||
"jobs": 2
|
||||
},
|
||||
{
|
||||
"name": "ci-macos-11",
|
||||
"configurePreset": "ci-macos-11",
|
||||
"displayName": "MacOS CI Build",
|
||||
"description": "This preset is used by the CI build on MacOS",
|
||||
"jobs": 2
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "ci-ubuntu-20.04",
|
||||
"configurePreset": "ci-ubuntu-20.04",
|
||||
"displayName": "CI Tests on Linux",
|
||||
"description": "Runs all tests on a linux configuration",
|
||||
"execution": {
|
||||
"jobs": 2
|
||||
},
|
||||
"output": {
|
||||
"outputOnFailure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-macos-11",
|
||||
"configurePreset": "ci-macos-11",
|
||||
"displayName": "CI Tests on MacOS",
|
||||
"description": "Runs all tests on a Mac configuration",
|
||||
"execution": {
|
||||
"jobs": 2
|
||||
},
|
||||
"output": {
|
||||
"outputOnFailure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-windows-2022",
|
||||
"configurePreset": "ci-windows-2022",
|
||||
"displayName": "CI Tests on windows",
|
||||
"description": "Runs all tests on a windows configuration",
|
||||
"configuration": "RelWithDebInfo",
|
||||
"execution": {
|
||||
"jobs": 2
|
||||
},
|
||||
"output": {
|
||||
"outputOnFailure": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
PROJECT_VERSION_MAJOR=1
|
||||
PROJECT_VERSION_MINOR=0
|
||||
PROJECT_VERSION_PATCH=0
|
||||
PROJECT_VERSION_PATCH=4
|
||||
# LICENSE
|
||||
LICENSE=AGPL-3.0
|
||||
# The network version.
|
||||
# 171023 - Darkflame Universe client
|
||||
# 171022 - Unmodded client
|
||||
NET_VERSION=171023
|
||||
NET_VERSION=171022
|
||||
# Debugging
|
||||
# __dynamic=1
|
||||
__dynamic=1
|
||||
# Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.
|
||||
# __ggdb=1
|
||||
# Set __ggdb to 1 to enable the -ggdb flag for the linker, including more debug info.
|
||||
@@ -16,3 +16,5 @@ NET_VERSION=171023
|
||||
# Set __include_backtrace__ to 1 to includes the backtrace library for better crashlogs.
|
||||
# __compile_backtrace__=1
|
||||
# Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries.
|
||||
__maria_db_connector_compile_jobs__=1
|
||||
# Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with.
|
||||
|
||||
@@ -36,23 +36,109 @@ In general, we follow the "fork-and-pull" Git workflow
|
||||
- Open a PR in our repository.
|
||||
|
||||
PRs should include (when applicable):
|
||||
- A descriptive title that covers the **entire** content of the pull request
|
||||
- Description
|
||||
- Motivation and Context
|
||||
- Type of Changes
|
||||
- How Has This Been Tested?
|
||||
- Screenshots
|
||||
|
||||
## Commits
|
||||
|
||||
Commits to this project should be concise, descriptive and to the point. Writing proper commits helps define a clear project history and makes it easier to browse the source and pinpoint issues. Although this might seem trivial, a pull request with improperly formatted commits will not be accepted. An overview of good commit practices can be found in [this](https://cbea.ms/git-commit/) article. In a nutshell, a good commit has:
|
||||
|
||||
#### one conceptual change with a subject line that reflects it
|
||||
|
||||
The subject line of the commit is what you specify when doing `git commit -m "<subject-line>"`. When making commit, make sure that you create it for one conceptual change. E.g. do not use a commit to dump all the changes you have locally, but split your changes into commits that conceptually make sense and use the subject line to refelct that. Some examples:
|
||||
|
||||
**Bad:**
|
||||
Commit message: `Document MovementAIComponent and add Avant Gardens Mech Scripts and fix Entity.cpp bug causing infinite loops`
|
||||
Changed files:
|
||||
- MovementAIComponent.cpp
|
||||
- AgMechScript.cpp
|
||||
- Entity.cpp
|
||||
|
||||
**Good:**
|
||||
|
||||
Commit message: `Document MovementAIComponent`
|
||||
Changed files:
|
||||
- MovementAIComponent.cpp
|
||||
|
||||
Commit message: `Add Avant Gardens Mech Scripts`
|
||||
Changed files:
|
||||
- AgMechScript.cpp
|
||||
|
||||
Commit message: `Fix Entity.cpp bug causing infinite loops`
|
||||
Changed files:
|
||||
- Entity.cpp
|
||||
|
||||
Not only does this logically make more sense, it'll make it easier to revert a conceptual change once something wrong with it. If you commit using the bad example but your bugfix turned out to introduce an even worse bug, all your changes have to be reverted, even though your other changes might not be broken. Splitting your commits into conceptually unique commits makes it easier to find and revert issues.
|
||||
|
||||
#### an imperative subject line
|
||||
|
||||
In the subject line it's also important to have an imperative writing style that covers the contents of your commit so that it easily reflects what it'll do when applied. We pick an imperative writing style so that all commits have equal tonality. An easy check for this is placing `When applied, this commit will ...` in front of your commit message and checking if that makes sense. Some examples:
|
||||
|
||||
**Bad:**
|
||||
```
|
||||
Nice commit :) -> "When applied, this commit will nice commit :)"
|
||||
```
|
||||
|
||||
**Bad:**
|
||||
```
|
||||
fixed bug -> "When applied, this commit will fixed bug"
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```
|
||||
Fix Entity.cpp bug causing infinite loop -> "When applied, this commit will fix Entity.cpp bug causing infinite loop"
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```
|
||||
Add Avant Gardens mech scripts -> "When applied, this commit will add Avant Gardens mech scripts"
|
||||
```
|
||||
|
||||
#### a subject line and a body
|
||||
|
||||
A good commit has a subject line that summarizes the change and a body that further describes the context required to understand the change. In this body you don't have to explain *what* the change was, as the code should reflect that, but *why* a change was made. Some examples:
|
||||
|
||||
**Bad:**
|
||||
```
|
||||
Add Avant Gardens mech scripts
|
||||
|
||||
Added the Avant Gardens mech scripts by creaing a new file called
|
||||
AgMechScripts.cpp and then adding the proper event handlers to that
|
||||
to send events to the client regarding changes of the mech.
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```
|
||||
Add Avant Gardens mech scripts
|
||||
|
||||
Added the Avant Gardens mech scripts as they were previously not
|
||||
added, which produced InvalidScript errors.
|
||||
```
|
||||
|
||||
## Development Resources
|
||||
|
||||
Check out a compiled list of development resources and tools [here](https://lu-dev.net/).
|
||||
|
||||
|
||||
Please use [.editorconfig](https://editorconfig.org/#pre-installed) with your preferred IDE.
|
||||
|
||||
And run:
|
||||
```bash
|
||||
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
```
|
||||
to ignore the gitblame of mass formatting commits
|
||||
|
||||
## Coding Style
|
||||
|
||||
This project has gone through multiple iterations of coding style. In the code you'll find a number of different coding styles in use. What follows is the preferred style for this project.
|
||||
|
||||
### General
|
||||
|
||||
Use 4 spaces instead of the tab character.
|
||||
**Never** use spaces instead of tabs. 1 Tab = 4 space character's width by default.
|
||||
|
||||
Use typically trailing braces everywhere (if, else, functions, structures, typedefs, class definitions, etc.)
|
||||
|
||||
@@ -77,7 +163,7 @@ if (x) {
|
||||
}
|
||||
```
|
||||
|
||||
Instead of
|
||||
Instead of
|
||||
|
||||
```cpp
|
||||
if ( x ) {
|
||||
|
||||
46
Docker.md
Normal file
46
Docker.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Run the Darkflame Server inside Docker
|
||||
|
||||
## What you need
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker)
|
||||
- [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop)
|
||||
- LEGO® Universe packed Client. Check the main [README](./README.md) for details on this.
|
||||
|
||||
## Run server inside Docker
|
||||
|
||||
1. Copy `.env.example` and save it as `.env` inside the root directory of this repository
|
||||
2. Edit the `.env` file and add your path to the root directory of your LEGO® Universe Client after `CLIENT_PATH=`
|
||||
3. Update other values in the `.env` file as needed (be sure to update passwords!)
|
||||
4. Run `docker compose up -d --build`
|
||||
5. Run `docker compose exec darkflame /app/MasterServer -a` and setup your admin account
|
||||
6. Follow the directions [here](https://github.com/DarkflameUniverse/AccountManager) to setup regular user accounts. The server will be accessible at: `http://<EXTERNAL_IP>:5000`
|
||||
7. Now you can see the output of the server with `docker compose logs -f --tail 100` or `docker compose logs -f --tail 100`. This can help you understand issues and there you can also see when the server finishes it's startup.
|
||||
8. You're ready to connect your client!
|
||||
|
||||
**NOTE #1**: If you're running an older version of Docker, you may need to use the command `docker-compose` instead of `docker compose`.
|
||||
|
||||
**NOTE #2**: To stop the server simply run `docker compose down` and to restart it just run `docker compose up -d` again. No need to run all the steps above every time.
|
||||
|
||||
**NOTE #3**: Docker buildkit needs to be enabled. https://docs.docker.com/develop/develop-images/build_enhancements/#to-enable-buildkit-builds
|
||||
|
||||
**NOTE #4**: Make sure to run the following in the repo root directory after cloning so submodules are also downloaded.
|
||||
```
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
**NOTE #5**: If DarkflameSetup fails due to not having cdclient.fdb, rename CDClient.fdb (in the same folder) to cdclient.fdb
|
||||
|
||||
## Disable brickbuildfix
|
||||
|
||||
If you don't need the http server running on port 80 do this:
|
||||
|
||||
1. Create a file with the name `docker-compose.override.yml` in the root of the repository
|
||||
2. Paste this content:
|
||||
|
||||
```yml
|
||||
services:
|
||||
brickbuildfix:
|
||||
profiles:
|
||||
- donotstart
|
||||
```
|
||||
|
||||
3. Now run `docker compose up -d`
|
||||
58
Docker_Windows.md
Normal file
58
Docker_Windows.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Installation under Windows
|
||||
## First Run
|
||||
1. Navigate to the [Docker download page](https://www.docker.com/products/docker-desktop) and download docker.
|
||||
|
||||

|
||||
|
||||
2. Once the file has finished downloading, run it and proceed through the installation. Make sure, "Install required Windows components for WSL 2" is checked.
|
||||
|
||||

|
||||
|
||||
3. If necessary, restart your computer.
|
||||
4. After the restart, Docker Desktop will automatically open. If it does not, simply start it like any other program.
|
||||
5. If a window "WSL 2 Installation is incomplete." pops up, follow the link and click "WSL2 Linux kernel update package for x64 machines". Run the downloaded file and once that finishes, click "Restart" in the Docker Desktop window.
|
||||
|
||||

|
||||
|
||||
6. Wait until Docker Desktop has started. You may skip the tutorial.
|
||||
7. You may want to disable "Open Docker Dashboard at startup" in _Settings_ -> _General_
|
||||
|
||||

|
||||
|
||||
8. Install [Git for Windows](https://git-scm.com/download/win). During the installation, simply confirming the defaults is sufficient.
|
||||
9. In the folder you wish to save the Server, right click and select "Git Bash Here".
|
||||
10. Type `git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer`
|
||||
11. Once the command has completed (you can see you path again and can enter commands), close the window.
|
||||
12. Inside the downloaded folder, copy `.env.example` and name the copy `.env`
|
||||
13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_.
|
||||
14. Change the text after `CLIENT_PATH=` to the location of your client. The folder you are pointing to must contain a folder called `client` which should contain the client files.
|
||||
> If you need the extra performance, place the client files in `\\wsl$\<your linux OS>\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems).
|
||||
|
||||
15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value.
|
||||
16. After `ACCOUNT_MANAGER_SECRET=` paste a "SHA 256-bit Key" from https://keygen.io/
|
||||
17. If you are not only hosting a local server, change the value after `EXTERNAL_IP=` to the external IP address of your computer.
|
||||
18. Change the two values `SECRET_VALUE_CHANGE_ME` to passwords only you know. Save and close the file.
|
||||
19. In the extracted folder hit Shift+Right Click and select "Open PowerShell window here".
|
||||
|
||||

|
||||
|
||||
17. In the new window, paste (with right click) or type `docker compose up -d --build` and confirm with enter.
|
||||
18. Once you see the blinking cursor and the path again, setup has finished and the server is already running.
|
||||
|
||||

|
||||
|
||||
19. Create an admin account by pasting `docker compose exec darkflame /app/MasterServer -a` and following the prompts.
|
||||
|
||||

|
||||
|
||||
20. You can now login with these credentials at `http://your_ip:5000` (replace your_ip with your external IP). There you can create your account for playing as well as generate keys for other people to join; use these at `http://your_ip:5000/activate`
|
||||
|
||||
## Normal Use
|
||||
1. In Docker Desktop you should now see an entry `darkflameserver-main` and when you click on it all containers but `DarkflameSetup` should eventually be green. That means the server is running.
|
||||
|
||||

|
||||
|
||||
2. For troubleshooting, you can check the logs of the various parts by clicking their entry.
|
||||
3. You can start and stop the server with the corresponding buttons. Once all containers are grey, the server has shut down, and when all containers but `DarkflameSetup` are green, the server is running. Note that starting and stopping takes some time, please be patient.
|
||||
|
||||

|
||||
169
README.md
169
README.md
@@ -27,25 +27,41 @@ Darkflame Universe is a server emulator and does not distribute any LEGO® Unive
|
||||
Development of the latest iteration of Darkflame Universe has been done primarily in a Unix-like environment and is where it has been tested and designed for deployment. It is therefore highly recommended that Darkflame Universe be built and deployed using a Unix-like environment for the most streamlined experience.
|
||||
|
||||
### Prerequisites
|
||||
**Clone the repository**
|
||||
#### Clone the repository
|
||||
```bash
|
||||
git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer
|
||||
```
|
||||
|
||||
**Python**
|
||||
#### Python
|
||||
|
||||
Some tools utilized to streamline the setup process require Python 3, make sure you have it installed.
|
||||
|
||||
**Choosing the right version for your client**
|
||||
|
||||
### Choosing the right version for your client
|
||||
DLU clients identify themselves using a higher version number than the regular live clients out there.
|
||||
This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client.
|
||||
|
||||
If you're using a DLU client, then you don't need to change anything. But if you're using any other client, you'll have to go into the "CMakeVariables.txt" file and change it to match your client's version. (likely 171022)
|
||||
If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number.
|
||||
|
||||
### Using Docker
|
||||
Refer to [Docker.md](/Docker.md).
|
||||
|
||||
For Windows, refer to [Docker_Windows.md](/Docker_Windows.md).
|
||||
|
||||
### Linux builds
|
||||
Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed.
|
||||
Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`.
|
||||
|
||||
CMake must be version 3.14 or higher!
|
||||
|
||||
#### Build the repository
|
||||
|
||||
You can either run `build.sh` when in the root folder of the repository:
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
Or manually run the commands used in `build.sh`:
|
||||
|
||||
**Build the repository**
|
||||
```bash
|
||||
# Create the build directory, preserving it if it already exists
|
||||
mkdir -p build
|
||||
@@ -54,33 +70,30 @@ cd build
|
||||
# Run CMake to generate make files
|
||||
cmake ..
|
||||
|
||||
# Run make to build the project. To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `make -j8`
|
||||
make
|
||||
# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8'
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### MacOS builds
|
||||
Ensure `cmake`, `zlib` and `open ssl` are installed as well as a compiler (e.g `clang` or `gcc`).
|
||||
|
||||
**Download precompiled MySQL connector**
|
||||
In the repository root folder run the following. Ensure -DOPENSSL_ROOT_DIR=/path/to/openssl points to your openssl install location
|
||||
```bash
|
||||
# Install required tools
|
||||
brew install boost mysql-connector-c++
|
||||
# Create the build directory, preserving it if it already exists
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
# Symlinks for finding the required modules
|
||||
sudo ln -s /usr/local/mysql-connector-c++/lib64/libmysqlcppconn.dylib /usr/local/mysql-connector-c++/lib64/libmysql.dylib
|
||||
sudo ln -s /usr/local/mysql-connector-c++/lib64/libcrypto.1.1.dylib /usr/local/mysql/lib/libcrypto.1.1.dylib
|
||||
```
|
||||
# Run CMake to generate build files
|
||||
cmake .. -DOPENSSL_ROOT_DIR=/path/to/openssl
|
||||
|
||||
Then follow the Linux build steps (gcc is not required), but before running `make`, run the following to make sure all the libs are available in the build folder:
|
||||
|
||||
```bash
|
||||
sudo ln -s /usr/local/mysql-connector-c++/lib64/libssl.1.1.dylib /path/to/build/folder/libssl.1.1.dylib
|
||||
sudo ln -s /usr/local/mysql-connector-c++/lib64/libcrypto.1.1.dylib /path/to/build/folder/libcrypto.1.1.dylib
|
||||
# Get cmake to build the project. If make files are being used then using make and appending `-j` and the amount of cores to utilize may be preferable, for example `make -j8`
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### Windows builds (native)
|
||||
Ensure that you have either the [MSVC](https://visualstudio.microsoft.com/vs/) or the [Clang](https://github.com/llvm/llvm-project/releases/) (recommended) compiler installed. You will also need to install [CMake](https://cmake.org/download/).
|
||||
Ensure that you have either the [MSVC](https://visualstudio.microsoft.com/vs/) or the [Clang](https://github.com/llvm/llvm-project/releases/) (recommended) compiler installed. You will also need to install [CMake](https://cmake.org/download/). Currently on native Windows the server will only work in Release mode.
|
||||
|
||||
**Build the repository**
|
||||
#### Build the repository
|
||||
```batch
|
||||
:: Create the build directory
|
||||
mkdir build
|
||||
@@ -90,20 +103,31 @@ cd build
|
||||
cmake ..
|
||||
|
||||
:: Run CMake with build flag to build
|
||||
cmake --build .
|
||||
cmake --build . --config Release
|
||||
```
|
||||
#### Windows for ARM has not been tested but should build by doing the following
|
||||
```batch
|
||||
:: Create the build directory
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
:: Run CMake to generate make files
|
||||
cmake .. -DMARIADB_BUILD_SOURCE=ON
|
||||
|
||||
:: Run CMake with build flag to build
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### Windows builds (WSL)
|
||||
This section will go through how to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) and building in a Linux environment under Windows. WSL requires Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11.
|
||||
|
||||
**Open the Command Prompt application with Administrator permissions and run the following:**
|
||||
#### Open the Command Prompt application with Administrator permissions and run the following:
|
||||
```bash
|
||||
# Installing Windows Subsystem for Linux
|
||||
wsl --install
|
||||
```
|
||||
|
||||
**Open the Ubuntu application and run the following:**
|
||||
#### Open the Ubuntu application and run the following:
|
||||
```bash
|
||||
# Make sure the install is up to date
|
||||
apt update && apt upgrade
|
||||
@@ -111,23 +135,31 @@ apt update && apt upgrade
|
||||
# Make sure the gcc, cmake, and build-essentials are installed
|
||||
sudo apt install gcc
|
||||
sudo apt install cmake
|
||||
sudo apt install build-essentials
|
||||
sudo apt install build-essential
|
||||
```
|
||||
|
||||
[**Follow the Linux instructions**](#linux-builds)
|
||||
|
||||
### ARM builds
|
||||
AArch64 builds should work on linux and MacOS using their respective build steps. Windows ARM should build but it has not been tested
|
||||
|
||||
### Updating your build
|
||||
To update your server to the latest version navigate to your cloned directory
|
||||
```bash
|
||||
cd /path/to/DarkflameServer
|
||||
```
|
||||
run the following commands to update to the latest changes
|
||||
```bash
|
||||
git pull
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
now follow the build section for your system
|
||||
|
||||
## Setting up the environment
|
||||
|
||||
### Database
|
||||
Darkflame Universe utilizes a MySQL/MariaDB database for account and character information.
|
||||
|
||||
Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running.
|
||||
* Create a database for Darkflame Universe to use
|
||||
* Run each SQL file in the order at which they appear [here](migrations/dlu/) on the database
|
||||
|
||||
### Resources
|
||||
|
||||
**LEGO® Universe 1.10.64**
|
||||
#### LEGO® Universe 1.10.64
|
||||
|
||||
This repository does not distribute any LEGO® Universe files. A full install of LEGO® Universe version 1.10.64 (latest) is required to finish setting up Darkflame Universe.
|
||||
|
||||
@@ -150,29 +182,39 @@ shasum -a 256 <file>
|
||||
certutil -hashfile <file> SHA256
|
||||
```
|
||||
|
||||
**Unpacking the client**
|
||||
#### Unpacking the client
|
||||
* Clone lcdr's utilities repository [here](https://github.com/lcdr/utils)
|
||||
* Use `pkextractor.pyw` to unpack the client files if they are not already unpacked
|
||||
|
||||
**Setup resource directory**
|
||||
#### Setup resource directory
|
||||
* In the `build` directory create a `res` directory if it does not already exist.
|
||||
* Copy over or create symlinks from `macros`, `BrickModels`, `chatplus_en_us.txt`, and `maps` in your client `res` directory to the server `build/res` directory
|
||||
* Copy over or create symlinks from `macros`, `BrickModels`, `chatplus_en_us.txt`, `names`, and `maps` in your client `res` directory to the server `build/res` directory
|
||||
* Unzip the navmeshes [here](./resources/navmeshes.zip) and place them in `build/res/maps/navmeshes`
|
||||
|
||||
**Setup locale**
|
||||
#### Setup locale
|
||||
* In the `build` directory create a `locale` directory if it does not already exist
|
||||
* Copy over or create symlinks from `locale.xml` in your client `locale` directory to the `build/locale` directory
|
||||
|
||||
**Client database**
|
||||
#### Client database
|
||||
* Use `fdb_to_sqlite.py` in lcdr's utilities on `res/cdclient.fdb` in the unpacked client to convert the client database to `cdclient.sqlite`
|
||||
* Move and rename `cdclient.sqlite` into `build/res/CDServer.sqlite`
|
||||
* Run each SQL file in the order at which they appear [here](migrations/cdserver/) on the SQLite database
|
||||
|
||||
**Configuration**
|
||||
### Database
|
||||
Darkflame Universe utilizes a MySQL/MariaDB database for account and character information.
|
||||
|
||||
Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running.
|
||||
* Create a database for Darkflame Universe to use
|
||||
|
||||
#### Configuration
|
||||
|
||||
After the server has been built there should be four `ini` files in the build director: `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`. Go through them and fill in the database credentials and configure other settings if necessary.
|
||||
|
||||
**Verify**
|
||||
#### Setup and Migrations
|
||||
|
||||
Use the command `./MasterServer -m` to setup the tables in the database. The first time this command is run on a database, the tables will be up to date with the most recent version. To update your database tables, run this command again. Multiple invocations will not affect any functionality.
|
||||
|
||||
#### Verify
|
||||
|
||||
Your build directory should now look like this:
|
||||
* AuthServer
|
||||
@@ -223,6 +265,7 @@ To connect to a server follow these steps:
|
||||
* Open it in a text editor and locate where it says `AUTHSERVERIP=0:`
|
||||
* Replace the contents after to `:` and the following `,` with what you configured as the server's public facing IP. For example `AUTHSERVERIP=0:localhost` for locally hosted servers
|
||||
* Launch `legouniverse.exe`, through `wine` if on a Unix-like operating system
|
||||
* Note that if you are on WSL2, you will need to configure the public IP in the server and client to be the IP of the WSL2 instance and not localhost, which can be found by running `ifconfig` in the terminal. Windows defaults to WSL1, so this will not apply to most users.
|
||||
|
||||
### Survival
|
||||
|
||||
@@ -232,6 +275,8 @@ The client script for the survival minigame has a bug in it which can cause the
|
||||
* Change `PlayerReady(self)` to `onPlayerReady(self)`
|
||||
* Save the file, overriding readonly mode if required
|
||||
|
||||
If you still experience the bug, try deleting/renaming `res/pack/scripts.pk`.
|
||||
|
||||
### Brick-By-Brick building
|
||||
|
||||
Brick-By-Brick building requires `PATCHSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be achieved by pointing it to `localhost` while having `sudo python -m http.server 80` running in the background.
|
||||
@@ -283,10 +328,10 @@ Here is a summary of the commands available in-game. All commands are prefixed b
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
instance-info
|
||||
instanceinfo
|
||||
</td>
|
||||
<td>
|
||||
/instance-info
|
||||
/instanceinfo
|
||||
</td>
|
||||
<td>
|
||||
Displays in the chat the current zone, clone, and instance id.
|
||||
@@ -380,30 +425,38 @@ Here is a summary of the commands available in-game. All commands are prefixed b
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Credits
|
||||
### Contributors to DLUv3
|
||||
* DarwinAnim8or
|
||||
* Wincent01
|
||||
* Mick
|
||||
* averysumner
|
||||
* Jon002
|
||||
* Jonny
|
||||
* Xiphoseer
|
||||
# Credits
|
||||
## Active Contributors
|
||||
* [EmosewaMC](https://github.com/EmosewaMC)
|
||||
* [Jettford](https://github.com/Jettford)
|
||||
* [Aaron K.](https://github.com/aronwk-aaron)
|
||||
|
||||
## DLU Team
|
||||
* [DarwinAnim8or](https://github.com/DarwinAnim8or)
|
||||
* [Wincent01](https://github.com/Wincent01)
|
||||
* [Mick](https://github.com/MickVermeulen)
|
||||
* [averysumner](https://github.com/codeshaunted)
|
||||
* [Jon002](https://github.com/jaller200)
|
||||
* [Jonny](https://github.com/cuzitsjonny)
|
||||
|
||||
### Research and tools
|
||||
* lcdr
|
||||
* [lcdr](https://github.com/lcdr)
|
||||
* [Xiphoseer](https://github.com/Xiphoseer)
|
||||
|
||||
### Community management
|
||||
* Neal
|
||||
* [Neal](https://github.com/NealSpellman)
|
||||
|
||||
### Former contributors
|
||||
* TheMachine
|
||||
* Matthew
|
||||
* Raine
|
||||
* [Raine](https://github.com/Rainebannister)
|
||||
* Bricknave
|
||||
|
||||
### Special thanks
|
||||
### Logo
|
||||
* Cole Peterson (BlasterBuilder)
|
||||
|
||||
## Special thanks
|
||||
* humanoid24
|
||||
* pwjones1969
|
||||
* BlasterBuilder for the logo
|
||||
* [Simon](https://github.com/SimonNitzsche)
|
||||
* ALL OF THE NETDEVIL AND LEGO TEAMS!
|
||||
|
||||
51
SECURITY.md
Normal file
51
SECURITY.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
At the moment, only the latest commit on the `main` branch will be supported for security vulnerabilities. Private server operators
|
||||
should keep their instances up to date and forks should regularily rebase on `main`.
|
||||
|
||||
| Branch | Supported |
|
||||
| ------- | ------------------ |
|
||||
| `main` | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you found a security vulnerability in DLU, please send a message to [darkflame-security@googlegroups.com][darkflame-security]. You should get a
|
||||
reply within *72 hours* that we have received your report and a tentative [CVSS score](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator).
|
||||
We will do a preliminary analysis to confirm that the vulnerability is a plausible claim and decline the report otherwise.
|
||||
|
||||
If possible, please include
|
||||
|
||||
1. reproducible steps on how to trigger the vulnerability
|
||||
2. a description on why you are convinced that it exists.
|
||||
3. any information you may have on active exploitation of the vulnerability (zero-day).
|
||||
|
||||
## Security Advisories
|
||||
|
||||
The project will release advisories on resolved vulnerabilities at <https://github.com/DarkflameUniverse/DarkflameServer/security/advisories>
|
||||
|
||||
## Receiving Security Updates
|
||||
|
||||
We set up [darkflame-security-announce@googlegroups.com][darkflame-security-announce] for private server operators to receive updates on vulnerabilities
|
||||
such as the release of [Security Advisories](#security-advisories) or early workarounds and recommendations to mitigate ongoing
|
||||
vulnerabilities.
|
||||
|
||||
Unfortunately, we cannot guarantee that announcements will be sent for every vulnerability.
|
||||
|
||||
## Embargo
|
||||
|
||||
We propose a 90 day (approx. 3 months) embargo on security vulnerabilities. That is, we ask everyone not to disclose the vulnerabilty
|
||||
publicly until either:
|
||||
|
||||
1. 90 days have passed from the time the first related email is sent to `darkflame-security@`
|
||||
2. a security advisory related to the vulnerability has been published by the project.
|
||||
|
||||
If you fail to comply with this embargo, you might be exluded from [receiving security updates](#receiving-security-updates).
|
||||
|
||||
## Bug Bounty
|
||||
|
||||
Unfortunately we cannot provide bug bounties at this time.
|
||||
|
||||
[darkflame-security]: mailto:darkflame-security@googlegroups.com
|
||||
[darkflame-security-announce]: https://groups.google.com/g/darkflame-security-announce
|
||||
7
build.sh
Normal file → Executable file
7
build.sh
Normal file → Executable file
@@ -5,5 +5,8 @@ cd build
|
||||
# Run cmake to generate make files
|
||||
cmake ..
|
||||
|
||||
# Run make to build the project. To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `make -j8`
|
||||
make
|
||||
# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8'
|
||||
cmake --build . --config Release
|
||||
|
||||
# Run migrations
|
||||
./MasterServer -m
|
||||
|
||||
@@ -37,14 +37,15 @@ int main(int argc, char** argv) {
|
||||
//Create all the objects we need to run our service:
|
||||
Game::logger = SetupLogger();
|
||||
if (!Game::logger) return 0;
|
||||
Game::logger->Log("AuthServer", "Starting Auth server...\n");
|
||||
Game::logger->Log("AuthServer", "Version: %i.%i\n", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
|
||||
Game::logger->Log("AuthServer", "Compiled on: %s\n", __TIMESTAMP__);
|
||||
Game::logger->Log("AuthServer", "Starting Auth server...");
|
||||
Game::logger->Log("AuthServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
|
||||
Game::logger->Log("AuthServer", "Compiled on: %s", __TIMESTAMP__);
|
||||
|
||||
//Read our config:
|
||||
dConfig config("authconfig.ini");
|
||||
Game::config = &config;
|
||||
Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console"))));
|
||||
Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1");
|
||||
|
||||
//Connect to the MySQL Database
|
||||
std::string mysql_host = config.GetValue("mysql_host");
|
||||
@@ -52,15 +53,15 @@ int main(int argc, char** argv) {
|
||||
std::string mysql_username = config.GetValue("mysql_username");
|
||||
std::string mysql_password = config.GetValue("mysql_password");
|
||||
|
||||
try {
|
||||
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
|
||||
} catch (sql::SQLException& ex) {
|
||||
Game::logger->Log("AuthServer", "Got an error while connecting to the database: %s\n", ex.what());
|
||||
Database::Destroy();
|
||||
try {
|
||||
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
|
||||
} catch (sql::SQLException& ex) {
|
||||
Game::logger->Log("AuthServer", "Got an error while connecting to the database: %s", ex.what());
|
||||
Database::Destroy("AuthServer");
|
||||
delete Game::server;
|
||||
delete Game::logger;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Find out the master's IP:
|
||||
std::string masterIP;
|
||||
@@ -77,10 +78,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
|
||||
int maxClients = 50;
|
||||
int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
|
||||
int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
|
||||
if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
|
||||
if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
|
||||
|
||||
|
||||
Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth);
|
||||
|
||||
//Run it until server gets a kill message from Master:
|
||||
@@ -97,8 +98,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
if (framesSinceMasterDisconnect >= 30)
|
||||
break; //Exit our loop, shut down.
|
||||
}
|
||||
else framesSinceMasterDisconnect = 0;
|
||||
} else framesSinceMasterDisconnect = 0;
|
||||
|
||||
//In world we'd update our other systems here.
|
||||
|
||||
@@ -133,8 +133,7 @@ int main(int argc, char** argv) {
|
||||
delete stmt;
|
||||
|
||||
framesSinceLastSQLPing = 0;
|
||||
}
|
||||
else framesSinceLastSQLPing++;
|
||||
} else framesSinceLastSQLPing++;
|
||||
|
||||
//Sleep our thread since auth can afford to.
|
||||
t += std::chrono::milliseconds(mediumFramerate); //Auth can run at a lower "fps"
|
||||
@@ -142,21 +141,24 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
//Delete our objects here:
|
||||
Database::Destroy();
|
||||
Database::Destroy("AuthServer");
|
||||
delete Game::server;
|
||||
delete Game::logger;
|
||||
|
||||
return 0;
|
||||
exit(EXIT_SUCCESS);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
dLogger * SetupLogger() {
|
||||
dLogger* SetupLogger() {
|
||||
std::string logPath = "./logs/AuthServer_" + std::to_string(time(nullptr)) + ".log";
|
||||
bool logToConsole = false;
|
||||
bool logDebugStatements = false;
|
||||
#ifdef _DEBUG
|
||||
logToConsole = true;
|
||||
logDebugStatements = true;
|
||||
#endif
|
||||
|
||||
return new dLogger(logPath, logToConsole);
|
||||
return new dLogger(logPath, logToConsole, logDebugStatements);
|
||||
}
|
||||
|
||||
void HandlePacket(Packet* packet) {
|
||||
|
||||
4
dAuthServer/CMakeLists.txt
Normal file
4
dAuthServer/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
set(DAUTHSERVER_SOURCES "AuthServer.cpp")
|
||||
|
||||
add_executable(AuthServer ${DAUTHSERVER_SOURCES})
|
||||
target_link_libraries(AuthServer ${COMMON_LIBRARIES})
|
||||
4
dChatFilter/CMakeLists.txt
Normal file
4
dChatFilter/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
set(DCHATFILTER_SOURCES "dChatFilter.cpp")
|
||||
|
||||
add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES})
|
||||
target_link_libraries(dChatFilter dDatabase)
|
||||
@@ -8,8 +8,9 @@
|
||||
#include <regex>
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "Database.h"
|
||||
#include "dLogger.h"
|
||||
#include "dConfig.h"
|
||||
#include "Database.h"
|
||||
#include "Game.h"
|
||||
|
||||
using namespace dChatFilterDCF;
|
||||
@@ -18,11 +19,15 @@ dChatFilter::dChatFilter(const std::string& filepath, bool dontGenerateDCF) {
|
||||
m_DontGenerateDCF = dontGenerateDCF;
|
||||
|
||||
if (!BinaryIO::DoesFileExist(filepath + ".dcf") || m_DontGenerateDCF) {
|
||||
ReadWordlistPlaintext(filepath + ".txt");
|
||||
if (!m_DontGenerateDCF) ExportWordlistToDCF(filepath + ".dcf");
|
||||
ReadWordlistPlaintext(filepath + ".txt", true);
|
||||
if (!m_DontGenerateDCF) ExportWordlistToDCF(filepath + ".dcf", true);
|
||||
} else if (!ReadWordlistDCF(filepath + ".dcf", true)) {
|
||||
ReadWordlistPlaintext(filepath + ".txt", true);
|
||||
ExportWordlistToDCF(filepath + ".dcf", true);
|
||||
}
|
||||
else {
|
||||
ReadWordlistDCF(filepath + ".dcf");
|
||||
|
||||
if (BinaryIO::DoesFileExist("blacklist.dcf")) {
|
||||
ReadWordlistDCF("blacklist.dcf", false);
|
||||
}
|
||||
|
||||
//Read player names that are ok as well:
|
||||
@@ -31,65 +36,71 @@ dChatFilter::dChatFilter(const std::string& filepath, bool dontGenerateDCF) {
|
||||
while (res->next()) {
|
||||
std::string line = res->getString(1).c_str();
|
||||
std::transform(line.begin(), line.end(), line.begin(), ::tolower); //Transform to lowercase
|
||||
m_Words.push_back(CalculateHash(line));
|
||||
m_ApprovedWords.push_back(CalculateHash(line));
|
||||
}
|
||||
delete res;
|
||||
delete stmt;
|
||||
}
|
||||
|
||||
dChatFilter::~dChatFilter() {
|
||||
m_Words.clear();
|
||||
m_ApprovedWords.clear();
|
||||
m_DeniedWords.clear();
|
||||
}
|
||||
|
||||
void dChatFilter::ReadWordlistPlaintext(const std::string& filepath) {
|
||||
void dChatFilter::ReadWordlistPlaintext(const std::string& filepath, bool whiteList) {
|
||||
std::ifstream file(filepath);
|
||||
if (file) {
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
|
||||
std::transform(line.begin(), line.end(), line.begin(), ::tolower); //Transform to lowercase
|
||||
m_Words.push_back(CalculateHash(line));
|
||||
if (whiteList) m_ApprovedWords.push_back(CalculateHash(line));
|
||||
else m_DeniedWords.push_back(CalculateHash(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dChatFilter::ReadWordlistDCF(const std::string& filepath) {
|
||||
bool dChatFilter::ReadWordlistDCF(const std::string& filepath, bool whiteList) {
|
||||
std::ifstream file(filepath, std::ios::binary);
|
||||
if (file) {
|
||||
fileHeader hdr;
|
||||
BinaryIO::BinaryRead(file, hdr);
|
||||
if (hdr.header != header) {
|
||||
std::cout << "Wrong file header!" << std::endl;
|
||||
file.close();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hdr.formatVersion <= formatVersion) {
|
||||
if (hdr.formatVersion == formatVersion) {
|
||||
size_t wordsToRead = 0;
|
||||
BinaryIO::BinaryRead(file, wordsToRead);
|
||||
m_Words.reserve(wordsToRead);
|
||||
if (whiteList) m_ApprovedWords.reserve(wordsToRead);
|
||||
else m_DeniedWords.reserve(wordsToRead);
|
||||
|
||||
size_t word = 0;
|
||||
for (size_t i = 0; i < wordsToRead; ++i) {
|
||||
BinaryIO::BinaryRead(file, word);
|
||||
m_Words.push_back(word);
|
||||
if (whiteList) m_ApprovedWords.push_back(word);
|
||||
else m_DeniedWords.push_back(word);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "Newer file or corrupt" << std::endl;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
file.close();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void dChatFilter::ExportWordlistToDCF(const std::string& filepath) {
|
||||
std::ofstream file(filepath, std::ios::binary);
|
||||
void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool whiteList) {
|
||||
std::ofstream file(filepath, std::ios::binary | std::ios_base::out);
|
||||
if (file) {
|
||||
BinaryIO::BinaryWrite(file, uint32_t(dChatFilterDCF::header));
|
||||
BinaryIO::BinaryWrite(file, uint32_t(dChatFilterDCF::formatVersion));
|
||||
BinaryIO::BinaryWrite(file, size_t(m_Words.size()));
|
||||
BinaryIO::BinaryWrite(file, size_t(whiteList ? m_ApprovedWords.size() : m_DeniedWords.size()));
|
||||
|
||||
for (size_t word : m_Words) {
|
||||
for (size_t word : whiteList ? m_ApprovedWords : m_DeniedWords) {
|
||||
BinaryIO::BinaryWrite(file, word);
|
||||
}
|
||||
|
||||
@@ -97,31 +108,45 @@ void dChatFilter::ExportWordlistToDCF(const std::string& filepath) {
|
||||
}
|
||||
}
|
||||
|
||||
bool dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel) {
|
||||
if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return true; //If anything but a forum mod, return true.
|
||||
if (message.empty()) return true;
|
||||
std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList) {
|
||||
if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return { }; //If anything but a forum mod, return true.
|
||||
if (message.empty()) return { };
|
||||
if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } };
|
||||
|
||||
std::stringstream sMessage(message);
|
||||
std::string segment;
|
||||
std::regex reg("(!*|\\?*|\\;*|\\.*|\\,*)");
|
||||
|
||||
std::vector<std::pair<uint8_t, uint8_t>> listOfBadSegments = std::vector<std::pair<uint8_t, uint8_t>>();
|
||||
|
||||
uint32_t position = 0;
|
||||
|
||||
while (std::getline(sMessage, segment, ' ')) {
|
||||
std::string originalSegment = segment;
|
||||
|
||||
std::transform(segment.begin(), segment.end(), segment.begin(), ::tolower); //Transform to lowercase
|
||||
segment = std::regex_replace(segment, reg, "");
|
||||
|
||||
size_t hash = CalculateHash(segment);
|
||||
|
||||
if (std::find(m_UserUnapprovedWordCache.begin(), m_UserUnapprovedWordCache.end(), hash) != m_UserUnapprovedWordCache.end()) {
|
||||
return false;
|
||||
if (std::find(m_UserUnapprovedWordCache.begin(), m_UserUnapprovedWordCache.end(), hash) != m_UserUnapprovedWordCache.end() && whiteList) {
|
||||
listOfBadSegments.emplace_back(position, originalSegment.length());
|
||||
}
|
||||
|
||||
if (!IsInWordlist(hash)) {
|
||||
if (std::find(m_ApprovedWords.begin(), m_ApprovedWords.end(), hash) == m_ApprovedWords.end() && whiteList) {
|
||||
m_UserUnapprovedWordCache.push_back(hash);
|
||||
return false;
|
||||
listOfBadSegments.emplace_back(position, originalSegment.length());
|
||||
}
|
||||
|
||||
if (std::find(m_DeniedWords.begin(), m_DeniedWords.end(), hash) != m_DeniedWords.end() && !whiteList) {
|
||||
m_UserUnapprovedWordCache.push_back(hash);
|
||||
listOfBadSegments.emplace_back(position, originalSegment.length());
|
||||
}
|
||||
|
||||
position += segment.length() + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
return listOfBadSegments;
|
||||
}
|
||||
|
||||
size_t dChatFilter::CalculateHash(const std::string& word) {
|
||||
@@ -131,7 +156,3 @@ size_t dChatFilter::CalculateHash(const std::string& word) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool dChatFilter::IsInWordlist(size_t word) {
|
||||
return std::find(m_Words.begin(), m_Words.end(), word) != m_Words.end();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace dChatFilterDCF {
|
||||
static const uint32_t header = ('D' + ('C' << 8) + ('F' << 16) + ('B' << 24));
|
||||
static const uint32_t formatVersion = 1;
|
||||
static const uint32_t formatVersion = 2;
|
||||
|
||||
struct fileHeader {
|
||||
uint32_t header;
|
||||
@@ -20,17 +20,17 @@ public:
|
||||
dChatFilter(const std::string& filepath, bool dontGenerateDCF);
|
||||
~dChatFilter();
|
||||
|
||||
void ReadWordlistPlaintext(const std::string & filepath);
|
||||
void ReadWordlistDCF(const std::string & filepath);
|
||||
void ExportWordlistToDCF(const std::string & filepath);
|
||||
bool IsSentenceOkay(const std::string& message, int gmLevel);
|
||||
void ReadWordlistPlaintext(const std::string& filepath, bool whiteList);
|
||||
bool ReadWordlistDCF(const std::string& filepath, bool whiteList);
|
||||
void ExportWordlistToDCF(const std::string& filepath, bool whiteList);
|
||||
std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList = true);
|
||||
|
||||
private:
|
||||
bool m_DontGenerateDCF;
|
||||
std::vector<size_t> m_Words;
|
||||
std::vector<size_t> m_DeniedWords;
|
||||
std::vector<size_t> m_ApprovedWords;
|
||||
std::vector<size_t> m_UserUnapprovedWordCache;
|
||||
|
||||
//Private functions:
|
||||
size_t CalculateHash(const std::string& word);
|
||||
bool IsInWordlist(size_t word);
|
||||
};
|
||||
|
||||
6
dChatServer/CMakeLists.txt
Normal file
6
dChatServer/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
set(DCHATSERVER_SOURCES "ChatPacketHandler.cpp"
|
||||
"ChatServer.cpp"
|
||||
"PlayerContainer.cpp")
|
||||
|
||||
add_executable(ChatServer ${DCHATSERVER_SOURCES})
|
||||
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
#include "BitStream.h"
|
||||
|
||||
struct PlayerData;
|
||||
enum class AddFriendResponseType : uint8_t;
|
||||
|
||||
namespace ChatPacketHandler {
|
||||
void HandleFriendlistRequest(Packet* packet);
|
||||
@@ -31,10 +32,9 @@ namespace ChatPacketHandler {
|
||||
void SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID);
|
||||
|
||||
//FriendData is the player we're SENDING this stuff to. Player is the friend that changed state.
|
||||
void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType);
|
||||
void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend);
|
||||
|
||||
void SendFriendRequest(PlayerData* receiver, PlayerData* sender, bool isBFFReq = false);
|
||||
void SendFriendResponse(PlayerData* receiver, PlayerData* sender, uint8_t responseCode = 3);
|
||||
void SendFriendRequest(PlayerData* receiver, PlayerData* sender);
|
||||
void SendFriendResponse(PlayerData* receiver, PlayerData* sender, AddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U);
|
||||
void SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,14 +40,15 @@ int main(int argc, char** argv) {
|
||||
//Create all the objects we need to run our service:
|
||||
Game::logger = SetupLogger();
|
||||
if (!Game::logger) return 0;
|
||||
Game::logger->Log("ChatServer", "Starting Chat server...\n");
|
||||
Game::logger->Log("ChatServer", "Version: %i.%i\n", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
|
||||
Game::logger->Log("ChatServer", "Compiled on: %s\n", __TIMESTAMP__);
|
||||
Game::logger->Log("ChatServer", "Starting Chat server...");
|
||||
Game::logger->Log("ChatServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
|
||||
Game::logger->Log("ChatServer", "Compiled on: %s", __TIMESTAMP__);
|
||||
|
||||
//Read our config:
|
||||
dConfig config("chatconfig.ini");
|
||||
Game::config = &config;
|
||||
Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console"))));
|
||||
Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1");
|
||||
|
||||
//Connect to the MySQL Database
|
||||
std::string mysql_host = config.GetValue("mysql_host");
|
||||
@@ -57,10 +58,9 @@ int main(int argc, char** argv) {
|
||||
|
||||
try {
|
||||
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
|
||||
}
|
||||
catch (sql::SQLException& ex) {
|
||||
Game::logger->Log("ChatServer", "Got an error while connecting to the database: %s\n", ex.what());
|
||||
Database::Destroy();
|
||||
} catch (sql::SQLException& ex) {
|
||||
Game::logger->Log("ChatServer", "Got an error while connecting to the database: %s", ex.what());
|
||||
Database::Destroy("ChatServer");
|
||||
delete Game::server;
|
||||
delete Game::logger;
|
||||
return 0;
|
||||
@@ -103,8 +103,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
if (framesSinceMasterDisconnect >= 30)
|
||||
break; //Exit our loop, shut down.
|
||||
}
|
||||
else framesSinceMasterDisconnect = 0;
|
||||
} else framesSinceMasterDisconnect = 0;
|
||||
|
||||
//In world we'd update our other systems here.
|
||||
|
||||
@@ -121,8 +120,7 @@ int main(int argc, char** argv) {
|
||||
if (framesSinceLastFlush >= 900) {
|
||||
Game::logger->Flush();
|
||||
framesSinceLastFlush = 0;
|
||||
}
|
||||
else framesSinceLastFlush++;
|
||||
} else framesSinceLastFlush++;
|
||||
|
||||
//Every 10 min we ping our sql server to keep it alive hopefully:
|
||||
if (framesSinceLastSQLPing >= 40000) {
|
||||
@@ -140,8 +138,7 @@ int main(int argc, char** argv) {
|
||||
delete stmt;
|
||||
|
||||
framesSinceLastSQLPing = 0;
|
||||
}
|
||||
else framesSinceLastSQLPing++;
|
||||
} else framesSinceLastSQLPing++;
|
||||
|
||||
//Sleep our thread since auth can afford to.
|
||||
t += std::chrono::milliseconds(mediumFramerate); //Chat can run at a lower "fps"
|
||||
@@ -149,30 +146,33 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
//Delete our objects here:
|
||||
Database::Destroy();
|
||||
Database::Destroy("ChatServer");
|
||||
delete Game::server;
|
||||
delete Game::logger;
|
||||
|
||||
return 0;
|
||||
exit(EXIT_SUCCESS);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
dLogger* SetupLogger() {
|
||||
std::string logPath = "./logs/ChatServer_" + std::to_string(time(nullptr)) + ".log";
|
||||
bool logToConsole = false;
|
||||
bool logDebugStatements = false;
|
||||
#ifdef _DEBUG
|
||||
logToConsole = true;
|
||||
logDebugStatements = true;
|
||||
#endif
|
||||
|
||||
return new dLogger(logPath, logToConsole);
|
||||
return new dLogger(logPath, logToConsole, logDebugStatements);
|
||||
}
|
||||
|
||||
void HandlePacket(Packet* packet) {
|
||||
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) {
|
||||
Game::logger->Log("ChatServer", "A server has disconnected, erasing their connected players from the list.\n");
|
||||
Game::logger->Log("ChatServer", "A server has disconnected, erasing their connected players from the list.");
|
||||
}
|
||||
|
||||
if (packet->data[0] == ID_NEW_INCOMING_CONNECTION) {
|
||||
Game::logger->Log("ChatServer", "A server is connecting, awaiting user list.\n");
|
||||
Game::logger->Log("ChatServer", "A server is connecting, awaiting user list.");
|
||||
}
|
||||
|
||||
if (packet->data[1] == CHAT_INTERNAL) {
|
||||
@@ -201,7 +201,7 @@ void HandlePacket(Packet* packet) {
|
||||
}
|
||||
|
||||
default:
|
||||
Game::logger->Log("ChatServer", "Unknown CHAT_INTERNAL id: %i\n", int(packet->data[3]));
|
||||
Game::logger->Log("ChatServer", "Unknown CHAT_INTERNAL id: %i", int(packet->data[3]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ void HandlePacket(Packet* packet) {
|
||||
break;
|
||||
|
||||
case MSG_CHAT_GET_IGNORE_LIST:
|
||||
Game::logger->Log("ChatServer", "Asked for ignore list, but is unimplemented right now.\n");
|
||||
Game::logger->Log("ChatServer", "Asked for ignore list, but is unimplemented right now.");
|
||||
break;
|
||||
|
||||
case MSG_CHAT_TEAM_GET_STATUS:
|
||||
@@ -268,21 +268,21 @@ void HandlePacket(Packet* packet) {
|
||||
case MSG_CHAT_TEAM_SET_LOOT:
|
||||
ChatPacketHandler::HandleTeamLootOption(packet);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
Game::logger->Log("ChatServer", "Unknown CHAT id: %i\n", int(packet->data[3]));
|
||||
Game::logger->Log("ChatServer", "Unknown CHAT id: %i", int(packet->data[3]));
|
||||
}
|
||||
}
|
||||
|
||||
if (packet->data[1] == WORLD) {
|
||||
switch (packet->data[3]) {
|
||||
case MSG_WORLD_CLIENT_ROUTE_PACKET: {
|
||||
printf("routing packet from world\n");
|
||||
Game::logger->Log("ChatServer", "Routing packet from world");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Game::logger->Log("ChatServer", "Unknown World id: %i\n", int(packet->data[3]));
|
||||
Game::logger->Log("ChatServer", "Unknown World id: %i", int(packet->data[3]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,25 @@ PlayerContainer::~PlayerContainer() {
|
||||
void PlayerContainer::InsertPlayer(Packet* packet) {
|
||||
CINSTREAM;
|
||||
PlayerData* data = new PlayerData();
|
||||
inStream.SetReadOffset(inStream.GetReadOffset() + 64);
|
||||
inStream.Read(data->playerID);
|
||||
inStream.Read(data->playerID);
|
||||
inStream.Read(data->playerName);
|
||||
|
||||
uint32_t len;
|
||||
inStream.Read<uint32_t>(len);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
char character; inStream.Read<char>(character);
|
||||
data->playerName += character;
|
||||
}
|
||||
|
||||
inStream.Read(data->zoneID);
|
||||
inStream.Read(data->muteExpire);
|
||||
data->sysAddr = packet->systemAddress;
|
||||
|
||||
mNames[data->playerID] = GeneralUtils::ASCIIToUTF16(std::string(data->playerName.C_String()));
|
||||
mNames[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName);
|
||||
|
||||
mPlayers.insert(std::make_pair(data->playerID, data));
|
||||
Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i\n", data->playerName.C_String(), data->playerID, data->zoneID.GetMapID());
|
||||
Game::logger->Log("PlayerContainer", "Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID());
|
||||
|
||||
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
|
||||
|
||||
@@ -49,39 +57,32 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
|
||||
inStream.Read(playerID);
|
||||
|
||||
//Before they get kicked, we need to also send a message to their friends saying that they disconnected.
|
||||
auto player = this->GetPlayerData(playerID);
|
||||
std::unique_ptr<PlayerData> player(this->GetPlayerData(playerID));
|
||||
|
||||
if (player == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& fr : player->friends) {
|
||||
//if (!fr.isOnline) continue;
|
||||
|
||||
auto fd = this->GetPlayerData(fr.friendID);
|
||||
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player, 0);
|
||||
if (fd) ChatPacketHandler::SendFriendUpdate(fd, player.get(), 0, fr.isBestFriend);
|
||||
}
|
||||
|
||||
auto* team = GetTeam(playerID);
|
||||
|
||||
if (team != nullptr)
|
||||
{
|
||||
//TeamStatusUpdate(team);
|
||||
if (team != nullptr) {
|
||||
const auto memberName = GeneralUtils::UTF8ToUTF16(std::string(player->playerName.c_str()));
|
||||
|
||||
const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(player->playerName.C_String()));
|
||||
|
||||
for (const auto memberId : team->memberIDs)
|
||||
{
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
auto* otherMember = GetPlayerData(memberId);
|
||||
|
||||
if (otherMember == nullptr) continue;
|
||||
|
||||
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, {0, 0, 0});
|
||||
//ChatPacketHandler::SendTeamRemovePlayer(otherMember, false, false, true, false, team->leaderID, player->playerID, memberName);
|
||||
ChatPacketHandler::SendTeamSetOffWorldFlag(otherMember, playerID, { 0, 0, 0 });
|
||||
}
|
||||
}
|
||||
|
||||
Game::logger->Log("PlayerContainer", "Removed user: %llu\n", playerID);
|
||||
Game::logger->Log("PlayerContainer", "Removed user: %llu", playerID);
|
||||
mPlayers.erase(playerID);
|
||||
|
||||
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
|
||||
@@ -94,8 +95,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
|
||||
insertLog->executeUpdate();
|
||||
}
|
||||
|
||||
void PlayerContainer::MuteUpdate(Packet* packet)
|
||||
{
|
||||
void PlayerContainer::MuteUpdate(Packet* packet) {
|
||||
CINSTREAM;
|
||||
LWOOBJID playerID;
|
||||
inStream.Read(playerID); //skip header
|
||||
@@ -105,9 +105,8 @@ void PlayerContainer::MuteUpdate(Packet* packet)
|
||||
|
||||
auto* player = this->GetPlayerData(playerID);
|
||||
|
||||
if (player == nullptr)
|
||||
{
|
||||
Game::logger->Log("PlayerContainer", "Failed to find user: %llu\n", playerID);
|
||||
if (player == nullptr) {
|
||||
Game::logger->Log("PlayerContainer", "Failed to find user: %llu", playerID);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -117,8 +116,7 @@ void PlayerContainer::MuteUpdate(Packet* packet)
|
||||
BroadcastMuteUpdate(playerID, expire);
|
||||
}
|
||||
|
||||
void PlayerContainer::CreateTeamServer(Packet* packet)
|
||||
{
|
||||
void PlayerContainer::CreateTeamServer(Packet* packet) {
|
||||
CINSTREAM;
|
||||
LWOOBJID playerID;
|
||||
inStream.Read(playerID); //skip header
|
||||
@@ -130,8 +128,7 @@ void PlayerContainer::CreateTeamServer(Packet* packet)
|
||||
|
||||
members.reserve(membersSize);
|
||||
|
||||
for (size_t i = 0; i < membersSize; i++)
|
||||
{
|
||||
for (size_t i = 0; i < membersSize; i++) {
|
||||
LWOOBJID member;
|
||||
inStream.Read(member);
|
||||
members.push_back(member);
|
||||
@@ -140,19 +137,17 @@ void PlayerContainer::CreateTeamServer(Packet* packet)
|
||||
LWOZONEID zoneId;
|
||||
|
||||
inStream.Read(zoneId);
|
||||
|
||||
|
||||
auto* team = CreateLocalTeam(members);
|
||||
|
||||
if (team != nullptr)
|
||||
{
|
||||
if (team != nullptr) {
|
||||
team->zoneId = zoneId;
|
||||
}
|
||||
|
||||
UpdateTeamsOnWorld(team, false);
|
||||
}
|
||||
|
||||
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time)
|
||||
{
|
||||
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_MUTE_UPDATE);
|
||||
|
||||
@@ -162,30 +157,23 @@ void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time)
|
||||
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
}
|
||||
|
||||
TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members)
|
||||
{
|
||||
if (members.empty())
|
||||
{
|
||||
TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members) {
|
||||
if (members.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeamData* newTeam = nullptr;
|
||||
|
||||
for (const auto member : members)
|
||||
{
|
||||
for (const auto member : members) {
|
||||
auto* team = GetTeam(member);
|
||||
|
||||
if (team != nullptr)
|
||||
{
|
||||
if (team != nullptr) {
|
||||
RemoveMember(team, member, false, false, true);
|
||||
}
|
||||
|
||||
if (newTeam == nullptr)
|
||||
{
|
||||
if (newTeam == nullptr) {
|
||||
newTeam = CreateTeam(member, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
AddMember(newTeam, member);
|
||||
}
|
||||
}
|
||||
@@ -197,14 +185,13 @@ TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members)
|
||||
return newTeam;
|
||||
}
|
||||
|
||||
TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local)
|
||||
{
|
||||
TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local) {
|
||||
auto* team = new TeamData();
|
||||
|
||||
|
||||
team->teamID = ++mTeamIDCounter;
|
||||
team->leaderID = leader;
|
||||
team->local = local;
|
||||
|
||||
|
||||
mTeams.push_back(team);
|
||||
|
||||
AddMember(team, leader);
|
||||
@@ -212,20 +199,17 @@ TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local)
|
||||
return team;
|
||||
}
|
||||
|
||||
TeamData* PlayerContainer::GetTeam(LWOOBJID playerID)
|
||||
{
|
||||
for (auto* team : mTeams)
|
||||
{
|
||||
TeamData* PlayerContainer::GetTeam(LWOOBJID playerID) {
|
||||
for (auto* team : mTeams) {
|
||||
if (std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID) == team->memberIDs.end()) continue;
|
||||
|
||||
return team;
|
||||
}
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID)
|
||||
{
|
||||
void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID) {
|
||||
const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID);
|
||||
|
||||
if (index != team->memberIDs.end()) return;
|
||||
@@ -237,64 +221,49 @@ void PlayerContainer::AddMember(TeamData* team, LWOOBJID playerID)
|
||||
|
||||
if (leader == nullptr || member == nullptr) return;
|
||||
|
||||
const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.C_String()));
|
||||
const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(member->playerName.C_String()));
|
||||
const auto leaderName = GeneralUtils::UTF8ToUTF16(leader->playerName);
|
||||
const auto memberName = GeneralUtils::UTF8ToUTF16(member->playerName);
|
||||
|
||||
ChatPacketHandler::SendTeamInviteConfirm(member, false, leader->playerID, leader->zoneID, team->lootFlag, 0, 0, leaderName);
|
||||
|
||||
/*
|
||||
ChatPacketHandler::SendTeamAddPlayer(member, false, false, false, leader->playerID, leaderName, leader->zoneID);
|
||||
|
||||
Game::logger->Log("PlayerContainer", "Team invite successfully accepted, leader: %s, member: %s\n", leader->playerName.C_String(), member->playerName.C_String());
|
||||
*/
|
||||
|
||||
if (!team->local)
|
||||
{
|
||||
if (!team->local) {
|
||||
ChatPacketHandler::SendTeamSetLeader(member, leader->playerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
|
||||
}
|
||||
|
||||
UpdateTeamsOnWorld(team, false);
|
||||
|
||||
for (const auto memberId : team->memberIDs)
|
||||
{
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
auto* otherMember = GetPlayerData(memberId);
|
||||
|
||||
if (otherMember == member) continue;
|
||||
|
||||
const auto otherMemberName = GetName(memberId);
|
||||
|
||||
|
||||
ChatPacketHandler::SendTeamAddPlayer(member, false, team->local, false, memberId, otherMemberName, otherMember != nullptr ? otherMember->zoneID : LWOZONEID(0, 0, 0));
|
||||
|
||||
if (otherMember != nullptr)
|
||||
{
|
||||
if (otherMember != nullptr) {
|
||||
ChatPacketHandler::SendTeamAddPlayer(otherMember, false, team->local, false, member->playerID, memberName, member->zoneID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disband, bool kicked, bool leaving, bool silent)
|
||||
{
|
||||
void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disband, bool kicked, bool leaving, bool silent) {
|
||||
const auto index = std::find(team->memberIDs.begin(), team->memberIDs.end(), playerID);
|
||||
|
||||
if (index == team->memberIDs.end()) return;
|
||||
|
||||
auto* member = GetPlayerData(playerID);
|
||||
|
||||
if (member != nullptr && !silent)
|
||||
{
|
||||
|
||||
if (member != nullptr && !silent) {
|
||||
ChatPacketHandler::SendTeamSetLeader(member, LWOOBJID_EMPTY);
|
||||
}
|
||||
|
||||
const auto memberName = GetName(playerID);
|
||||
|
||||
for (const auto memberId : team->memberIDs)
|
||||
{
|
||||
if (silent && memberId == playerID)
|
||||
{
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
if (silent && memberId == playerID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -309,25 +278,19 @@ void PlayerContainer::RemoveMember(TeamData* team, LWOOBJID playerID, bool disba
|
||||
|
||||
UpdateTeamsOnWorld(team, false);
|
||||
|
||||
if (team->memberIDs.size() <= 1)
|
||||
{
|
||||
if (team->memberIDs.size() <= 1) {
|
||||
DisbandTeam(team);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playerID == team->leaderID)
|
||||
{
|
||||
} else {
|
||||
if (playerID == team->leaderID) {
|
||||
PromoteMember(team, team->memberIDs[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader)
|
||||
{
|
||||
void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader) {
|
||||
team->leaderID = newLeader;
|
||||
|
||||
for (const auto memberId : team->memberIDs)
|
||||
{
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
auto* otherMember = GetPlayerData(memberId);
|
||||
|
||||
if (otherMember == nullptr) continue;
|
||||
@@ -336,24 +299,22 @@ void PlayerContainer::PromoteMember(TeamData* team, LWOOBJID newLeader)
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerContainer::DisbandTeam(TeamData* team)
|
||||
{
|
||||
void PlayerContainer::DisbandTeam(TeamData* team) {
|
||||
const auto index = std::find(mTeams.begin(), mTeams.end(), team);
|
||||
|
||||
if (index == mTeams.end()) return;
|
||||
|
||||
for (const auto memberId : team->memberIDs)
|
||||
{
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
auto* otherMember = GetPlayerData(memberId);
|
||||
|
||||
if (otherMember == nullptr) continue;
|
||||
|
||||
const auto memberName = GeneralUtils::ASCIIToUTF16(std::string(otherMember->playerName.C_String()));
|
||||
const auto memberName = GeneralUtils::UTF8ToUTF16(otherMember->playerName);
|
||||
|
||||
ChatPacketHandler::SendTeamSetLeader(otherMember, LWOOBJID_EMPTY);
|
||||
ChatPacketHandler::SendTeamRemovePlayer(otherMember, true, false, false, team->local, team->leaderID, otherMember->playerID, memberName);
|
||||
}
|
||||
|
||||
|
||||
UpdateTeamsOnWorld(team, true);
|
||||
|
||||
mTeams.erase(index);
|
||||
@@ -361,8 +322,7 @@ void PlayerContainer::DisbandTeam(TeamData* team)
|
||||
delete team;
|
||||
}
|
||||
|
||||
void PlayerContainer::TeamStatusUpdate(TeamData* team)
|
||||
{
|
||||
void PlayerContainer::TeamStatusUpdate(TeamData* team) {
|
||||
const auto index = std::find(mTeams.begin(), mTeams.end(), team);
|
||||
|
||||
if (index == mTeams.end()) return;
|
||||
@@ -371,41 +331,32 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team)
|
||||
|
||||
if (leader == nullptr) return;
|
||||
|
||||
const auto leaderName = GeneralUtils::ASCIIToUTF16(std::string(leader->playerName.C_String()));
|
||||
const auto leaderName = GeneralUtils::UTF8ToUTF16(leader->playerName);
|
||||
|
||||
for (const auto memberId : team->memberIDs)
|
||||
{
|
||||
for (const auto memberId : team->memberIDs) {
|
||||
auto* otherMember = GetPlayerData(memberId);
|
||||
|
||||
if (otherMember == nullptr) continue;
|
||||
|
||||
if (!team->local)
|
||||
{
|
||||
if (!team->local) {
|
||||
ChatPacketHandler::SendTeamStatus(otherMember, team->leaderID, leader->zoneID, team->lootFlag, 0, leaderName);
|
||||
}
|
||||
else
|
||||
{
|
||||
//ChatPacketHandler::SendTeamStatus(otherMember, LWOOBJID_EMPTY, LWOZONEID(0, 0, 0), 1, 0, u"");
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTeamsOnWorld(team, false);
|
||||
}
|
||||
|
||||
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam)
|
||||
{
|
||||
void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
|
||||
CBITSTREAM;
|
||||
PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_TEAM_UPDATE);
|
||||
|
||||
bitStream.Write(team->teamID);
|
||||
bitStream.Write(deleteTeam);
|
||||
|
||||
if (!deleteTeam)
|
||||
{
|
||||
if (!deleteTeam) {
|
||||
bitStream.Write(team->lootFlag);
|
||||
bitStream.Write(static_cast<char>(team->memberIDs.size()));
|
||||
for (const auto memberID : team->memberIDs)
|
||||
{
|
||||
for (const auto memberID : team->memberIDs) {
|
||||
bitStream.Write(memberID);
|
||||
}
|
||||
}
|
||||
@@ -413,8 +364,7 @@ void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam)
|
||||
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
}
|
||||
|
||||
std::u16string PlayerContainer::GetName(LWOOBJID playerID)
|
||||
{
|
||||
std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
|
||||
const auto& pair = mNames.find(playerID);
|
||||
|
||||
if (pair == mNames.end()) return u"";
|
||||
@@ -422,20 +372,16 @@ std::u16string PlayerContainer::GetName(LWOOBJID playerID)
|
||||
return pair->second;
|
||||
}
|
||||
|
||||
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName)
|
||||
{
|
||||
for (const auto& pair : mNames)
|
||||
{
|
||||
if (pair.second == playerName)
|
||||
{
|
||||
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
|
||||
for (const auto& pair : mNames) {
|
||||
if (pair.second == playerName) {
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return LWOOBJID_EMPTY;
|
||||
}
|
||||
|
||||
bool PlayerContainer::GetIsMuted(PlayerData* data)
|
||||
{
|
||||
bool PlayerContainer::GetIsMuted(PlayerData* data) {
|
||||
return data->muteExpire == 1 || data->muteExpire > time(NULL);
|
||||
}
|
||||
|
||||
@@ -9,17 +9,18 @@
|
||||
|
||||
struct PlayerData {
|
||||
LWOOBJID playerID;
|
||||
RakNet::RakString playerName;
|
||||
std::string playerName;
|
||||
SystemAddress sysAddr;
|
||||
LWOZONEID zoneID;
|
||||
std::vector<FriendData> friends;
|
||||
time_t muteExpire;
|
||||
uint8_t countOfBestFriends = 0;
|
||||
};
|
||||
|
||||
struct TeamData {
|
||||
LWOOBJID teamID = LWOOBJID_EMPTY; // Internal use
|
||||
LWOOBJID leaderID = LWOOBJID_EMPTY;
|
||||
std::vector<LWOOBJID> memberIDs {};
|
||||
std::vector<LWOOBJID> memberIDs{};
|
||||
uint8_t lootFlag = 0;
|
||||
bool local = false;
|
||||
LWOZONEID zoneId = {};
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
PlayerData* GetPlayerData(const std::string& playerName) {
|
||||
for (auto player : mPlayers) {
|
||||
if (player.second) {
|
||||
std::string pn = player.second->playerName.C_String();
|
||||
std::string pn = player.second->playerName.c_str();
|
||||
if (pn == playerName) return player.second;
|
||||
}
|
||||
}
|
||||
|
||||
160
dCommon/AMFDeserialize.cpp
Normal file
160
dCommon/AMFDeserialize.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "AMFDeserialize.h"
|
||||
|
||||
#include "AMFFormat.h"
|
||||
|
||||
/**
|
||||
* AMF3 Reference document https://rtmp.veriskope.com/pdf/amf3-file-format-spec.pdf
|
||||
* AMF3 Deserializer written by EmosewaMC
|
||||
*/
|
||||
|
||||
AMFValue* AMFDeserialize::Read(RakNet::BitStream* inStream) {
|
||||
if (!inStream) return nullptr;
|
||||
AMFValue* returnValue = nullptr;
|
||||
// Read in the value type from the bitStream
|
||||
int8_t marker;
|
||||
inStream->Read(marker);
|
||||
// Based on the typing, create the value associated with that and return the base value class
|
||||
switch (marker) {
|
||||
case AMFValueType::AMFUndefined: {
|
||||
returnValue = new AMFUndefinedValue();
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFNull: {
|
||||
returnValue = new AMFNullValue();
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFFalse: {
|
||||
returnValue = new AMFFalseValue();
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFTrue: {
|
||||
returnValue = new AMFTrueValue();
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFInteger: {
|
||||
returnValue = ReadAmfInteger(inStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFDouble: {
|
||||
returnValue = ReadAmfDouble(inStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFString: {
|
||||
returnValue = ReadAmfString(inStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFValueType::AMFArray: {
|
||||
returnValue = ReadAmfArray(inStream);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO We do not need these values, but if someone wants to implement them
|
||||
// then please do so and add the corresponding unit tests.
|
||||
case AMFValueType::AMFXMLDoc:
|
||||
case AMFValueType::AMFDate:
|
||||
case AMFValueType::AMFObject:
|
||||
case AMFValueType::AMFXML:
|
||||
case AMFValueType::AMFByteArray:
|
||||
case AMFValueType::AMFVectorInt:
|
||||
case AMFValueType::AMFVectorUInt:
|
||||
case AMFValueType::AMFVectorDouble:
|
||||
case AMFValueType::AMFVectorObject:
|
||||
case AMFValueType::AMFDictionary: {
|
||||
throw static_cast<AMFValueType>(marker);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw static_cast<AMFValueType>(marker);
|
||||
break;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
uint32_t AMFDeserialize::ReadU29(RakNet::BitStream* inStream) {
|
||||
bool byteFlag = true;
|
||||
uint32_t actualNumber{};
|
||||
uint8_t numberOfBytesRead{};
|
||||
while (byteFlag && numberOfBytesRead < 4) {
|
||||
uint8_t byte{};
|
||||
inStream->Read(byte);
|
||||
// Parse the byte
|
||||
if (numberOfBytesRead < 3) {
|
||||
byteFlag = byte & static_cast<uint8_t>(1 << 7);
|
||||
byte = byte << 1UL;
|
||||
}
|
||||
// Combine the read byte with our current read in number
|
||||
actualNumber <<= 8UL;
|
||||
actualNumber |= static_cast<uint32_t>(byte);
|
||||
// If we are not done reading in bytes, shift right 1 bit
|
||||
if (numberOfBytesRead < 3) actualNumber = actualNumber >> 1UL;
|
||||
numberOfBytesRead++;
|
||||
}
|
||||
return actualNumber;
|
||||
}
|
||||
|
||||
std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) {
|
||||
auto length = ReadU29(inStream);
|
||||
// Check if this is a reference
|
||||
bool isReference = length % 2 == 1;
|
||||
// Right shift by 1 bit to get index if reference or size of next string if value
|
||||
length = length >> 1;
|
||||
if (isReference) {
|
||||
std::string value(length, 0);
|
||||
inStream->Read(&value[0], length);
|
||||
// Empty strings are never sent by reference
|
||||
if (!value.empty()) accessedElements.push_back(value);
|
||||
return value;
|
||||
} else {
|
||||
// Length is a reference to a previous index - use that as the read in value
|
||||
return accessedElements[length];
|
||||
}
|
||||
}
|
||||
|
||||
AMFValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) {
|
||||
auto doubleValue = new AMFDoubleValue();
|
||||
double value;
|
||||
inStream->Read<double>(value);
|
||||
doubleValue->SetDoubleValue(value);
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
AMFValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) {
|
||||
auto arrayValue = new AMFArrayValue();
|
||||
|
||||
// Read size of dense array
|
||||
auto sizeOfDenseArray = (ReadU29(inStream) >> 1);
|
||||
|
||||
// Then read Key'd portion
|
||||
while (true) {
|
||||
auto key = ReadString(inStream);
|
||||
// No more values when we encounter an empty string
|
||||
if (key.size() == 0) break;
|
||||
arrayValue->InsertValue(key, Read(inStream));
|
||||
}
|
||||
|
||||
// Finally read dense portion
|
||||
for (uint32_t i = 0; i < sizeOfDenseArray; i++) {
|
||||
arrayValue->PushBackValue(Read(inStream));
|
||||
}
|
||||
|
||||
return arrayValue;
|
||||
}
|
||||
|
||||
AMFValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) {
|
||||
auto stringValue = new AMFStringValue();
|
||||
stringValue->SetStringValue(ReadString(inStream));
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
AMFValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) {
|
||||
auto integerValue = new AMFIntegerValue();
|
||||
integerValue->SetIntegerValue(ReadU29(inStream));
|
||||
return integerValue;
|
||||
}
|
||||
71
dCommon/AMFDeserialize.h
Normal file
71
dCommon/AMFDeserialize.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include "BitStream.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class AMFValue;
|
||||
class AMFDeserialize {
|
||||
public:
|
||||
/**
|
||||
* Read an AMF3 value from a bitstream.
|
||||
*
|
||||
* @param inStream inStream to read value from.
|
||||
* @return Returns an AMFValue with all the information from the bitStream in it.
|
||||
*/
|
||||
AMFValue* Read(RakNet::BitStream* inStream);
|
||||
private:
|
||||
/**
|
||||
* @brief Private method to read a U29 integer from a bitstream
|
||||
*
|
||||
* @param inStream bitstream to read data from
|
||||
* @return The number as an unsigned 29 bit integer
|
||||
*/
|
||||
uint32_t ReadU29(RakNet::BitStream* inStream);
|
||||
|
||||
/**
|
||||
* @brief Reads a string from a bitstream
|
||||
*
|
||||
* @param inStream bitStream to read data from
|
||||
* @return The read string
|
||||
*/
|
||||
std::string ReadString(RakNet::BitStream* inStream);
|
||||
|
||||
/**
|
||||
* @brief Read an AMFDouble value from a bitStream
|
||||
*
|
||||
* @param inStream bitStream to read data from
|
||||
* @return Double value represented as an AMFValue
|
||||
*/
|
||||
AMFValue* ReadAmfDouble(RakNet::BitStream* inStream);
|
||||
|
||||
/**
|
||||
* @brief Read an AMFArray from a bitStream
|
||||
*
|
||||
* @param inStream bitStream to read data from
|
||||
* @return Array value represented as an AMFValue
|
||||
*/
|
||||
AMFValue* ReadAmfArray(RakNet::BitStream* inStream);
|
||||
|
||||
/**
|
||||
* @brief Read an AMFString from a bitStream
|
||||
*
|
||||
* @param inStream bitStream to read data from
|
||||
* @return String value represented as an AMFValue
|
||||
*/
|
||||
AMFValue* ReadAmfString(RakNet::BitStream* inStream);
|
||||
|
||||
/**
|
||||
* @brief Read an AMFInteger from a bitStream
|
||||
*
|
||||
* @param inStream bitStream to read data from
|
||||
* @return Integer value represented as an AMFValue
|
||||
*/
|
||||
AMFValue* ReadAmfInteger(RakNet::BitStream* inStream);
|
||||
|
||||
/**
|
||||
* List of strings read so far saved to be read by reference.
|
||||
*/
|
||||
std::vector<std::string> accessedElements;
|
||||
};
|
||||
@@ -2,156 +2,170 @@
|
||||
|
||||
// AMFInteger
|
||||
void AMFIntegerValue::SetIntegerValue(uint32_t value) {
|
||||
this->value = value;
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
uint32_t AMFIntegerValue::GetIntegerValue() {
|
||||
return this->value;
|
||||
return this->value;
|
||||
}
|
||||
|
||||
// AMFDouble
|
||||
void AMFDoubleValue::SetDoubleValue(double value) {
|
||||
this->value = value;
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
double AMFDoubleValue::GetDoubleValue() {
|
||||
return this->value;
|
||||
return this->value;
|
||||
}
|
||||
|
||||
// AMFString
|
||||
void AMFStringValue::SetStringValue(const std::string& value) {
|
||||
this->value = value;
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
std::string AMFStringValue::GetStringValue() {
|
||||
return this->value;
|
||||
return this->value;
|
||||
}
|
||||
|
||||
// AMFXMLDoc
|
||||
void AMFXMLDocValue::SetXMLDocValue(const std::string& value) {
|
||||
this->xmlData = value;
|
||||
this->xmlData = value;
|
||||
}
|
||||
|
||||
std::string AMFXMLDocValue::GetXMLDocValue() {
|
||||
return this->xmlData;
|
||||
return this->xmlData;
|
||||
}
|
||||
|
||||
// AMFDate
|
||||
void AMFDateValue::SetDateValue(uint64_t value) {
|
||||
this->millisecondTimestamp = value;
|
||||
this->millisecondTimestamp = value;
|
||||
}
|
||||
|
||||
uint64_t AMFDateValue::GetDateValue() {
|
||||
return this->millisecondTimestamp;
|
||||
return this->millisecondTimestamp;
|
||||
}
|
||||
|
||||
// AMFArray Insert Value
|
||||
void AMFArrayValue::InsertValue(const std::string& key, AMFValue* value) {
|
||||
this->associative.insert(std::make_pair(key, value));
|
||||
this->associative.insert(std::make_pair(key, value));
|
||||
}
|
||||
|
||||
// AMFArray Remove Value
|
||||
void AMFArrayValue::RemoveValue(const std::string& key) {
|
||||
_AMFArrayMap_::iterator it = this->associative.find(key);
|
||||
if (it != this->associative.end()) {
|
||||
this->associative.erase(it);
|
||||
}
|
||||
_AMFArrayMap_::iterator it = this->associative.find(key);
|
||||
if (it != this->associative.end()) {
|
||||
this->associative.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// AMFArray Find Value
|
||||
AMFValue* AMFArrayValue::FindValue(const std::string& key) {
|
||||
_AMFArrayMap_::iterator it = this->associative.find(key);
|
||||
if (it != this->associative.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
_AMFArrayMap_::iterator it = this->associative.find(key);
|
||||
if (it != this->associative.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// AMFArray Get Associative Iterator Begin
|
||||
_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueBegin() {
|
||||
return this->associative.begin();
|
||||
return this->associative.begin();
|
||||
}
|
||||
|
||||
// AMFArray Get Associative Iterator End
|
||||
_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueEnd() {
|
||||
return this->associative.end();
|
||||
return this->associative.end();
|
||||
}
|
||||
|
||||
// AMFArray Push Back Value
|
||||
void AMFArrayValue::PushBackValue(AMFValue* value) {
|
||||
this->dense.push_back(value);
|
||||
this->dense.push_back(value);
|
||||
}
|
||||
|
||||
// AMFArray Pop Back Value
|
||||
void AMFArrayValue::PopBackValue() {
|
||||
this->dense.pop_back();
|
||||
this->dense.pop_back();
|
||||
}
|
||||
|
||||
// AMFArray Get Dense List Size
|
||||
uint32_t AMFArrayValue::GetDenseValueSize() {
|
||||
return (uint32_t)this->dense.size();
|
||||
return (uint32_t)this->dense.size();
|
||||
}
|
||||
|
||||
// AMFArray Get value at index in Dense List
|
||||
AMFValue* AMFArrayValue::GetValueAt(uint32_t index) {
|
||||
return this->dense.at(index);
|
||||
return this->dense.at(index);
|
||||
}
|
||||
|
||||
// AMFArray Get Dense Iterator Begin
|
||||
_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorBegin() {
|
||||
return this->dense.begin();
|
||||
return this->dense.begin();
|
||||
}
|
||||
|
||||
// AMFArray Get Dense Iterator End
|
||||
_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorEnd() {
|
||||
return this->dense.end();
|
||||
return this->dense.end();
|
||||
}
|
||||
|
||||
AMFArrayValue::~AMFArrayValue() {
|
||||
for (auto valueToDelete : GetDenseArray()) {
|
||||
if (valueToDelete) delete valueToDelete;
|
||||
}
|
||||
for (auto valueToDelete : GetAssociativeMap()) {
|
||||
if (valueToDelete.second) delete valueToDelete.second;
|
||||
}
|
||||
}
|
||||
|
||||
// AMFObject Constructor
|
||||
AMFObjectValue::AMFObjectValue(std::vector<std::pair<std::string, AMFValueType>> traits) {
|
||||
this->traits.reserve(traits.size());
|
||||
std::vector<std::pair<std::string, AMFValueType>>::iterator it = traits.begin();
|
||||
while (it != traits.end()) {
|
||||
this->traits.insert(std::make_pair(it->first, std::make_pair(it->second, new AMFNullValue())));
|
||||
it++;
|
||||
}
|
||||
this->traits.reserve(traits.size());
|
||||
std::vector<std::pair<std::string, AMFValueType>>::iterator it = traits.begin();
|
||||
while (it != traits.end()) {
|
||||
this->traits.insert(std::make_pair(it->first, std::make_pair(it->second, new AMFNullValue())));
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
// AMFObject Set Value
|
||||
void AMFObjectValue::SetTraitValue(const std::string& trait, AMFValue* value) {
|
||||
if (value) {
|
||||
_AMFObjectTraits_::iterator it = this->traits.find(trait);
|
||||
if (it != this->traits.end()) {
|
||||
if (it->second.first == value->GetValueType()) {
|
||||
it->second.second = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value) {
|
||||
_AMFObjectTraits_::iterator it = this->traits.find(trait);
|
||||
if (it != this->traits.end()) {
|
||||
if (it->second.first == value->GetValueType()) {
|
||||
it->second.second = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AMFObject Get Value
|
||||
AMFValue* AMFObjectValue::GetTraitValue(const std::string& trait) {
|
||||
_AMFObjectTraits_::iterator it = this->traits.find(trait);
|
||||
if (it != this->traits.end()) {
|
||||
return it->second.second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
_AMFObjectTraits_::iterator it = this->traits.find(trait);
|
||||
if (it != this->traits.end()) {
|
||||
return it->second.second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// AMFObject Get Trait Iterator Begin
|
||||
_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorBegin() {
|
||||
return this->traits.begin();
|
||||
return this->traits.begin();
|
||||
}
|
||||
|
||||
// AMFObject Get Trait Iterator End
|
||||
_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorEnd() {
|
||||
return this->traits.end();
|
||||
return this->traits.end();
|
||||
}
|
||||
|
||||
// AMFObject Get Trait Size
|
||||
uint32_t AMFObjectValue::GetTraitArrayCount() {
|
||||
return (uint32_t)this->traits.size();
|
||||
return (uint32_t)this->traits.size();
|
||||
}
|
||||
|
||||
AMFObjectValue::~AMFObjectValue() {
|
||||
for (auto valueToDelete = GetTraitsIteratorBegin(); valueToDelete != GetTraitsIteratorEnd(); valueToDelete++) {
|
||||
if (valueToDelete->second.second) delete valueToDelete->second.second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,42 +23,43 @@ class AMFValue; // Forward declaration
|
||||
|
||||
//! An enum for each AMF value type
|
||||
enum AMFValueType : unsigned char {
|
||||
AMFUndefined = 0x00, //!< An undefined AMF Value
|
||||
AMFNull = 0x01, //!< A null AMF value
|
||||
AMFFalse = 0x02, //!< A false AMF value
|
||||
AMFTrue = 0x03, //!< A true AMF value
|
||||
AMFInteger = 0x04, //!< An integer AMF value
|
||||
AMFDouble = 0x05, //!< A double AMF value
|
||||
AMFString = 0x06, //!< A string AMF value
|
||||
AMFXMLDoc = 0x07, //!< An XML Doc AMF value
|
||||
AMFDate = 0x08, //!< A date AMF value
|
||||
AMFArray = 0x09, //!< An array AMF value
|
||||
AMFObject = 0x0A, //!< An object AMF value
|
||||
AMFXML = 0x0B, //!< An XML AMF value
|
||||
AMFByteArray = 0x0C, //!< A byte array AMF value
|
||||
AMFVectorInt = 0x0D, //!< An integer vector AMF value
|
||||
AMFVectorUInt = 0x0E, //!< An unsigned integer AMF value
|
||||
AMFVectorDouble = 0x0F, //!< A double vector AMF value
|
||||
AMFVectorObject = 0x10, //!< An object vector AMF value
|
||||
AMFDictionary = 0x11 //!< A dictionary AMF value
|
||||
AMFUndefined = 0x00, //!< An undefined AMF Value
|
||||
AMFNull = 0x01, //!< A null AMF value
|
||||
AMFFalse = 0x02, //!< A false AMF value
|
||||
AMFTrue = 0x03, //!< A true AMF value
|
||||
AMFInteger = 0x04, //!< An integer AMF value
|
||||
AMFDouble = 0x05, //!< A double AMF value
|
||||
AMFString = 0x06, //!< A string AMF value
|
||||
AMFXMLDoc = 0x07, //!< An XML Doc AMF value
|
||||
AMFDate = 0x08, //!< A date AMF value
|
||||
AMFArray = 0x09, //!< An array AMF value
|
||||
AMFObject = 0x0A, //!< An object AMF value
|
||||
AMFXML = 0x0B, //!< An XML AMF value
|
||||
AMFByteArray = 0x0C, //!< A byte array AMF value
|
||||
AMFVectorInt = 0x0D, //!< An integer vector AMF value
|
||||
AMFVectorUInt = 0x0E, //!< An unsigned integer AMF value
|
||||
AMFVectorDouble = 0x0F, //!< A double vector AMF value
|
||||
AMFVectorObject = 0x10, //!< An object vector AMF value
|
||||
AMFDictionary = 0x11 //!< A dictionary AMF value
|
||||
};
|
||||
|
||||
//! An enum for the object value types
|
||||
enum AMFObjectValueType : unsigned char {
|
||||
AMFObjectAnonymous = 0x01,
|
||||
AMFObjectTyped = 0x02,
|
||||
AMFObjectDynamic = 0x03,
|
||||
AMFObjectExternalizable = 0x04
|
||||
AMFObjectAnonymous = 0x01,
|
||||
AMFObjectTyped = 0x02,
|
||||
AMFObjectDynamic = 0x03,
|
||||
AMFObjectExternalizable = 0x04
|
||||
};
|
||||
|
||||
//! The base AMF value class
|
||||
class AMFValue {
|
||||
public:
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
virtual AMFValueType GetValueType() = 0;
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
virtual AMFValueType GetValueType() = 0;
|
||||
virtual ~AMFValue() {};
|
||||
};
|
||||
|
||||
//! A typedef for a pointer to an AMF value
|
||||
@@ -70,299 +71,314 @@ typedef AMFValue* NDGFxValue;
|
||||
//! The undefined value AMF type
|
||||
class AMFUndefinedValue : public AMFValue {
|
||||
private:
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFUndefined; }
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFUndefined; }
|
||||
};
|
||||
|
||||
//! The null value AMF type
|
||||
class AMFNullValue : public AMFValue {
|
||||
private:
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFNull; }
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFNull; }
|
||||
};
|
||||
|
||||
//! The false value AMF type
|
||||
class AMFFalseValue : public AMFValue {
|
||||
private:
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFFalse; }
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFFalse; }
|
||||
};
|
||||
|
||||
//! The true value AMF type
|
||||
class AMFTrueValue : public AMFValue {
|
||||
private:
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFTrue; }
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFTrue; }
|
||||
};
|
||||
|
||||
//! The integer value AMF type
|
||||
class AMFIntegerValue : public AMFValue {
|
||||
private:
|
||||
uint32_t value; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFInteger; }
|
||||
|
||||
uint32_t value; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFInteger; }
|
||||
|
||||
public:
|
||||
//! Sets the integer value
|
||||
/*!
|
||||
\param value The value to set
|
||||
*/
|
||||
void SetIntegerValue(uint32_t value);
|
||||
|
||||
//! Gets the integer value
|
||||
/*!
|
||||
\return The integer value
|
||||
*/
|
||||
uint32_t GetIntegerValue();
|
||||
//! Sets the integer value
|
||||
/*!
|
||||
\param value The value to set
|
||||
*/
|
||||
void SetIntegerValue(uint32_t value);
|
||||
|
||||
//! Gets the integer value
|
||||
/*!
|
||||
\return The integer value
|
||||
*/
|
||||
uint32_t GetIntegerValue();
|
||||
};
|
||||
|
||||
//! The double value AMF type
|
||||
class AMFDoubleValue : public AMFValue {
|
||||
private:
|
||||
double value; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFDouble; }
|
||||
|
||||
double value; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFDouble; }
|
||||
|
||||
public:
|
||||
//! Sets the double value
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetDoubleValue(double value);
|
||||
|
||||
//! Gets the double value
|
||||
/*!
|
||||
\return The double value
|
||||
*/
|
||||
double GetDoubleValue();
|
||||
//! Sets the double value
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetDoubleValue(double value);
|
||||
|
||||
//! Gets the double value
|
||||
/*!
|
||||
\return The double value
|
||||
*/
|
||||
double GetDoubleValue();
|
||||
};
|
||||
|
||||
//! The string value AMF type
|
||||
class AMFStringValue : public AMFValue {
|
||||
private:
|
||||
std::string value; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFString; }
|
||||
|
||||
std::string value; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFString; }
|
||||
|
||||
public:
|
||||
//! Sets the string value
|
||||
/*!
|
||||
\param value The string value to set to
|
||||
*/
|
||||
void SetStringValue(const std::string& value);
|
||||
|
||||
//! Gets the string value
|
||||
/*!
|
||||
\return The string value
|
||||
*/
|
||||
std::string GetStringValue();
|
||||
//! Sets the string value
|
||||
/*!
|
||||
\param value The string value to set to
|
||||
*/
|
||||
void SetStringValue(const std::string& value);
|
||||
|
||||
//! Gets the string value
|
||||
/*!
|
||||
\return The string value
|
||||
*/
|
||||
std::string GetStringValue();
|
||||
};
|
||||
|
||||
//! The XML doc value AMF type
|
||||
class AMFXMLDocValue : public AMFValue {
|
||||
private:
|
||||
std::string xmlData; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFXMLDoc; }
|
||||
|
||||
std::string xmlData; //!< The value of the AMF type
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFXMLDoc; }
|
||||
|
||||
public:
|
||||
//! Sets the XML Doc value
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetXMLDocValue(const std::string& value);
|
||||
|
||||
//! Gets the XML Doc value
|
||||
/*!
|
||||
\return The XML Doc value
|
||||
*/
|
||||
std::string GetXMLDocValue();
|
||||
//! Sets the XML Doc value
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetXMLDocValue(const std::string& value);
|
||||
|
||||
//! Gets the XML Doc value
|
||||
/*!
|
||||
\return The XML Doc value
|
||||
*/
|
||||
std::string GetXMLDocValue();
|
||||
};
|
||||
|
||||
//! The date value AMF type
|
||||
class AMFDateValue : public AMFValue {
|
||||
private:
|
||||
uint64_t millisecondTimestamp; //!< The time in milliseconds since the ephoch
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFDate; }
|
||||
|
||||
uint64_t millisecondTimestamp; //!< The time in milliseconds since the ephoch
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFDate; }
|
||||
|
||||
public:
|
||||
//! Sets the date time
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetDateValue(uint64_t value);
|
||||
|
||||
//! Gets the date value
|
||||
/*!
|
||||
\return The date value in milliseconds since the epoch
|
||||
*/
|
||||
uint64_t GetDateValue();
|
||||
//! Sets the date time
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetDateValue(uint64_t value);
|
||||
|
||||
//! Gets the date value
|
||||
/*!
|
||||
\return The date value in milliseconds since the epoch
|
||||
*/
|
||||
uint64_t GetDateValue();
|
||||
};
|
||||
|
||||
//! The array value AMF type
|
||||
// This object will manage it's own memory map and list. Do not delete its values.
|
||||
class AMFArrayValue : public AMFValue {
|
||||
private:
|
||||
_AMFArrayMap_ associative; //!< The array map (associative part)
|
||||
_AMFArrayList_ dense; //!< The array list (dense part)
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFArray; }
|
||||
|
||||
_AMFArrayMap_ associative; //!< The array map (associative part)
|
||||
_AMFArrayList_ dense; //!< The array list (dense part)
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFArray; }
|
||||
|
||||
public:
|
||||
//! Inserts an item into the array map for a specific key
|
||||
/*!
|
||||
\param key The key to set
|
||||
\param value The value to add
|
||||
*/
|
||||
void InsertValue(const std::string& key, AMFValue* value);
|
||||
|
||||
//! Removes an item for a specific key
|
||||
/*!
|
||||
\param key The key to remove
|
||||
*/
|
||||
void RemoveValue(const std::string& key);
|
||||
|
||||
//! Finds an AMF value
|
||||
/*!
|
||||
\return The AMF value if found, nullptr otherwise
|
||||
*/
|
||||
AMFValue* FindValue(const std::string& key);
|
||||
|
||||
//! Returns where the associative iterator begins
|
||||
/*!
|
||||
\return Where the array map iterator begins
|
||||
*/
|
||||
_AMFArrayMap_::iterator GetAssociativeIteratorValueBegin();
|
||||
|
||||
//! Returns where the associative iterator ends
|
||||
/*!
|
||||
\return Where the array map iterator ends
|
||||
*/
|
||||
_AMFArrayMap_::iterator GetAssociativeIteratorValueEnd();
|
||||
|
||||
//! Pushes back a value into the array list
|
||||
/*!
|
||||
\param value The value to push back
|
||||
*/
|
||||
void PushBackValue(AMFValue* value);
|
||||
|
||||
//! Pops back the last value in the array list
|
||||
void PopBackValue();
|
||||
|
||||
//! Gets the count of the dense list
|
||||
/*!
|
||||
\return The dense list size
|
||||
*/
|
||||
uint32_t GetDenseValueSize();
|
||||
|
||||
//! Gets a specific value from the list for the specified index
|
||||
/*!
|
||||
\param index The index to get
|
||||
*/
|
||||
AMFValue* GetValueAt(uint32_t index);
|
||||
|
||||
//! Returns where the dense iterator begins
|
||||
/*!
|
||||
\return Where the iterator begins
|
||||
*/
|
||||
_AMFArrayList_::iterator GetDenseIteratorBegin();
|
||||
|
||||
//! Returns where the dense iterator ends
|
||||
/*!
|
||||
\return Where the iterator ends
|
||||
*/
|
||||
_AMFArrayList_::iterator GetDenseIteratorEnd();
|
||||
~AMFArrayValue() override;
|
||||
//! Inserts an item into the array map for a specific key
|
||||
/*!
|
||||
\param key The key to set
|
||||
\param value The value to add
|
||||
*/
|
||||
void InsertValue(const std::string& key, AMFValue* value);
|
||||
|
||||
//! Removes an item for a specific key
|
||||
/*!
|
||||
\param key The key to remove
|
||||
*/
|
||||
void RemoveValue(const std::string& key);
|
||||
|
||||
//! Finds an AMF value
|
||||
/*!
|
||||
\return The AMF value if found, nullptr otherwise
|
||||
*/
|
||||
AMFValue* FindValue(const std::string& key);
|
||||
|
||||
//! Returns where the associative iterator begins
|
||||
/*!
|
||||
\return Where the array map iterator begins
|
||||
*/
|
||||
_AMFArrayMap_::iterator GetAssociativeIteratorValueBegin();
|
||||
|
||||
//! Returns where the associative iterator ends
|
||||
/*!
|
||||
\return Where the array map iterator ends
|
||||
*/
|
||||
_AMFArrayMap_::iterator GetAssociativeIteratorValueEnd();
|
||||
|
||||
//! Pushes back a value into the array list
|
||||
/*!
|
||||
\param value The value to push back
|
||||
*/
|
||||
void PushBackValue(AMFValue* value);
|
||||
|
||||
//! Pops back the last value in the array list
|
||||
void PopBackValue();
|
||||
|
||||
//! Gets the count of the dense list
|
||||
/*!
|
||||
\return The dense list size
|
||||
*/
|
||||
uint32_t GetDenseValueSize();
|
||||
|
||||
//! Gets a specific value from the list for the specified index
|
||||
/*!
|
||||
\param index The index to get
|
||||
*/
|
||||
AMFValue* GetValueAt(uint32_t index);
|
||||
|
||||
//! Returns where the dense iterator begins
|
||||
/*!
|
||||
\return Where the iterator begins
|
||||
*/
|
||||
_AMFArrayList_::iterator GetDenseIteratorBegin();
|
||||
|
||||
//! Returns where the dense iterator ends
|
||||
/*!
|
||||
\return Where the iterator ends
|
||||
*/
|
||||
_AMFArrayList_::iterator GetDenseIteratorEnd();
|
||||
|
||||
//! Returns the associative map
|
||||
/*!
|
||||
\return The associative map
|
||||
*/
|
||||
_AMFArrayMap_ GetAssociativeMap() { return this->associative; };
|
||||
|
||||
//! Returns the dense array
|
||||
/*!
|
||||
\return The dense array
|
||||
*/
|
||||
_AMFArrayList_ GetDenseArray() { return this->dense; };
|
||||
};
|
||||
|
||||
//! The anonymous object value AMF type
|
||||
class AMFObjectValue : public AMFValue {
|
||||
private:
|
||||
_AMFObjectTraits_ traits; //!< The object traits
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFObject; }
|
||||
|
||||
_AMFObjectTraits_ traits; //!< The object traits
|
||||
|
||||
//! Returns the AMF value type
|
||||
/*!
|
||||
\return The AMF value type
|
||||
*/
|
||||
AMFValueType GetValueType() { return AMFObject; }
|
||||
~AMFObjectValue() override;
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
/*!
|
||||
\param traits The traits to set
|
||||
*/
|
||||
AMFObjectValue(std::vector<std::pair<std::string, AMFValueType>> traits);
|
||||
|
||||
//! Gets the object value type
|
||||
/*!
|
||||
\return The object value type
|
||||
*/
|
||||
virtual AMFObjectValueType GetObjectValueType() { return AMFObjectAnonymous; }
|
||||
|
||||
//! Sets the value of a trait
|
||||
/*!
|
||||
\param trait The trait to set the value for
|
||||
\param value The AMF value to set
|
||||
*/
|
||||
void SetTraitValue(const std::string& trait, AMFValue* value);
|
||||
|
||||
//! Gets a trait value
|
||||
/*!
|
||||
\param trait The trait to get the value for
|
||||
\return The trait value
|
||||
*/
|
||||
AMFValue* GetTraitValue(const std::string& trait);
|
||||
|
||||
//! Gets the beginning of the object traits iterator
|
||||
/*!
|
||||
\return The AMF trait array iterator begin
|
||||
*/
|
||||
_AMFObjectTraits_::iterator GetTraitsIteratorBegin();
|
||||
|
||||
//! Gets the end of the object traits iterator
|
||||
/*!
|
||||
\return The AMF trait array iterator begin
|
||||
*/
|
||||
_AMFObjectTraits_::iterator GetTraitsIteratorEnd();
|
||||
|
||||
//! Gets the amount of traits
|
||||
/*!
|
||||
\return The amount of traits
|
||||
*/
|
||||
uint32_t GetTraitArrayCount();
|
||||
//! Constructor
|
||||
/*!
|
||||
\param traits The traits to set
|
||||
*/
|
||||
AMFObjectValue(std::vector<std::pair<std::string, AMFValueType>> traits);
|
||||
|
||||
//! Gets the object value type
|
||||
/*!
|
||||
\return The object value type
|
||||
*/
|
||||
virtual AMFObjectValueType GetObjectValueType() { return AMFObjectAnonymous; }
|
||||
|
||||
//! Sets the value of a trait
|
||||
/*!
|
||||
\param trait The trait to set the value for
|
||||
\param value The AMF value to set
|
||||
*/
|
||||
void SetTraitValue(const std::string& trait, AMFValue* value);
|
||||
|
||||
//! Gets a trait value
|
||||
/*!
|
||||
\param trait The trait to get the value for
|
||||
\return The trait value
|
||||
*/
|
||||
AMFValue* GetTraitValue(const std::string& trait);
|
||||
|
||||
//! Gets the beginning of the object traits iterator
|
||||
/*!
|
||||
\return The AMF trait array iterator begin
|
||||
*/
|
||||
_AMFObjectTraits_::iterator GetTraitsIteratorBegin();
|
||||
|
||||
//! Gets the end of the object traits iterator
|
||||
/*!
|
||||
\return The AMF trait array iterator begin
|
||||
*/
|
||||
_AMFObjectTraits_::iterator GetTraitsIteratorEnd();
|
||||
|
||||
//! Gets the amount of traits
|
||||
/*!
|
||||
\return The amount of traits
|
||||
*/
|
||||
uint32_t GetTraitArrayCount();
|
||||
};
|
||||
|
||||
@@ -3,269 +3,248 @@
|
||||
// Writes an AMFValue pointer to a RakNet::BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value) {
|
||||
if (value != nullptr) {
|
||||
AMFValueType type = value->GetValueType();
|
||||
|
||||
switch (type) {
|
||||
case AMFUndefined: {
|
||||
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFNull: {
|
||||
AMFNullValue* v = (AMFNullValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFFalse: {
|
||||
AMFFalseValue* v = (AMFFalseValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFTrue: {
|
||||
AMFTrueValue* v = (AMFTrueValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFInteger: {
|
||||
AMFIntegerValue* v = (AMFIntegerValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFString: {
|
||||
AMFStringValue* v = (AMFStringValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFXMLDoc: {
|
||||
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFDate: {
|
||||
AMFDateValue* v = (AMFDateValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFArray: {
|
||||
AMFArrayValue* v = (AMFArrayValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != nullptr) {
|
||||
AMFValueType type = value->GetValueType();
|
||||
|
||||
switch (type) {
|
||||
case AMFUndefined: {
|
||||
AMFUndefinedValue* v = (AMFUndefinedValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFNull: {
|
||||
AMFNullValue* v = (AMFNullValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFFalse: {
|
||||
AMFFalseValue* v = (AMFFalseValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFTrue: {
|
||||
AMFTrueValue* v = (AMFTrueValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFInteger: {
|
||||
AMFIntegerValue* v = (AMFIntegerValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFDouble: {
|
||||
AMFDoubleValue* v = (AMFDoubleValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFString: {
|
||||
AMFStringValue* v = (AMFStringValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFXMLDoc: {
|
||||
AMFXMLDocValue* v = (AMFXMLDocValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFDate: {
|
||||
AMFDateValue* v = (AMFDateValue*)value;
|
||||
this->Write(*v);
|
||||
break;
|
||||
}
|
||||
|
||||
case AMFArray: {
|
||||
this->Write((AMFArrayValue*)value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A private function to write an value to a RakNet::BitStream
|
||||
/**
|
||||
* A private function to write an value to a RakNet::BitStream
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteUInt29(RakNet::BitStream* bs, uint32_t v) {
|
||||
unsigned char b4 = (unsigned char)v;
|
||||
if (v < 0x00200000) {
|
||||
b4 = b4 & 0x7F;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b3;
|
||||
v = v >> 7;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b2;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
bs->Write(b2);
|
||||
}
|
||||
|
||||
bs->Write(b3);
|
||||
}
|
||||
} else {
|
||||
unsigned char b1;
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
|
||||
v = v >> 8;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b1 = ((unsigned char)(v)) | 0x80;
|
||||
|
||||
bs->Write(b1);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
}
|
||||
|
||||
bs->Write(b4);
|
||||
unsigned char b4 = (unsigned char)v;
|
||||
if (v < 0x00200000) {
|
||||
b4 = b4 & 0x7F;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b3;
|
||||
v = v >> 7;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
if (v > 0x7F) {
|
||||
unsigned char b2;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
bs->Write(b2);
|
||||
}
|
||||
|
||||
bs->Write(b3);
|
||||
}
|
||||
} else {
|
||||
unsigned char b1;
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
|
||||
v = v >> 8;
|
||||
b3 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b2 = ((unsigned char)(v)) | 0x80;
|
||||
v = v >> 7;
|
||||
b1 = ((unsigned char)(v)) | 0x80;
|
||||
|
||||
bs->Write(b1);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
}
|
||||
|
||||
bs->Write(b4);
|
||||
}
|
||||
|
||||
// Writes a flag number to a RakNet::BitStream
|
||||
/**
|
||||
* Writes a flag number to a RakNet::BitStream
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) {
|
||||
v = (v << 1) | 0x01;
|
||||
WriteUInt29(bs, v);
|
||||
v = (v << 1) | 0x01;
|
||||
WriteUInt29(bs, v);
|
||||
}
|
||||
|
||||
// Writes an AMFString to a RakNet::BitStream
|
||||
/**
|
||||
* Writes an AMFString to a RakNet::BitStream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFString(RakNet::BitStream* bs, const std::string& str) {
|
||||
WriteFlagNumber(bs, (uint32_t)str.size());
|
||||
bs->Write(str.c_str(), (uint32_t)str.size());
|
||||
WriteFlagNumber(bs, (uint32_t)str.size());
|
||||
bs->Write(str.c_str(), (uint32_t)str.size());
|
||||
}
|
||||
|
||||
// Writes an AMF U16 to a RakNet::BitStream
|
||||
/**
|
||||
* Writes an U16 to a bitstream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) {
|
||||
unsigned char b2;
|
||||
b2 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
bs->Write((unsigned char)value);
|
||||
bs->Write(b2);
|
||||
bs->Write(value);
|
||||
}
|
||||
|
||||
// Writes an AMF U32 to RakNet::BitStream
|
||||
/**
|
||||
* Writes an U32 to a bitstream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) {
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
unsigned char b4;
|
||||
|
||||
b4 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b3 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b2 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
|
||||
bs->Write((unsigned char)value);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
bs->Write(b4);
|
||||
bs->Write(value);
|
||||
}
|
||||
|
||||
// Writes an AMF U64 to RakNet::BitStream
|
||||
/**
|
||||
* Writes an U64 to a bitstream
|
||||
*
|
||||
* RakNet writes in the correct byte order - do not reverse this.
|
||||
*/
|
||||
void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) {
|
||||
unsigned char b2;
|
||||
unsigned char b3;
|
||||
unsigned char b4;
|
||||
unsigned char b5;
|
||||
unsigned char b6;
|
||||
unsigned char b7;
|
||||
unsigned char b8;
|
||||
|
||||
b8 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b7 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b6 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b5 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b4 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b3 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
b2 = (unsigned char)value;
|
||||
value = value >> 8;
|
||||
|
||||
bs->Write((unsigned char)value);
|
||||
bs->Write(b2);
|
||||
bs->Write(b3);
|
||||
bs->Write(b4);
|
||||
bs->Write(b5);
|
||||
bs->Write(b6);
|
||||
bs->Write(b7);
|
||||
bs->Write(b8);
|
||||
bs->Write(value);
|
||||
}
|
||||
|
||||
|
||||
// Writes an AMFUndefinedValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value) {
|
||||
this->Write(AMFUndefined);
|
||||
this->Write(AMFUndefined);
|
||||
}
|
||||
|
||||
// Writes an AMFNullValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value) {
|
||||
this->Write(AMFNull);
|
||||
this->Write(AMFNull);
|
||||
}
|
||||
|
||||
// Writes an AMFFalseValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value) {
|
||||
this->Write(AMFFalse);
|
||||
this->Write(AMFFalse);
|
||||
}
|
||||
|
||||
// Writes an AMFTrueValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value) {
|
||||
this->Write(AMFTrue);
|
||||
this->Write(AMFTrue);
|
||||
}
|
||||
|
||||
// Writes an AMFIntegerValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value) {
|
||||
this->Write(AMFInteger);
|
||||
WriteUInt29(this, value.GetIntegerValue());
|
||||
this->Write(AMFInteger);
|
||||
WriteUInt29(this, value.GetIntegerValue());
|
||||
}
|
||||
|
||||
// Writes an AMFDoubleValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value) {
|
||||
this->Write(AMFDouble);
|
||||
double d = value.GetDoubleValue();
|
||||
WriteAMFU64(this, *((unsigned long long*)&d));
|
||||
this->Write(AMFDouble);
|
||||
double d = value.GetDoubleValue();
|
||||
WriteAMFU64(this, *((unsigned long long*) & d));
|
||||
}
|
||||
|
||||
// Writes an AMFStringValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value) {
|
||||
this->Write(AMFString);
|
||||
std::string v = value.GetStringValue();
|
||||
WriteAMFString(this, v);
|
||||
this->Write(AMFString);
|
||||
std::string v = value.GetStringValue();
|
||||
WriteAMFString(this, v);
|
||||
}
|
||||
|
||||
// Writes an AMFXMLDocValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value) {
|
||||
this->Write(AMFXMLDoc);
|
||||
std::string v = value.GetXMLDocValue();
|
||||
WriteAMFString(this, v);
|
||||
this->Write(AMFXMLDoc);
|
||||
std::string v = value.GetXMLDocValue();
|
||||
WriteAMFString(this, v);
|
||||
}
|
||||
|
||||
// Writes an AMFDateValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value) {
|
||||
this->Write(AMFDate);
|
||||
uint64_t date = value.GetDateValue();
|
||||
WriteAMFU64(this, date);
|
||||
this->Write(AMFDate);
|
||||
uint64_t date = value.GetDateValue();
|
||||
WriteAMFU64(this, date);
|
||||
}
|
||||
|
||||
// Writes an AMFArrayValue to BitStream
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFArrayValue>(AMFArrayValue value) {
|
||||
this->Write(AMFArray);
|
||||
uint32_t denseSize = value.GetDenseValueSize();
|
||||
WriteFlagNumber(this, denseSize);
|
||||
|
||||
_AMFArrayMap_::iterator it = value.GetAssociativeIteratorValueBegin();
|
||||
_AMFArrayMap_::iterator end = value.GetAssociativeIteratorValueEnd();
|
||||
|
||||
while (it != end) {
|
||||
WriteAMFString(this, it->first);
|
||||
this->Write(it->second);
|
||||
it++;
|
||||
}
|
||||
|
||||
this->Write(AMFNull);
|
||||
|
||||
if (denseSize > 0) {
|
||||
_AMFArrayList_::iterator it2 = value.GetDenseIteratorBegin();
|
||||
_AMFArrayList_::iterator end2 = value.GetDenseIteratorEnd();
|
||||
|
||||
while (it2 != end2) {
|
||||
this->Write(*it2);
|
||||
it2++;
|
||||
}
|
||||
}
|
||||
void RakNet::BitStream::Write<AMFArrayValue*>(AMFArrayValue* value) {
|
||||
this->Write(AMFArray);
|
||||
uint32_t denseSize = value->GetDenseValueSize();
|
||||
WriteFlagNumber(this, denseSize);
|
||||
|
||||
_AMFArrayMap_::iterator it = value->GetAssociativeIteratorValueBegin();
|
||||
_AMFArrayMap_::iterator end = value->GetAssociativeIteratorValueEnd();
|
||||
|
||||
while (it != end) {
|
||||
WriteAMFString(this, it->first);
|
||||
this->Write(it->second);
|
||||
it++;
|
||||
}
|
||||
|
||||
this->Write(AMFNull);
|
||||
|
||||
if (denseSize > 0) {
|
||||
_AMFArrayList_::iterator it2 = value->GetDenseIteratorBegin();
|
||||
_AMFArrayList_::iterator end2 = value->GetDenseIteratorEnd();
|
||||
|
||||
while (it2 != end2) {
|
||||
this->Write(*it2);
|
||||
it2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,86 +7,86 @@
|
||||
#include <BitStream.h>
|
||||
|
||||
/*!
|
||||
\file AMFBitStream.hpp
|
||||
\brief A class that implements native writing of AMF values to RakNet::BitStream
|
||||
\file AMFFormat_BitStream.h
|
||||
\brief A class that implements native writing of AMF values to RakNet::BitStream
|
||||
*/
|
||||
|
||||
// We are using the RakNet namespace
|
||||
// We are using the RakNet namespace
|
||||
namespace RakNet {
|
||||
//! Writes an AMFValue pointer to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value);
|
||||
|
||||
//! Writes an AMFUndefinedValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value);
|
||||
|
||||
//! Writes an AMFNullValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value);
|
||||
|
||||
//! Writes an AMFFalseValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value);
|
||||
|
||||
//! Writes an AMFTrueValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value);
|
||||
|
||||
//! Writes an AMFIntegerValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value);
|
||||
|
||||
//! Writes an AMFDoubleValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value);
|
||||
|
||||
//! Writes an AMFStringValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value);
|
||||
|
||||
//! Writes an AMFXMLDocValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value);
|
||||
|
||||
//! Writes an AMFDateValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value);
|
||||
|
||||
//! Writes an AMFArrayValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template<>
|
||||
void RakNet::BitStream::Write<AMFArrayValue>(AMFArrayValue value);
|
||||
}
|
||||
//! Writes an AMFValue pointer to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFValue*>(AMFValue* value);
|
||||
|
||||
//! Writes an AMFUndefinedValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFUndefinedValue>(AMFUndefinedValue value);
|
||||
|
||||
//! Writes an AMFNullValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFNullValue>(AMFNullValue value);
|
||||
|
||||
//! Writes an AMFFalseValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFFalseValue>(AMFFalseValue value);
|
||||
|
||||
//! Writes an AMFTrueValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFTrueValue>(AMFTrueValue value);
|
||||
|
||||
//! Writes an AMFIntegerValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFIntegerValue>(AMFIntegerValue value);
|
||||
|
||||
//! Writes an AMFDoubleValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFDoubleValue>(AMFDoubleValue value);
|
||||
|
||||
//! Writes an AMFStringValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFStringValue>(AMFStringValue value);
|
||||
|
||||
//! Writes an AMFXMLDocValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFXMLDocValue>(AMFXMLDocValue value);
|
||||
|
||||
//! Writes an AMFDateValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFDateValue>(AMFDateValue value);
|
||||
|
||||
//! Writes an AMFArrayValue to a RakNet::BitStream
|
||||
/*!
|
||||
\param value The value to write
|
||||
*/
|
||||
template <>
|
||||
void RakNet::BitStream::Write<AMFArrayValue*>(AMFArrayValue* value);
|
||||
} // namespace RakNet
|
||||
|
||||
15
dCommon/AddFriendResponseCode.h
Normal file
15
dCommon/AddFriendResponseCode.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ADDFRIENDRESPONSECODE__H__
|
||||
#define __ADDFRIENDRESPONSECODE__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class AddFriendResponseCode : uint8_t {
|
||||
ACCEPTED = 0,
|
||||
REJECTED,
|
||||
BUSY,
|
||||
CANCELLED
|
||||
};
|
||||
|
||||
#endif //!__ADDFRIENDRESPONSECODE__H__
|
||||
24
dCommon/AddFriendResponseType.h
Normal file
24
dCommon/AddFriendResponseType.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ADDFRIENDRESPONSETYPE__H__
|
||||
#define __ADDFRIENDRESPONSETYPE__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class AddFriendResponseType : uint8_t {
|
||||
ACCEPTED = 0,
|
||||
ALREADYFRIEND,
|
||||
INVALIDCHARACTER,
|
||||
GENERALERROR,
|
||||
YOURFRIENDSLISTFULL,
|
||||
THEIRFRIENDLISTFULL,
|
||||
DECLINED,
|
||||
BUSY,
|
||||
NOTONLINE,
|
||||
WAITINGAPPROVAL,
|
||||
MYTHRAN,
|
||||
CANCELLED,
|
||||
FRIENDISFREETRIAL
|
||||
};
|
||||
|
||||
#endif //!__ADDFRIENDRESPONSETYPE__H__
|
||||
@@ -10,7 +10,7 @@ void BinaryIO::WriteString(const std::string& stringToWrite, std::ofstream& outs
|
||||
}
|
||||
|
||||
//For reading null-terminated strings
|
||||
std::string BinaryIO::ReadString(std::ifstream & instream) {
|
||||
std::string BinaryIO::ReadString(std::ifstream& instream) {
|
||||
std::string toReturn;
|
||||
char buffer;
|
||||
|
||||
@@ -37,7 +37,7 @@ std::string BinaryIO::ReadString(std::ifstream& instream, size_t size) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::string BinaryIO::ReadWString(std::ifstream & instream) {
|
||||
std::string BinaryIO::ReadWString(std::ifstream& instream) {
|
||||
size_t size;
|
||||
BinaryRead(instream, size);
|
||||
//toReturn.resize(size);
|
||||
|
||||
@@ -9,15 +9,15 @@ namespace BinaryIO {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::istream & BinaryRead(std::istream& stream, T& value) {
|
||||
if (!stream.good())
|
||||
std::istream& BinaryRead(std::istream& stream, T& value) {
|
||||
if (!stream.good())
|
||||
printf("bla");
|
||||
|
||||
return stream.read(reinterpret_cast<char*>(&value), sizeof(T));
|
||||
}
|
||||
|
||||
void WriteString(const std::string& stringToWrite, std::ofstream& outstream);
|
||||
std::string ReadString(std::ifstream & instream);
|
||||
std::string ReadString(std::ifstream& instream);
|
||||
std::string ReadString(std::ifstream& instream, size_t size);
|
||||
std::string ReadWString(std::ifstream& instream);
|
||||
|
||||
|
||||
27
dCommon/CMakeLists.txt
Normal file
27
dCommon/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
set(DCOMMON_SOURCES "AMFFormat.cpp"
|
||||
"AMFDeserialize.cpp"
|
||||
"AMFFormat_BitStream.cpp"
|
||||
"BinaryIO.cpp"
|
||||
"dConfig.cpp"
|
||||
"Diagnostics.cpp"
|
||||
"dLogger.cpp"
|
||||
"GeneralUtils.cpp"
|
||||
"LDFFormat.cpp"
|
||||
"MD5.cpp"
|
||||
"Metrics.cpp"
|
||||
"NiPoint3.cpp"
|
||||
"NiQuaternion.cpp"
|
||||
"SHA512.cpp"
|
||||
"Type.cpp"
|
||||
"ZCompression.cpp")
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/dCommon/)
|
||||
|
||||
add_library(dCommon STATIC ${DCOMMON_SOURCES})
|
||||
|
||||
target_link_libraries(dCommon bcrypt)
|
||||
|
||||
if (UNIX)
|
||||
find_package(ZLIB REQUIRED)
|
||||
target_link_libraries(dCommon ZLIB::ZLIB)
|
||||
endif()
|
||||
@@ -2,58 +2,59 @@
|
||||
|
||||
// If we're on Win32, we'll include our minidump writer
|
||||
#ifdef _WIN32
|
||||
#include <Dbghelp.h>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Dbghelp.h>
|
||||
|
||||
#include "Game.h"
|
||||
#include "dLogger.h"
|
||||
|
||||
void make_minidump(EXCEPTION_POINTERS* e) {
|
||||
auto hDbgHelp = LoadLibraryA("dbghelp");
|
||||
if (hDbgHelp == nullptr)
|
||||
return;
|
||||
auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
|
||||
if (pMiniDumpWriteDump == nullptr)
|
||||
return;
|
||||
auto hDbgHelp = LoadLibraryA("dbghelp");
|
||||
if (hDbgHelp == nullptr)
|
||||
return;
|
||||
auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
|
||||
if (pMiniDumpWriteDump == nullptr)
|
||||
return;
|
||||
|
||||
char name[MAX_PATH];
|
||||
{
|
||||
auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
|
||||
SYSTEMTIME t;
|
||||
GetSystemTime(&t);
|
||||
wsprintfA(nameEnd - strlen(".exe"),
|
||||
"_%4d%02d%02d_%02d%02d%02d.dmp",
|
||||
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
|
||||
}
|
||||
char name[MAX_PATH];
|
||||
{
|
||||
auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
|
||||
SYSTEMTIME t;
|
||||
GetSystemTime(&t);
|
||||
wsprintfA(nameEnd - strlen(".exe"),
|
||||
"_%4d%02d%02d_%02d%02d%02d.dmp",
|
||||
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
|
||||
}
|
||||
|
||||
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
|
||||
exceptionInfo.ThreadId = GetCurrentThreadId();
|
||||
exceptionInfo.ExceptionPointers = e;
|
||||
exceptionInfo.ClientPointers = FALSE;
|
||||
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
|
||||
exceptionInfo.ThreadId = GetCurrentThreadId();
|
||||
exceptionInfo.ExceptionPointers = e;
|
||||
exceptionInfo.ClientPointers = FALSE;
|
||||
|
||||
auto dumped = pMiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
|
||||
e ? &exceptionInfo : nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
auto dumped = pMiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
|
||||
e ? &exceptionInfo : nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
CloseHandle(hFile);
|
||||
CloseHandle(hFile);
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) {
|
||||
make_minidump(e);
|
||||
if (Game::logger)
|
||||
Game::logger->Flush(); // Flush our log if we have one, before exiting.
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
make_minidump(e);
|
||||
if (Game::logger)
|
||||
Game::logger->Flush(); // Flush our log if we have one, before exiting.
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -74,146 +75,146 @@ LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) {
|
||||
#include <backtrace-supported.h>
|
||||
|
||||
struct bt_ctx {
|
||||
struct backtrace_state* state;
|
||||
int error;
|
||||
struct backtrace_state* state;
|
||||
int error;
|
||||
};
|
||||
|
||||
static inline void Bt(struct backtrace_state* state) {
|
||||
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
|
||||
FILE* file = fopen(fileName.c_str(), "w+");
|
||||
if (file != nullptr) {
|
||||
backtrace_print(state, 2, file);
|
||||
fclose(file);
|
||||
}
|
||||
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
|
||||
FILE* file = fopen(fileName.c_str(), "w+");
|
||||
if (file != nullptr) {
|
||||
backtrace_print(state, 2, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
backtrace_print(state, 2, stdout);
|
||||
backtrace_print(state, 2, stdout);
|
||||
}
|
||||
|
||||
static void ErrorCallback(void* data, const char* msg, int errnum) {
|
||||
auto* ctx = (struct bt_ctx*)data;
|
||||
fprintf(stderr, "ERROR: %s (%d)", msg, errnum);
|
||||
ctx->error = 1;
|
||||
auto* ctx = (struct bt_ctx*)data;
|
||||
fprintf(stderr, "ERROR: %s (%d)", msg, errnum);
|
||||
ctx->error = 1;
|
||||
|
||||
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
|
||||
FILE* file = fopen(fileName.c_str(), "w+");
|
||||
if (file != nullptr) {
|
||||
fprintf(file, "ERROR: %s (%d)", msg, errnum);
|
||||
fclose(file);
|
||||
}
|
||||
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
|
||||
FILE* file = fopen(fileName.c_str(), "w+");
|
||||
if (file != nullptr) {
|
||||
fprintf(file, "ERROR: %s (%d)", msg, errnum);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "Type.h"
|
||||
|
||||
void GenerateDump() {
|
||||
std::string cmd = "sudo gcore " + std::to_string(getpid());
|
||||
system(cmd.c_str());
|
||||
std::string cmd = "sudo gcore " + std::to_string(getpid());
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void CatchUnhandled(int sig) {
|
||||
#ifndef __include_backtrace__
|
||||
|
||||
if (Diagnostics::GetProduceMemoryDump()) {
|
||||
GenerateDump();
|
||||
}
|
||||
if (Diagnostics::GetProduceMemoryDump()) {
|
||||
GenerateDump();
|
||||
}
|
||||
|
||||
void* array[10];
|
||||
size_t size;
|
||||
void* array[10];
|
||||
size_t size;
|
||||
|
||||
// get void*'s for all entries on the stack
|
||||
size = backtrace(array, 10);
|
||||
// get void*'s for all entries on the stack
|
||||
size = backtrace(array, 10);
|
||||
|
||||
printf("Fatal error %i\nStacktrace:\n", sig);
|
||||
printf("Fatal error %i\nStacktrace:\n", sig);
|
||||
#if defined(__GNUG__) and defined(__dynamic)
|
||||
|
||||
// Loop through the returned addresses, and get the symbols to be demangled
|
||||
char** strings = backtrace_symbols(array, size);
|
||||
// Loop through the returned addresses, and get the symbols to be demangled
|
||||
char** strings = backtrace_symbols(array, size);
|
||||
|
||||
// Print the stack trace
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' and extract the function name
|
||||
std::string functionName = strings[i];
|
||||
std::string::size_type start = functionName.find('(');
|
||||
std::string::size_type end = functionName.find('+');
|
||||
if (start != std::string::npos && end != std::string::npos) {
|
||||
std::string demangled = functionName.substr(start + 1, end - start - 1);
|
||||
// Print the stack trace
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// Take a string like './WorldServer(_ZN19SlashCommandHandler17HandleChatCommandERKSbIDsSt11char_traitsIDsESaIDsEEP6EntityRK13SystemAddress+0x6187) [0x55869c44ecf7]' and extract the function name
|
||||
std::string functionName = strings[i];
|
||||
std::string::size_type start = functionName.find('(');
|
||||
std::string::size_type end = functionName.find('+');
|
||||
if (start != std::string::npos && end != std::string::npos) {
|
||||
std::string demangled = functionName.substr(start + 1, end - start - 1);
|
||||
|
||||
demangled = demangle(functionName.c_str());
|
||||
demangled = demangle(functionName.c_str());
|
||||
|
||||
if (demangled.empty()) {
|
||||
printf("[%02d] %s\n", i, demangled.c_str());
|
||||
} else {
|
||||
printf("[%02d] %s\n", i, functionName.c_str());
|
||||
}
|
||||
} else {
|
||||
printf("[%02d] %s\n", i, functionName.c_str());
|
||||
}
|
||||
}
|
||||
if (demangled.empty()) {
|
||||
printf("[%02zu] %s\n", i, demangled.c_str());
|
||||
} else {
|
||||
printf("[%02zu] %s\n", i, functionName.c_str());
|
||||
}
|
||||
} else {
|
||||
printf("[%02zu] %s\n", i, functionName.c_str());
|
||||
}
|
||||
}
|
||||
#else
|
||||
backtrace_symbols_fd(array, size, STDOUT_FILENO);
|
||||
backtrace_symbols_fd(array, size, STDOUT_FILENO);
|
||||
#endif
|
||||
|
||||
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
|
||||
FILE* file = fopen(fileName.c_str(), "w+");
|
||||
if (file != NULL) {
|
||||
// print out all the frames to stderr
|
||||
fprintf(file, "Error: signal %d:\n", sig);
|
||||
backtrace_symbols_fd(array, size, fileno(file));
|
||||
fclose(file);
|
||||
}
|
||||
std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log";
|
||||
FILE* file = fopen(fileName.c_str(), "w+");
|
||||
if (file != NULL) {
|
||||
// print out all the frames to stderr
|
||||
fprintf(file, "Error: signal %d:\n", sig);
|
||||
backtrace_symbols_fd(array, size, fileno(file));
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct backtrace_state* state = backtrace_create_state(
|
||||
Diagnostics::GetProcessFileName().c_str(),
|
||||
BACKTRACE_SUPPORTS_THREADS,
|
||||
ErrorCallback,
|
||||
nullptr);
|
||||
struct backtrace_state* state = backtrace_create_state(
|
||||
Diagnostics::GetProcessFileName().c_str(),
|
||||
BACKTRACE_SUPPORTS_THREADS,
|
||||
ErrorCallback,
|
||||
nullptr);
|
||||
|
||||
struct bt_ctx ctx = {state, 0};
|
||||
Bt(state);
|
||||
struct bt_ctx ctx = { state, 0 };
|
||||
Bt(state);
|
||||
|
||||
#endif
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void CritErrHdlr(int sig_num, siginfo_t* info, void* ucontext) {
|
||||
CatchUnhandled(sig_num);
|
||||
CatchUnhandled(sig_num);
|
||||
}
|
||||
|
||||
void OnTerminate() {
|
||||
CatchUnhandled(-1);
|
||||
CatchUnhandled(-1);
|
||||
}
|
||||
|
||||
void MakeBacktrace() {
|
||||
struct sigaction sigact;
|
||||
struct sigaction sigact;
|
||||
|
||||
sigact.sa_sigaction = CritErrHdlr;
|
||||
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
sigact.sa_sigaction = CritErrHdlr;
|
||||
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
|
||||
if (sigaction(SIGSEGV, &sigact, (struct sigaction*)nullptr) != 0 ||
|
||||
sigaction(SIGFPE, &sigact, (struct sigaction*)nullptr) != 0 ||
|
||||
sigaction(SIGABRT, &sigact, (struct sigaction*)nullptr) != 0 ||
|
||||
sigaction(SIGILL, &sigact, (struct sigaction*)nullptr) != 0) {
|
||||
fprintf(stderr, "error setting signal handler for %d (%s)\n",
|
||||
SIGSEGV,
|
||||
strsignal(SIGSEGV));
|
||||
if (sigaction(SIGSEGV, &sigact, (struct sigaction*)nullptr) != 0 ||
|
||||
sigaction(SIGFPE, &sigact, (struct sigaction*)nullptr) != 0 ||
|
||||
sigaction(SIGABRT, &sigact, (struct sigaction*)nullptr) != 0 ||
|
||||
sigaction(SIGILL, &sigact, (struct sigaction*)nullptr) != 0) {
|
||||
fprintf(stderr, "error setting signal handler for %d (%s)\n",
|
||||
SIGSEGV,
|
||||
strsignal(SIGSEGV));
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::set_terminate(OnTerminate);
|
||||
std::set_terminate(OnTerminate);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Diagnostics::Initialize() {
|
||||
#ifdef _WIN32
|
||||
SetUnhandledExceptionFilter(unhandled_handler);
|
||||
SetUnhandledExceptionFilter(unhandled_handler);
|
||||
#elif defined(__linux__) //&& !defined(__clang__)
|
||||
MakeBacktrace();
|
||||
MakeBacktrace();
|
||||
#else
|
||||
fprintf(stderr, "Diagnostics not supported on this platform.\n");
|
||||
fprintf(stderr, "Diagnostics not supported on this platform.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -223,33 +224,33 @@ std::string Diagnostics::m_OutDirectory{};
|
||||
bool Diagnostics::m_ProduceMemoryDump{};
|
||||
|
||||
void Diagnostics::SetProcessName(const std::string& name) {
|
||||
m_ProcessName = name;
|
||||
m_ProcessName = name;
|
||||
}
|
||||
|
||||
void Diagnostics::SetProcessFileName(const std::string& name) {
|
||||
m_ProcessFileName = name;
|
||||
m_ProcessFileName = name;
|
||||
}
|
||||
|
||||
void Diagnostics::SetOutDirectory(const std::string& path) {
|
||||
m_OutDirectory = path;
|
||||
m_OutDirectory = path;
|
||||
}
|
||||
|
||||
void Diagnostics::SetProduceMemoryDump(bool value) {
|
||||
m_ProduceMemoryDump = value;
|
||||
m_ProduceMemoryDump = value;
|
||||
}
|
||||
|
||||
const std::string& Diagnostics::GetProcessName() {
|
||||
return m_ProcessName;
|
||||
return m_ProcessName;
|
||||
}
|
||||
|
||||
const std::string& Diagnostics::GetProcessFileName() {
|
||||
return m_ProcessFileName;
|
||||
return m_ProcessFileName;
|
||||
}
|
||||
|
||||
const std::string& Diagnostics::GetOutDirectory() {
|
||||
return m_OutDirectory;
|
||||
return m_OutDirectory;
|
||||
}
|
||||
|
||||
bool Diagnostics::GetProduceMemoryDump() {
|
||||
return m_ProduceMemoryDump;
|
||||
return m_ProduceMemoryDump;
|
||||
}
|
||||
|
||||
@@ -5,27 +5,27 @@
|
||||
class Diagnostics
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Initialize();
|
||||
|
||||
static void SetProcessName(const std::string& name);
|
||||
static void SetProcessName(const std::string& name);
|
||||
|
||||
static void SetProcessFileName(const std::string& name);
|
||||
static void SetProcessFileName(const std::string& name);
|
||||
|
||||
static void SetOutDirectory(const std::string& path);
|
||||
static void SetOutDirectory(const std::string& path);
|
||||
|
||||
static void SetProduceMemoryDump(bool value);
|
||||
static void SetProduceMemoryDump(bool value);
|
||||
|
||||
static const std::string& GetProcessName();
|
||||
static const std::string& GetProcessName();
|
||||
|
||||
static const std::string& GetProcessFileName();
|
||||
static const std::string& GetProcessFileName();
|
||||
|
||||
static const std::string& GetOutDirectory();
|
||||
static const std::string& GetOutDirectory();
|
||||
|
||||
static bool GetProduceMemoryDump();
|
||||
static bool GetProduceMemoryDump();
|
||||
|
||||
private:
|
||||
static std::string m_ProcessName;
|
||||
static std::string m_ProcessFileName;
|
||||
static std::string m_OutDirectory;
|
||||
static bool m_ProduceMemoryDump;
|
||||
static std::string m_ProcessName;
|
||||
static std::string m_ProcessFileName;
|
||||
static std::string m_OutDirectory;
|
||||
static bool m_ProduceMemoryDump;
|
||||
};
|
||||
|
||||
@@ -23,4 +23,4 @@ namespace Game {
|
||||
extern std::mt19937 randomEngine;
|
||||
extern RakPeerInterface* chatServer;
|
||||
extern SystemAddress chatSysAddr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,166 +6,266 @@
|
||||
#include <algorithm>
|
||||
|
||||
template <typename T>
|
||||
inline size_t MinSize(size_t size, const std::basic_string<T>& string) {
|
||||
if (size == size_t(-1) || size > string.size()) {
|
||||
return string.size();
|
||||
} else {
|
||||
return size;
|
||||
}
|
||||
inline size_t MinSize(size_t size, const std::basic_string_view<T>& string) {
|
||||
if (size == size_t(-1) || size > string.size()) {
|
||||
return string.size();
|
||||
} else {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsLeadSurrogate(char16_t c) {
|
||||
return (0xD800 <= c) && (c <= 0xDBFF);
|
||||
return (0xD800 <= c) && (c <= 0xDBFF);
|
||||
}
|
||||
|
||||
inline bool IsTrailSurrogate(char16_t c) {
|
||||
return (0xDC00 <= c) && (c <= 0xDFFF);
|
||||
return (0xDC00 <= c) && (c <= 0xDFFF);
|
||||
}
|
||||
|
||||
inline void PushUTF8CodePoint(std::string& ret, char32_t cp) {
|
||||
if (cp <= 0x007F) {
|
||||
ret.push_back(cp);
|
||||
} else if (cp <= 0x07FF) {
|
||||
ret.push_back(0xC0 | (cp >> 6));
|
||||
ret.push_back(0x80 | (cp & 0x3F));
|
||||
} else if (cp <= 0xFFFF) {
|
||||
ret.push_back(0xE0 | (cp >> 12));
|
||||
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
|
||||
ret.push_back(0x80 | (cp & 0x3F));
|
||||
} else if (cp <= 0x10FFFF) {
|
||||
ret.push_back(0xF0 | (cp >> 18));
|
||||
ret.push_back(0x80 | ((cp >> 12) & 0x3F));
|
||||
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
|
||||
ret.push_back(0x80 | (cp & 0x3F));
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
if (cp <= 0x007F) {
|
||||
ret.push_back(static_cast<uint8_t>(cp));
|
||||
} else if (cp <= 0x07FF) {
|
||||
ret.push_back(0xC0 | (cp >> 6));
|
||||
ret.push_back(0x80 | (cp & 0x3F));
|
||||
} else if (cp <= 0xFFFF) {
|
||||
ret.push_back(0xE0 | (cp >> 12));
|
||||
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
|
||||
ret.push_back(0x80 | (cp & 0x3F));
|
||||
} else if (cp <= 0x10FFFF) {
|
||||
ret.push_back(0xF0 | (cp >> 18));
|
||||
ret.push_back(0x80 | ((cp >> 12) & 0x3F));
|
||||
ret.push_back(0x80 | ((cp >> 6) & 0x3F));
|
||||
ret.push_back(0x80 | (cp & 0x3F));
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr const char16_t REPLACEMENT_CHARACTER = 0xFFFD;
|
||||
|
||||
bool _IsSuffixChar(uint8_t c) {
|
||||
return (c & 0xC0) == 0x80;
|
||||
}
|
||||
|
||||
bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
|
||||
size_t rem = slice.length();
|
||||
const uint8_t* bytes = (const uint8_t*)&slice.front();
|
||||
if (rem > 0) {
|
||||
uint8_t first = bytes[0];
|
||||
if (first < 0x80) { // 1 byte character
|
||||
out = static_cast<uint32_t>(first & 0x7F);
|
||||
slice.remove_prefix(1);
|
||||
return true;
|
||||
} else if (first < 0xC0) {
|
||||
// middle byte, not valid at start, fall through
|
||||
} else if (first < 0xE0) { // two byte character
|
||||
if (rem > 1) {
|
||||
uint8_t second = bytes[1];
|
||||
if (_IsSuffixChar(second)) {
|
||||
out = (static_cast<uint32_t>(first & 0x1F) << 6)
|
||||
+ static_cast<uint32_t>(second & 0x3F);
|
||||
slice.remove_prefix(2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (first < 0xF0) { // three byte character
|
||||
if (rem > 2) {
|
||||
uint8_t second = bytes[1];
|
||||
uint8_t third = bytes[2];
|
||||
if (_IsSuffixChar(second) && _IsSuffixChar(third)) {
|
||||
out = (static_cast<uint32_t>(first & 0x0F) << 12)
|
||||
+ (static_cast<uint32_t>(second & 0x3F) << 6)
|
||||
+ static_cast<uint32_t>(third & 0x3F);
|
||||
slice.remove_prefix(3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (first < 0xF8) { // four byte character
|
||||
if (rem > 3) {
|
||||
uint8_t second = bytes[1];
|
||||
uint8_t third = bytes[2];
|
||||
uint8_t fourth = bytes[3];
|
||||
if (_IsSuffixChar(second) && _IsSuffixChar(third) && _IsSuffixChar(fourth)) {
|
||||
out = (static_cast<uint32_t>(first & 0x07) << 18)
|
||||
+ (static_cast<uint32_t>(second & 0x3F) << 12)
|
||||
+ (static_cast<uint32_t>(third & 0x3F) << 6)
|
||||
+ static_cast<uint32_t>(fourth & 0x3F);
|
||||
slice.remove_prefix(4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
out = static_cast<uint32_t>(REPLACEMENT_CHARACTER);
|
||||
slice.remove_prefix(1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// See <https://www.ietf.org/rfc/rfc2781.html#section-2.1>
|
||||
bool PushUTF16CodePoint(std::u16string& output, uint32_t U, size_t size) {
|
||||
if (output.length() >= size) return false;
|
||||
if (U < 0x10000) {
|
||||
// If U < 0x10000, encode U as a 16-bit unsigned integer and terminate.
|
||||
output.push_back(static_cast<uint16_t>(U));
|
||||
return true;
|
||||
} else if (U > 0x10FFFF) {
|
||||
output.push_back(REPLACEMENT_CHARACTER);
|
||||
return true;
|
||||
} else if (output.length() + 1 < size) {
|
||||
// Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
|
||||
// U' must be less than or equal to 0xFFFFF. That is, U' can be
|
||||
// represented in 20 bits.
|
||||
uint32_t Ut = U - 0x10000;
|
||||
|
||||
// Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
|
||||
// 0xDC00, respectively. These integers each have 10 bits free to
|
||||
// encode the character value, for a total of 20 bits.
|
||||
uint16_t W1 = 0xD800;
|
||||
uint16_t W2 = 0xDC00;
|
||||
|
||||
// Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
|
||||
// bits of W1 and the 10 low-order bits of U' to the 10 low-order
|
||||
// bits of W2.
|
||||
W1 += static_cast<uint16_t>((Ut & 0x3FC00) >> 10);
|
||||
W2 += static_cast<uint16_t>((Ut & 0x3FF) >> 0);
|
||||
|
||||
// Terminate.
|
||||
output.push_back(W1); // high surrogate
|
||||
output.push_back(W2); // low surrogate
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
std::u16string GeneralUtils::UTF8ToUTF16(const std::string_view& string, size_t size) {
|
||||
size_t newSize = MinSize(size, string);
|
||||
std::u16string output;
|
||||
output.reserve(newSize);
|
||||
std::string_view iterator = string;
|
||||
|
||||
uint32_t c;
|
||||
while (_NextUTF8Char(iterator, c) && PushUTF16CodePoint(output, c, size)) {}
|
||||
return output;
|
||||
}
|
||||
|
||||
//! Converts an std::string (ASCII) to UCS-2 / UTF-16
|
||||
std::u16string GeneralUtils::ASCIIToUTF16(const std::string& string, size_t size) {
|
||||
size_t newSize = MinSize(size, string);
|
||||
std::u16string ret;
|
||||
ret.reserve(newSize);
|
||||
std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view& string, size_t size) {
|
||||
size_t newSize = MinSize(size, string);
|
||||
std::u16string ret;
|
||||
ret.reserve(newSize);
|
||||
|
||||
for (size_t i = 0; i < newSize; i++) {
|
||||
char c = string[i];
|
||||
assert(c > 0 && c <= 127);
|
||||
ret.push_back(static_cast<char16_t>(c));
|
||||
}
|
||||
for (size_t i = 0; i < newSize; i++) {
|
||||
char c = string[i];
|
||||
// Note: both 7-bit ascii characters and REPLACEMENT_CHARACTER fit in one char16_t
|
||||
ret.push_back((c > 0 && c <= 127) ? static_cast<char16_t>(c) : REPLACEMENT_CHARACTER);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! Converts a (potentially-ill-formed) UTF-16 string to UTF-8
|
||||
//! See: <http://simonsapin.github.io/wtf-8/#decoding-ill-formed-utf-16>
|
||||
std::string GeneralUtils::UTF16ToWTF8(const std::u16string& string, size_t size) {
|
||||
size_t newSize = MinSize(size, string);
|
||||
std::string ret;
|
||||
ret.reserve(newSize);
|
||||
std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view& string, size_t size) {
|
||||
size_t newSize = MinSize(size, string);
|
||||
std::string ret;
|
||||
ret.reserve(newSize);
|
||||
|
||||
for (size_t i = 0; i < newSize; i++) {
|
||||
char16_t u = string[i];
|
||||
if (IsLeadSurrogate(u) && (i + 1) < newSize) {
|
||||
char16_t next = string[i + 1];
|
||||
if (IsTrailSurrogate(next)) {
|
||||
i += 1;
|
||||
char32_t cp = 0x10000
|
||||
+ ((static_cast<char32_t>(u) - 0xD800) << 10)
|
||||
+ (static_cast<char32_t>(next) - 0xDC00);
|
||||
PushUTF8CodePoint(ret, cp);
|
||||
} else {
|
||||
PushUTF8CodePoint(ret, u);
|
||||
}
|
||||
} else {
|
||||
PushUTF8CodePoint(ret, u);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < newSize; i++) {
|
||||
char16_t u = string[i];
|
||||
if (IsLeadSurrogate(u) && (i + 1) < newSize) {
|
||||
char16_t next = string[i + 1];
|
||||
if (IsTrailSurrogate(next)) {
|
||||
i += 1;
|
||||
char32_t cp = 0x10000
|
||||
+ ((static_cast<char32_t>(u) - 0xD800) << 10)
|
||||
+ (static_cast<char32_t>(next) - 0xDC00);
|
||||
PushUTF8CodePoint(ret, cp);
|
||||
} else {
|
||||
PushUTF8CodePoint(ret, u);
|
||||
}
|
||||
} else {
|
||||
PushUTF8CodePoint(ret, u);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool GeneralUtils::CaseInsensitiveStringCompare(const std::string& a, const std::string& b) {
|
||||
return std::equal(a.begin(), a.end (), b.begin(), b.end(),[](char a, char b) { return tolower(a) == tolower(b); });
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) { return tolower(a) == tolower(b); });
|
||||
}
|
||||
|
||||
// MARK: Bits
|
||||
|
||||
//! Sets a specific bit in a signed 64-bit integer
|
||||
int64_t GeneralUtils::SetBit(int64_t value, uint32_t index) {
|
||||
return value |= 1ULL << index;
|
||||
return value |= 1ULL << index;
|
||||
}
|
||||
|
||||
//! Clears a specific bit in a signed 64-bit integer
|
||||
int64_t GeneralUtils::ClearBit(int64_t value, uint32_t index) {
|
||||
return value &= ~(1ULL << index);
|
||||
return value &= ~(1ULL << index);
|
||||
}
|
||||
|
||||
//! Checks a specific bit in a signed 64-bit integer
|
||||
bool GeneralUtils::CheckBit(int64_t value, uint32_t index) {
|
||||
return value & (1ULL << index);
|
||||
return value & (1ULL << index);
|
||||
}
|
||||
|
||||
bool GeneralUtils::ReplaceInString(std::string& str, const std::string& from, const std::string& to) {
|
||||
size_t start_pos = str.find(from);
|
||||
if(start_pos == std::string::npos)
|
||||
return false;
|
||||
str.replace(start_pos, from.length(), to);
|
||||
return true;
|
||||
size_t start_pos = str.find(from);
|
||||
if (start_pos == std::string::npos)
|
||||
return false;
|
||||
str.replace(start_pos, from.length(), to);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t delimiter)
|
||||
{
|
||||
std::vector<std::wstring> vector = std::vector<std::wstring>();
|
||||
std::wstring current;
|
||||
std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t delimiter) {
|
||||
std::vector<std::wstring> vector = std::vector<std::wstring>();
|
||||
std::wstring current;
|
||||
|
||||
for (const auto& c : str) {
|
||||
if (c == delimiter) {
|
||||
vector.push_back(current);
|
||||
current = L"";
|
||||
} else {
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
for (const auto& c : str) {
|
||||
if (c == delimiter) {
|
||||
vector.push_back(current);
|
||||
current = L"";
|
||||
} else {
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
|
||||
vector.push_back(current);
|
||||
return vector;
|
||||
vector.push_back(current);
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::vector<std::u16string> GeneralUtils::SplitString(std::u16string& str, char16_t delimiter)
|
||||
{
|
||||
std::vector<std::u16string> vector = std::vector<std::u16string>();
|
||||
std::u16string current;
|
||||
std::vector<std::u16string> GeneralUtils::SplitString(std::u16string& str, char16_t delimiter) {
|
||||
std::vector<std::u16string> vector = std::vector<std::u16string>();
|
||||
std::u16string current;
|
||||
|
||||
for (const auto& c : str) {
|
||||
if (c == delimiter) {
|
||||
vector.push_back(current);
|
||||
current = u"";
|
||||
} else {
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
for (const auto& c : str) {
|
||||
if (c == delimiter) {
|
||||
vector.push_back(current);
|
||||
current = u"";
|
||||
} else {
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
|
||||
vector.push_back(current);
|
||||
return vector;
|
||||
vector.push_back(current);
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char delimiter)
|
||||
{
|
||||
std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char delimiter) {
|
||||
std::vector<std::string> vector = std::vector<std::string>();
|
||||
std::string current = "";
|
||||
|
||||
for (size_t i = 0; i < str.length(); i++)
|
||||
{
|
||||
for (size_t i = 0; i < str.length(); i++) {
|
||||
char c = str[i];
|
||||
|
||||
if (c == delimiter)
|
||||
{
|
||||
if (c == delimiter) {
|
||||
vector.push_back(current);
|
||||
current = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
@@ -175,16 +275,65 @@ std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::u16string GeneralUtils::ReadWString(RakNet::BitStream *inStream) {
|
||||
uint32_t length;
|
||||
inStream->Read<uint32_t>(length);
|
||||
std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) {
|
||||
uint32_t length;
|
||||
inStream->Read<uint32_t>(length);
|
||||
|
||||
std::u16string string;
|
||||
for (auto i = 0; i < length; i++) {
|
||||
uint16_t c;
|
||||
inStream->Read(c);
|
||||
string.push_back(c);
|
||||
}
|
||||
std::u16string string;
|
||||
for (auto i = 0; i < length; i++) {
|
||||
uint16_t c;
|
||||
inStream->Read(c);
|
||||
string.push_back(c);
|
||||
}
|
||||
|
||||
return string;
|
||||
return string;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) {
|
||||
std::vector<std::string> names;
|
||||
std::string search_path = folder + "/*.*";
|
||||
WIN32_FIND_DATA fd;
|
||||
HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
names.push_back(fd.cFileName);
|
||||
}
|
||||
} while (::FindNextFile(hFind, &fd));
|
||||
::FindClose(hFind);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
std::vector<std::string> GeneralUtils::GetFileNamesFromFolder(const std::string& folder) {
|
||||
std::vector<std::string> names;
|
||||
struct dirent* entry;
|
||||
DIR* dir = opendir(folder.c_str());
|
||||
if (dir == NULL) {
|
||||
return names;
|
||||
}
|
||||
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
std::string value(entry->d_name, strlen(entry->d_name));
|
||||
if (value == "." || value == "..") {
|
||||
continue;
|
||||
}
|
||||
names.push_back(value);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return names;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -18,109 +18,119 @@
|
||||
\brief A namespace containing general utility functions
|
||||
*/
|
||||
|
||||
//! The general utils namespace
|
||||
//! The general utils namespace
|
||||
namespace GeneralUtils {
|
||||
//! Converts a plain ASCII string to a UTF-16 string
|
||||
/*!
|
||||
\param string The string to convert
|
||||
\param size A size to trim the string to. Default is -1 (No trimming)
|
||||
\return An UTF-16 representation of the string
|
||||
*/
|
||||
std::u16string ASCIIToUTF16(const std::string& string, size_t size = -1);
|
||||
//! Converts a plain ASCII string to a UTF-16 string
|
||||
/*!
|
||||
\param string The string to convert
|
||||
\param size A size to trim the string to. Default is -1 (No trimming)
|
||||
\return An UTF-16 representation of the string
|
||||
*/
|
||||
std::u16string ASCIIToUTF16(const std::string_view& string, size_t size = -1);
|
||||
|
||||
//! Converts a UTF-16 string to a UTF-8 string
|
||||
/*!
|
||||
\param string The string to convert
|
||||
\param size A size to trim the string to. Default is -1 (No trimming)
|
||||
\return An UTF-8 representation of the string
|
||||
*/
|
||||
std::string UTF16ToWTF8(const std::u16string& string, size_t size = -1);
|
||||
//! Converts a UTF-8 String to a UTF-16 string
|
||||
/*!
|
||||
\param string The string to convert
|
||||
\param size A size to trim the string to. Default is -1 (No trimming)
|
||||
\return An UTF-16 representation of the string
|
||||
*/
|
||||
std::u16string UTF8ToUTF16(const std::string_view& string, size_t size = -1);
|
||||
|
||||
/**
|
||||
* Compares two basic strings but does so ignoring case sensitivity
|
||||
* \param a the first string to compare against the second string
|
||||
* \param b the second string to compare against the first string
|
||||
* @return if the two strings are equal
|
||||
*/
|
||||
bool CaseInsensitiveStringCompare(const std::string& a, const std::string& b);
|
||||
//! Internal, do not use
|
||||
bool _NextUTF8Char(std::string_view& slice, uint32_t& out);
|
||||
|
||||
// MARK: Bits
|
||||
//! Converts a UTF-16 string to a UTF-8 string
|
||||
/*!
|
||||
\param string The string to convert
|
||||
\param size A size to trim the string to. Default is -1 (No trimming)
|
||||
\return An UTF-8 representation of the string
|
||||
*/
|
||||
std::string UTF16ToWTF8(const std::u16string_view& string, size_t size = -1);
|
||||
|
||||
// MARK: Bits
|
||||
/**
|
||||
* Compares two basic strings but does so ignoring case sensitivity
|
||||
* \param a the first string to compare against the second string
|
||||
* \param b the second string to compare against the first string
|
||||
* @return if the two strings are equal
|
||||
*/
|
||||
bool CaseInsensitiveStringCompare(const std::string& a, const std::string& b);
|
||||
|
||||
//! Sets a bit on a numerical value
|
||||
template <typename T>
|
||||
void SetBit(T& value, size_t index) {
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
|
||||
if (index > (sizeof(T) * 8) - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
value |= static_cast<T>(1) << index;
|
||||
}
|
||||
|
||||
//! Clears a bit on a numerical value
|
||||
template <typename T>
|
||||
void ClearBit(T& value, size_t index) {
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
|
||||
if (index > (sizeof(T) * 8 - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
value &= ~(static_cast<T>(1) << index);
|
||||
}
|
||||
|
||||
//! Sets a specific bit in a signed 64-bit integer
|
||||
/*!
|
||||
\param value The value to set the bit for
|
||||
\param index The index of the bit
|
||||
*/
|
||||
int64_t SetBit(int64_t value, uint32_t index);
|
||||
|
||||
//! Clears a specific bit in a signed 64-bit integer
|
||||
/*!
|
||||
\param value The value to clear the bit from
|
||||
\param index The index of the bit
|
||||
*/
|
||||
int64_t ClearBit(int64_t value, uint32_t index);
|
||||
|
||||
//! Checks a specific bit in a signed 64-bit integer
|
||||
/*!
|
||||
\parma value The value to check the bit in
|
||||
\param index The index of the bit
|
||||
\return Whether or not the bit is set
|
||||
*/
|
||||
bool CheckBit(int64_t value, uint32_t index);
|
||||
// MARK: Bits
|
||||
|
||||
// MARK: Random Number Generation
|
||||
// MARK: Bits
|
||||
|
||||
//! Generates a random number
|
||||
/*!
|
||||
\param min The minimum the generate from
|
||||
\param max The maximum to generate to
|
||||
*/
|
||||
template <typename T>
|
||||
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
|
||||
// Make sure it is a numeric type
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
//! Sets a bit on a numerical value
|
||||
template <typename T>
|
||||
void SetBit(T& value, size_t index) {
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
|
||||
if constexpr (std::is_integral_v<T>) { // constexpr only necessary on first statement
|
||||
std::uniform_int_distribution<T> distribution(min, max);
|
||||
return distribution(Game::randomEngine);
|
||||
}
|
||||
else if (std::is_floating_point_v<T>) {
|
||||
std::uniform_real_distribution<T> distribution(min, max);
|
||||
return distribution(Game::randomEngine);
|
||||
}
|
||||
if (index > (sizeof(T) * 8) - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
value |= static_cast<T>(1) << index;
|
||||
}
|
||||
|
||||
//! Clears a bit on a numerical value
|
||||
template <typename T>
|
||||
void ClearBit(T& value, size_t index) {
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
|
||||
if (index > (sizeof(T) * 8 - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
value &= ~(static_cast<T>(1) << index);
|
||||
}
|
||||
|
||||
//! Sets a specific bit in a signed 64-bit integer
|
||||
/*!
|
||||
\param value The value to set the bit for
|
||||
\param index The index of the bit
|
||||
*/
|
||||
int64_t SetBit(int64_t value, uint32_t index);
|
||||
|
||||
//! Clears a specific bit in a signed 64-bit integer
|
||||
/*!
|
||||
\param value The value to clear the bit from
|
||||
\param index The index of the bit
|
||||
*/
|
||||
int64_t ClearBit(int64_t value, uint32_t index);
|
||||
|
||||
//! Checks a specific bit in a signed 64-bit integer
|
||||
/*!
|
||||
\parma value The value to check the bit in
|
||||
\param index The index of the bit
|
||||
\return Whether or not the bit is set
|
||||
*/
|
||||
bool CheckBit(int64_t value, uint32_t index);
|
||||
|
||||
// MARK: Random Number Generation
|
||||
|
||||
//! Generates a random number
|
||||
/*!
|
||||
\param min The minimum the generate from
|
||||
\param max The maximum to generate to
|
||||
*/
|
||||
template <typename T>
|
||||
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
|
||||
// Make sure it is a numeric type
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
|
||||
if constexpr (std::is_integral_v<T>) { // constexpr only necessary on first statement
|
||||
std::uniform_int_distribution<T> distribution(min, max);
|
||||
return distribution(Game::randomEngine);
|
||||
} else if (std::is_floating_point_v<T>) {
|
||||
std::uniform_real_distribution<T> distribution(min, max);
|
||||
return distribution(Game::randomEngine);
|
||||
}
|
||||
|
||||
return T();
|
||||
}
|
||||
|
||||
return T();
|
||||
}
|
||||
|
||||
bool ReplaceInString(std::string& str, const std::string& from, const std::string& to);
|
||||
|
||||
std::u16string ReadWString(RakNet::BitStream *inStream);
|
||||
std::u16string ReadWString(RakNet::BitStream* inStream);
|
||||
|
||||
std::vector<std::wstring> SplitString(std::wstring& str, wchar_t delimiter);
|
||||
|
||||
@@ -128,83 +138,71 @@ namespace GeneralUtils {
|
||||
|
||||
std::vector<std::string> SplitString(const std::string& str, char delimiter);
|
||||
|
||||
template <typename T>
|
||||
T Parse(const char* value);
|
||||
std::vector<std::string> GetFileNamesFromFolder(const std::string& folder);
|
||||
|
||||
template <typename T>
|
||||
T Parse(const char* value);
|
||||
|
||||
template <>
|
||||
inline int32_t Parse(const char* value)
|
||||
{
|
||||
return std::stoi(value);
|
||||
inline int32_t Parse(const char* value) {
|
||||
return std::stoi(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t Parse(const char* value)
|
||||
{
|
||||
return std::stoll(value);
|
||||
}
|
||||
template <>
|
||||
inline int64_t Parse(const char* value) {
|
||||
return std::stoll(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float Parse(const char* value)
|
||||
{
|
||||
return std::stof(value);
|
||||
}
|
||||
template <>
|
||||
inline float Parse(const char* value) {
|
||||
return std::stof(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double Parse(const char* value)
|
||||
{
|
||||
return std::stod(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint32_t Parse(const char* value)
|
||||
{
|
||||
return std::stoul(value);
|
||||
}
|
||||
template <>
|
||||
inline double Parse(const char* value) {
|
||||
return std::stod(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint64_t Parse(const char* value)
|
||||
{
|
||||
return std::stoull(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TryParse(const char* value, T& dst)
|
||||
{
|
||||
try
|
||||
{
|
||||
dst = Parse<T>(value);
|
||||
template <>
|
||||
inline uint32_t Parse(const char* value) {
|
||||
return std::stoul(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
template <>
|
||||
inline uint64_t Parse(const char* value) {
|
||||
return std::stoull(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T Parse(const std::string& value)
|
||||
{
|
||||
return Parse<T>(value.c_str());
|
||||
}
|
||||
template <typename T>
|
||||
bool TryParse(const char* value, T& dst) {
|
||||
try {
|
||||
dst = Parse<T>(value);
|
||||
|
||||
template <typename T>
|
||||
bool TryParse(const std::string& value, T& dst)
|
||||
{
|
||||
return TryParse<T>(value.c_str(), dst);
|
||||
}
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::u16string to_u16string(T value)
|
||||
{
|
||||
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
|
||||
}
|
||||
template <typename T>
|
||||
T Parse(const std::string& value) {
|
||||
return Parse<T>(value.c_str());
|
||||
}
|
||||
|
||||
// From boost::hash_combine
|
||||
template <class T>
|
||||
void hash_combine(std::size_t& s, const T& v)
|
||||
{
|
||||
std::hash<T> h;
|
||||
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
|
||||
}
|
||||
template <typename T>
|
||||
bool TryParse(const std::string& value, T& dst) {
|
||||
return TryParse<T>(value.c_str(), dst);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::u16string to_u16string(T value) {
|
||||
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
|
||||
}
|
||||
|
||||
// From boost::hash_combine
|
||||
template <class T>
|
||||
void hash_combine(std::size_t& s, const T& v) {
|
||||
std::hash<T> h;
|
||||
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,25 +8,25 @@
|
||||
#include <vector>
|
||||
|
||||
//! Returns a pointer to a LDFData value based on string format
|
||||
LDFBaseData * LDFBaseData::DataFromString(const std::string& format) {
|
||||
|
||||
// First, check the format
|
||||
std::istringstream ssFormat(format);
|
||||
std::string token;
|
||||
|
||||
std::vector<std::string> keyValueArray;
|
||||
while (std::getline(ssFormat, token, '=')) {
|
||||
keyValueArray.push_back(token);
|
||||
}
|
||||
|
||||
if (keyValueArray.size() == 2) {
|
||||
std::u16string key = GeneralUtils::ASCIIToUTF16(keyValueArray[0]);
|
||||
|
||||
std::vector<std::string> dataArray;
|
||||
std::istringstream ssData(keyValueArray[1]);
|
||||
while (std::getline(ssData, token, ':')) {
|
||||
dataArray.push_back(token);
|
||||
}
|
||||
LDFBaseData* LDFBaseData::DataFromString(const std::string& format) {
|
||||
|
||||
// First, check the format
|
||||
std::istringstream ssFormat(format);
|
||||
std::string token;
|
||||
|
||||
std::vector<std::string> keyValueArray;
|
||||
while (std::getline(ssFormat, token, '=')) {
|
||||
keyValueArray.push_back(token);
|
||||
}
|
||||
|
||||
if (keyValueArray.size() == 2) {
|
||||
std::u16string key = GeneralUtils::ASCIIToUTF16(keyValueArray[0]);
|
||||
|
||||
std::vector<std::string> dataArray;
|
||||
std::istringstream ssData(keyValueArray[1]);
|
||||
while (std::getline(ssData, token, ':')) {
|
||||
dataArray.push_back(token);
|
||||
}
|
||||
|
||||
if (dataArray.size() > 2) { // hacky fix for strings with colons in them
|
||||
std::vector<std::string> newDataArray;
|
||||
@@ -39,96 +39,86 @@ LDFBaseData * LDFBaseData::DataFromString(const std::string& format) {
|
||||
newDataArray.push_back(value);
|
||||
dataArray = newDataArray;
|
||||
}
|
||||
|
||||
if ((dataArray[0] == "0" || dataArray[0] == "13") && dataArray.size() == 1) {
|
||||
dataArray.push_back("");
|
||||
}
|
||||
|
||||
if (dataArray.size() == 2) {
|
||||
eLDFType type = static_cast<eLDFType>(stoi(dataArray[0]));
|
||||
|
||||
switch (type) {
|
||||
case LDF_TYPE_UTF_16: {
|
||||
std::u16string data = GeneralUtils::ASCIIToUTF16(dataArray[1]);
|
||||
return new LDFData<std::u16string>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_S32: {
|
||||
int32_t data = static_cast<int32_t>(stol(dataArray[1]));
|
||||
return new LDFData<int32_t>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_FLOAT: {
|
||||
float data = static_cast<float>(stof(dataArray[1]));
|
||||
return new LDFData<float>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_DOUBLE: {
|
||||
double data = static_cast<float>(stod(dataArray[1]));
|
||||
return new LDFData<double>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_U32:
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
if (dataArray[1] == "true")
|
||||
{
|
||||
data = 1;
|
||||
}
|
||||
else if (dataArray[1] == "false")
|
||||
{
|
||||
data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = static_cast<uint32_t>(stoul(dataArray[1]));
|
||||
}
|
||||
|
||||
return new LDFData<uint32_t>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_BOOLEAN: {
|
||||
bool data;
|
||||
|
||||
if (dataArray[1] == "true")
|
||||
{
|
||||
data = true;
|
||||
}
|
||||
else if (dataArray[1] == "false")
|
||||
{
|
||||
data = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = static_cast<bool>(stoi(dataArray[1]));
|
||||
}
|
||||
|
||||
return new LDFData<bool>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_U64: {
|
||||
uint64_t data = static_cast<uint64_t>(stoull(dataArray[1]));
|
||||
return new LDFData<uint64_t>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_OBJID: {
|
||||
LWOOBJID data = static_cast<LWOOBJID>(stoll(dataArray[1]));
|
||||
return new LDFData<LWOOBJID>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_UTF_8: {
|
||||
std::string data = dataArray[1];
|
||||
return new LDFData<std::string>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_UNKNOWN: {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
|
||||
if ((dataArray[0] == "0" || dataArray[0] == "13") && dataArray.size() == 1) {
|
||||
dataArray.push_back("");
|
||||
}
|
||||
|
||||
if (dataArray.size() == 2) {
|
||||
eLDFType type = static_cast<eLDFType>(stoi(dataArray[0]));
|
||||
|
||||
switch (type) {
|
||||
case LDF_TYPE_UTF_16: {
|
||||
std::u16string data = GeneralUtils::UTF8ToUTF16(dataArray[1]);
|
||||
return new LDFData<std::u16string>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_S32: {
|
||||
int32_t data = static_cast<int32_t>(stoull(dataArray[1]));
|
||||
return new LDFData<int32_t>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_FLOAT: {
|
||||
float data = static_cast<float>(stof(dataArray[1]));
|
||||
return new LDFData<float>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_DOUBLE: {
|
||||
double data = static_cast<float>(stod(dataArray[1]));
|
||||
return new LDFData<double>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_U32:
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
if (dataArray[1] == "true") {
|
||||
data = 1;
|
||||
} else if (dataArray[1] == "false") {
|
||||
data = 0;
|
||||
} else {
|
||||
data = static_cast<uint32_t>(stoul(dataArray[1]));
|
||||
}
|
||||
|
||||
return new LDFData<uint32_t>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_BOOLEAN: {
|
||||
bool data;
|
||||
|
||||
if (dataArray[1] == "true") {
|
||||
data = true;
|
||||
} else if (dataArray[1] == "false") {
|
||||
data = false;
|
||||
} else {
|
||||
data = static_cast<bool>(stoi(dataArray[1]));
|
||||
}
|
||||
|
||||
return new LDFData<bool>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_U64: {
|
||||
uint64_t data = static_cast<uint64_t>(stoull(dataArray[1]));
|
||||
return new LDFData<uint64_t>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_OBJID: {
|
||||
LWOOBJID data = static_cast<LWOOBJID>(stoll(dataArray[1]));
|
||||
return new LDFData<LWOOBJID>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_UTF_8: {
|
||||
std::string data = dataArray[1];
|
||||
return new LDFData<std::string>(key, data);
|
||||
}
|
||||
|
||||
case LDF_TYPE_UNKNOWN: {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,64 +17,64 @@
|
||||
\brief A collection of LDF format classes
|
||||
*/
|
||||
|
||||
//! An enum for LDF Data Types
|
||||
//! An enum for LDF Data Types
|
||||
enum eLDFType {
|
||||
LDF_TYPE_UNKNOWN = -1, //!< Unknown data type
|
||||
LDF_TYPE_UTF_16 = 0, //!< UTF-16 wstring data type
|
||||
LDF_TYPE_S32 = 1, //!< Signed 32-bit data type
|
||||
LDF_TYPE_FLOAT = 3, //!< Float data type
|
||||
LDF_TYPE_DOUBLE = 4, //!< Double data type
|
||||
LDF_TYPE_U32 = 5, //!< Unsigned 32-bit data type
|
||||
LDF_TYPE_BOOLEAN = 7, //!< Boolean data type
|
||||
LDF_TYPE_U64 = 8, //!< Unsigned 64-bit data type (originally signed, templates won't work with both S64 & OBJID
|
||||
LDF_TYPE_OBJID = 9, //!< Signed 64-bit data type (reserved for object IDs)
|
||||
LDF_TYPE_UTF_8 = 13, //!< UTF-8 string data type
|
||||
LDF_TYPE_UNKNOWN = -1, //!< Unknown data type
|
||||
LDF_TYPE_UTF_16 = 0, //!< UTF-16 wstring data type
|
||||
LDF_TYPE_S32 = 1, //!< Signed 32-bit data type
|
||||
LDF_TYPE_FLOAT = 3, //!< Float data type
|
||||
LDF_TYPE_DOUBLE = 4, //!< Double data type
|
||||
LDF_TYPE_U32 = 5, //!< Unsigned 32-bit data type
|
||||
LDF_TYPE_BOOLEAN = 7, //!< Boolean data type
|
||||
LDF_TYPE_U64 = 8, //!< Unsigned 64-bit data type (originally signed, templates won't work with both S64 & OBJID
|
||||
LDF_TYPE_OBJID = 9, //!< Signed 64-bit data type (reserved for object IDs)
|
||||
LDF_TYPE_UTF_8 = 13, //!< UTF-8 string data type
|
||||
};
|
||||
|
||||
//! A base class for the LDF data
|
||||
class LDFBaseData {
|
||||
public:
|
||||
|
||||
//! Destructor
|
||||
virtual ~LDFBaseData(void) { }
|
||||
|
||||
//! Writes the data to a packet
|
||||
/*!
|
||||
\param packet The packet
|
||||
*/
|
||||
virtual void WriteToPacket(RakNet::BitStream * packet) = 0;
|
||||
|
||||
//! Gets the key
|
||||
/*!
|
||||
\return The key
|
||||
*/
|
||||
virtual const std::u16string& GetKey(void) = 0;
|
||||
|
||||
//! Gets the value type
|
||||
/*!
|
||||
\return The value type
|
||||
*/
|
||||
virtual eLDFType GetValueType(void) = 0;
|
||||
|
||||
//! Gets a string from the key/value pair
|
||||
/*!
|
||||
\param includeKey Whether or not to include the key in the data
|
||||
\param includeTypeId Whether or not to include the type id in the data
|
||||
\return The string representation of the data
|
||||
*/
|
||||
virtual std::string GetString(bool includeKey = true, bool includeTypeId = true) = 0;
|
||||
|
||||
virtual std::string GetValueAsString() = 0;
|
||||
|
||||
virtual LDFBaseData * Copy() = 0;
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
//! Returns a pointer to a LDFData value based on string format
|
||||
/*!
|
||||
\param format The format
|
||||
*/
|
||||
static LDFBaseData * DataFromString(const std::string& format);
|
||||
//! Destructor
|
||||
virtual ~LDFBaseData(void) {}
|
||||
|
||||
//! Writes the data to a packet
|
||||
/*!
|
||||
\param packet The packet
|
||||
*/
|
||||
virtual void WriteToPacket(RakNet::BitStream* packet) = 0;
|
||||
|
||||
//! Gets the key
|
||||
/*!
|
||||
\return The key
|
||||
*/
|
||||
virtual const std::u16string& GetKey(void) = 0;
|
||||
|
||||
//! Gets the value type
|
||||
/*!
|
||||
\return The value type
|
||||
*/
|
||||
virtual eLDFType GetValueType(void) = 0;
|
||||
|
||||
//! Gets a string from the key/value pair
|
||||
/*!
|
||||
\param includeKey Whether or not to include the key in the data
|
||||
\param includeTypeId Whether or not to include the type id in the data
|
||||
\return The string representation of the data
|
||||
*/
|
||||
virtual std::string GetString(bool includeKey = true, bool includeTypeId = true) = 0;
|
||||
|
||||
virtual std::string GetValueAsString() = 0;
|
||||
|
||||
virtual LDFBaseData* Copy() = 0;
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
//! Returns a pointer to a LDFData value based on string format
|
||||
/*!
|
||||
\param format The format
|
||||
*/
|
||||
static LDFBaseData* DataFromString(const std::string& format);
|
||||
|
||||
};
|
||||
|
||||
@@ -82,115 +82,115 @@ public:
|
||||
template<typename T>
|
||||
class LDFData : public LDFBaseData {
|
||||
private:
|
||||
std::u16string key;
|
||||
T value;
|
||||
|
||||
//! Writes the key to the packet
|
||||
void WriteKey(RakNet::BitStream * packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->key.length() * sizeof(uint16_t)));
|
||||
for (uint32_t i = 0; i < this->key.length(); ++i) {
|
||||
packet->Write(static_cast<uint16_t>(this->key[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//! Writes the value to the packet
|
||||
void WriteValue(RakNet::BitStream * packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
packet->Write(this->value);
|
||||
}
|
||||
std::u16string key;
|
||||
T value;
|
||||
|
||||
//! Writes the key to the packet
|
||||
void WriteKey(RakNet::BitStream* packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->key.length() * sizeof(uint16_t)));
|
||||
for (uint32_t i = 0; i < this->key.length(); ++i) {
|
||||
packet->Write(static_cast<uint16_t>(this->key[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//! Writes the value to the packet
|
||||
void WriteValue(RakNet::BitStream* packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
packet->Write(this->value);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Initializer
|
||||
LDFData(const std::u16string& key, const T& value) {
|
||||
this->key = key;
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
~LDFData(void) override { }
|
||||
|
||||
//! Gets the value
|
||||
/*!
|
||||
\return The value
|
||||
*/
|
||||
const T& GetValue(void) { return this->value; }
|
||||
|
||||
//! Sets the value
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetValue(T value) { this->value = value; };
|
||||
|
||||
//! Gets the value string
|
||||
/*!
|
||||
\return The value string
|
||||
*/
|
||||
std::string GetValueString(void) { return ""; }
|
||||
|
||||
//! Writes the data to a packet
|
||||
/*!
|
||||
\param packet The packet
|
||||
*/
|
||||
void WriteToPacket(RakNet::BitStream * packet) override {
|
||||
this->WriteKey(packet);
|
||||
this->WriteValue(packet);
|
||||
}
|
||||
|
||||
//! Gets the key
|
||||
/*!
|
||||
\return The key
|
||||
*/
|
||||
const std::u16string& GetKey(void) override { return this->key; }
|
||||
|
||||
//! Gets the LDF Type
|
||||
/*!
|
||||
\return The LDF value type
|
||||
*/
|
||||
eLDFType GetValueType(void) override { return LDF_TYPE_UNKNOWN; }
|
||||
|
||||
//! Gets the string data
|
||||
/*!
|
||||
\param includeKey Whether or not to include the key in the data
|
||||
\param includeTypeId Whether or not to include the type id in the data
|
||||
\return The string representation of the data
|
||||
*/
|
||||
std::string GetString(const bool includeKey = true, const bool includeTypeId = true) override {
|
||||
if (GetValueType() == -1) {
|
||||
return GeneralUtils::UTF16ToWTF8(this->key) + "=-1:<server variable>";
|
||||
}
|
||||
//! Initializer
|
||||
LDFData(const std::u16string& key, const T& value) {
|
||||
this->key = key;
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
std::stringstream stream;
|
||||
//! Destructor
|
||||
~LDFData(void) override {}
|
||||
|
||||
if (includeKey) {
|
||||
const std::string& sKey = GeneralUtils::UTF16ToWTF8(this->key, this->key.size());
|
||||
|
||||
stream << sKey << "=";
|
||||
}
|
||||
//! Gets the value
|
||||
/*!
|
||||
\return The value
|
||||
*/
|
||||
const T& GetValue(void) { return this->value; }
|
||||
|
||||
if (includeTypeId) {
|
||||
const std::string& sType = std::to_string(this->GetValueType());
|
||||
//! Sets the value
|
||||
/*!
|
||||
\param value The value to set to
|
||||
*/
|
||||
void SetValue(T value) { this->value = value; };
|
||||
|
||||
|
||||
stream << sType << ":";
|
||||
}
|
||||
//! Gets the value string
|
||||
/*!
|
||||
\return The value string
|
||||
*/
|
||||
std::string GetValueString(void) { return ""; }
|
||||
|
||||
const std::string& sData = this->GetValueString();
|
||||
|
||||
stream << sData;
|
||||
//! Writes the data to a packet
|
||||
/*!
|
||||
\param packet The packet
|
||||
*/
|
||||
void WriteToPacket(RakNet::BitStream* packet) override {
|
||||
this->WriteKey(packet);
|
||||
this->WriteValue(packet);
|
||||
}
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string GetValueAsString() override {
|
||||
return this->GetValueString();
|
||||
}
|
||||
|
||||
LDFBaseData * Copy() override {
|
||||
return new LDFData<T>(key, value);
|
||||
}
|
||||
|
||||
inline static T Default = {};
|
||||
//! Gets the key
|
||||
/*!
|
||||
\return The key
|
||||
*/
|
||||
const std::u16string& GetKey(void) override { return this->key; }
|
||||
|
||||
//! Gets the LDF Type
|
||||
/*!
|
||||
\return The LDF value type
|
||||
*/
|
||||
eLDFType GetValueType(void) override { return LDF_TYPE_UNKNOWN; }
|
||||
|
||||
//! Gets the string data
|
||||
/*!
|
||||
\param includeKey Whether or not to include the key in the data
|
||||
\param includeTypeId Whether or not to include the type id in the data
|
||||
\return The string representation of the data
|
||||
*/
|
||||
std::string GetString(const bool includeKey = true, const bool includeTypeId = true) override {
|
||||
if (GetValueType() == -1) {
|
||||
return GeneralUtils::UTF16ToWTF8(this->key) + "=-1:<server variable>";
|
||||
}
|
||||
|
||||
std::stringstream stream;
|
||||
|
||||
if (includeKey) {
|
||||
const std::string& sKey = GeneralUtils::UTF16ToWTF8(this->key, this->key.size());
|
||||
|
||||
stream << sKey << "=";
|
||||
}
|
||||
|
||||
if (includeTypeId) {
|
||||
const std::string& sType = std::to_string(this->GetValueType());
|
||||
|
||||
|
||||
stream << sType << ":";
|
||||
}
|
||||
|
||||
const std::string& sData = this->GetValueString();
|
||||
|
||||
stream << sData;
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string GetValueAsString() override {
|
||||
return this->GetValueString();
|
||||
}
|
||||
|
||||
LDFBaseData* Copy() override {
|
||||
return new LDFData<T>(key, value);
|
||||
}
|
||||
|
||||
inline static T Default = {};
|
||||
};
|
||||
|
||||
// LDF Types
|
||||
@@ -206,38 +206,38 @@ template<> inline eLDFType LDFData<std::string>::GetValueType(void) { return LDF
|
||||
|
||||
// The specialized version for std::u16string (UTF-16)
|
||||
template<>
|
||||
inline void LDFData<std::u16string>::WriteValue(RakNet::BitStream * packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
|
||||
packet->Write(static_cast<uint32_t>(this->value.length()));
|
||||
for (uint32_t i = 0; i < this->value.length(); ++i) {
|
||||
packet->Write(static_cast<uint16_t>(this->value[i]));
|
||||
}
|
||||
inline void LDFData<std::u16string>::WriteValue(RakNet::BitStream* packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
|
||||
packet->Write(static_cast<uint32_t>(this->value.length()));
|
||||
for (uint32_t i = 0; i < this->value.length(); ++i) {
|
||||
packet->Write(static_cast<uint16_t>(this->value[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// The specialized version for bool
|
||||
template<>
|
||||
inline void LDFData<bool>::WriteValue(RakNet::BitStream * packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
|
||||
packet->Write(static_cast<uint8_t>(this->value));
|
||||
inline void LDFData<bool>::WriteValue(RakNet::BitStream* packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
|
||||
packet->Write(static_cast<uint8_t>(this->value));
|
||||
}
|
||||
|
||||
// The specialized version for std::string (UTF-8)
|
||||
template<>
|
||||
inline void LDFData<std::string>::WriteValue(RakNet::BitStream * packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
|
||||
packet->Write(static_cast<uint32_t>(this->value.length()));
|
||||
for (uint32_t i = 0; i < this->value.length(); ++i) {
|
||||
packet->Write(static_cast<uint8_t>(this->value[i]));
|
||||
}
|
||||
inline void LDFData<std::string>::WriteValue(RakNet::BitStream* packet) {
|
||||
packet->Write(static_cast<uint8_t>(this->GetValueType()));
|
||||
|
||||
packet->Write(static_cast<uint32_t>(this->value.length()));
|
||||
for (uint32_t i = 0; i < this->value.length(); ++i) {
|
||||
packet->Write(static_cast<uint8_t>(this->value[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: String Data
|
||||
template<> inline std::string LDFData<std::u16string>::GetValueString(void) {
|
||||
//std::string toReturn(this->value.begin(), this->value.end());
|
||||
//return toReturn;
|
||||
//std::string toReturn(this->value.begin(), this->value.end());
|
||||
//return toReturn;
|
||||
|
||||
return GeneralUtils::UTF16ToWTF8(this->value, this->value.size());
|
||||
}
|
||||
|
||||
438
dCommon/MD5.cpp
438
dCommon/MD5.cpp
@@ -1,36 +1,36 @@
|
||||
/* MD5
|
||||
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
|
||||
for bzflag (http://www.bzflag.org)
|
||||
|
||||
|
||||
based on:
|
||||
|
||||
|
||||
md5.h and md5.c
|
||||
reference implemantion of RFC 1321
|
||||
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* interface header */
|
||||
/* interface header */
|
||||
#include "MD5.h"
|
||||
|
||||
/* system implementation headers */
|
||||
@@ -59,304 +59,290 @@
|
||||
|
||||
// F, G, H and I are basic MD5 functions.
|
||||
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
|
||||
return x&y | ~x&z;
|
||||
return x & y | ~x & z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
|
||||
return x&z | y&~z;
|
||||
return x & z | y & ~z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
|
||||
return x^y^z;
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
|
||||
return y ^ (x | ~z);
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
// rotate_left rotates x left n bits.
|
||||
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
|
||||
return (x << n) | (x >> (32 - n));
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
// Rotation is separate from addition to prevent recomputation.
|
||||
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
|
||||
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
|
||||
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
|
||||
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
|
||||
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// default ctor, just initailize
|
||||
MD5::MD5()
|
||||
{
|
||||
init();
|
||||
MD5::MD5() {
|
||||
init();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// nifty shortcut ctor, compute MD5 for string and finalize it right away
|
||||
MD5::MD5(const std::string &text)
|
||||
{
|
||||
init();
|
||||
update(text.c_str(), text.length());
|
||||
finalize();
|
||||
MD5::MD5(const std::string& text) {
|
||||
init();
|
||||
update(text.c_str(), text.length());
|
||||
finalize();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
void MD5::init()
|
||||
{
|
||||
finalized = false;
|
||||
|
||||
count[0] = 0;
|
||||
count[1] = 0;
|
||||
|
||||
// load magic initialization constants.
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
void MD5::init() {
|
||||
finalized = false;
|
||||
|
||||
count[0] = 0;
|
||||
count[1] = 0;
|
||||
|
||||
// load magic initialization constants.
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
|
||||
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
|
||||
{
|
||||
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
|
||||
(((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
|
||||
void MD5::decode(uint4 output[], const uint1 input[], size_type len) {
|
||||
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
|
||||
(((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// encodes input (uint4) into output (unsigned char). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
|
||||
{
|
||||
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = input[i] & 0xff;
|
||||
output[j + 1] = (input[i] >> 8) & 0xff;
|
||||
output[j + 2] = (input[i] >> 16) & 0xff;
|
||||
output[j + 3] = (input[i] >> 24) & 0xff;
|
||||
}
|
||||
void MD5::encode(uint1 output[], const uint4 input[], size_type len) {
|
||||
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = input[i] & 0xff;
|
||||
output[j + 1] = (input[i] >> 8) & 0xff;
|
||||
output[j + 2] = (input[i] >> 16) & 0xff;
|
||||
output[j + 3] = (input[i] >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// apply MD5 algo on a block
|
||||
void MD5::transform(const uint1 block[blocksize])
|
||||
{
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
decode(x, block, blocksize);
|
||||
|
||||
/* Round 1 */
|
||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(x, 0, sizeof x);
|
||||
void MD5::transform(const uint1 block[blocksize]) {
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
decode(x, block, blocksize);
|
||||
|
||||
/* Round 1 */
|
||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(x, 0, sizeof x);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// MD5 block update operation. Continues an MD5 message-digest
|
||||
// operation, processing another message block
|
||||
void MD5::update(const unsigned char input[], size_type length)
|
||||
{
|
||||
// compute number of bytes mod 64
|
||||
size_type index = count[0] / 8 % blocksize;
|
||||
|
||||
// Update number of bits
|
||||
if ((count[0] += (length << 3)) < (length << 3))
|
||||
count[1]++;
|
||||
count[1] += (length >> 29);
|
||||
|
||||
// number of bytes we need to fill in buffer
|
||||
size_type firstpart = 64 - index;
|
||||
|
||||
size_type i;
|
||||
|
||||
// transform as many times as possible.
|
||||
if (length >= firstpart)
|
||||
{
|
||||
// fill buffer first, transform
|
||||
memcpy(&buffer[index], input, firstpart);
|
||||
transform(buffer);
|
||||
|
||||
// transform chunks of blocksize (64 bytes)
|
||||
for (i = firstpart; i + blocksize <= length; i += blocksize)
|
||||
transform(&input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
// buffer remaining input
|
||||
memcpy(&buffer[index], &input[i], length - i);
|
||||
void MD5::update(const unsigned char input[], size_type length) {
|
||||
// compute number of bytes mod 64
|
||||
size_type index = count[0] / 8 % blocksize;
|
||||
|
||||
// Update number of bits
|
||||
if ((count[0] += (length << 3)) < (length << 3))
|
||||
count[1]++;
|
||||
count[1] += (length >> 29);
|
||||
|
||||
// number of bytes we need to fill in buffer
|
||||
size_type firstpart = 64 - index;
|
||||
|
||||
size_type i;
|
||||
|
||||
// transform as many times as possible.
|
||||
if (length >= firstpart) {
|
||||
// fill buffer first, transform
|
||||
memcpy(&buffer[index], input, firstpart);
|
||||
transform(buffer);
|
||||
|
||||
// transform chunks of blocksize (64 bytes)
|
||||
for (i = firstpart; i + blocksize <= length; i += blocksize)
|
||||
transform(&input[i]);
|
||||
|
||||
index = 0;
|
||||
} else
|
||||
i = 0;
|
||||
|
||||
// buffer remaining input
|
||||
memcpy(&buffer[index], &input[i], length - i);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// for convenience provide a verson with signed char
|
||||
void MD5::update(const char input[], size_type length)
|
||||
{
|
||||
update((const unsigned char*)input, length);
|
||||
void MD5::update(const char input[], size_type length) {
|
||||
update((const unsigned char*)input, length);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
// the message digest and zeroizing the context.
|
||||
MD5& MD5::finalize()
|
||||
{
|
||||
static unsigned char padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (!finalized) {
|
||||
// Save number of bits
|
||||
unsigned char bits[8];
|
||||
encode(bits, count, 8);
|
||||
|
||||
// pad out to 56 mod 64.
|
||||
size_type index = count[0] / 8 % 64;
|
||||
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update(padding, padLen);
|
||||
|
||||
// Append length (before padding)
|
||||
update(bits, 8);
|
||||
|
||||
// Store state in digest
|
||||
encode(digest, state, 16);
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
memset(count, 0, sizeof count);
|
||||
|
||||
finalized = true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
MD5& MD5::finalize() {
|
||||
static unsigned char padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (!finalized) {
|
||||
// Save number of bits
|
||||
unsigned char bits[8];
|
||||
encode(bits, count, 8);
|
||||
|
||||
// pad out to 56 mod 64.
|
||||
size_type index = count[0] / 8 % 64;
|
||||
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update(padding, padLen);
|
||||
|
||||
// Append length (before padding)
|
||||
update(bits, 8);
|
||||
|
||||
// Store state in digest
|
||||
encode(digest, state, 16);
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
memset(count, 0, sizeof count);
|
||||
|
||||
finalized = true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// return hex representation of digest as string
|
||||
std::string MD5::hexdigest() const
|
||||
{
|
||||
if (!finalized)
|
||||
return "";
|
||||
|
||||
char buf[33];
|
||||
for (int i = 0; i<16; i++)
|
||||
sprintf(buf + i * 2, "%02x", digest[i]);
|
||||
buf[32] = 0;
|
||||
|
||||
return std::string(buf);
|
||||
std::string MD5::hexdigest() const {
|
||||
if (!finalized)
|
||||
return "";
|
||||
|
||||
char buf[33];
|
||||
for (int i = 0; i < 16; i++)
|
||||
sprintf(buf + i * 2, "%02x", digest[i]);
|
||||
buf[32] = 0;
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, MD5 md5)
|
||||
{
|
||||
return out << md5.hexdigest();
|
||||
std::ostream& operator<<(std::ostream& out, MD5 md5) {
|
||||
return out << md5.hexdigest();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
std::string md5(const std::string str)
|
||||
{
|
||||
MD5 md5 = MD5(str);
|
||||
|
||||
return md5.hexdigest();
|
||||
std::string md5(const std::string str) {
|
||||
MD5 md5 = MD5(str);
|
||||
|
||||
return md5.hexdigest();
|
||||
}
|
||||
|
||||
106
dCommon/MD5.h
106
dCommon/MD5.h
@@ -1,33 +1,33 @@
|
||||
/* MD5
|
||||
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
|
||||
for bzflag (http://www.bzflag.org)
|
||||
|
||||
|
||||
based on:
|
||||
|
||||
|
||||
md5.h and md5.c
|
||||
reference implementation of RFC 1321
|
||||
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BZF_MD5_H
|
||||
@@ -37,55 +37,55 @@
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// a small class for calculating MD5 hashes of strings or byte arrays
|
||||
// it is not meant to be fast or secure
|
||||
//
|
||||
// usage: 1) feed it blocks of uchars with update()
|
||||
// 2) finalize()
|
||||
// 3) get hexdigest() string
|
||||
// or
|
||||
// MD5(std::string).hexdigest()
|
||||
//
|
||||
// assumes that char is 8 bit and int is 32 bit
|
||||
// a small class for calculating MD5 hashes of strings or byte arrays
|
||||
// it is not meant to be fast or secure
|
||||
//
|
||||
// usage: 1) feed it blocks of uchars with update()
|
||||
// 2) finalize()
|
||||
// 3) get hexdigest() string
|
||||
// or
|
||||
// MD5(std::string).hexdigest()
|
||||
//
|
||||
// assumes that char is 8 bit and int is 32 bit
|
||||
class MD5
|
||||
{
|
||||
public:
|
||||
typedef unsigned int size_type; // must be 32bit
|
||||
|
||||
MD5();
|
||||
MD5(const std::string& text);
|
||||
void update(const unsigned char *buf, size_type length);
|
||||
void update(const char *buf, size_type length);
|
||||
MD5& finalize();
|
||||
std::string hexdigest() const;
|
||||
friend std::ostream& operator<<(std::ostream&, MD5 md5);
|
||||
|
||||
typedef unsigned int size_type; // must be 32bit
|
||||
|
||||
MD5();
|
||||
MD5(const std::string& text);
|
||||
void update(const unsigned char* buf, size_type length);
|
||||
void update(const char* buf, size_type length);
|
||||
MD5& finalize();
|
||||
std::string hexdigest() const;
|
||||
friend std::ostream& operator<<(std::ostream&, MD5 md5);
|
||||
|
||||
private:
|
||||
void init();
|
||||
typedef unsigned char uint1; // 8bit
|
||||
typedef unsigned int uint4; // 32bit
|
||||
enum { blocksize = 64 }; // VC6 won't eat a const static int here
|
||||
|
||||
void transform(const uint1 block[blocksize]);
|
||||
static void decode(uint4 output[], const uint1 input[], size_type len);
|
||||
static void encode(uint1 output[], const uint4 input[], size_type len);
|
||||
|
||||
bool finalized;
|
||||
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
|
||||
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
|
||||
uint4 state[4]; // digest so far
|
||||
uint1 digest[16]; // the result
|
||||
|
||||
// low level logic operations
|
||||
static inline uint4 F(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 rotate_left(uint4 x, int n);
|
||||
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
void init();
|
||||
typedef unsigned char uint1; // 8bit
|
||||
typedef unsigned int uint4; // 32bit
|
||||
enum { blocksize = 64 }; // VC6 won't eat a const static int here
|
||||
|
||||
void transform(const uint1 block[blocksize]);
|
||||
static void decode(uint4 output[], const uint1 input[], size_type len);
|
||||
static void encode(uint1 output[], const uint4 input[], size_type len);
|
||||
|
||||
bool finalized;
|
||||
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
|
||||
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
|
||||
uint4 state[4]; // digest so far
|
||||
uint1 digest[16]; // the result
|
||||
|
||||
// low level logic operations
|
||||
static inline uint4 F(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 rotate_left(uint4 x, int n);
|
||||
static inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
};
|
||||
|
||||
std::string md5(const std::string str);
|
||||
|
||||
@@ -4,174 +4,156 @@
|
||||
|
||||
std::unordered_map<MetricVariable, Metric*> Metrics::m_Metrics = {};
|
||||
std::vector<MetricVariable> Metrics::m_Variables = {
|
||||
MetricVariable::GameLoop,
|
||||
MetricVariable::PacketHandling,
|
||||
MetricVariable::UpdateEntities,
|
||||
MetricVariable::UpdateSpawners,
|
||||
MetricVariable::Physics,
|
||||
MetricVariable::UpdateReplica,
|
||||
MetricVariable::Ghosting,
|
||||
MetricVariable::CPUTime,
|
||||
MetricVariable::Sleep,
|
||||
MetricVariable::Frame,
|
||||
MetricVariable::GameLoop,
|
||||
MetricVariable::PacketHandling,
|
||||
MetricVariable::UpdateEntities,
|
||||
MetricVariable::UpdateSpawners,
|
||||
MetricVariable::Physics,
|
||||
MetricVariable::UpdateReplica,
|
||||
MetricVariable::Ghosting,
|
||||
MetricVariable::CPUTime,
|
||||
MetricVariable::Sleep,
|
||||
MetricVariable::Frame,
|
||||
#ifdef BUILD_VISUAL_DEBUGGER
|
||||
MetricVariable::VisualDebugger,
|
||||
#endif
|
||||
};
|
||||
|
||||
void Metrics::AddMeasurement(MetricVariable variable, int64_t value)
|
||||
{
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
void Metrics::AddMeasurement(MetricVariable variable, int64_t value) {
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
|
||||
Metric* metric;
|
||||
Metric* metric;
|
||||
|
||||
if (iter == m_Metrics.end())
|
||||
{
|
||||
metric = new Metric();
|
||||
if (iter == m_Metrics.end()) {
|
||||
metric = new Metric();
|
||||
|
||||
m_Metrics[variable] = metric;
|
||||
}
|
||||
else
|
||||
{
|
||||
metric = iter->second;
|
||||
}
|
||||
m_Metrics[variable] = metric;
|
||||
} else {
|
||||
metric = iter->second;
|
||||
}
|
||||
|
||||
AddMeasurement(metric, value);
|
||||
AddMeasurement(metric, value);
|
||||
}
|
||||
|
||||
void Metrics::AddMeasurement(Metric* metric, int64_t value)
|
||||
{
|
||||
const auto index = metric->measurementIndex;
|
||||
void Metrics::AddMeasurement(Metric* metric, int64_t value) {
|
||||
const auto index = metric->measurementIndex;
|
||||
|
||||
metric->measurements[index] = value;
|
||||
metric->measurements[index] = value;
|
||||
|
||||
if (metric->max == -1 || value > metric->max)
|
||||
{
|
||||
metric->max = value;
|
||||
}
|
||||
else if (metric->min == -1 || metric->min > value)
|
||||
{
|
||||
metric->min = value;
|
||||
}
|
||||
if (metric->max == -1 || value > metric->max) {
|
||||
metric->max = value;
|
||||
} else if (metric->min == -1 || metric->min > value) {
|
||||
metric->min = value;
|
||||
}
|
||||
|
||||
if (metric->measurementSize < MAX_MEASURMENT_POINTS)
|
||||
{
|
||||
metric->measurementSize++;
|
||||
}
|
||||
if (metric->measurementSize < MAX_MEASURMENT_POINTS) {
|
||||
metric->measurementSize++;
|
||||
}
|
||||
|
||||
metric->measurementIndex = (index + 1) % MAX_MEASURMENT_POINTS;
|
||||
metric->measurementIndex = (index + 1) % MAX_MEASURMENT_POINTS;
|
||||
}
|
||||
|
||||
const Metric* Metrics::GetMetric(MetricVariable variable)
|
||||
{
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
const Metric* Metrics::GetMetric(MetricVariable variable) {
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
|
||||
if (iter == m_Metrics.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (iter == m_Metrics.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Metric* metric = iter->second;
|
||||
Metric* metric = iter->second;
|
||||
|
||||
int64_t average = 0;
|
||||
int64_t average = 0;
|
||||
|
||||
for (size_t i = 0; i < metric->measurementSize; i++)
|
||||
{
|
||||
average += metric->measurements[i];
|
||||
}
|
||||
for (size_t i = 0; i < metric->measurementSize; i++) {
|
||||
average += metric->measurements[i];
|
||||
}
|
||||
|
||||
average /= metric->measurementSize;
|
||||
average /= metric->measurementSize;
|
||||
|
||||
metric->average = average;
|
||||
|
||||
return metric;
|
||||
metric->average = average;
|
||||
|
||||
return metric;
|
||||
}
|
||||
|
||||
void Metrics::StartMeasurement(MetricVariable variable)
|
||||
{
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
void Metrics::StartMeasurement(MetricVariable variable) {
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
|
||||
Metric* metric;
|
||||
Metric* metric;
|
||||
|
||||
if (iter == m_Metrics.end())
|
||||
{
|
||||
metric = new Metric();
|
||||
if (iter == m_Metrics.end()) {
|
||||
metric = new Metric();
|
||||
|
||||
m_Metrics[variable] = metric;
|
||||
}
|
||||
else
|
||||
{
|
||||
metric = iter->second;
|
||||
}
|
||||
m_Metrics[variable] = metric;
|
||||
} else {
|
||||
metric = iter->second;
|
||||
}
|
||||
|
||||
metric->activeMeasurement = std::chrono::high_resolution_clock::now();
|
||||
metric->activeMeasurement = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
void Metrics::EndMeasurement(MetricVariable variable)
|
||||
{
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
void Metrics::EndMeasurement(MetricVariable variable) {
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
const auto& iter = m_Metrics.find(variable);
|
||||
|
||||
if (iter == m_Metrics.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (iter == m_Metrics.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Metric* metric = iter->second;
|
||||
Metric* metric = iter->second;
|
||||
|
||||
const auto elapsed = end - metric->activeMeasurement;
|
||||
const auto elapsed = end - metric->activeMeasurement;
|
||||
|
||||
const auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
|
||||
const auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
|
||||
|
||||
AddMeasurement(metric, nanoseconds);
|
||||
AddMeasurement(metric, nanoseconds);
|
||||
}
|
||||
|
||||
float Metrics::ToMiliseconds(int64_t nanoseconds)
|
||||
{
|
||||
return (float) nanoseconds / 1e6;
|
||||
float Metrics::ToMiliseconds(int64_t nanoseconds) {
|
||||
return (float)nanoseconds / 1e6;
|
||||
}
|
||||
|
||||
std::string Metrics::MetricVariableToString(MetricVariable variable)
|
||||
{
|
||||
switch (variable)
|
||||
{
|
||||
case MetricVariable::GameLoop:
|
||||
return "GameLoop";
|
||||
case MetricVariable::PacketHandling:
|
||||
return "PacketHandling";
|
||||
case MetricVariable::UpdateEntities:
|
||||
return "UpdateEntities";
|
||||
case MetricVariable::UpdateSpawners:
|
||||
return "UpdateSpawners";
|
||||
case MetricVariable::Physics:
|
||||
return "Physics";
|
||||
case MetricVariable::UpdateReplica:
|
||||
return "UpdateReplica";
|
||||
case MetricVariable::Sleep:
|
||||
return "Sleep";
|
||||
case MetricVariable::CPUTime:
|
||||
return "CPUTime";
|
||||
case MetricVariable::Frame:
|
||||
return "Frame";
|
||||
case MetricVariable::Ghosting:
|
||||
return "Ghosting";
|
||||
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
std::string Metrics::MetricVariableToString(MetricVariable variable) {
|
||||
switch (variable) {
|
||||
case MetricVariable::GameLoop:
|
||||
return "GameLoop";
|
||||
case MetricVariable::PacketHandling:
|
||||
return "PacketHandling";
|
||||
case MetricVariable::UpdateEntities:
|
||||
return "UpdateEntities";
|
||||
case MetricVariable::UpdateSpawners:
|
||||
return "UpdateSpawners";
|
||||
case MetricVariable::Physics:
|
||||
return "Physics";
|
||||
case MetricVariable::UpdateReplica:
|
||||
return "UpdateReplica";
|
||||
case MetricVariable::Sleep:
|
||||
return "Sleep";
|
||||
case MetricVariable::CPUTime:
|
||||
return "CPUTime";
|
||||
case MetricVariable::Frame:
|
||||
return "Frame";
|
||||
case MetricVariable::Ghosting:
|
||||
return "Ghosting";
|
||||
#ifdef BUILD_VISUAL_DEBUGGER
|
||||
case MetricVariable::VisualDebugger:
|
||||
return "VisualDebugger";
|
||||
#endif
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<MetricVariable>& Metrics::GetAllMetrics()
|
||||
{
|
||||
return m_Variables;
|
||||
const std::vector<MetricVariable>& Metrics::GetAllMetrics() {
|
||||
return m_Variables;
|
||||
}
|
||||
|
||||
void Metrics::Clear()
|
||||
{
|
||||
for (const auto& pair : m_Metrics)
|
||||
{
|
||||
delete pair.second;
|
||||
}
|
||||
|
||||
m_Metrics.clear();
|
||||
void Metrics::Clear() {
|
||||
for (const auto& pair : m_Metrics) {
|
||||
delete pair.second;
|
||||
}
|
||||
|
||||
m_Metrics.clear();
|
||||
}
|
||||
|
||||
/* RSS Memory utilities
|
||||
@@ -207,46 +189,44 @@ void Metrics::Clear()
|
||||
#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the peak (maximum so far) resident set size (physical
|
||||
* memory use) measured in bytes, or zero if the value cannot be
|
||||
* determined on this OS.
|
||||
*/
|
||||
size_t Metrics::GetPeakRSS()
|
||||
{
|
||||
/**
|
||||
* Returns the peak (maximum so far) resident set size (physical
|
||||
* memory use) measured in bytes, or zero if the value cannot be
|
||||
* determined on this OS.
|
||||
*/
|
||||
size_t Metrics::GetPeakRSS() {
|
||||
#if defined(_WIN32)
|
||||
/* Windows -------------------------------------------------- */
|
||||
PROCESS_MEMORY_COUNTERS info;
|
||||
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
|
||||
return (size_t)info.PeakWorkingSetSize;
|
||||
/* Windows -------------------------------------------------- */
|
||||
PROCESS_MEMORY_COUNTERS info;
|
||||
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
|
||||
return (size_t)info.PeakWorkingSetSize;
|
||||
|
||||
#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
|
||||
/* AIX and Solaris ------------------------------------------ */
|
||||
struct psinfo psinfo;
|
||||
int fd = -1;
|
||||
if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
|
||||
return (size_t)0L; /* Can't open? */
|
||||
if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
|
||||
{
|
||||
close( fd );
|
||||
return (size_t)0L; /* Can't read? */
|
||||
}
|
||||
close( fd );
|
||||
return (size_t)(psinfo.pr_rssize * 1024L);
|
||||
/* AIX and Solaris ------------------------------------------ */
|
||||
struct psinfo psinfo;
|
||||
int fd = -1;
|
||||
if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1)
|
||||
return (size_t)0L; /* Can't open? */
|
||||
if (read(fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) {
|
||||
close(fd);
|
||||
return (size_t)0L; /* Can't read? */
|
||||
}
|
||||
close(fd);
|
||||
return (size_t)(psinfo.pr_rssize * 1024L);
|
||||
|
||||
#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
|
||||
/* BSD, Linux, and OSX -------------------------------------- */
|
||||
struct rusage rusage;
|
||||
getrusage( RUSAGE_SELF, &rusage );
|
||||
/* BSD, Linux, and OSX -------------------------------------- */
|
||||
struct rusage rusage;
|
||||
getrusage(RUSAGE_SELF, &rusage);
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
return (size_t)rusage.ru_maxrss;
|
||||
return (size_t)rusage.ru_maxrss;
|
||||
#else
|
||||
return (size_t)(rusage.ru_maxrss * 1024L);
|
||||
return (size_t)(rusage.ru_maxrss * 1024L);
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Unknown OS ----------------------------------------------- */
|
||||
return (size_t)0L; /* Unsupported. */
|
||||
/* Unknown OS ----------------------------------------------- */
|
||||
return (size_t)0L; /* Unsupported. */
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -255,49 +235,46 @@ size_t Metrics::GetPeakRSS()
|
||||
* Returns the current resident set size (physical memory use) measured
|
||||
* in bytes, or zero if the value cannot be determined on this OS.
|
||||
*/
|
||||
size_t Metrics::GetCurrentRSS()
|
||||
{
|
||||
size_t Metrics::GetCurrentRSS() {
|
||||
#if defined(_WIN32)
|
||||
/* Windows -------------------------------------------------- */
|
||||
PROCESS_MEMORY_COUNTERS info;
|
||||
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
|
||||
return (size_t)info.WorkingSetSize;
|
||||
/* Windows -------------------------------------------------- */
|
||||
PROCESS_MEMORY_COUNTERS info;
|
||||
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
|
||||
return (size_t)info.WorkingSetSize;
|
||||
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
/* OSX ------------------------------------------------------ */
|
||||
struct mach_task_basic_info info;
|
||||
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
|
||||
(task_info_t)&info, &infoCount ) != KERN_SUCCESS )
|
||||
return (size_t)0L; /* Can't access? */
|
||||
return (size_t)info.resident_size;
|
||||
/* OSX ------------------------------------------------------ */
|
||||
struct mach_task_basic_info info;
|
||||
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
|
||||
(task_info_t)&info, &infoCount) != KERN_SUCCESS)
|
||||
return (size_t)0L; /* Can't access? */
|
||||
return (size_t)info.resident_size;
|
||||
|
||||
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
|
||||
/* Linux ---------------------------------------------------- */
|
||||
long rss = 0L;
|
||||
FILE* fp = NULL;
|
||||
if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
|
||||
return (size_t)0L; /* Can't open? */
|
||||
if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
|
||||
{
|
||||
fclose( fp );
|
||||
return (size_t)0L; /* Can't read? */
|
||||
}
|
||||
fclose( fp );
|
||||
return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
|
||||
/* Linux ---------------------------------------------------- */
|
||||
long rss = 0L;
|
||||
FILE* fp = NULL;
|
||||
if ((fp = fopen("/proc/self/statm", "r")) == NULL)
|
||||
return (size_t)0L; /* Can't open? */
|
||||
if (fscanf(fp, "%*s%ld", &rss) != 1) {
|
||||
fclose(fp);
|
||||
return (size_t)0L; /* Can't read? */
|
||||
}
|
||||
fclose(fp);
|
||||
return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
|
||||
|
||||
#else
|
||||
/* AIX, BSD, Solaris, and Unknown OS ------------------------ */
|
||||
return (size_t)0L; /* Unsupported. */
|
||||
/* AIX, BSD, Solaris, and Unknown OS ------------------------ */
|
||||
return (size_t)0L; /* Unsupported. */
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
size_t Metrics::GetProcessID()
|
||||
{
|
||||
size_t Metrics::GetProcessID() {
|
||||
#if defined(_WIN32)
|
||||
return GetCurrentProcessId();
|
||||
return GetCurrentProcessId();
|
||||
#else
|
||||
return getpid();
|
||||
return getpid();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -10,52 +10,55 @@
|
||||
|
||||
enum class MetricVariable : int32_t
|
||||
{
|
||||
GameLoop,
|
||||
PacketHandling,
|
||||
UpdateEntities,
|
||||
UpdateSpawners,
|
||||
Physics,
|
||||
UpdateReplica,
|
||||
Ghosting,
|
||||
CPUTime,
|
||||
Sleep,
|
||||
Frame,
|
||||
GameLoop,
|
||||
PacketHandling,
|
||||
UpdateEntities,
|
||||
UpdateSpawners,
|
||||
Physics,
|
||||
UpdateReplica,
|
||||
Ghosting,
|
||||
CPUTime,
|
||||
Sleep,
|
||||
Frame,
|
||||
#ifdef BUILD_VISUAL_DEBUGGER
|
||||
VisualDebugger
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Metric
|
||||
{
|
||||
int64_t measurements[MAX_MEASURMENT_POINTS] = {};
|
||||
size_t measurementIndex = 0;
|
||||
size_t measurementSize = 0;
|
||||
int64_t max = -1;
|
||||
int64_t min = -1;
|
||||
int64_t average = 0;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> activeMeasurement;
|
||||
int64_t measurements[MAX_MEASURMENT_POINTS] = {};
|
||||
size_t measurementIndex = 0;
|
||||
size_t measurementSize = 0;
|
||||
int64_t max = -1;
|
||||
int64_t min = -1;
|
||||
int64_t average = 0;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> activeMeasurement;
|
||||
};
|
||||
|
||||
class Metrics
|
||||
{
|
||||
public:
|
||||
~Metrics();
|
||||
~Metrics();
|
||||
|
||||
static void AddMeasurement(MetricVariable variable, int64_t value);
|
||||
static void AddMeasurement(Metric* metric, int64_t value);
|
||||
static const Metric* GetMetric(MetricVariable variable);
|
||||
static void StartMeasurement(MetricVariable variable);
|
||||
static void EndMeasurement(MetricVariable variable);
|
||||
static float ToMiliseconds(int64_t nanoseconds);
|
||||
static std::string MetricVariableToString(MetricVariable variable);
|
||||
static const std::vector<MetricVariable>& GetAllMetrics();
|
||||
static void AddMeasurement(MetricVariable variable, int64_t value);
|
||||
static void AddMeasurement(Metric* metric, int64_t value);
|
||||
static const Metric* GetMetric(MetricVariable variable);
|
||||
static void StartMeasurement(MetricVariable variable);
|
||||
static void EndMeasurement(MetricVariable variable);
|
||||
static float ToMiliseconds(int64_t nanoseconds);
|
||||
static std::string MetricVariableToString(MetricVariable variable);
|
||||
static const std::vector<MetricVariable>& GetAllMetrics();
|
||||
|
||||
static size_t GetPeakRSS();
|
||||
static size_t GetCurrentRSS();
|
||||
static size_t GetProcessID();
|
||||
static size_t GetPeakRSS();
|
||||
static size_t GetCurrentRSS();
|
||||
static size_t GetProcessID();
|
||||
|
||||
static void Clear();
|
||||
static void Clear();
|
||||
|
||||
private:
|
||||
Metrics();
|
||||
Metrics();
|
||||
|
||||
static std::unordered_map<MetricVariable, Metric*> m_Metrics;
|
||||
static std::vector<MetricVariable> m_Variables;
|
||||
static std::unordered_map<MetricVariable, Metric*> m_Metrics;
|
||||
static std::vector<MetricVariable> m_Variables;
|
||||
};
|
||||
|
||||
@@ -13,23 +13,23 @@ const NiPoint3 NiPoint3::UNIT_ALL(1.0f, 1.0f, 1.0f);
|
||||
|
||||
//! Initializer
|
||||
NiPoint3::NiPoint3(void) {
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
//! Initializer
|
||||
NiPoint3::NiPoint3(float x, float y, float z) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
//! Copy Constructor
|
||||
NiPoint3::NiPoint3(const NiPoint3& point) {
|
||||
this->x = point.x;
|
||||
this->y = point.y;
|
||||
this->z = point.z;
|
||||
this->x = point.x;
|
||||
this->y = point.y;
|
||||
this->z = point.z;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
@@ -39,68 +39,63 @@ NiPoint3::~NiPoint3(void) {}
|
||||
|
||||
//! Gets the X coordinate
|
||||
float NiPoint3::GetX(void) const {
|
||||
return this->x;
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
void NiPoint3::SetX(float x) {
|
||||
this->x = x;
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
float NiPoint3::GetY(void) const {
|
||||
return this->y;
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
void NiPoint3::SetY(float y) {
|
||||
this->y = y;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
float NiPoint3::GetZ(void) const {
|
||||
return this->z;
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
void NiPoint3::SetZ(float z) {
|
||||
this->z = z;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
//! Gets the length of the vector
|
||||
float NiPoint3::Length(void) const {
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//! Gets the squared length of a vector
|
||||
float NiPoint3::SquaredLength(void) const {
|
||||
return (x*x + y*y + z*z);
|
||||
return (x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//! Returns the dot product of the vector dotted with another vector
|
||||
float NiPoint3::DotProduct(const Vector3& vec) const {
|
||||
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
|
||||
float NiPoint3::DotProduct(const NiPoint3& vec) const {
|
||||
return ((this->x * vec.x) + (this->y * vec.y) + (this->z * vec.z));
|
||||
}
|
||||
|
||||
//! Returns the cross product of the vector crossed with another vector
|
||||
Vector3 NiPoint3::CrossProduct(const Vector3& vec) const {
|
||||
return Vector3(((this->y * vec.z) - (this->z * vec.y)),
|
||||
((this->z * vec.x) - (this->x * vec.z)),
|
||||
((this->x * vec.y) - (this->y * vec.x)));
|
||||
NiPoint3 NiPoint3::CrossProduct(const NiPoint3& vec) const {
|
||||
return NiPoint3(((this->y * vec.z) - (this->z * vec.y)),
|
||||
((this->z * vec.x) - (this->x * vec.z)),
|
||||
((this->x * vec.y) - (this->y * vec.x)));
|
||||
}
|
||||
|
||||
//! Unitize the vector
|
||||
NiPoint3 NiPoint3::Unitize(void) const {
|
||||
NiPoint3 unitVec;
|
||||
float length = this->Length();
|
||||
float length = this->Length();
|
||||
|
||||
unitVec.x = length != 0 ? this->x / length : 0;
|
||||
unitVec.y = length != 0 ? this->y / length : 0;
|
||||
unitVec.z = length != 0 ? this->z / length : 0;
|
||||
|
||||
return unitVec;
|
||||
return length != 0 ? *this / length : NiPoint3::ZERO;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,57 +103,57 @@ NiPoint3 NiPoint3::Unitize(void) const {
|
||||
|
||||
//! Operator to check for equality
|
||||
bool NiPoint3::operator==(const NiPoint3& point) const {
|
||||
return point.x == this->x && point.y == this->y && point.z == this->z;
|
||||
return point.x == this->x && point.y == this->y && point.z == this->z;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool NiPoint3::operator!=(const NiPoint3& point) const {
|
||||
return !(*this == point);
|
||||
return !(*this == point);
|
||||
}
|
||||
|
||||
//! Operator for subscripting
|
||||
float& NiPoint3::operator[](int i) {
|
||||
float * base = &x;
|
||||
return (float&)base[i];
|
||||
float* base = &x;
|
||||
return (float&)base[i];
|
||||
}
|
||||
|
||||
//! Operator for subscripting
|
||||
const float& NiPoint3::operator[](int i) const {
|
||||
const float * base = &x;
|
||||
return (float&)base[i];
|
||||
const float* base = &x;
|
||||
return (float&)base[i];
|
||||
}
|
||||
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3 NiPoint3::operator+(const NiPoint3& point) const {
|
||||
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
|
||||
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
|
||||
}
|
||||
|
||||
//! Operator for subtraction of vectors
|
||||
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
|
||||
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
|
||||
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);
|
||||
}
|
||||
|
||||
//! Operator for addition of a scalar on all vector components
|
||||
NiPoint3 NiPoint3::operator+(float fScalar) const {
|
||||
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
|
||||
return NiPoint3(this->x + fScalar, this->y + fScalar, this->z + fScalar);
|
||||
}
|
||||
|
||||
//! Operator for subtraction of a scalar on all vector components
|
||||
NiPoint3 NiPoint3::operator-(float fScalar) const {
|
||||
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
|
||||
return NiPoint3(this->x - fScalar, this->y - fScalar, this->z - fScalar);
|
||||
}
|
||||
|
||||
//! Operator for scalar multiplication of a vector
|
||||
NiPoint3 NiPoint3::operator*(float fScalar) const {
|
||||
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
|
||||
return NiPoint3(this->x * fScalar, this->y * fScalar, this->z * fScalar);
|
||||
}
|
||||
|
||||
//! Operator for scalar division of a vector
|
||||
NiPoint3 NiPoint3::operator/(float fScalar) const {
|
||||
float retX = this->x != 0 ? this->x / fScalar : 0;
|
||||
float retY = this->y != 0 ? this->y / fScalar : 0;
|
||||
float retZ = this->z != 0 ? this->z / fScalar : 0;
|
||||
return NiPoint3(retX, retY, retZ);
|
||||
float retX = this->x != 0 ? this->x / fScalar : 0;
|
||||
float retY = this->y != 0 ? this->y / fScalar : 0;
|
||||
float retZ = this->z != 0 ? this->z / fScalar : 0;
|
||||
return NiPoint3(retX, retY, retZ);
|
||||
}
|
||||
|
||||
|
||||
@@ -166,96 +161,91 @@ NiPoint3 NiPoint3::operator/(float fScalar) const {
|
||||
|
||||
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
|
||||
bool NiPoint3::IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint) {
|
||||
if (this->x < minPoint.x) return false;
|
||||
if (this->x > maxPoint.x) return false;
|
||||
if (this->y < minPoint.y) return false;
|
||||
if (this->y > maxPoint.y) return false;
|
||||
if (this->x < minPoint.x) return false;
|
||||
if (this->x > maxPoint.x) return false;
|
||||
if (this->y < minPoint.y) return false;
|
||||
if (this->y > maxPoint.y) return false;
|
||||
|
||||
return (this->z < maxPoint.z && this->z > minPoint.z);
|
||||
return (this->z < maxPoint.z&& this->z > minPoint.z);
|
||||
}
|
||||
|
||||
//! Checks to see if the point (or vector) is within a sphere
|
||||
bool NiPoint3::IsWithinSpehere(const NiPoint3& sphereCenter, float radius) {
|
||||
Vector3 diffVec = Vector3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
|
||||
return (diffVec.SquaredLength() <= (radius * radius));
|
||||
NiPoint3 diffVec = NiPoint3(x - sphereCenter.GetX(), y - sphereCenter.GetY(), z - sphereCenter.GetZ());
|
||||
return (diffVec.SquaredLength() <= (radius * radius));
|
||||
}
|
||||
|
||||
NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p)
|
||||
{
|
||||
if (a == b) return a;
|
||||
NiPoint3 NiPoint3::ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p) {
|
||||
if (a == b) return a;
|
||||
|
||||
const auto pa = p - a;
|
||||
const auto ab = b - a;
|
||||
const auto pa = p - a;
|
||||
const auto ab = b - a;
|
||||
|
||||
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
|
||||
const auto t = pa.DotProduct(ab) / ab.SquaredLength();
|
||||
|
||||
if (t <= 0.0f) return a;
|
||||
|
||||
if (t >= 1.0f) return b;
|
||||
|
||||
return a + ab * t;
|
||||
if (t <= 0.0f) return a;
|
||||
|
||||
if (t >= 1.0f) return b;
|
||||
|
||||
return a + ab * t;
|
||||
}
|
||||
|
||||
float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b)
|
||||
{
|
||||
const auto dot = a.DotProduct(b);
|
||||
const auto lenA = a.SquaredLength();
|
||||
const auto lenB = a.SquaredLength();
|
||||
return acos(dot / sqrt(lenA * lenB));
|
||||
float NiPoint3::Angle(const NiPoint3& a, const NiPoint3& b) {
|
||||
const auto dot = a.DotProduct(b);
|
||||
const auto lenA = a.SquaredLength();
|
||||
const auto lenB = a.SquaredLength();
|
||||
return acos(dot / sqrt(lenA * lenB));
|
||||
}
|
||||
|
||||
float NiPoint3::Distance(const NiPoint3& a, const NiPoint3& b)
|
||||
{
|
||||
const auto dx = a.x - b.x;
|
||||
const auto dy = a.y - b.y;
|
||||
const auto dz = a.z - b.z;
|
||||
float NiPoint3::Distance(const NiPoint3& a, const NiPoint3& b) {
|
||||
const auto dx = a.x - b.x;
|
||||
const auto dy = a.y - b.y;
|
||||
const auto dz = a.z - b.z;
|
||||
|
||||
return std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
return std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b)
|
||||
{
|
||||
const auto dx = a.x - b.x;
|
||||
const auto dy = a.y - b.y;
|
||||
const auto dz = a.z - b.z;
|
||||
float NiPoint3::DistanceSquared(const NiPoint3& a, const NiPoint3& b) {
|
||||
const auto dx = a.x - b.x;
|
||||
const auto dy = a.y - b.y;
|
||||
const auto dz = a.z - b.z;
|
||||
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta)
|
||||
{
|
||||
float dx = target.x - current.x;
|
||||
float dy = target.y - current.y;
|
||||
float dz = target.z - current.z;
|
||||
float lengthSquared = (float) ((double) dx * (double) dx + (double) dy * (double) dy + (double) dz * (double) dz);
|
||||
if ((double) lengthSquared == 0.0 || (double) maxDistanceDelta >= 0.0 && (double) lengthSquared <= (double) maxDistanceDelta * (double) maxDistanceDelta)
|
||||
return target;
|
||||
float length = (float) std::sqrt((double) lengthSquared);
|
||||
return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta);
|
||||
NiPoint3 NiPoint3::MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta) {
|
||||
float dx = target.x - current.x;
|
||||
float dy = target.y - current.y;
|
||||
float dz = target.z - current.z;
|
||||
float lengthSquared = (float)((double)dx * (double)dx + (double)dy * (double)dy + (double)dz * (double)dz);
|
||||
if ((double)lengthSquared == 0.0 || (double)maxDistanceDelta >= 0.0 && (double)lengthSquared <= (double)maxDistanceDelta * (double)maxDistanceDelta)
|
||||
return target;
|
||||
float length = (float)std::sqrt((double)lengthSquared);
|
||||
return NiPoint3(current.x + dx / length * maxDistanceDelta, current.y + dy / length * maxDistanceDelta, current.z + dz / length * maxDistanceDelta);
|
||||
}
|
||||
|
||||
//This code is yoinked from the MS XNA code, so it should be right, even if it's horrible.
|
||||
NiPoint3 NiPoint3::RotateByQuaternion(const NiQuaternion& rotation) {
|
||||
Vector3 vector;
|
||||
float num12 = rotation.x + rotation.x;
|
||||
float num2 = rotation.y + rotation.y;
|
||||
float num = rotation.z + rotation.z;
|
||||
float num11 = rotation.w * num12;
|
||||
float num10 = rotation.w * num2;
|
||||
float num9 = rotation.w * num;
|
||||
float num8 = rotation.x * num12;
|
||||
float num7 = rotation.x * num2;
|
||||
float num6 = rotation.x * num;
|
||||
float num5 = rotation.y * num2;
|
||||
float num4 = rotation.y * num;
|
||||
float num3 = rotation.z * num;
|
||||
NiPoint3 vector;
|
||||
float num12 = rotation.x + rotation.x;
|
||||
float num2 = rotation.y + rotation.y;
|
||||
float num = rotation.z + rotation.z;
|
||||
float num11 = rotation.w * num12;
|
||||
float num10 = rotation.w * num2;
|
||||
float num9 = rotation.w * num;
|
||||
float num8 = rotation.x * num12;
|
||||
float num7 = rotation.x * num2;
|
||||
float num6 = rotation.x * num;
|
||||
float num5 = rotation.y * num2;
|
||||
float num4 = rotation.y * num;
|
||||
float num3 = rotation.z * num;
|
||||
|
||||
NiPoint3 value = *this;
|
||||
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
|
||||
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
|
||||
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
|
||||
vector.x = num15;
|
||||
vector.y = num14;
|
||||
vector.z = num13;
|
||||
return vector;
|
||||
}
|
||||
NiPoint3 value = *this;
|
||||
float num15 = ((value.x * ((1.0f - num5) - num3)) + (value.y * (num7 - num9))) + (value.z * (num6 + num10));
|
||||
float num14 = ((value.x * (num7 + num9)) + (value.y * ((1.0f - num8) - num3))) + (value.z * (num4 - num11));
|
||||
float num13 = ((value.x * (num6 - num10)) + (value.y * (num4 + num11))) + (value.z * ((1.0f - num8) - num5));
|
||||
vector.x = num15;
|
||||
vector.y = num14;
|
||||
vector.z = num13;
|
||||
return vector;
|
||||
}
|
||||
|
||||
@@ -7,182 +7,181 @@
|
||||
|
||||
class NiPoint3;
|
||||
class NiQuaternion;
|
||||
typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoint3 class, but typedef'd for clarity in some cases
|
||||
|
||||
//! A custom class the defines a point in space
|
||||
class NiPoint3 {
|
||||
public:
|
||||
float x; //!< The x position
|
||||
float y; //!< The y position
|
||||
float z; //!< The z position
|
||||
float x; //!< The x position
|
||||
float y; //!< The y position
|
||||
float z; //!< The z position
|
||||
|
||||
|
||||
//! Initializer
|
||||
NiPoint3(void);
|
||||
//! Initializer
|
||||
NiPoint3(void);
|
||||
|
||||
//! Initializer
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
NiPoint3(float x, float y, float z);
|
||||
//! Initializer
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
NiPoint3(float x, float y, float z);
|
||||
|
||||
//! Copy Constructor
|
||||
/*!
|
||||
\param point The point to copy
|
||||
*/
|
||||
NiPoint3(const NiPoint3& point);
|
||||
//! Copy Constructor
|
||||
/*!
|
||||
\param point The point to copy
|
||||
*/
|
||||
NiPoint3(const NiPoint3& point);
|
||||
|
||||
//! Destructor
|
||||
~NiPoint3(void);
|
||||
//! Destructor
|
||||
~NiPoint3(void);
|
||||
|
||||
// MARK: Constants
|
||||
static const NiPoint3 ZERO; //!< Point(0, 0, 0)
|
||||
static const NiPoint3 UNIT_X; //!< Point(1, 0, 0)
|
||||
static const NiPoint3 UNIT_Y; //!< Point(0, 1, 0)
|
||||
static const NiPoint3 UNIT_Z; //!< Point(0, 0, 1)
|
||||
static const NiPoint3 UNIT_ALL; //!< Point(1, 1, 1)
|
||||
// MARK: Constants
|
||||
static const NiPoint3 ZERO; //!< Point(0, 0, 0)
|
||||
static const NiPoint3 UNIT_X; //!< Point(1, 0, 0)
|
||||
static const NiPoint3 UNIT_Y; //!< Point(0, 1, 0)
|
||||
static const NiPoint3 UNIT_Z; //!< Point(0, 0, 1)
|
||||
static const NiPoint3 UNIT_ALL; //!< Point(1, 1, 1)
|
||||
|
||||
// MARK: Getters / Setters
|
||||
// MARK: Getters / Setters
|
||||
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
float GetX(void) const;
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
float GetX(void) const;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
void SetX(float x);
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
void SetX(float x);
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
float GetY(void) const;
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
float GetY(void) const;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
void SetY(float y);
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
void SetY(float y);
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
float GetZ(void) const;
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
float GetZ(void) const;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
void SetZ(float z);
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
void SetZ(float z);
|
||||
|
||||
|
||||
// MARK: Member Functions
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Gets the length of the vector
|
||||
/*!
|
||||
\return The scalar length of the vector
|
||||
*/
|
||||
float Length(void) const;
|
||||
//! Gets the length of the vector
|
||||
/*!
|
||||
\return The scalar length of the vector
|
||||
*/
|
||||
float Length(void) const;
|
||||
|
||||
//! Gets the squared length of a vector
|
||||
/*!
|
||||
\return The squared length of a vector
|
||||
*/
|
||||
float SquaredLength(void) const;
|
||||
//! Gets the squared length of a vector
|
||||
/*!
|
||||
\return The squared length of a vector
|
||||
*/
|
||||
float SquaredLength(void) const;
|
||||
|
||||
//! Returns the dot product of the vector dotted with another vector
|
||||
/*!
|
||||
\param vec The second vector
|
||||
\return The dot product of the two vectors
|
||||
*/
|
||||
float DotProduct(const Vector3& vec) const;
|
||||
//! Returns the dot product of the vector dotted with another vector
|
||||
/*!
|
||||
\param vec The second vector
|
||||
\return The dot product of the two vectors
|
||||
*/
|
||||
float DotProduct(const NiPoint3& vec) const;
|
||||
|
||||
//! Returns the cross product of the vector crossed with another vector
|
||||
/*!
|
||||
\param vec The second vector
|
||||
\return The cross product of the two vectors
|
||||
*/
|
||||
Vector3 CrossProduct(const Vector3& vec) const;
|
||||
//! Returns the cross product of the vector crossed with another vector
|
||||
/*!
|
||||
\param vec The second vector
|
||||
\return The cross product of the two vectors
|
||||
*/
|
||||
NiPoint3 CrossProduct(const NiPoint3& vec) const;
|
||||
|
||||
//! Unitize the vector
|
||||
/*!
|
||||
\returns The current vector
|
||||
*/
|
||||
NiPoint3 Unitize(void) const;
|
||||
//! Unitize the vector
|
||||
/*!
|
||||
\returns The current vector
|
||||
*/
|
||||
NiPoint3 Unitize(void) const;
|
||||
|
||||
|
||||
// MARK: Operators
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool operator==(const NiPoint3& point) const;
|
||||
//! Operator to check for equality
|
||||
bool operator==(const NiPoint3& point) const;
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool operator!=(const NiPoint3& point) const;
|
||||
//! Operator to check for inequality
|
||||
bool operator!=(const NiPoint3& point) const;
|
||||
|
||||
//! Operator for subscripting
|
||||
float& operator[](int i);
|
||||
//! Operator for subscripting
|
||||
float& operator[](int i);
|
||||
|
||||
//! Operator for subscripting
|
||||
const float& operator[](int i) const;
|
||||
//! Operator for subscripting
|
||||
const float& operator[](int i) const;
|
||||
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3 operator+(const NiPoint3& point) const;
|
||||
//! Operator for addition of vectors
|
||||
NiPoint3 operator+(const NiPoint3& point) const;
|
||||
|
||||
//! Operator for subtraction of vectors
|
||||
NiPoint3 operator-(const NiPoint3& point) const;
|
||||
//! Operator for subtraction of vectors
|
||||
NiPoint3 operator-(const NiPoint3& point) const;
|
||||
|
||||
//! Operator for addition of a scalar on all vector components
|
||||
NiPoint3 operator+(float fScalar) const;
|
||||
//! Operator for addition of a scalar on all vector components
|
||||
NiPoint3 operator+(float fScalar) const;
|
||||
|
||||
//! Operator for subtraction of a scalar on all vector components
|
||||
NiPoint3 operator-(float fScalar) const;
|
||||
//! Operator for subtraction of a scalar on all vector components
|
||||
NiPoint3 operator-(float fScalar) const;
|
||||
|
||||
//! Operator for scalar multiplication of a vector
|
||||
NiPoint3 operator*(float fScalar) const;
|
||||
//! Operator for scalar multiplication of a vector
|
||||
NiPoint3 operator*(float fScalar) const;
|
||||
|
||||
//! Operator for scalar division of a vector
|
||||
NiPoint3 operator/(float fScalar) const;
|
||||
//! Operator for scalar division of a vector
|
||||
NiPoint3 operator/(float fScalar) const;
|
||||
|
||||
|
||||
// MARK: Helper Functions
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
|
||||
/*!
|
||||
\param minPoint The minimum point of the bounding box
|
||||
\param maxPoint The maximum point of the bounding box
|
||||
\return Whether or not this point lies within the box
|
||||
*/
|
||||
bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint);
|
||||
//! Checks to see if the point (or vector) is with an Axis-Aligned Bounding Box
|
||||
/*!
|
||||
\param minPoint The minimum point of the bounding box
|
||||
\param maxPoint The maximum point of the bounding box
|
||||
\return Whether or not this point lies within the box
|
||||
*/
|
||||
bool IsWithinAxisAlignedBox(const NiPoint3& minPoint, const NiPoint3& maxPoint);
|
||||
|
||||
//! Checks to see if the point (or vector) is within a sphere
|
||||
/*!
|
||||
\param sphereCenter The sphere center
|
||||
\param radius The radius
|
||||
*/
|
||||
bool IsWithinSpehere(const NiPoint3& sphereCenter, float radius);
|
||||
//! Checks to see if the point (or vector) is within a sphere
|
||||
/*!
|
||||
\param sphereCenter The sphere center
|
||||
\param radius The radius
|
||||
*/
|
||||
bool IsWithinSpehere(const NiPoint3& sphereCenter, float radius);
|
||||
|
||||
/*!
|
||||
\param a Start of line
|
||||
\param b End of line
|
||||
\param p Refrence point
|
||||
\return The point of line AB which is closest to P
|
||||
*/
|
||||
static NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p);
|
||||
/*!
|
||||
\param a Start of line
|
||||
\param b End of line
|
||||
\param p Refrence point
|
||||
\return The point of line AB which is closest to P
|
||||
*/
|
||||
static NiPoint3 ClosestPointOnLine(const NiPoint3& a, const NiPoint3& b, const NiPoint3& p);
|
||||
|
||||
static float Angle(const NiPoint3& a, const NiPoint3& b);
|
||||
static float Angle(const NiPoint3& a, const NiPoint3& b);
|
||||
|
||||
static float Distance(const NiPoint3& a, const NiPoint3& b);
|
||||
|
||||
static float DistanceSquared(const NiPoint3& a, const NiPoint3& b);
|
||||
static float Distance(const NiPoint3& a, const NiPoint3& b);
|
||||
|
||||
static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta);
|
||||
static float DistanceSquared(const NiPoint3& a, const NiPoint3& b);
|
||||
|
||||
NiPoint3 RotateByQuaternion(const NiQuaternion& rotation);
|
||||
static NiPoint3 MoveTowards(const NiPoint3& current, const NiPoint3& target, float maxDistanceDelta);
|
||||
|
||||
NiPoint3 RotateByQuaternion(const NiQuaternion& rotation);
|
||||
};
|
||||
|
||||
@@ -8,18 +8,18 @@ const NiQuaternion NiQuaternion::IDENTITY(1, 0, 0, 0);
|
||||
|
||||
//! The initializer
|
||||
NiQuaternion::NiQuaternion(void) {
|
||||
this->w = 1;
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
this->w = 1;
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
//! The initializer
|
||||
NiQuaternion::NiQuaternion(float w, float x, float y, float z) {
|
||||
this->w = w;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
this->w = w;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
@@ -30,98 +30,97 @@ NiQuaternion::~NiQuaternion(void) {}
|
||||
|
||||
//! Gets the W coordinate
|
||||
float NiQuaternion::GetW(void) const {
|
||||
return this->w;
|
||||
return this->w;
|
||||
}
|
||||
|
||||
//! Sets the W coordinate
|
||||
void NiQuaternion::SetW(float w) {
|
||||
this->w = w;
|
||||
this->w = w;
|
||||
}
|
||||
|
||||
//! Gets the X coordinate
|
||||
float NiQuaternion::GetX(void) const {
|
||||
return this->x;
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
void NiQuaternion::SetX(float x) {
|
||||
this->x = x;
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
float NiQuaternion::GetY(void) const {
|
||||
return this->y;
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
void NiQuaternion::SetY(float y) {
|
||||
this->y = y;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
float NiQuaternion::GetZ(void) const {
|
||||
return this->z;
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
void NiQuaternion::SetZ(float z) {
|
||||
this->z = z;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
Vector3 NiQuaternion::GetForwardVector(void) const {
|
||||
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
|
||||
NiPoint3 NiQuaternion::GetForwardVector(void) const {
|
||||
return NiPoint3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
|
||||
}
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
Vector3 NiQuaternion::GetUpVector(void) const {
|
||||
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
|
||||
NiPoint3 NiQuaternion::GetUpVector(void) const {
|
||||
return NiPoint3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
|
||||
}
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
Vector3 NiQuaternion::GetRightVector(void) const {
|
||||
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
|
||||
NiPoint3 NiQuaternion::GetRightVector(void) const {
|
||||
return NiPoint3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
|
||||
}
|
||||
|
||||
Vector3 NiQuaternion::GetEulerAngles() const {
|
||||
Vector3 angles;
|
||||
NiPoint3 NiQuaternion::GetEulerAngles() const {
|
||||
NiPoint3 angles;
|
||||
|
||||
// roll (x-axis rotation)
|
||||
const float sinr_cosp = 2 * (w * x + y * z);
|
||||
const float cosr_cosp = 1 - 2 * (x * x + y * y);
|
||||
angles.x = std::atan2(sinr_cosp, cosr_cosp);
|
||||
// roll (x-axis rotation)
|
||||
const float sinr_cosp = 2 * (w * x + y * z);
|
||||
const float cosr_cosp = 1 - 2 * (x * x + y * y);
|
||||
angles.x = std::atan2(sinr_cosp, cosr_cosp);
|
||||
|
||||
// pitch (y-axis rotation)
|
||||
const float sinp = 2 * (w * y - z * x);
|
||||
|
||||
if (std::abs(sinp) >= 1) {
|
||||
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
|
||||
}
|
||||
else {
|
||||
angles.y = std::asin(sinp);
|
||||
}
|
||||
// pitch (y-axis rotation)
|
||||
const float sinp = 2 * (w * y - z * x);
|
||||
|
||||
// yaw (z-axis rotation)
|
||||
const float siny_cosp = 2 * (w * z + x * y);
|
||||
const float cosy_cosp = 1 - 2 * (y * y + z * z);
|
||||
angles.z = std::atan2(siny_cosp, cosy_cosp);
|
||||
if (std::abs(sinp) >= 1) {
|
||||
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
|
||||
} else {
|
||||
angles.y = std::asin(sinp);
|
||||
}
|
||||
|
||||
return angles;
|
||||
// yaw (z-axis rotation)
|
||||
const float siny_cosp = 2 * (w * z + x * y);
|
||||
const float cosy_cosp = 1 - 2 * (y * y + z * z);
|
||||
angles.z = std::atan2(siny_cosp, cosy_cosp);
|
||||
|
||||
return angles;
|
||||
}
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool NiQuaternion::operator==(const NiQuaternion& rot) const {
|
||||
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
|
||||
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool NiQuaternion::operator!=(const NiQuaternion& rot) const {
|
||||
return !(*this == rot);
|
||||
return !(*this == rot);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,65 +134,63 @@ NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& d
|
||||
source.y = 0.0f;
|
||||
dest.y = 0.0f;
|
||||
|
||||
NiPoint3 forwardVector = NiPoint3(dest - source).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3::UNIT_Z;
|
||||
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
|
||||
|
||||
float dot = posZ.DotProduct(forwardVector);
|
||||
float rotAngle = static_cast<float>(acos(dot));
|
||||
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
NiPoint3 forwardVector = NiPoint3(dest - source).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3::UNIT_Z;
|
||||
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
|
||||
|
||||
float dot = posZ.DotProduct(forwardVector);
|
||||
float rotAngle = static_cast<float>(acos(dot));
|
||||
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint)
|
||||
{
|
||||
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3::UNIT_Z;
|
||||
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
|
||||
|
||||
float dot = posZ.DotProduct(forwardVector);
|
||||
float rotAngle = static_cast<float>(acos(dot));
|
||||
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3::UNIT_Z;
|
||||
NiPoint3 vecA = posZ.CrossProduct(forwardVector).Unitize();
|
||||
|
||||
float dot = posZ.DotProduct(forwardVector);
|
||||
float rotAngle = static_cast<float>(acos(dot));
|
||||
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
NiQuaternion NiQuaternion::CreateFromAxisAngle(const Vector3& axis, float angle) {
|
||||
float halfAngle = angle * 0.5f;
|
||||
float s = static_cast<float>(sin(halfAngle));
|
||||
|
||||
NiQuaternion q;
|
||||
q.x = axis.GetX() * s;
|
||||
q.y = axis.GetY() * s;
|
||||
q.z = axis.GetZ() * s;
|
||||
q.w = static_cast<float>(cos(halfAngle));
|
||||
|
||||
return q;
|
||||
NiQuaternion NiQuaternion::CreateFromAxisAngle(const NiPoint3& axis, float angle) {
|
||||
float halfAngle = angle * 0.5f;
|
||||
float s = static_cast<float>(sin(halfAngle));
|
||||
|
||||
NiQuaternion q;
|
||||
q.x = axis.GetX() * s;
|
||||
q.y = axis.GetY() * s;
|
||||
q.z = axis.GetZ() * s;
|
||||
q.w = static_cast<float>(cos(halfAngle));
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles)
|
||||
{
|
||||
// Abbreviations for the various angular functions
|
||||
float cy = cos(eulerAngles.z * 0.5);
|
||||
float sy = sin(eulerAngles.z * 0.5);
|
||||
float cp = cos(eulerAngles.y * 0.5);
|
||||
float sp = sin(eulerAngles.y * 0.5);
|
||||
float cr = cos(eulerAngles.x * 0.5);
|
||||
float sr = sin(eulerAngles.x * 0.5);
|
||||
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles) {
|
||||
// Abbreviations for the various angular functions
|
||||
float cy = cos(eulerAngles.z * 0.5);
|
||||
float sy = sin(eulerAngles.z * 0.5);
|
||||
float cp = cos(eulerAngles.y * 0.5);
|
||||
float sp = sin(eulerAngles.y * 0.5);
|
||||
float cr = cos(eulerAngles.x * 0.5);
|
||||
float sr = sin(eulerAngles.x * 0.5);
|
||||
|
||||
NiQuaternion q;
|
||||
q.w = cr * cp * cy + sr * sp * sy;
|
||||
q.x = sr * cp * cy - cr * sp * sy;
|
||||
q.y = cr * sp * cy + sr * cp * sy;
|
||||
q.z = cr * cp * sy - sr * sp * cy;
|
||||
NiQuaternion q;
|
||||
q.w = cr * cp * cy + sr * sp * sy;
|
||||
q.x = sr * cp * cy - cr * sp * sy;
|
||||
q.y = cr * sp * cy + sr * cp * sy;
|
||||
q.z = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
return q;
|
||||
return q;
|
||||
}
|
||||
|
||||
@@ -9,143 +9,142 @@
|
||||
*/
|
||||
|
||||
class NiQuaternion;
|
||||
typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version of NiQuaternion
|
||||
|
||||
//! A class that defines a rotation in space
|
||||
class NiQuaternion {
|
||||
public:
|
||||
float w; //!< The w coordinate
|
||||
float x; //!< The x coordinate
|
||||
float y; //!< The y coordinate
|
||||
float z; //!< The z coordinate
|
||||
|
||||
|
||||
//! The initializer
|
||||
NiQuaternion(void);
|
||||
|
||||
//! The initializer
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
\param x The x coordinate
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
NiQuaternion(float w, float x, float y, float z);
|
||||
|
||||
//! Destructor
|
||||
~NiQuaternion(void);
|
||||
|
||||
// MARK: Constants
|
||||
static const NiQuaternion IDENTITY; //!< Quaternion(1, 0, 0, 0)
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
/*!
|
||||
\return The w coordinate
|
||||
*/
|
||||
float GetW(void) const;
|
||||
|
||||
//! Sets the W coordinate
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
*/
|
||||
void SetW(float w);
|
||||
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
float GetX(void) const;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
void SetX(float x);
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
float GetY(void) const;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
void SetY(float y);
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
float GetZ(void) const;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
void SetZ(float z);
|
||||
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
/*!
|
||||
\return The forward vector of the quaternion
|
||||
*/
|
||||
Vector3 GetForwardVector(void) const;
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
/*!
|
||||
\return The up vector fo the quaternion
|
||||
*/
|
||||
Vector3 GetUpVector(void) const;
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
/*!
|
||||
\return The right vector of the quaternion
|
||||
*/
|
||||
Vector3 GetRightVector(void) const;
|
||||
float w; //!< The w coordinate
|
||||
float x; //!< The x coordinate
|
||||
float y; //!< The y coordinate
|
||||
float z; //!< The z coordinate
|
||||
|
||||
Vector3 GetEulerAngles() const;
|
||||
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool operator==(const NiQuaternion& rot) const;
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool operator!=(const NiQuaternion& rot) const;
|
||||
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
/*!
|
||||
\param axis The axis that is used
|
||||
\param angle The angle relative to this axis
|
||||
\return A quaternion created from the axis and angle
|
||||
*/
|
||||
static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
|
||||
|
||||
static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
|
||||
//! The initializer
|
||||
NiQuaternion(void);
|
||||
|
||||
//! The initializer
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
\param x The x coordinate
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
NiQuaternion(float w, float x, float y, float z);
|
||||
|
||||
//! Destructor
|
||||
~NiQuaternion(void);
|
||||
|
||||
// MARK: Constants
|
||||
static const NiQuaternion IDENTITY; //!< Quaternion(1, 0, 0, 0)
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
/*!
|
||||
\return The w coordinate
|
||||
*/
|
||||
float GetW(void) const;
|
||||
|
||||
//! Sets the W coordinate
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
*/
|
||||
void SetW(float w);
|
||||
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
float GetX(void) const;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
void SetX(float x);
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
float GetY(void) const;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
void SetY(float y);
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
float GetZ(void) const;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
void SetZ(float z);
|
||||
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
/*!
|
||||
\return The forward vector of the quaternion
|
||||
*/
|
||||
NiPoint3 GetForwardVector(void) const;
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
/*!
|
||||
\return The up vector fo the quaternion
|
||||
*/
|
||||
NiPoint3 GetUpVector(void) const;
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
/*!
|
||||
\return The right vector of the quaternion
|
||||
*/
|
||||
NiPoint3 GetRightVector(void) const;
|
||||
|
||||
NiPoint3 GetEulerAngles() const;
|
||||
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
bool operator==(const NiQuaternion& rot) const;
|
||||
|
||||
//! Operator to check for inequality
|
||||
bool operator!=(const NiQuaternion& rot) const;
|
||||
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
/*!
|
||||
\param axis The axis that is used
|
||||
\param angle The angle relative to this axis
|
||||
\return A quaternion created from the axis and angle
|
||||
*/
|
||||
static NiQuaternion CreateFromAxisAngle(const NiPoint3& axis, float angle);
|
||||
|
||||
static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
|
||||
};
|
||||
|
||||
@@ -7,36 +7,36 @@
|
||||
*/
|
||||
enum class PermissionMap : uint64_t
|
||||
{
|
||||
/**
|
||||
* Reserved for future use, bit 0-3.
|
||||
*/
|
||||
/**
|
||||
* Reserved for future use, bit 0-3.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The character has restricted trade acccess, bit 4.
|
||||
*/
|
||||
RestrictedTradeAccess = 0x1 << 4,
|
||||
/**
|
||||
* The character has restricted trade acccess, bit 4.
|
||||
*/
|
||||
RestrictedTradeAccess = 0x1 << 4,
|
||||
|
||||
/**
|
||||
* The character has restricted mail access, bit 5.
|
||||
*/
|
||||
RestrictedMailAccess = 0x1 << 5,
|
||||
/**
|
||||
* The character has restricted mail access, bit 5.
|
||||
*/
|
||||
RestrictedMailAccess = 0x1 << 5,
|
||||
|
||||
/**
|
||||
* The character has restricted chat access, bit 6.
|
||||
*/
|
||||
RestrictedChatAccess = 0x1 << 6,
|
||||
/**
|
||||
* The character has restricted chat access, bit 6.
|
||||
*/
|
||||
RestrictedChatAccess = 0x1 << 6,
|
||||
|
||||
//
|
||||
// Combined permissions
|
||||
//
|
||||
//
|
||||
// Combined permissions
|
||||
//
|
||||
|
||||
/**
|
||||
* The character is marked as 'old', restricted from trade and mail.
|
||||
*/
|
||||
Old = RestrictedTradeAccess | RestrictedMailAccess,
|
||||
/**
|
||||
* The character is marked as 'old', restricted from trade and mail.
|
||||
*/
|
||||
Old = RestrictedTradeAccess | RestrictedMailAccess,
|
||||
|
||||
/**
|
||||
* The character is soft banned, restricted from trade, mail, and chat.
|
||||
*/
|
||||
SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess,
|
||||
/**
|
||||
* The character is soft banned, restricted from trade, mail, and chat.
|
||||
*/
|
||||
SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess,
|
||||
};
|
||||
|
||||
@@ -5,153 +5,148 @@
|
||||
|
||||
const unsigned long long SHA512::sha512_k[80] = //ULL = uint64
|
||||
{ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL };
|
||||
|
||||
void SHA512::transform(const unsigned char *message, unsigned int block_nb)
|
||||
{
|
||||
uint64 w[80];
|
||||
uint64 wv[8];
|
||||
uint64 t1, t2;
|
||||
const unsigned char *sub_block;
|
||||
int i, j;
|
||||
for (i = 0; i < (int)block_nb; i++) {
|
||||
sub_block = message + (i << 7);
|
||||
for (j = 0; j < 16; j++) {
|
||||
SHA2_PACK64(&sub_block[j << 3], &w[j]);
|
||||
}
|
||||
for (j = 16; j < 80; j++) {
|
||||
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
wv[j] = m_h[j];
|
||||
}
|
||||
for (j = 0; j < 80; j++) {
|
||||
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
|
||||
+ sha512_k[j] + w[j];
|
||||
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||
wv[7] = wv[6];
|
||||
wv[6] = wv[5];
|
||||
wv[5] = wv[4];
|
||||
wv[4] = wv[3] + t1;
|
||||
wv[3] = wv[2];
|
||||
wv[2] = wv[1];
|
||||
wv[1] = wv[0];
|
||||
wv[0] = t1 + t2;
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
m_h[j] += wv[j];
|
||||
}
|
||||
|
||||
}
|
||||
void SHA512::transform(const unsigned char* message, unsigned int block_nb) {
|
||||
uint64 w[80];
|
||||
uint64 wv[8];
|
||||
uint64 t1, t2;
|
||||
const unsigned char* sub_block;
|
||||
int i, j;
|
||||
for (i = 0; i < (int)block_nb; i++) {
|
||||
sub_block = message + (i << 7);
|
||||
for (j = 0; j < 16; j++) {
|
||||
SHA2_PACK64(&sub_block[j << 3], &w[j]);
|
||||
}
|
||||
for (j = 16; j < 80; j++) {
|
||||
w[j] = SHA512_F4(w[j - 2]) + w[j - 7] + SHA512_F3(w[j - 15]) + w[j - 16];
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
wv[j] = m_h[j];
|
||||
}
|
||||
for (j = 0; j < 80; j++) {
|
||||
t1 = wv[7] + SHA512_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
|
||||
+ sha512_k[j] + w[j];
|
||||
t2 = SHA512_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||
wv[7] = wv[6];
|
||||
wv[6] = wv[5];
|
||||
wv[5] = wv[4];
|
||||
wv[4] = wv[3] + t1;
|
||||
wv[3] = wv[2];
|
||||
wv[2] = wv[1];
|
||||
wv[1] = wv[0];
|
||||
wv[0] = t1 + t2;
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
m_h[j] += wv[j];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SHA512::init()
|
||||
{
|
||||
m_h[0] = 0x6a09e667f3bcc908ULL;
|
||||
m_h[1] = 0xbb67ae8584caa73bULL;
|
||||
m_h[2] = 0x3c6ef372fe94f82bULL;
|
||||
m_h[3] = 0xa54ff53a5f1d36f1ULL;
|
||||
m_h[4] = 0x510e527fade682d1ULL;
|
||||
m_h[5] = 0x9b05688c2b3e6c1fULL;
|
||||
m_h[6] = 0x1f83d9abfb41bd6bULL;
|
||||
m_h[7] = 0x5be0cd19137e2179ULL;
|
||||
m_len = 0;
|
||||
m_tot_len = 0;
|
||||
void SHA512::init() {
|
||||
m_h[0] = 0x6a09e667f3bcc908ULL;
|
||||
m_h[1] = 0xbb67ae8584caa73bULL;
|
||||
m_h[2] = 0x3c6ef372fe94f82bULL;
|
||||
m_h[3] = 0xa54ff53a5f1d36f1ULL;
|
||||
m_h[4] = 0x510e527fade682d1ULL;
|
||||
m_h[5] = 0x9b05688c2b3e6c1fULL;
|
||||
m_h[6] = 0x1f83d9abfb41bd6bULL;
|
||||
m_h[7] = 0x5be0cd19137e2179ULL;
|
||||
m_len = 0;
|
||||
m_tot_len = 0;
|
||||
}
|
||||
|
||||
void SHA512::update(const unsigned char *message, unsigned int len)
|
||||
{
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char *shifted_message;
|
||||
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
|
||||
rem_len = len < tmp_len ? len : tmp_len;
|
||||
memcpy(&m_block[m_len], message, rem_len);
|
||||
if (m_len + len < SHA384_512_BLOCK_SIZE) {
|
||||
m_len += len;
|
||||
return;
|
||||
}
|
||||
new_len = len - rem_len;
|
||||
block_nb = new_len / SHA384_512_BLOCK_SIZE;
|
||||
shifted_message = message + rem_len;
|
||||
transform(m_block, 1);
|
||||
transform(shifted_message, block_nb);
|
||||
rem_len = new_len % SHA384_512_BLOCK_SIZE;
|
||||
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
|
||||
m_len = rem_len;
|
||||
m_tot_len += (block_nb + 1) << 7;
|
||||
void SHA512::update(const unsigned char* message, unsigned int len) {
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char* shifted_message;
|
||||
tmp_len = SHA384_512_BLOCK_SIZE - m_len;
|
||||
rem_len = len < tmp_len ? len : tmp_len;
|
||||
memcpy(&m_block[m_len], message, rem_len);
|
||||
if (m_len + len < SHA384_512_BLOCK_SIZE) {
|
||||
m_len += len;
|
||||
return;
|
||||
}
|
||||
new_len = len - rem_len;
|
||||
block_nb = new_len / SHA384_512_BLOCK_SIZE;
|
||||
shifted_message = message + rem_len;
|
||||
transform(m_block, 1);
|
||||
transform(shifted_message, block_nb);
|
||||
rem_len = new_len % SHA384_512_BLOCK_SIZE;
|
||||
memcpy(m_block, &shifted_message[block_nb << 7], rem_len);
|
||||
m_len = rem_len;
|
||||
m_tot_len += (block_nb + 1) << 7;
|
||||
}
|
||||
|
||||
void SHA512::final(unsigned char *digest)
|
||||
{
|
||||
unsigned int block_nb;
|
||||
unsigned int pm_len;
|
||||
unsigned int len_b;
|
||||
int i;
|
||||
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
|
||||
< (m_len % SHA384_512_BLOCK_SIZE));
|
||||
len_b = (m_tot_len + m_len) << 3;
|
||||
pm_len = block_nb << 7;
|
||||
memset(m_block + m_len, 0, pm_len - m_len);
|
||||
m_block[m_len] = 0x80;
|
||||
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
|
||||
transform(m_block, block_nb);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
|
||||
}
|
||||
void SHA512::final(unsigned char* digest) {
|
||||
unsigned int block_nb;
|
||||
unsigned int pm_len;
|
||||
unsigned int len_b;
|
||||
int i;
|
||||
block_nb = 1 + ((SHA384_512_BLOCK_SIZE - 17)
|
||||
< (m_len % SHA384_512_BLOCK_SIZE));
|
||||
len_b = (m_tot_len + m_len) << 3;
|
||||
pm_len = block_nb << 7;
|
||||
memset(m_block + m_len, 0, pm_len - m_len);
|
||||
m_block[m_len] = 0x80;
|
||||
SHA2_UNPACK32(len_b, m_block + pm_len - 4);
|
||||
transform(m_block, block_nb);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SHA2_UNPACK64(m_h[i], &digest[i << 3]);
|
||||
}
|
||||
}
|
||||
|
||||
std::string sha512(std::string input)
|
||||
{
|
||||
unsigned char digest[SHA512::DIGEST_SIZE];
|
||||
memset(digest, 0, SHA512::DIGEST_SIZE);
|
||||
class SHA512 ctx;
|
||||
ctx.init();
|
||||
ctx.update((unsigned char*)input.c_str(), input.length());
|
||||
ctx.final(digest);
|
||||
std::string sha512(std::string input) {
|
||||
unsigned char digest[SHA512::DIGEST_SIZE];
|
||||
memset(digest, 0, SHA512::DIGEST_SIZE);
|
||||
class SHA512 ctx;
|
||||
ctx.init();
|
||||
ctx.update((unsigned char*)input.c_str(), input.length());
|
||||
ctx.final(digest);
|
||||
|
||||
char buf[2 * SHA512::DIGEST_SIZE + 1];
|
||||
buf[2 * SHA512::DIGEST_SIZE] = 0;
|
||||
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
|
||||
sprintf(buf + i * 2, "%02x", digest[i]);
|
||||
char buf[2 * SHA512::DIGEST_SIZE + 1];
|
||||
buf[2 * SHA512::DIGEST_SIZE] = 0;
|
||||
for (int i = 0; i < SHA512::DIGEST_SIZE; i++)
|
||||
sprintf(buf + i * 2, "%02x", digest[i]);
|
||||
|
||||
return std::string(buf);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
@@ -5,25 +5,25 @@
|
||||
|
||||
class SHA512 {
|
||||
protected:
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
const static uint64 sha512_k[];
|
||||
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
const static uint64 sha512_k[];
|
||||
static const unsigned int SHA384_512_BLOCK_SIZE = (1024 / 8);
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update(const unsigned char *message, unsigned int len);
|
||||
void final(unsigned char *digest);
|
||||
static const unsigned int DIGEST_SIZE = (512 / 8);
|
||||
|
||||
void init();
|
||||
void update(const unsigned char* message, unsigned int len);
|
||||
void final(unsigned char* digest);
|
||||
static const unsigned int DIGEST_SIZE = (512 / 8);
|
||||
|
||||
protected:
|
||||
void transform(const unsigned char *message, unsigned int block_nb);
|
||||
unsigned int m_tot_len;
|
||||
unsigned int m_len;
|
||||
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
|
||||
uint64 m_h[8];
|
||||
void transform(const unsigned char* message, unsigned int block_nb);
|
||||
unsigned int m_tot_len;
|
||||
unsigned int m_len;
|
||||
unsigned char m_block[2 * SHA384_512_BLOCK_SIZE];
|
||||
uint64 m_h[8];
|
||||
};
|
||||
|
||||
std::string sha512(std::string input);
|
||||
|
||||
@@ -6,22 +6,22 @@
|
||||
|
||||
std::string demangle(const char* name) {
|
||||
|
||||
int status = -4; // some arbitrary value to eliminate the compiler warning
|
||||
int status = -4; // some arbitrary value to eliminate the compiler warning
|
||||
|
||||
// enable c++11 by passing the flag -std=c++11 to g++
|
||||
std::unique_ptr<char, void(*)(void*)> res {
|
||||
abi::__cxa_demangle(name, NULL, NULL, &status),
|
||||
std::free
|
||||
};
|
||||
// enable c++11 by passing the flag -std=c++11 to g++
|
||||
std::unique_ptr<char, void(*)(void*)> res{
|
||||
abi::__cxa_demangle(name, NULL, NULL, &status),
|
||||
std::free
|
||||
};
|
||||
|
||||
return (status==0) ? res.get() : name ;
|
||||
return (status == 0) ? res.get() : name;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// does nothing if not g++
|
||||
std::string demangle(const char* name) {
|
||||
return name;
|
||||
return name;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,5 +8,5 @@ std::string demangle(const char* name);
|
||||
template <class T>
|
||||
std::string type(const T& t) {
|
||||
|
||||
return demangle(typeid(t).name());
|
||||
return demangle(typeid(t).name());
|
||||
}
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
#include "ZCompression.h"
|
||||
#include "ZCompression.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
namespace ZCompression
|
||||
{
|
||||
int32_t GetMaxCompressedLength(int32_t nLenSrc)
|
||||
{
|
||||
int32_t n16kBlocks = (nLenSrc + 16383) / 16384; // round up any fraction of a block
|
||||
return (nLenSrc + 6 + (n16kBlocks * 5));
|
||||
}
|
||||
namespace ZCompression {
|
||||
int32_t GetMaxCompressedLength(int32_t nLenSrc) {
|
||||
int32_t n16kBlocks = (nLenSrc + 16383) / 16384; // round up any fraction of a block
|
||||
return (nLenSrc + 6 + (n16kBlocks * 5));
|
||||
}
|
||||
|
||||
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst)
|
||||
{
|
||||
z_stream zInfo = { 0 };
|
||||
zInfo.total_in = zInfo.avail_in = nLenSrc;
|
||||
zInfo.total_out = zInfo.avail_out = nLenDst;
|
||||
zInfo.next_in = const_cast<Bytef*>(abSrc);
|
||||
zInfo.next_out = abDst;
|
||||
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst) {
|
||||
z_stream zInfo = { 0 };
|
||||
zInfo.total_in = zInfo.avail_in = nLenSrc;
|
||||
zInfo.total_out = zInfo.avail_out = nLenDst;
|
||||
zInfo.next_in = const_cast<Bytef*>(abSrc);
|
||||
zInfo.next_out = abDst;
|
||||
|
||||
int nErr, nRet = -1;
|
||||
nErr = deflateInit(&zInfo, Z_DEFAULT_COMPRESSION); // zlib function
|
||||
if (nErr == Z_OK) {
|
||||
nErr = deflate(&zInfo, Z_FINISH); // zlib function
|
||||
if (nErr == Z_STREAM_END) {
|
||||
nRet = zInfo.total_out;
|
||||
}
|
||||
}
|
||||
deflateEnd(&zInfo); // zlib function
|
||||
return(nRet);
|
||||
int nErr, nRet = -1;
|
||||
nErr = deflateInit(&zInfo, Z_DEFAULT_COMPRESSION); // zlib function
|
||||
if (nErr == Z_OK) {
|
||||
nErr = deflate(&zInfo, Z_FINISH); // zlib function
|
||||
if (nErr == Z_STREAM_END) {
|
||||
nRet = zInfo.total_out;
|
||||
}
|
||||
}
|
||||
deflateEnd(&zInfo); // zlib function
|
||||
return(nRet);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr)
|
||||
{
|
||||
// Get the size of the decompressed data
|
||||
z_stream zInfo = { 0 };
|
||||
zInfo.total_in = zInfo.avail_in = nLenSrc;
|
||||
zInfo.total_out = zInfo.avail_out = nLenDst;
|
||||
zInfo.next_in = const_cast<Bytef*>(abSrc);
|
||||
zInfo.next_out = abDst;
|
||||
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr) {
|
||||
// Get the size of the decompressed data
|
||||
z_stream zInfo = { 0 };
|
||||
zInfo.total_in = zInfo.avail_in = nLenSrc;
|
||||
zInfo.total_out = zInfo.avail_out = nLenDst;
|
||||
zInfo.next_in = const_cast<Bytef*>(abSrc);
|
||||
zInfo.next_out = abDst;
|
||||
|
||||
int nRet = -1;
|
||||
nErr = inflateInit(&zInfo); // zlib function
|
||||
if (nErr == Z_OK) {
|
||||
nErr = inflate(&zInfo, Z_FINISH); // zlib function
|
||||
if (nErr == Z_STREAM_END) {
|
||||
nRet = zInfo.total_out;
|
||||
}
|
||||
}
|
||||
inflateEnd(&zInfo); // zlib function
|
||||
return(nRet);
|
||||
|
||||
/*
|
||||
z_stream zInfo = { 0 };
|
||||
zInfo.total_in = zInfo.avail_in = nLenSrc;
|
||||
zInfo.total_out = zInfo.avail_out = nLenDst;
|
||||
zInfo.next_in = const_cast<Bytef*>(abSrc);
|
||||
zInfo.next_out = const_cast<Bytef*>(abDst);
|
||||
int nRet = -1;
|
||||
nErr = inflateInit(&zInfo); // zlib function
|
||||
if (nErr == Z_OK) {
|
||||
nErr = inflate(&zInfo, Z_FINISH); // zlib function
|
||||
if (nErr == Z_STREAM_END) {
|
||||
nRet = zInfo.total_out;
|
||||
}
|
||||
}
|
||||
inflateEnd(&zInfo); // zlib function
|
||||
return(nRet);
|
||||
|
||||
int nRet = -1;
|
||||
nErr = inflateInit(&zInfo); // zlib function
|
||||
if (nErr == Z_OK) {
|
||||
nErr = inflate(&zInfo, Z_FINISH); // zlib function
|
||||
if (nErr == Z_STREAM_END) {
|
||||
nRet = zInfo.total_out;
|
||||
}
|
||||
}
|
||||
inflateEnd(&zInfo); // zlib function
|
||||
return(nRet); // -1 or len of output
|
||||
*/
|
||||
}
|
||||
}
|
||||
/*
|
||||
z_stream zInfo = { 0 };
|
||||
zInfo.total_in = zInfo.avail_in = nLenSrc;
|
||||
zInfo.total_out = zInfo.avail_out = nLenDst;
|
||||
zInfo.next_in = const_cast<Bytef*>(abSrc);
|
||||
zInfo.next_out = const_cast<Bytef*>(abDst);
|
||||
|
||||
int nRet = -1;
|
||||
nErr = inflateInit(&zInfo); // zlib function
|
||||
if (nErr == Z_OK) {
|
||||
nErr = inflate(&zInfo, Z_FINISH); // zlib function
|
||||
if (nErr == Z_STREAM_END) {
|
||||
nRet = zInfo.total_out;
|
||||
}
|
||||
}
|
||||
inflateEnd(&zInfo); // zlib function
|
||||
return(nRet); // -1 or len of output
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ZCompression
|
||||
{
|
||||
#include "dPlatforms.h"
|
||||
|
||||
#ifndef DARKFLAME_PLATFORM_WIN32
|
||||
|
||||
namespace ZCompression {
|
||||
int32_t GetMaxCompressedLength(int32_t nLenSrc);
|
||||
|
||||
int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst);
|
||||
|
||||
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,9 @@ const uint64_t LWOZONEID_INVALID = 0; //!< Invalid LWOZONEID
|
||||
|
||||
typedef std::set<LWOOBJID> TSetObjID;
|
||||
|
||||
const float PI = 3.14159f;
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#if defined(__unix) || defined(__APPLE__)
|
||||
//For Linux:
|
||||
@@ -103,61 +105,61 @@ private:
|
||||
const LWOSCENEID LWOSCENEID_INVALID = -1;
|
||||
|
||||
struct LWONameValue {
|
||||
uint32_t length = 0; //!< The length of the name
|
||||
std::u16string name; //!< The name
|
||||
|
||||
LWONameValue(void) {}
|
||||
|
||||
LWONameValue(const std::u16string& name) {
|
||||
this->name = name;
|
||||
this->length = static_cast<uint32_t>(name.length());
|
||||
}
|
||||
|
||||
~LWONameValue(void) {}
|
||||
uint32_t length = 0; //!< The length of the name
|
||||
std::u16string name; //!< The name
|
||||
|
||||
LWONameValue(void) {}
|
||||
|
||||
LWONameValue(const std::u16string& name) {
|
||||
this->name = name;
|
||||
this->length = static_cast<uint32_t>(name.length());
|
||||
}
|
||||
|
||||
~LWONameValue(void) {}
|
||||
};
|
||||
|
||||
struct FriendData {
|
||||
public:
|
||||
bool isOnline = false;
|
||||
bool isBestFriend = false;
|
||||
bool isFTP = false;
|
||||
LWOZONEID zoneID;
|
||||
LWOOBJID friendID;
|
||||
std::string friendName;
|
||||
bool isOnline = false;
|
||||
bool isBestFriend = false;
|
||||
bool isFTP = false;
|
||||
LWOZONEID zoneID;
|
||||
LWOOBJID friendID;
|
||||
std::string friendName;
|
||||
|
||||
void Serialize(RakNet::BitStream& bitStream) {
|
||||
bitStream.Write<uint8_t>(isOnline);
|
||||
bitStream.Write<uint8_t>(isBestFriend);
|
||||
bitStream.Write<uint8_t>(isFTP);
|
||||
bitStream.Write<uint32_t>(0); //???
|
||||
bitStream.Write<uint8_t>(0); //???
|
||||
bitStream.Write(zoneID.GetMapID());
|
||||
bitStream.Write(zoneID.GetInstanceID());
|
||||
bitStream.Write(zoneID.GetCloneID());
|
||||
bitStream.Write(friendID);
|
||||
|
||||
uint32_t maxSize = 33;
|
||||
uint32_t size = static_cast<uint32_t>(friendName.length());
|
||||
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
|
||||
void Serialize(RakNet::BitStream& bitStream) {
|
||||
bitStream.Write<uint8_t>(isOnline);
|
||||
bitStream.Write<uint8_t>(isBestFriend);
|
||||
bitStream.Write<uint8_t>(isFTP);
|
||||
bitStream.Write<uint32_t>(0); //???
|
||||
bitStream.Write<uint8_t>(0); //???
|
||||
bitStream.Write(zoneID.GetMapID());
|
||||
bitStream.Write(zoneID.GetInstanceID());
|
||||
bitStream.Write(zoneID.GetCloneID());
|
||||
bitStream.Write(friendID);
|
||||
|
||||
if (size > maxSize) size = maxSize;
|
||||
uint32_t maxSize = 33;
|
||||
uint32_t size = static_cast<uint32_t>(friendName.length());
|
||||
uint32_t remSize = static_cast<uint32_t>(maxSize - size);
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
bitStream.Write(static_cast<uint16_t>(friendName[i]));
|
||||
}
|
||||
if (size > maxSize) size = maxSize;
|
||||
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
bitStream.Write(static_cast<uint16_t>(0));
|
||||
}
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
bitStream.Write(static_cast<uint16_t>(friendName[i]));
|
||||
}
|
||||
|
||||
bitStream.Write<uint32_t>(0); //???
|
||||
bitStream.Write<uint16_t>(0); //???
|
||||
}
|
||||
for (uint32_t j = 0; j < remSize; ++j) {
|
||||
bitStream.Write(static_cast<uint16_t>(0));
|
||||
}
|
||||
|
||||
bitStream.Write<uint32_t>(0); //???
|
||||
bitStream.Write<uint16_t>(0); //???
|
||||
}
|
||||
};
|
||||
|
||||
struct Brick {
|
||||
uint32_t designerID;
|
||||
uint32_t materialID;
|
||||
uint32_t designerID;
|
||||
uint32_t materialID;
|
||||
};
|
||||
|
||||
//This union is used by the behavior system
|
||||
@@ -169,26 +171,26 @@ union suchar {
|
||||
//=========== DLU ENUMS ============
|
||||
|
||||
enum eGameMasterLevel : int32_t {
|
||||
GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player.
|
||||
GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers.
|
||||
GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
|
||||
GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items.
|
||||
GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban.
|
||||
GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties.
|
||||
GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
|
||||
GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
|
||||
GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live.
|
||||
GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates.
|
||||
GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player.
|
||||
GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers.
|
||||
GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
|
||||
GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items.
|
||||
GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban.
|
||||
GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties.
|
||||
GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
|
||||
GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
|
||||
GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live.
|
||||
GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates.
|
||||
};
|
||||
|
||||
//=========== LU ENUMS ============
|
||||
|
||||
//! An enum for object ID bits
|
||||
enum eObjectBits : int32_t {
|
||||
OBJECT_BIT_PERSISTENT = 32, //!< The 32 bit index
|
||||
OBJECT_BIT_CLIENT = 46, //!< The 46 bit index
|
||||
OBJECT_BIT_SPAWNED = 58, //!< The 58 bit index
|
||||
OBJECT_BIT_CHARACTER = 60 //!< The 60 bit index
|
||||
OBJECT_BIT_PERSISTENT = 32, //!< The 32 bit index
|
||||
OBJECT_BIT_CLIENT = 46, //!< The 46 bit index
|
||||
OBJECT_BIT_SPAWNED = 58, //!< The 58 bit index
|
||||
OBJECT_BIT_CHARACTER = 60 //!< The 60 bit index
|
||||
};
|
||||
|
||||
//! An enum for MatchUpdate types
|
||||
@@ -208,18 +210,18 @@ enum eCyclingMode : uint32_t {
|
||||
};
|
||||
|
||||
enum eCinematicEvent : uint32_t {
|
||||
STARTED,
|
||||
WAYPOINT,
|
||||
ENDED,
|
||||
STARTED,
|
||||
WAYPOINT,
|
||||
ENDED,
|
||||
};
|
||||
|
||||
//! An enum for character creation responses
|
||||
enum eCreationResponse : uint8_t {
|
||||
CREATION_RESPONSE_SUCCESS = 0, //!< The creation was successful
|
||||
CREATION_RESPONSE_OBJECT_ID_UNAVAILABLE, //!< The Object ID can't be used
|
||||
CREATION_RESPONSE_NAME_NOT_ALLOWED, //!< The name is not allowed
|
||||
CREATION_RESPONSE_PREDEFINED_NAME_IN_USE, //!< The predefined name is already in use
|
||||
CREATION_RESPONSE_CUSTOM_NAME_IN_USE //!< The custom name is already in use
|
||||
CREATION_RESPONSE_SUCCESS = 0, //!< The creation was successful
|
||||
CREATION_RESPONSE_OBJECT_ID_UNAVAILABLE, //!< The Object ID can't be used
|
||||
CREATION_RESPONSE_NAME_NOT_ALLOWED, //!< The name is not allowed
|
||||
CREATION_RESPONSE_PREDEFINED_NAME_IN_USE, //!< The predefined name is already in use
|
||||
CREATION_RESPONSE_CUSTOM_NAME_IN_USE //!< The custom name is already in use
|
||||
};
|
||||
|
||||
//! An enum for login responses
|
||||
@@ -234,21 +236,21 @@ enum eLoginResponse : uint8_t {
|
||||
|
||||
//! An enum for character rename responses
|
||||
enum eRenameResponse : uint8_t {
|
||||
RENAME_RESPONSE_SUCCESS = 0, //!< The renaming was successful
|
||||
RENAME_RESPONSE_UNKNOWN_ERROR, //!< There was an unknown error
|
||||
RENAME_RESPONSE_NAME_UNAVAILABLE, //!< The name is unavailable
|
||||
RENAME_RESPONSE_NAME_IN_USE //!< The name is already in use
|
||||
RENAME_RESPONSE_SUCCESS = 0, //!< The renaming was successful
|
||||
RENAME_RESPONSE_UNKNOWN_ERROR, //!< There was an unknown error
|
||||
RENAME_RESPONSE_NAME_UNAVAILABLE, //!< The name is unavailable
|
||||
RENAME_RESPONSE_NAME_IN_USE //!< The name is already in use
|
||||
};
|
||||
|
||||
//! A replica packet type
|
||||
enum eReplicaPacketType {
|
||||
PACKET_TYPE_CONSTRUCTION, //!< A construction packet
|
||||
PACKET_TYPE_SERIALIZATION, //!< A serialization packet
|
||||
PACKET_TYPE_DESTRUCTION //!< A destruction packet
|
||||
PACKET_TYPE_CONSTRUCTION, //!< A construction packet
|
||||
PACKET_TYPE_SERIALIZATION, //!< A serialization packet
|
||||
PACKET_TYPE_DESTRUCTION //!< A destruction packet
|
||||
};
|
||||
|
||||
enum ServerDisconnectIdentifiers {
|
||||
SERVER_DISCON_UNKNOWN_SERVER_ERROR = 0, //!< Unknown server error
|
||||
SERVER_DISCON_UNKNOWN_SERVER_ERROR = 0, //!< Unknown server error
|
||||
SERVER_DISCON_DUPLICATE_LOGIN = 4, //!< Used when another user with the same username is logged in (duplicate login)
|
||||
SERVER_DISCON_SERVER_SHUTDOWN = 5, //!< Used when the server is shutdown
|
||||
SERVER_DISCON_SERVER_MAP_LOAD_FAILURE = 6, //!< Used when the server cannot load a map
|
||||
@@ -263,80 +265,80 @@ enum ServerDisconnectIdentifiers {
|
||||
|
||||
//! The Behavior Types for use with the AI system
|
||||
enum eCombatBehaviorTypes : uint32_t {
|
||||
PASSIVE = 0, //!< The object is passive
|
||||
AGGRESSIVE = 1, //!< The object is aggressive
|
||||
PASSIVE_TURRET = 2, //!< The object is a passive turret
|
||||
AGGRESSIVE_TURRET = 3 //!< The object is an aggressive turret
|
||||
PASSIVE = 0, //!< The object is passive
|
||||
AGGRESSIVE = 1, //!< The object is aggressive
|
||||
PASSIVE_TURRET = 2, //!< The object is a passive turret
|
||||
AGGRESSIVE_TURRET = 3 //!< The object is an aggressive turret
|
||||
};
|
||||
|
||||
//! The Combat Role Type for use with the AI system
|
||||
enum eCombatRoleType : uint32_t {
|
||||
MELEE = 0, //!< Used for melee attacks
|
||||
RANGED = 1, //!< Used for range attacks
|
||||
SUPPORT = 2 //!< Used for support
|
||||
MELEE = 0, //!< Used for melee attacks
|
||||
RANGED = 1, //!< Used for range attacks
|
||||
SUPPORT = 2 //!< Used for support
|
||||
};
|
||||
|
||||
//! The kill types for the Die packet
|
||||
enum eKillType : uint32_t {
|
||||
VIOLENT,
|
||||
SILENT
|
||||
VIOLENT,
|
||||
SILENT
|
||||
};
|
||||
|
||||
//! The various world states used throughout the server
|
||||
enum eObjectWorldState {
|
||||
WORLDSTATE_INWORLD, //!< Probably used when the object is in the world
|
||||
WORLDSTATE_ATTACHED, //!< Probably used when the object is attached to another object
|
||||
WORLDSTATE_INVENTORY //!< Probably used when the object is in an inventory
|
||||
WORLDSTATE_INWORLD, //!< Probably used when the object is in the world
|
||||
WORLDSTATE_ATTACHED, //!< Probably used when the object is attached to another object
|
||||
WORLDSTATE_INVENTORY //!< Probably used when the object is in an inventory
|
||||
};
|
||||
|
||||
//! The trigger stats (???)
|
||||
enum eTriggerStat {
|
||||
INVALID_STAT, //!< ???
|
||||
HEALTH, //!< Probably used for health
|
||||
ARMOR, //!< Probably used for armor
|
||||
IMAGINATION //!< Probably used for imagination
|
||||
INVALID_STAT, //!< ???
|
||||
HEALTH, //!< Probably used for health
|
||||
ARMOR, //!< Probably used for armor
|
||||
IMAGINATION //!< Probably used for imagination
|
||||
};
|
||||
|
||||
//! The trigger operations (???)
|
||||
enum eTriggerOperator {
|
||||
INVALID_OPER, //!< ???
|
||||
EQUAL, //!< ???
|
||||
NOT_EQUAL, //!< ???
|
||||
GREATER, //!< ???
|
||||
GREATER_EQUAL, //!< ???
|
||||
LESS, //!< ???
|
||||
LESS_EQUAL //!< ???
|
||||
INVALID_OPER, //!< ???
|
||||
EQUAL, //!< ???
|
||||
NOT_EQUAL, //!< ???
|
||||
GREATER, //!< ???
|
||||
GREATER_EQUAL, //!< ???
|
||||
LESS, //!< ???
|
||||
LESS_EQUAL //!< ???
|
||||
};
|
||||
|
||||
//! The various build types
|
||||
enum eBuildType {
|
||||
BUILD_NOWHERE, //!< Used if something can't be built anywhere
|
||||
BUILD_IN_WORLD, //!< Used if something can be built in the world
|
||||
BUILD_ON_PROPERTY //!< Used if something can be build on a property
|
||||
BUILD_NOWHERE, //!< Used if something can't be built anywhere
|
||||
BUILD_IN_WORLD, //!< Used if something can be built in the world
|
||||
BUILD_ON_PROPERTY //!< Used if something can be build on a property
|
||||
};
|
||||
|
||||
//! Quickbuild fail reasons
|
||||
enum eFailReason : uint32_t {
|
||||
REASON_NOT_GIVEN,
|
||||
REASON_OUT_OF_IMAGINATION,
|
||||
REASON_CANCELED_EARLY,
|
||||
REASON_BUILD_ENDED
|
||||
REASON_NOT_GIVEN,
|
||||
REASON_OUT_OF_IMAGINATION,
|
||||
REASON_CANCELED_EARLY,
|
||||
REASON_BUILD_ENDED
|
||||
};
|
||||
|
||||
//! Terminate interaction type
|
||||
enum eTerminateType : uint32_t {
|
||||
RANGE,
|
||||
USER,
|
||||
FROM_INTERACTION
|
||||
RANGE,
|
||||
USER,
|
||||
FROM_INTERACTION
|
||||
};
|
||||
|
||||
//! The combat state
|
||||
enum eCombatState {
|
||||
IDLE, //!< The AI is in an idle state
|
||||
AGGRO, //!< The AI is in an aggressive state
|
||||
TETHER, //!< The AI is being redrawn back to tether point
|
||||
SPAWN, //!< The AI is spawning
|
||||
DEAD //!< The AI is dead
|
||||
IDLE, //!< The AI is in an idle state
|
||||
AGGRO, //!< The AI is in an aggressive state
|
||||
TETHER, //!< The AI is being redrawn back to tether point
|
||||
SPAWN, //!< The AI is spawning
|
||||
DEAD //!< The AI is dead
|
||||
};
|
||||
|
||||
enum eControlSceme {
|
||||
@@ -348,7 +350,7 @@ enum eControlSceme {
|
||||
SCHEME_DRIVING,
|
||||
SCHEME_TAMING,
|
||||
SCHEME_MODULAR_BUILD,
|
||||
SCHEME_WEAR_A_ROBOT //== freecam?
|
||||
SCHEME_WEAR_A_ROBOT //== freecam?
|
||||
};
|
||||
|
||||
enum eStunState {
|
||||
@@ -357,110 +359,90 @@ enum eStunState {
|
||||
};
|
||||
|
||||
enum eNotifyType {
|
||||
NOTIFY_TYPE_SUCCESS,
|
||||
NOTIFY_TYPE_QUIT,
|
||||
NOTIFY_TYPE_FAILED,
|
||||
NOTIFY_TYPE_BEGIN,
|
||||
NOTIFY_TYPE_READY,
|
||||
NOTIFY_TYPE_NAMINGPET
|
||||
NOTIFY_TYPE_SUCCESS,
|
||||
NOTIFY_TYPE_QUIT,
|
||||
NOTIFY_TYPE_FAILED,
|
||||
NOTIFY_TYPE_BEGIN,
|
||||
NOTIFY_TYPE_READY,
|
||||
NOTIFY_TYPE_NAMINGPET
|
||||
};
|
||||
|
||||
enum eReplicaComponentType : int32_t {
|
||||
COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1, //!< The ControllablePhysics Component
|
||||
COMPONENT_TYPE_RENDER = 2, //!< The Render Component
|
||||
COMPONENT_TYPE_SIMPLE_PHYSICS = 3, //!< The SimplePhysics Component
|
||||
COMPONENT_TYPE_CHARACTER = 4, //!< The Character Component
|
||||
COMPONENT_TYPE_SCRIPT = 5, //!< The Script Component
|
||||
COMPONENT_TYPE_BOUNCER = 6, //!< The Bouncer Component
|
||||
COMPONENT_TYPE_BUFF = 7, //!< The Buff Component
|
||||
COMPONENT_TYPE_SKILL = 9, //!< The Skill Component
|
||||
COMPONENT_TYPE_ITEM = 11, //!< The Item Component
|
||||
COMPONENT_TYPE_VENDOR = 16, //!< The Vendor Component
|
||||
COMPONENT_TYPE_INVENTORY = 17, //!< The Inventory Component
|
||||
COMPONENT_TYPE_SHOOTING_GALLERY = 19, //!< The Shooting Gallery Component
|
||||
COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20, //!< The RigidBodyPhantomPhysics Component
|
||||
COMPONENT_TYPE_COLLECTIBLE = 23, //!< The Collectible Component
|
||||
COMPONENT_TYPE_MOVING_PLATFORM = 25, //!< The MovingPlatform Component
|
||||
COMPONENT_TYPE_PET = 26, //!< The Pet Component
|
||||
COMPONENT_TYPE_VEHICLE_PHYSICS = 30, //!< The VehiclePhysics Component
|
||||
COMPONENT_TYPE_MOVEMENT_AI = 31, //!< The MovementAI Component
|
||||
COMPONENT_TYPE_PROPERTY = 36, //!< The Property Component
|
||||
COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39, //!< The ScriptedActivity Component
|
||||
COMPONENT_TYPE_PHANTOM_PHYSICS = 40, //!< The PhantomPhysics Component
|
||||
COMPONENT_TYPE_PROPERTY_ENTRANCE = 43, //!< The PhantomPhysics Component
|
||||
COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45, //!< The PropertyManagement Component
|
||||
COMPONENT_TYPE_REBUILD = 48, //!< The Rebuild Component
|
||||
COMPONENT_TYPE_SWITCH = 49, //!< The Switch Component
|
||||
COMPONENT_TYPE_ZONE_CONTROL = 50, //!< The ZoneControl Component
|
||||
COMPONENT_TYPE_PACKAGE = 53, //!< The Package Component
|
||||
COMPONENT_TYPE_PLAYER_FLAG = 58, //!< The PlayerFlag Component
|
||||
COMPONENT_TYPE_BASE_COMBAT_AI = 60, //!< The BaseCombatAI Component
|
||||
COMPONENT_TYPE_MODULE_ASSEMBLY = 61, //!< The ModuleAssembly Component
|
||||
COMPONENT_TYPE_PROPERTY_VENDOR = 65, //!< The PropertyVendor Component
|
||||
COMPONENT_TYPE_ROCKET_LAUNCH = 67, //!< The RocketLaunch Component
|
||||
COMPONENT_TYPE_RACING_CONTROL = 71, //!< The RacingControl Component
|
||||
COMPONENT_TYPE_MISSION_OFFER = 73, //!< The MissionOffer Component
|
||||
COMPONENT_TYPE_EXHIBIT = 75, //!< The Exhibit Component
|
||||
COMPONENT_TYPE_RACING_STATS = 74, //!< The Exhibit Component
|
||||
COMPONENT_TYPE_SOUND_TRIGGER = 77, //!< The Sound Trigger Component
|
||||
COMPONENT_TYPE_PROXIMITY_MONITOR = 78, //!< The Proximity Monitor Component
|
||||
COMPONENT_TYPE_MISSION = 84, //!< The Mission Component
|
||||
COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97, //!< The LUP Launchpad Componen
|
||||
COMPONENT_TYPE_RAIL_ACTIVATOR = 104,
|
||||
COMPONENT_TYPE_POSSESSOR = 107, //!< The Component 107
|
||||
COMPONENT_TYPE_POSSESSABLE = 108, //!< The Component 108
|
||||
COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component
|
||||
COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component
|
||||
COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1, //!< The ControllablePhysics Component
|
||||
COMPONENT_TYPE_RENDER = 2, //!< The Render Component
|
||||
COMPONENT_TYPE_SIMPLE_PHYSICS = 3, //!< The SimplePhysics Component
|
||||
COMPONENT_TYPE_CHARACTER = 4, //!< The Character Component
|
||||
COMPONENT_TYPE_SCRIPT = 5, //!< The Script Component
|
||||
COMPONENT_TYPE_BOUNCER = 6, //!< The Bouncer Component
|
||||
COMPONENT_TYPE_BUFF = 7, //!< The Buff Component
|
||||
COMPONENT_TYPE_SKILL = 9, //!< The Skill Component
|
||||
COMPONENT_TYPE_ITEM = 11, //!< The Item Component
|
||||
COMPONENT_TYPE_VENDOR = 16, //!< The Vendor Component
|
||||
COMPONENT_TYPE_INVENTORY = 17, //!< The Inventory Component
|
||||
COMPONENT_TYPE_SHOOTING_GALLERY = 19, //!< The Shooting Gallery Component
|
||||
COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20, //!< The RigidBodyPhantomPhysics Component
|
||||
COMPONENT_TYPE_COLLECTIBLE = 23, //!< The Collectible Component
|
||||
COMPONENT_TYPE_MOVING_PLATFORM = 25, //!< The MovingPlatform Component
|
||||
COMPONENT_TYPE_PET = 26, //!< The Pet Component
|
||||
COMPONENT_TYPE_VEHICLE_PHYSICS = 30, //!< The VehiclePhysics Component
|
||||
COMPONENT_TYPE_MOVEMENT_AI = 31, //!< The MovementAI Component
|
||||
COMPONENT_TYPE_PROPERTY = 36, //!< The Property Component
|
||||
COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39, //!< The ScriptedActivity Component
|
||||
COMPONENT_TYPE_PHANTOM_PHYSICS = 40, //!< The PhantomPhysics Component
|
||||
COMPONENT_TYPE_MODEL = 42, //!< The Model Component
|
||||
COMPONENT_TYPE_PROPERTY_ENTRANCE = 43, //!< The PhantomPhysics Component
|
||||
COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45, //!< The PropertyManagement Component
|
||||
COMPONENT_TYPE_REBUILD = 48, //!< The Rebuild Component
|
||||
COMPONENT_TYPE_SWITCH = 49, //!< The Switch Component
|
||||
COMPONENT_TYPE_ZONE_CONTROL = 50, //!< The ZoneControl Component
|
||||
COMPONENT_TYPE_PACKAGE = 53, //!< The Package Component
|
||||
COMPONENT_TYPE_PLAYER_FLAG = 58, //!< The PlayerFlag Component
|
||||
COMPONENT_TYPE_BASE_COMBAT_AI = 60, //!< The BaseCombatAI Component
|
||||
COMPONENT_TYPE_MODULE_ASSEMBLY = 61, //!< The ModuleAssembly Component
|
||||
COMPONENT_TYPE_PROPERTY_VENDOR = 65, //!< The PropertyVendor Component
|
||||
COMPONENT_TYPE_ROCKET_LAUNCH = 67, //!< The RocketLaunch Component
|
||||
COMPONENT_TYPE_RACING_CONTROL = 71, //!< The RacingControl Component
|
||||
COMPONENT_TYPE_MISSION_OFFER = 73, //!< The MissionOffer Component
|
||||
COMPONENT_TYPE_EXHIBIT = 75, //!< The Exhibit Component
|
||||
COMPONENT_TYPE_RACING_STATS = 74, //!< The Racing Stats Component
|
||||
COMPONENT_TYPE_SOUND_TRIGGER = 77, //!< The Sound Trigger Component
|
||||
COMPONENT_TYPE_PROXIMITY_MONITOR = 78, //!< The Proximity Monitor Component
|
||||
COMPONENT_TYPE_MISSION = 84, //!< The Mission Component
|
||||
COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97, //!< The LUP Launchpad Componen
|
||||
COMPONENT_TYPE_RAIL_ACTIVATOR = 104, //!< The Rail Activator Component
|
||||
COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT = 106, //!< The Player Forced Movement Component
|
||||
COMPONENT_TYPE_POSSESSABLE = 108, //!< The Possessable Component
|
||||
COMPONENT_TYPE_LEVEL_PROGRESSION = 109, //!< The Level Progression Component
|
||||
COMPONENT_TYPE_POSSESSOR = 110, //!< The Possessor Component
|
||||
COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component
|
||||
COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component
|
||||
};
|
||||
|
||||
COMPONENT_TYPE_MODEL = 5398484 //look man idk
|
||||
enum class UseItemResponse : uint32_t {
|
||||
NoImaginationForPet = 1,
|
||||
FailedPrecondition,
|
||||
MountsNotAllowed
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the different types of inventories an entity may have
|
||||
*/
|
||||
enum eInventoryType : uint32_t {
|
||||
ITEMS = 0,
|
||||
VAULT_ITEMS,
|
||||
BRICKS,
|
||||
TEMP_ITEMS = 4,
|
||||
MODELS,
|
||||
TEMP_MODELS,
|
||||
BEHAVIORS,
|
||||
PROPERTY_DEEDS,
|
||||
ITEMS = 0,
|
||||
VAULT_ITEMS,
|
||||
BRICKS,
|
||||
TEMP_ITEMS = 4,
|
||||
MODELS,
|
||||
TEMP_MODELS,
|
||||
BEHAVIORS,
|
||||
PROPERTY_DEEDS,
|
||||
VENDOR_BUYBACK = 11,
|
||||
HIDDEN = 12, //Used for missional items
|
||||
VAULT_MODELS = 14,
|
||||
HIDDEN = 12, //Used for missional items
|
||||
VAULT_MODELS = 14,
|
||||
ITEM_SETS, //internal
|
||||
INVALID // made up, for internal use!!!
|
||||
};
|
||||
|
||||
enum eItemType : int32_t {
|
||||
ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type
|
||||
ITEM_TYPE_BRICK = 1, //!< A brick
|
||||
ITEM_TYPE_HAT = 2, //!< A hat / head item
|
||||
ITEM_TYPE_HAIR = 3, //!< A hair item
|
||||
ITEM_TYPE_NECK = 4, //!< A neck item
|
||||
ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item
|
||||
ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item
|
||||
ITEM_TYPE_LEGS = 7, //!< A pants item
|
||||
ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item
|
||||
ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item
|
||||
ITEM_TYPE_BEHAVIOR = 10, //!< A behavior
|
||||
ITEM_TYPE_PROPERTY = 11, //!< A property
|
||||
ITEM_TYPE_MODEL = 12, //!< A model
|
||||
ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item
|
||||
ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item
|
||||
ITEM_TYPE_CHEST = 15, //!< A chest item
|
||||
ITEM_TYPE_EGG = 16, //!< An egg
|
||||
ITEM_TYPE_PET_FOOD = 17, //!< A pet food item
|
||||
ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item
|
||||
ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item
|
||||
ITEM_TYPE_PACKAGE = 20, //!< A package
|
||||
ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model
|
||||
ITEM_TYPE_VEHICLE = 22, //!< A vehicle
|
||||
ITEM_TYPE_CURRENCY = 23 //!< Currency
|
||||
};
|
||||
|
||||
enum eRebuildState : uint32_t {
|
||||
REBUILD_OPEN,
|
||||
REBUILD_COMPLETED = 2,
|
||||
@@ -469,6 +451,34 @@ enum eRebuildState : uint32_t {
|
||||
REBUILD_INCOMPLETE
|
||||
};
|
||||
|
||||
/**
|
||||
* The loot source's type.
|
||||
*/
|
||||
enum eLootSourceType : int32_t {
|
||||
LOOT_SOURCE_NONE = 0,
|
||||
LOOT_SOURCE_CHEST,
|
||||
LOOT_SOURCE_MISSION,
|
||||
LOOT_SOURCE_MAIL,
|
||||
LOOT_SOURCE_CURRENCY,
|
||||
LOOT_SOURCE_ACHIEVEMENT,
|
||||
LOOT_SOURCE_TRADE,
|
||||
LOOT_SOURCE_QUICKBUILD,
|
||||
LOOT_SOURCE_DELETION,
|
||||
LOOT_SOURCE_VENDOR,
|
||||
LOOT_SOURCE_ACTIVITY,
|
||||
LOOT_SOURCE_PICKUP,
|
||||
LOOT_SOURCE_BRICK,
|
||||
LOOT_SOURCE_PROPERTY,
|
||||
LOOT_SOURCE_MODERATION,
|
||||
LOOT_SOURCE_EXHIBIT,
|
||||
LOOT_SOURCE_INVENTORY,
|
||||
LOOT_SOURCE_CLAIMCODE,
|
||||
LOOT_SOURCE_CONSUMPTION,
|
||||
LOOT_SOURCE_CRAFTING,
|
||||
LOOT_SOURCE_LEVEL_REWARD,
|
||||
LOOT_SOURCE_RELOCATE
|
||||
};
|
||||
|
||||
enum eGameActivities : uint32_t {
|
||||
ACTIVITY_NONE,
|
||||
ACTIVITY_QUICKBUILDING,
|
||||
@@ -534,7 +544,7 @@ enum ePlayerFlags {
|
||||
TOOLTIP_TALK_TO_SKYLAND_TO_GET_HAT = 52,
|
||||
MODULAR_BUILD_PLAYER_PLACES_FIRST_MODEL_IN_SCRATCH = 53,
|
||||
MODULAR_BUILD_FIRST_ARROW_DISPLAY_FOR_MODULE = 54,
|
||||
AG_BEACON_QB,_SO_THE_PLAYER_CAN_ALWAYS_BUILD_THEM = 55,
|
||||
AG_BEACON_QB_SO_THE_PLAYER_CAN_ALWAYS_BUILD_THEM = 55,
|
||||
GF_PET_DIG_FLAG_1 = 56,
|
||||
GF_PET_DIG_FLAG_2 = 57,
|
||||
GF_PET_DIG_FLAG_3 = 58,
|
||||
@@ -546,7 +556,7 @@ enum ePlayerFlags {
|
||||
ENTER_BBB_FROM_PROPERTY_EDIT_CONFIRMATION_DIALOG = 64,
|
||||
AG_FIRST_COMBAT_COMPLETE = 65,
|
||||
AG_COMPLETE_BOB_MISSION = 66,
|
||||
NJ_GARMADON_CINEMATIC_SEEN = 125,
|
||||
NJ_GARMADON_CINEMATIC_SEEN = 125,
|
||||
ELEPHANT_PET_3050 = 801,
|
||||
CAT_PET_3054 = 802,
|
||||
TRICERATOPS_PET_3195 = 803,
|
||||
@@ -620,23 +630,23 @@ enum ePlayerFlags {
|
||||
GF_BINOC_IN_CROC_AREA = 1308,
|
||||
GF_BINOC_IN_JAIL_AREA = 1309,
|
||||
GF_BINOC_TELESCOPE_NEXT_TO_CAPTAIN_JACK = 1310,
|
||||
NT_PLINTH_REBUILD = 1919,
|
||||
NT_FACTION_SPY_DUKE = 1974,
|
||||
NT_FACTION_SPY_OVERBUILD = 1976,
|
||||
NT_FACTION_SPY_HAEL = 1977,
|
||||
NJ_EARTH_SPINJITZU = 2030,
|
||||
NJ_LIGHTNING_SPINJITZU = 2031,
|
||||
NJ_ICE_SPINJITZU = 2032,
|
||||
NJ_FIRE_SPINJITZU = 2033,
|
||||
NJ_WU_SHOW_DAILY_CHEST = 2099
|
||||
NJ_EARTH_SPINJITZU = 2030,
|
||||
NJ_LIGHTNING_SPINJITZU = 2031,
|
||||
NJ_ICE_SPINJITZU = 2032,
|
||||
NJ_FIRE_SPINJITZU = 2033,
|
||||
NJ_WU_SHOW_DAILY_CHEST = 2099
|
||||
};
|
||||
|
||||
|
||||
//======== FUNC ===========
|
||||
|
||||
template<typename T>
|
||||
inline T const& clamp(const T& val, const T& low, const T& high) {
|
||||
if (val < low) return low;
|
||||
else if (val > high) return high;
|
||||
|
||||
return val;
|
||||
if (val < low) return low;
|
||||
else if (val > high) return high;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ dConfig::dConfig(const std::string& filepath) {
|
||||
if (line[0] != '#') ProcessLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dConfig::~dConfig(void) {
|
||||
}
|
||||
@@ -31,15 +31,15 @@ void dConfig::ProcessLine(const std::string& line) {
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(ss, segment, '=')) {
|
||||
seglist.push_back(segment);
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
if (seglist.size() != 2) return;
|
||||
|
||||
//Make sure that on Linux, we remove special characters:
|
||||
if (!seglist[1].empty() && seglist[1][seglist[1].size() - 1] == '\r')
|
||||
seglist[1].erase(seglist[1].size() - 1);
|
||||
seglist[1].erase(seglist[1].size() - 1);
|
||||
|
||||
m_Keys.push_back(seglist[0]);
|
||||
m_Values.push_back(seglist[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,4 @@ private:
|
||||
std::vector<std::string> m_Keys;
|
||||
std::vector<std::string> m_Values;
|
||||
std::string m_EmptyString;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "dLogger.h"
|
||||
|
||||
dLogger::dLogger(const std::string& outpath, bool logToConsole) {
|
||||
dLogger::dLogger(const std::string& outpath, bool logToConsole, bool logDebugStatements) {
|
||||
m_logToConsole = logToConsole;
|
||||
m_logDebugStatements = logDebugStatements;
|
||||
m_outpath = outpath;
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -9,7 +10,7 @@ dLogger::dLogger(const std::string& outpath, bool logToConsole) {
|
||||
if (!mFile) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
|
||||
#else
|
||||
fp = fopen(outpath.c_str(), "wt");
|
||||
if (fp == NULL) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
|
||||
if (fp == NULL) { printf("Couldn't open %s for writing!\n", outpath.c_str()); }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,114 +25,80 @@ dLogger::~dLogger() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void dLogger::LogBasic(const std::string & message) {
|
||||
void dLogger::vLog(const char* format, va_list args) {
|
||||
#ifdef _WIN32
|
||||
time_t t = time(NULL);
|
||||
struct tm time;
|
||||
localtime_s(&time, &t);
|
||||
char timeStr[70];
|
||||
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time);
|
||||
char message[2048];
|
||||
vsnprintf(message, 2048, format, args);
|
||||
|
||||
if (m_logToConsole) std::cout << "[" << timeStr << "] " << message;
|
||||
mFile << "[" << timeStr << "] " << message;
|
||||
#else
|
||||
time_t t = time(NULL);
|
||||
struct tm* time = localtime(&t);
|
||||
char timeStr[70];
|
||||
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time);
|
||||
char message[2048];
|
||||
vsnprintf(message, 2048, format, args);
|
||||
|
||||
if (m_logToConsole) {
|
||||
fputs("[", stdout);
|
||||
fputs(timeStr, stdout);
|
||||
fputs("] ", stdout);
|
||||
fputs(message, stdout);
|
||||
}
|
||||
|
||||
if (fp != nullptr) {
|
||||
fputs("[", fp);
|
||||
fputs(timeStr, fp);
|
||||
fputs("] ", fp);
|
||||
fputs(message, fp);
|
||||
} else {
|
||||
printf("Logger not initialized!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dLogger::LogBasic(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vLog(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void dLogger::LogBasic(const std::string& message) {
|
||||
LogBasic(message.c_str());
|
||||
}
|
||||
|
||||
void dLogger::LogBasic(const char * format, ...) {
|
||||
#ifdef _WIN32
|
||||
time_t t = time(NULL);
|
||||
struct tm time;
|
||||
localtime_s(&time, &t);
|
||||
|
||||
char timeStr[70];
|
||||
|
||||
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time);
|
||||
|
||||
char message[2048];
|
||||
void dLogger::Log(const char* className, const char* format, ...) {
|
||||
va_list args;
|
||||
std::string log = "[" + std::string(className) + "] " + std::string(format) + "\n";
|
||||
va_start(args, format);
|
||||
vsprintf_s(message, format, args);
|
||||
vLog(log.c_str(), args);
|
||||
va_end(args);
|
||||
|
||||
if (m_logToConsole) std::cout << "[" << "time machine broke" << "] " << message;
|
||||
mFile << "[" << "time" << "] " << message;
|
||||
#else
|
||||
time_t t = time(NULL);
|
||||
struct tm * time = localtime(&t);
|
||||
char timeStr[70];
|
||||
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time);
|
||||
|
||||
char message[2048];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf(message, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (m_logToConsole) {
|
||||
fputs("[", stdout);
|
||||
fputs(timeStr, stdout);
|
||||
fputs("] ", stdout);
|
||||
fputs(message, stdout);
|
||||
}
|
||||
|
||||
if (fp != nullptr) {
|
||||
fputs("[", fp);
|
||||
fputs(timeStr, fp);
|
||||
fputs("] ", fp);
|
||||
fputs(message, fp);
|
||||
} else {
|
||||
printf("Logger not initialized!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dLogger::Log(const char * className, const char * format, ...) {
|
||||
#ifdef _WIN32
|
||||
time_t t = time(NULL);
|
||||
struct tm time;
|
||||
localtime_s(&time, &t);
|
||||
|
||||
char timeStr[70];
|
||||
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", &time);
|
||||
|
||||
char message[2048];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf_s(message, format, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
if (m_logToConsole) std::cout << "[" << "timeStr" << "] [" << className << "]: " << message;
|
||||
mFile << "[" << "timeStr" << "] [" << className << "]: " << message;
|
||||
#else
|
||||
time_t t = time(NULL);
|
||||
struct tm * time = localtime(&t);
|
||||
char timeStr[70];
|
||||
strftime(timeStr, sizeof(timeStr), "%d-%m-%y %H:%M:%S", time);
|
||||
|
||||
char message[2048];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf(message, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (m_logToConsole) {
|
||||
fputs("[", stdout);
|
||||
fputs(timeStr, stdout);
|
||||
fputs("] ", stdout);
|
||||
fputs("[", stdout);
|
||||
fputs(className, stdout);
|
||||
fputs("]: ", stdout);
|
||||
fputs(message, stdout);
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
fputs("[", fp);
|
||||
fputs(timeStr, fp);
|
||||
fputs("] ", fp);
|
||||
fputs("[", fp);
|
||||
fputs(className, fp);
|
||||
fputs("]: ", fp);
|
||||
fputs(message, fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dLogger::Log(const std::string & className, const std::string & message) {
|
||||
void dLogger::Log(const std::string& className, const std::string& message) {
|
||||
Log(className.c_str(), message.c_str());
|
||||
}
|
||||
|
||||
void dLogger::LogDebug(const char* className, const char* format, ...) {
|
||||
if (!m_logDebugStatements) return;
|
||||
va_list args;
|
||||
std::string log = "[" + std::string(className) + "] " + std::string(format);
|
||||
va_start(args, format);
|
||||
vLog(log.c_str(), args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void dLogger::LogDebug(const std::string& className, const std::string& message) {
|
||||
LogDebug(className.c_str(), message.c_str());
|
||||
}
|
||||
|
||||
void dLogger::Flush() {
|
||||
#ifdef _WIN32
|
||||
mFile.flush();
|
||||
|
||||
@@ -7,27 +7,32 @@
|
||||
|
||||
class dLogger {
|
||||
public:
|
||||
dLogger(const std::string& outpath, bool logToConsole);
|
||||
dLogger(const std::string& outpath, bool logToConsole, bool logDebugStatements);
|
||||
~dLogger();
|
||||
|
||||
void SetLogToConsole(bool logToConsole) { m_logToConsole = logToConsole; }
|
||||
void SetLogDebugStatements(bool logDebugStatements) { m_logDebugStatements = logDebugStatements; }
|
||||
void vLog(const char* format, va_list args);
|
||||
|
||||
void LogBasic(const std::string& message);
|
||||
void LogBasic(const char* format, ...);
|
||||
void Log(const char* className, const char* format, ...);
|
||||
void Log(const std::string& className, const std::string& message);
|
||||
void LogDebug(const std::string& className, const std::string& message);
|
||||
void LogDebug(const char* className, const char* format, ...);
|
||||
|
||||
void Flush();
|
||||
|
||||
const bool GetIsLoggingToConsole() const { return m_logToConsole; }
|
||||
|
||||
private:
|
||||
bool m_logDebugStatements;
|
||||
bool m_logToConsole;
|
||||
std::string m_outpath;
|
||||
std::ofstream mFile;
|
||||
|
||||
#ifndef _WIN32
|
||||
//Glorious linux can run with SPEED:
|
||||
FILE* fp = nullptr;
|
||||
#endif
|
||||
};
|
||||
#ifndef _WIN32
|
||||
//Glorious linux can run with SPEED:
|
||||
FILE* fp = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
29
dCommon/dPlatforms.h
Normal file
29
dCommon/dPlatforms.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define DARKFLAME_PLATFORM_WIN32
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
|
||||
#define DARKFLAME_PLATFORM_IOS
|
||||
#elif TARGET_OS_MAC
|
||||
#define DARKFLAME_PLATFORM_MACOS
|
||||
#else
|
||||
#error unknown Apple operating system
|
||||
#endif
|
||||
#elif defined(__unix__)
|
||||
#define DARKFLAME_PLATFORM_UNIX
|
||||
#if defined(__ANDROID__)
|
||||
#define DARKFLAME_PLATFORM_ANDROID
|
||||
#elif defined(__linux__)
|
||||
#define DARKFLAME_PLATFORM_LINUX
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
#define DARKFLAME_PLATFORM_FREEBSD
|
||||
#elif defined(__CYGWIN__)
|
||||
#define DARKFLAME_PLATFORM_CYGWIN
|
||||
#else
|
||||
#error unknown unix operating system
|
||||
#endif
|
||||
#else
|
||||
#error unknown operating system
|
||||
#endif
|
||||
44
dCommon/eAninmationFlags.h
Normal file
44
dCommon/eAninmationFlags.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __EANINMATIONFLAGS__H__
|
||||
#define __EANINMATIONFLAGS__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eAnimationFlags : uint32_t {
|
||||
IDLE_INVALID = 0, // made up, for internal use!!!
|
||||
IDLE_BASIC,
|
||||
IDLE_SWIM,
|
||||
IDLE_CARRY,
|
||||
IDLE_SWORD,
|
||||
IDLE_HAMMER,
|
||||
IDLE_SPEAR,
|
||||
IDLE_PISTOL,
|
||||
IDLE_BOW,
|
||||
IDLE_COMBAT,
|
||||
IDLE_JETPACK,
|
||||
IDLE_HORSE,
|
||||
IDLE_SG,
|
||||
IDLE_ORGAN,
|
||||
IDLE_SKATEBOARD,
|
||||
IDLE_DAREDEVIL,
|
||||
IDLE_SAMURAI,
|
||||
IDLE_SUMMONER,
|
||||
IDLE_BUCCANEER,
|
||||
IDLE_MISC,
|
||||
IDLE_NINJA,
|
||||
IDLE_MISC1,
|
||||
IDLE_MISC2,
|
||||
IDLE_MISC3,
|
||||
IDLE_MISC4,
|
||||
IDLE_MISC5,
|
||||
IDLE_MISC6,
|
||||
IDLE_MISC7,
|
||||
IDLE_MISC8,
|
||||
IDLE_MISC9,
|
||||
IDLE_MISC10,
|
||||
IDLE_MISC11,
|
||||
IDLE_MISC12
|
||||
};
|
||||
|
||||
#endif //!__EANINMATIONFLAGS__H__
|
||||
36
dCommon/eItemType.h
Normal file
36
dCommon/eItemType.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __EITEMTYPE__H__
|
||||
#define __EITEMTYPE__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eItemType : int32_t {
|
||||
ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type
|
||||
ITEM_TYPE_BRICK = 1, //!< A brick
|
||||
ITEM_TYPE_HAT = 2, //!< A hat / head item
|
||||
ITEM_TYPE_HAIR = 3, //!< A hair item
|
||||
ITEM_TYPE_NECK = 4, //!< A neck item
|
||||
ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item
|
||||
ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item
|
||||
ITEM_TYPE_LEGS = 7, //!< A pants item
|
||||
ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item
|
||||
ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item
|
||||
ITEM_TYPE_BEHAVIOR = 10, //!< A behavior
|
||||
ITEM_TYPE_PROPERTY = 11, //!< A property
|
||||
ITEM_TYPE_MODEL = 12, //!< A model
|
||||
ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item
|
||||
ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item
|
||||
ITEM_TYPE_CHEST = 15, //!< A chest item
|
||||
ITEM_TYPE_EGG = 16, //!< An egg
|
||||
ITEM_TYPE_PET_FOOD = 17, //!< A pet food item
|
||||
ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item
|
||||
ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item
|
||||
ITEM_TYPE_PACKAGE = 20, //!< A package
|
||||
ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model
|
||||
ITEM_TYPE_VEHICLE = 22, //!< A vehicle
|
||||
ITEM_TYPE_CURRENCY = 23, //!< Currency
|
||||
ITEM_TYPE_MOUNT = 24 //!< A Mount
|
||||
};
|
||||
|
||||
#endif //!__EITEMTYPE__H__
|
||||
14
dCommon/eUnequippableActiveType.h
Normal file
14
dCommon/eUnequippableActiveType.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __EUNEQUIPPABLEACTIVETYPE__H__
|
||||
#define __EUNEQUIPPABLEACTIVETYPE__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eUnequippableActiveType : int32_t {
|
||||
INVALID = -1,
|
||||
PET = 0,
|
||||
MOUNT
|
||||
};
|
||||
|
||||
#endif //!__EUNEQUIPPABLEACTIVETYPE__H__
|
||||
@@ -2,14 +2,19 @@
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
|
||||
// Static Variables
|
||||
static CppSQLite3DB * conn = new CppSQLite3DB();
|
||||
static CppSQLite3DB* conn = new CppSQLite3DB();
|
||||
|
||||
//! Opens a connection with the CDClient
|
||||
void CDClientDatabase::Connect(const std::string& filename) {
|
||||
conn->open(filename.c_str());
|
||||
conn->open(filename.c_str());
|
||||
}
|
||||
|
||||
//! Queries the CDClient
|
||||
CppSQLite3Query CDClientDatabase::ExecuteQuery(const std::string& query) {
|
||||
return conn->execQuery(query.c_str());
|
||||
return conn->execQuery(query.c_str());
|
||||
}
|
||||
|
||||
//! Makes prepared statements
|
||||
CppSQLite3Statement CDClientDatabase::CreatePreppedStmt(const std::string& query) {
|
||||
return conn->compileStatement(query.c_str());
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
// Enable this to cache all entries in each table for fast access, comes with more memory cost
|
||||
//#define CDCLIENT_CACHE_ALL
|
||||
// Enable this to cache all entries in each table for fast access, comes with more memory cost
|
||||
//#define CDCLIENT_CACHE_ALL
|
||||
|
||||
// Enable this to skip some unused columns in some tables
|
||||
// Enable this to skip some unused columns in some tables
|
||||
#define UNUSED(v)
|
||||
|
||||
/*!
|
||||
@@ -24,20 +24,26 @@
|
||||
\brief An interface between the CDClient.sqlite file and the server
|
||||
*/
|
||||
|
||||
//! The CDClient Database namespace
|
||||
//! The CDClient Database namespace
|
||||
namespace CDClientDatabase {
|
||||
|
||||
//! Opens a connection with the CDClient
|
||||
/*!
|
||||
\param filename The filename
|
||||
*/
|
||||
void Connect(const std::string& filename);
|
||||
|
||||
//! Queries the CDClient
|
||||
/*!
|
||||
\param query The query
|
||||
\return The results of the query
|
||||
*/
|
||||
CppSQLite3Query ExecuteQuery(const std::string& query);
|
||||
|
||||
|
||||
//! Opens a connection with the CDClient
|
||||
/*!
|
||||
\param filename The filename
|
||||
*/
|
||||
void Connect(const std::string& filename);
|
||||
|
||||
//! Queries the CDClient
|
||||
/*!
|
||||
\param query The query
|
||||
\return The results of the query
|
||||
*/
|
||||
CppSQLite3Query ExecuteQuery(const std::string& query);
|
||||
|
||||
//! Queries the CDClient and parses arguments
|
||||
/*!
|
||||
\param query The query with formatted arguments
|
||||
\return prepared SQLite Statement
|
||||
*/
|
||||
CppSQLite3Statement CreatePreppedStmt(const std::string& query);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "CDClientManager.h"
|
||||
|
||||
// Static Variables
|
||||
CDClientManager * CDClientManager::m_Address = nullptr;
|
||||
CDClientManager* CDClientManager::m_Address = nullptr;
|
||||
|
||||
//! Initializes the manager
|
||||
void CDClientManager::Initialize(void) {
|
||||
tables.insert(std::make_pair("ActivityRewards", new CDActivityRewardsTable()));
|
||||
UNUSED(tables.insert(std::make_pair("Animations", new CDAnimationsTable())));
|
||||
tables.insert(std::make_pair("BehaviorParameter", new CDBehaviorParameterTable()));
|
||||
UNUSED(tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable())));
|
||||
tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable()));
|
||||
tables.insert(std::make_pair("ComponentsRegistry", new CDComponentsRegistryTable()));
|
||||
tables.insert(std::make_pair("CurrencyTable", new CDCurrencyTableTable()));
|
||||
tables.insert(std::make_pair("DestructibleComponent", new CDDestructibleComponentTable()));
|
||||
|
||||
@@ -52,45 +52,45 @@
|
||||
\brief A manager for the CDClient tables
|
||||
*/
|
||||
|
||||
//! Manages all data from the CDClient
|
||||
//! Manages all data from the CDClient
|
||||
class CDClientManager {
|
||||
private:
|
||||
static CDClientManager * m_Address; //!< The singleton address
|
||||
|
||||
std::unordered_map<std::string, CDTable*> tables; //!< The tables
|
||||
|
||||
static CDClientManager* m_Address; //!< The singleton address
|
||||
|
||||
std::unordered_map<std::string, CDTable*> tables; //!< The tables
|
||||
|
||||
public:
|
||||
|
||||
//! The singleton method
|
||||
static CDClientManager * Instance() {
|
||||
if (m_Address == 0) {
|
||||
m_Address = new CDClientManager;
|
||||
}
|
||||
|
||||
return m_Address;
|
||||
}
|
||||
|
||||
//! Initializes the manager
|
||||
void Initialize(void);
|
||||
|
||||
//! Fetches a CDClient table
|
||||
/*!
|
||||
This function uses typename T which must be a subclass of CDTable.
|
||||
It returns the class that conforms to the class name
|
||||
|
||||
\param tableName The table name
|
||||
\return The class or nullptr
|
||||
*/
|
||||
template<typename T>
|
||||
T * GetTable(const std::string& tableName) {
|
||||
static_assert(std::is_base_of<CDTable, T>::value, "T should inherit from CDTable!");
|
||||
|
||||
for (auto itr = this->tables.begin(); itr != this->tables.end(); ++itr) {
|
||||
if (itr->first == tableName) {
|
||||
return dynamic_cast<T*>(itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//! The singleton method
|
||||
static CDClientManager* Instance() {
|
||||
if (m_Address == 0) {
|
||||
m_Address = new CDClientManager;
|
||||
}
|
||||
|
||||
return m_Address;
|
||||
}
|
||||
|
||||
//! Initializes the manager
|
||||
void Initialize(void);
|
||||
|
||||
//! Fetches a CDClient table
|
||||
/*!
|
||||
This function uses typename T which must be a subclass of CDTable.
|
||||
It returns the class that conforms to the class name
|
||||
|
||||
\param tableName The table name
|
||||
\return The class or nullptr
|
||||
*/
|
||||
template<typename T>
|
||||
T* GetTable(const std::string& tableName) {
|
||||
static_assert(std::is_base_of<CDTable, T>::value, "T should inherit from CDTable!");
|
||||
|
||||
for (auto itr = this->tables.begin(); itr != this->tables.end(); ++itr) {
|
||||
if (itr->first == tableName) {
|
||||
return dynamic_cast<T*>(itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
13
dDatabase/CMakeLists.txt
Normal file
13
dDatabase/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
set(DDATABASE_SOURCES "CDClientDatabase.cpp"
|
||||
"CDClientManager.cpp"
|
||||
"Database.cpp"
|
||||
"MigrationRunner.cpp")
|
||||
|
||||
add_subdirectory(Tables)
|
||||
|
||||
foreach(file ${DDATABASE_TABLES_SOURCES})
|
||||
set(DDATABASE_SOURCES ${DDATABASE_SOURCES} "Tables/${file}")
|
||||
endforeach()
|
||||
|
||||
add_library(dDatabase STATIC ${DDATABASE_SOURCES})
|
||||
target_link_libraries(dDatabase sqlite3 mariadbConnCpp)
|
||||
@@ -6,11 +6,12 @@ using namespace std;
|
||||
|
||||
#pragma warning (disable:4251) //Disables SQL warnings
|
||||
|
||||
sql::Driver * Database::driver;
|
||||
sql::Connection * Database::con;
|
||||
sql::Driver* Database::driver;
|
||||
sql::Connection* Database::con;
|
||||
sql::Properties Database::props;
|
||||
std::string Database::database;
|
||||
|
||||
void Database::Connect(const string& host, const string& database, const string& username, const string& password) {
|
||||
driver = get_driver_instance();
|
||||
|
||||
//To bypass debug issues:
|
||||
std::string newHost = "tcp://" + host;
|
||||
@@ -19,16 +20,33 @@ void Database::Connect(const string& host, const string& database, const string&
|
||||
const char* szUsername = username.c_str();
|
||||
const char* szPassword = password.c_str();
|
||||
|
||||
con = driver->connect(szHost, szUsername, szPassword);
|
||||
con->setSchema(szDatabase);
|
||||
driver = sql::mariadb::get_driver_instance();
|
||||
|
||||
bool myTrue = true;
|
||||
con->setClientOption("MYSQL_OPT_RECONNECT", &myTrue);
|
||||
} //Connect
|
||||
sql::Properties properties;
|
||||
properties["hostName"] = szHost;
|
||||
properties["user"] = szUsername;
|
||||
properties["password"] = szPassword;
|
||||
properties["autoReconnect"] = "true";
|
||||
|
||||
void Database::Destroy() {
|
||||
Database::props = properties;
|
||||
Database::database = database;
|
||||
|
||||
Database::Connect();
|
||||
}
|
||||
|
||||
void Database::Connect() {
|
||||
con = driver->connect(Database::props);
|
||||
con->setSchema(Database::database);
|
||||
}
|
||||
|
||||
void Database::Destroy(std::string source, bool log) {
|
||||
if (!con) return;
|
||||
cout << "Destroying MySQL connection!" << endl;
|
||||
|
||||
if (log) {
|
||||
if (source != "") Game::logger->Log("Database", "Destroying MySQL connection from %s!", source.c_str());
|
||||
else Game::logger->Log("Database", "Destroying MySQL connection!");
|
||||
}
|
||||
|
||||
con->close();
|
||||
delete con;
|
||||
} //Destroy
|
||||
@@ -44,33 +62,24 @@ sql::PreparedStatement* Database::CreatePreppedStmt(const std::string& query) {
|
||||
sql::SQLString str(test, size);
|
||||
|
||||
if (!con) {
|
||||
//Connect to the MySQL Database
|
||||
std::string mysql_host = Game::config->GetValue("mysql_host");
|
||||
std::string mysql_database = Game::config->GetValue("mysql_database");
|
||||
std::string mysql_username = Game::config->GetValue("mysql_username");
|
||||
std::string mysql_password = Game::config->GetValue("mysql_password");
|
||||
|
||||
Connect(mysql_host, mysql_database, mysql_username, mysql_password);
|
||||
Game::logger->Log("Database", "Trying to reconnect to MySQL\n");
|
||||
Connect();
|
||||
Game::logger->Log("Database", "Trying to reconnect to MySQL");
|
||||
}
|
||||
|
||||
if (!con->isValid() || con->isClosed())
|
||||
{
|
||||
if (!con->isValid() || con->isClosed()) {
|
||||
delete con;
|
||||
|
||||
con = nullptr;
|
||||
|
||||
//Connect to the MySQL Database
|
||||
std::string mysql_host = Game::config->GetValue("mysql_host");
|
||||
std::string mysql_database = Game::config->GetValue("mysql_database");
|
||||
std::string mysql_username = Game::config->GetValue("mysql_username");
|
||||
std::string mysql_password = Game::config->GetValue("mysql_password");
|
||||
|
||||
Connect(mysql_host, mysql_database, mysql_username, mysql_password);
|
||||
Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection\n");
|
||||
Connect();
|
||||
Game::logger->Log("Database", "Trying to reconnect to MySQL from invalid or closed connection");
|
||||
}
|
||||
|
||||
|
||||
auto* stmt = con->prepareStatement(str);
|
||||
|
||||
return stmt;
|
||||
} //CreatePreppedStmt
|
||||
} //CreatePreppedStmt
|
||||
|
||||
void Database::Commit() {
|
||||
Database::con->commit();
|
||||
}
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mysql_connection.h>
|
||||
#include <cppconn/driver.h>
|
||||
#include <cppconn/exception.h>
|
||||
#include <cppconn/resultset.h>
|
||||
#include <cppconn/statement.h>
|
||||
#include <cppconn/prepared_statement.h>
|
||||
#include <cppconn/sqlstring.h>
|
||||
#include <conncpp.hpp>
|
||||
|
||||
class MySqlException : public std::runtime_error {
|
||||
public:
|
||||
@@ -17,12 +11,19 @@ public:
|
||||
|
||||
class Database {
|
||||
private:
|
||||
static sql::Driver *driver;
|
||||
static sql::Connection *con;
|
||||
|
||||
static sql::Driver* driver;
|
||||
static sql::Connection* con;
|
||||
static sql::Properties props;
|
||||
static std::string database;
|
||||
public:
|
||||
static void Connect(const std::string& host, const std::string& database, const std::string& username, const std::string& password);
|
||||
static void Destroy();
|
||||
static void Connect();
|
||||
static void Destroy(std::string source = "", bool log = true);
|
||||
|
||||
static sql::Statement* CreateStmt();
|
||||
static sql::PreparedStatement* CreatePreppedStmt(const std::string& query);
|
||||
static void Commit();
|
||||
|
||||
static std::string GetDatabase() { return database; }
|
||||
static sql::Properties GetProperties() { return props; }
|
||||
};
|
||||
|
||||
77
dDatabase/MigrationRunner.cpp
Normal file
77
dDatabase/MigrationRunner.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "MigrationRunner.h"
|
||||
|
||||
#include "GeneralUtils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
|
||||
void MigrationRunner::RunMigrations() {
|
||||
auto stmt = Database::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP());");
|
||||
stmt->executeQuery();
|
||||
delete stmt;
|
||||
|
||||
sql::SQLString finalSQL = "";
|
||||
Migration checkMigration{};
|
||||
|
||||
for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/")) {
|
||||
auto migration = LoadMigration(entry);
|
||||
|
||||
if (migration.data.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
checkMigration = migration;
|
||||
|
||||
stmt = Database::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;");
|
||||
stmt->setString(1, migration.name);
|
||||
auto res = stmt->executeQuery();
|
||||
bool doExit = res->next();
|
||||
delete res;
|
||||
delete stmt;
|
||||
if (doExit) continue;
|
||||
|
||||
Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str());
|
||||
|
||||
finalSQL.append(migration.data);
|
||||
finalSQL.append('\n');
|
||||
|
||||
stmt = Database::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);");
|
||||
stmt->setString(1, entry);
|
||||
stmt->execute();
|
||||
delete stmt;
|
||||
}
|
||||
|
||||
if (!finalSQL.empty()) {
|
||||
try {
|
||||
auto simpleStatement = Database::CreateStmt();
|
||||
simpleStatement->execute(finalSQL);
|
||||
delete simpleStatement;
|
||||
} catch (sql::SQLException e) {
|
||||
Game::logger->Log("MigrationRunner", "Encountered error running migration: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Migration MigrationRunner::LoadMigration(std::string path) {
|
||||
Migration migration{};
|
||||
std::ifstream file("./migrations/" + path);
|
||||
|
||||
if (file.is_open()) {
|
||||
std::hash<std::string> hash;
|
||||
|
||||
std::string line;
|
||||
std::string total = "";
|
||||
|
||||
while (std::getline(file, line)) {
|
||||
total += line;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
migration.name = path;
|
||||
migration.data = total;
|
||||
}
|
||||
|
||||
return migration;
|
||||
}
|
||||
19
dDatabase/MigrationRunner.h
Normal file
19
dDatabase/MigrationRunner.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Database.h"
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "Game.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dLogger.h"
|
||||
|
||||
struct Migration {
|
||||
std::string data;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class MigrationRunner {
|
||||
public:
|
||||
static void RunMigrations();
|
||||
static Migration LoadMigration(std::string path);
|
||||
};
|
||||
@@ -49,7 +49,7 @@ CDActivitiesTable::CDActivitiesTable(void) {
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDActivitiesTable::~CDActivitiesTable(void) { }
|
||||
CDActivitiesTable::~CDActivitiesTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDActivitiesTable::GetName(void) const {
|
||||
|
||||
@@ -2,59 +2,59 @@
|
||||
|
||||
//! Constructor
|
||||
CDActivityRewardsTable::CDActivityRewardsTable(void) {
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ActivityRewards");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ActivityRewards");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
|
||||
while (!tableData.eof()) {
|
||||
CDActivityRewards entry;
|
||||
entry.objectTemplate = tableData.getIntField(0, -1);
|
||||
entry.ActivityRewardIndex = tableData.getIntField(1, -1);
|
||||
entry.activityRating = tableData.getIntField(2, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(3, -1);
|
||||
entry.CurrencyIndex = tableData.getIntField(4, -1);
|
||||
entry.ChallengeRating = tableData.getIntField(5, -1);
|
||||
entry.description = tableData.getStringField(6, "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
|
||||
while (!tableData.eof()) {
|
||||
CDActivityRewards entry;
|
||||
entry.objectTemplate = tableData.getIntField(0, -1);
|
||||
entry.ActivityRewardIndex = tableData.getIntField(1, -1);
|
||||
entry.activityRating = tableData.getIntField(2, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(3, -1);
|
||||
entry.CurrencyIndex = tableData.getIntField(4, -1);
|
||||
entry.ChallengeRating = tableData.getIntField(5, -1);
|
||||
entry.description = tableData.getStringField(6, "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDActivityRewardsTable::~CDActivityRewardsTable(void) { }
|
||||
CDActivityRewardsTable::~CDActivityRewardsTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDActivityRewardsTable::GetName(void) const {
|
||||
return "ActivityRewards";
|
||||
return "ActivityRewards";
|
||||
}
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(CDActivityRewards)> predicate) {
|
||||
|
||||
std::vector<CDActivityRewards> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
|
||||
std::vector<CDActivityRewards> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//! Gets all the entries in the table
|
||||
std::vector<CDActivityRewards> CDActivityRewardsTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
@@ -8,47 +8,47 @@
|
||||
\brief Contains data for the ActivityRewards table
|
||||
*/
|
||||
|
||||
//! ActivityRewards Entry Struct
|
||||
//! ActivityRewards Entry Struct
|
||||
struct CDActivityRewards {
|
||||
unsigned int objectTemplate; //!< The object template (?)
|
||||
unsigned int ActivityRewardIndex; //!< The activity reward index
|
||||
int activityRating; //!< The activity rating
|
||||
unsigned int LootMatrixIndex; //!< The loot matrix index
|
||||
unsigned int CurrencyIndex; //!< The currency index
|
||||
unsigned int ChallengeRating; //!< The challenge rating
|
||||
std::string description; //!< The description
|
||||
unsigned int objectTemplate; //!< The object template (?)
|
||||
unsigned int ActivityRewardIndex; //!< The activity reward index
|
||||
int activityRating; //!< The activity rating
|
||||
unsigned int LootMatrixIndex; //!< The loot matrix index
|
||||
unsigned int CurrencyIndex; //!< The currency index
|
||||
unsigned int ChallengeRating; //!< The challenge rating
|
||||
std::string description; //!< The description
|
||||
};
|
||||
|
||||
|
||||
//! ActivityRewards table
|
||||
class CDActivityRewardsTable : public CDTable {
|
||||
private:
|
||||
std::vector<CDActivityRewards> entries;
|
||||
|
||||
std::vector<CDActivityRewards> entries;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDActivityRewardsTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDActivityRewardsTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDActivityRewards> GetEntries(void) const;
|
||||
|
||||
|
||||
//! Constructor
|
||||
CDActivityRewardsTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDActivityRewardsTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDActivityRewards> GetEntries(void) const;
|
||||
|
||||
};
|
||||
|
||||
@@ -2,65 +2,65 @@
|
||||
|
||||
//! Constructor
|
||||
CDAnimationsTable::CDAnimationsTable(void) {
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Animations");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Animations");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
|
||||
while (!tableData.eof()) {
|
||||
CDAnimations entry;
|
||||
entry.animationGroupID = tableData.getIntField(0, -1);
|
||||
entry.animation_type = tableData.getStringField(1, "");
|
||||
entry.animation_name = tableData.getStringField(2, "");
|
||||
entry.chance_to_play = tableData.getFloatField(3, -1.0f);
|
||||
entry.min_loops = tableData.getIntField(4, -1);
|
||||
entry.max_loops = tableData.getIntField(5, -1);
|
||||
entry.animation_length = tableData.getFloatField(6, -1.0f);
|
||||
entry.hideEquip = tableData.getIntField(7, -1) == 1 ? true : false;
|
||||
entry.ignoreUpperBody = tableData.getIntField(8, -1) == 1 ? true : false;
|
||||
entry.restartable = tableData.getIntField(9, -1) == 1 ? true : false;
|
||||
entry.face_animation_name = tableData.getStringField(10, "");
|
||||
entry.priority = tableData.getFloatField(11, -1.0f);
|
||||
entry.blendTime = tableData.getFloatField(12, -1.0f);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
|
||||
while (!tableData.eof()) {
|
||||
CDAnimations entry;
|
||||
entry.animationGroupID = tableData.getIntField(0, -1);
|
||||
entry.animation_type = tableData.getStringField(1, "");
|
||||
entry.animation_name = tableData.getStringField(2, "");
|
||||
entry.chance_to_play = tableData.getFloatField(3, -1.0f);
|
||||
entry.min_loops = tableData.getIntField(4, -1);
|
||||
entry.max_loops = tableData.getIntField(5, -1);
|
||||
entry.animation_length = tableData.getFloatField(6, -1.0f);
|
||||
entry.hideEquip = tableData.getIntField(7, -1) == 1 ? true : false;
|
||||
entry.ignoreUpperBody = tableData.getIntField(8, -1) == 1 ? true : false;
|
||||
entry.restartable = tableData.getIntField(9, -1) == 1 ? true : false;
|
||||
entry.face_animation_name = tableData.getStringField(10, "");
|
||||
entry.priority = tableData.getFloatField(11, -1.0f);
|
||||
entry.blendTime = tableData.getFloatField(12, -1.0f);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDAnimationsTable::~CDAnimationsTable(void) { }
|
||||
CDAnimationsTable::~CDAnimationsTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDAnimationsTable::GetName(void) const {
|
||||
return "Animations";
|
||||
return "Animations";
|
||||
}
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
std::vector<CDAnimations> CDAnimationsTable::Query(std::function<bool(CDAnimations)> predicate) {
|
||||
|
||||
std::vector<CDAnimations> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
|
||||
std::vector<CDAnimations> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//! Gets all the entries in the table
|
||||
std::vector<CDAnimations> CDAnimationsTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
@@ -8,53 +8,53 @@
|
||||
\brief Contains data for the Animations table
|
||||
*/
|
||||
|
||||
//! Animations Entry Struct
|
||||
//! Animations Entry Struct
|
||||
struct CDAnimations {
|
||||
unsigned int animationGroupID; //!< The animation group ID
|
||||
std::string animation_type; //!< The animation type
|
||||
std::string animation_name; //!< The animation name
|
||||
float chance_to_play; //!< The chance to play the animation
|
||||
unsigned int min_loops; //!< The minimum number of loops
|
||||
unsigned int max_loops; //!< The maximum number of loops
|
||||
float animation_length; //!< The animation length
|
||||
bool hideEquip; //!< Whether or not to hide the equip
|
||||
bool ignoreUpperBody; //!< Whether or not to ignore the upper body
|
||||
bool restartable; //!< Whether or not the animation is restartable
|
||||
std::string face_animation_name; //!< The face animation name
|
||||
float priority; //!< The priority
|
||||
float blendTime; //!< The blend time
|
||||
unsigned int animationGroupID; //!< The animation group ID
|
||||
std::string animation_type; //!< The animation type
|
||||
std::string animation_name; //!< The animation name
|
||||
float chance_to_play; //!< The chance to play the animation
|
||||
unsigned int min_loops; //!< The minimum number of loops
|
||||
unsigned int max_loops; //!< The maximum number of loops
|
||||
float animation_length; //!< The animation length
|
||||
bool hideEquip; //!< Whether or not to hide the equip
|
||||
bool ignoreUpperBody; //!< Whether or not to ignore the upper body
|
||||
bool restartable; //!< Whether or not the animation is restartable
|
||||
std::string face_animation_name; //!< The face animation name
|
||||
float priority; //!< The priority
|
||||
float blendTime; //!< The blend time
|
||||
};
|
||||
|
||||
|
||||
//! Animations table
|
||||
class CDAnimationsTable : public CDTable {
|
||||
private:
|
||||
std::vector<CDAnimations> entries;
|
||||
|
||||
std::vector<CDAnimations> entries;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDAnimationsTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDAnimationsTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDAnimations> Query(std::function<bool(CDAnimations)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDAnimations> GetEntries(void) const;
|
||||
|
||||
|
||||
//! Constructor
|
||||
CDAnimationsTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDAnimationsTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDAnimations> Query(std::function<bool(CDAnimations)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDAnimations> GetEntries(void) const;
|
||||
|
||||
};
|
||||
|
||||
@@ -3,88 +3,67 @@
|
||||
|
||||
//! Constructor
|
||||
CDBehaviorParameterTable::CDBehaviorParameterTable(void) {
|
||||
#ifdef CDCLIENT_CACHE_ALL
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
|
||||
while (!tableData.eof()) {
|
||||
CDBehaviorParameter entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
entry.parameterID = tableData.getStringField(1, "");
|
||||
entry.value = tableData.getFloatField(2, -1.0f);
|
||||
|
||||
//Check if we have an entry with this ID:
|
||||
auto it = m_entries.find(entry.behaviorID);
|
||||
if (it != m_entries.end()) {
|
||||
it->second.insert(std::make_pair(entry.parameterID, entry.value));
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
|
||||
size_t hash = 0;
|
||||
while (!tableData.eof()) {
|
||||
hash = 0;
|
||||
CDBehaviorParameter entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
auto candidateStringToAdd = std::string(tableData.getStringField(1, ""));
|
||||
auto parameter = m_ParametersList.find(candidateStringToAdd);
|
||||
if (parameter != m_ParametersList.end()) {
|
||||
entry.parameterID = parameter;
|
||||
} else {
|
||||
entry.parameterID = m_ParametersList.insert(candidateStringToAdd).first;
|
||||
}
|
||||
else {
|
||||
//Otherwise, insert it:
|
||||
m_entries.insert(std::make_pair(entry.behaviorID, std::map<std::string, float>()));
|
||||
auto jit = m_entries.find(entry.behaviorID);
|
||||
entry.value = tableData.getFloatField(2, -1.0f);
|
||||
|
||||
//Add our value as well:
|
||||
jit->second.insert(std::make_pair(entry.parameterID, entry.value));
|
||||
}
|
||||
GeneralUtils::hash_combine(hash, entry.behaviorID);
|
||||
GeneralUtils::hash_combine(hash, *entry.parameterID);
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
auto it = m_Entries.find(entry.behaviorID);
|
||||
m_ParametersList.insert(*entry.parameterID);
|
||||
m_Entries.insert(std::make_pair(hash, entry));
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
tableData.finalize();
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDBehaviorParameterTable::~CDBehaviorParameterTable(void) { }
|
||||
CDBehaviorParameterTable::~CDBehaviorParameterTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDBehaviorParameterTable::GetName(void) const {
|
||||
return "BehaviorParameter";
|
||||
return "BehaviorParameter";
|
||||
}
|
||||
|
||||
float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name)
|
||||
{
|
||||
CDBehaviorParameter CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
|
||||
CDBehaviorParameter returnValue;
|
||||
returnValue.behaviorID = 0;
|
||||
returnValue.parameterID = m_ParametersList.end();
|
||||
returnValue.value = defaultValue;
|
||||
|
||||
size_t hash = 0;
|
||||
GeneralUtils::hash_combine(hash, behaviorID);
|
||||
GeneralUtils::hash_combine(hash, name);
|
||||
|
||||
// Search for specific perameter
|
||||
// Search for specific parameter
|
||||
const auto& it = m_Entries.find(hash);
|
||||
if (it != m_Entries.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Check if this behavior has already been checked
|
||||
const auto& itChecked = m_Entries.find(behaviorID);
|
||||
if (itChecked != m_Entries.end()) {
|
||||
return itChecked->second;
|
||||
}
|
||||
|
||||
#ifndef CDCLIENT_CACHE_ALL
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(behaviorID);
|
||||
|
||||
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
|
||||
|
||||
m_Entries.insert_or_assign(behaviorID, 0);
|
||||
|
||||
while (!tableData.eof()) {
|
||||
const std::string parameterID = tableData.getStringField(0, "");
|
||||
const float value = tableData.getFloatField(1, 0);
|
||||
|
||||
size_t parameterHash = 0;
|
||||
GeneralUtils::hash_combine(parameterHash, behaviorID);
|
||||
GeneralUtils::hash_combine(parameterHash, parameterID);
|
||||
|
||||
m_Entries.insert_or_assign(parameterHash, value);
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
const auto& it2 = m_Entries.find(hash);
|
||||
if (it2 != m_Entries.end()) {
|
||||
return it2->second;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return it != m_Entries.end() ? it->second : returnValue;
|
||||
}
|
||||
|
||||
std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) {
|
||||
size_t hash;
|
||||
std::map<std::string, float> returnInfo;
|
||||
for (auto parameterCandidate : m_ParametersList) {
|
||||
hash = 0;
|
||||
GeneralUtils::hash_combine(hash, behaviorID);
|
||||
GeneralUtils::hash_combine(hash, parameterCandidate);
|
||||
auto infoCandidate = m_Entries.find(hash);
|
||||
if (infoCandidate != m_Entries.end()) {
|
||||
returnInfo.insert(std::make_pair(*(infoCandidate->second.parameterID), infoCandidate->second.value));
|
||||
}
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
@@ -2,38 +2,41 @@
|
||||
|
||||
// Custom Classes
|
||||
#include "CDTable.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
/*!
|
||||
\file CDBehaviorParameterTable.hpp
|
||||
\brief Contains data for the BehaviorParameter table
|
||||
*/
|
||||
|
||||
//! BehaviorParameter Entry Struct
|
||||
//! BehaviorParameter Entry Struct
|
||||
struct CDBehaviorParameter {
|
||||
unsigned int behaviorID; //!< The Behavior ID
|
||||
std::string parameterID; //!< The Parameter ID
|
||||
float value; //!< The value of the behavior template
|
||||
unsigned int behaviorID; //!< The Behavior ID
|
||||
std::unordered_set<std::string>::iterator parameterID; //!< The Parameter ID
|
||||
float value; //!< The value of the behavior template
|
||||
};
|
||||
|
||||
//! BehaviorParameter table
|
||||
class CDBehaviorParameterTable : public CDTable {
|
||||
private:
|
||||
std::map<size_t, float> m_Entries;
|
||||
|
||||
std::unordered_map<size_t, CDBehaviorParameter> m_Entries;
|
||||
std::unordered_set<std::string> m_ParametersList;
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDBehaviorParameterTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDBehaviorParameterTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
float GetEntry(const uint32_t behaviorID, const std::string& name);
|
||||
|
||||
//! Constructor
|
||||
CDBehaviorParameterTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDBehaviorParameterTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
CDBehaviorParameter GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0);
|
||||
|
||||
std::map<std::string, float> GetParametersByBehaviorID(uint32_t behaviorID);
|
||||
};
|
||||
|
||||
@@ -2,56 +2,76 @@
|
||||
|
||||
//! Constructor
|
||||
CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) {
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BehaviorTemplate");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM BehaviorTemplate");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate");
|
||||
while (!tableData.eof()) {
|
||||
CDBehaviorTemplate entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
entry.templateID = tableData.getIntField(1, -1);
|
||||
entry.effectID = tableData.getIntField(2, -1);
|
||||
entry.effectHandle = tableData.getStringField(3, "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate");
|
||||
while (!tableData.eof()) {
|
||||
CDBehaviorTemplate entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
entry.templateID = tableData.getIntField(1, -1);
|
||||
entry.effectID = tableData.getIntField(2, -1);
|
||||
auto candidateToAdd = tableData.getStringField(3, "");
|
||||
auto parameter = m_EffectHandles.find(candidateToAdd);
|
||||
if (parameter != m_EffectHandles.end()) {
|
||||
entry.effectHandle = parameter;
|
||||
} else {
|
||||
entry.effectHandle = m_EffectHandles.insert(candidateToAdd).first;
|
||||
}
|
||||
|
||||
this->entries.push_back(entry);
|
||||
this->entriesMappedByBehaviorID.insert(std::make_pair(entry.behaviorID, entry));
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDBehaviorTemplateTable::~CDBehaviorTemplateTable(void) { }
|
||||
CDBehaviorTemplateTable::~CDBehaviorTemplateTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDBehaviorTemplateTable::GetName(void) const {
|
||||
return "BehaviorTemplate";
|
||||
return "BehaviorTemplate";
|
||||
}
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<bool(CDBehaviorTemplate)> predicate) {
|
||||
|
||||
std::vector<CDBehaviorTemplate> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
|
||||
std::vector<CDBehaviorTemplate> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//! Gets all the entries in the table
|
||||
std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behaviorID) {
|
||||
auto entry = this->entriesMappedByBehaviorID.find(behaviorID);
|
||||
if (entry == this->entriesMappedByBehaviorID.end()) {
|
||||
CDBehaviorTemplate entryToReturn;
|
||||
entryToReturn.behaviorID = 0;
|
||||
entryToReturn.effectHandle = m_EffectHandles.end();
|
||||
entryToReturn.effectID = 0;
|
||||
return entryToReturn;
|
||||
} else {
|
||||
return entry->second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,50 +2,54 @@
|
||||
|
||||
// Custom Classes
|
||||
#include "CDTable.h"
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
/*!
|
||||
\file CDBehaviorTemplateTable.hpp
|
||||
\brief Contains data for the BehaviorTemplate table
|
||||
*/
|
||||
|
||||
//! BehaviorTemplate Entry Struct
|
||||
//! BehaviorTemplate Entry Struct
|
||||
struct CDBehaviorTemplate {
|
||||
unsigned int behaviorID; //!< The Behavior ID
|
||||
unsigned int templateID; //!< The Template ID (LOT)
|
||||
unsigned int effectID; //!< The Effect ID attached
|
||||
std::string effectHandle; //!< The effect handle
|
||||
unsigned int behaviorID; //!< The Behavior ID
|
||||
unsigned int templateID; //!< The Template ID (LOT)
|
||||
unsigned int effectID; //!< The Effect ID attached
|
||||
std::unordered_set<std::string>::iterator effectHandle; //!< The effect handle
|
||||
};
|
||||
|
||||
|
||||
//! BehaviorTemplate table
|
||||
class CDBehaviorTemplateTable : public CDTable {
|
||||
private:
|
||||
std::vector<CDBehaviorTemplate> entries;
|
||||
|
||||
std::vector<CDBehaviorTemplate> entries;
|
||||
std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID;
|
||||
std::unordered_set<std::string> m_EffectHandles;
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDBehaviorTemplateTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDBehaviorTemplateTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDBehaviorTemplate> GetEntries(void) const;
|
||||
|
||||
|
||||
//! Constructor
|
||||
CDBehaviorTemplateTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDBehaviorTemplateTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDBehaviorTemplate> GetEntries(void) const;
|
||||
|
||||
const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID);
|
||||
};
|
||||
|
||||
@@ -11,9 +11,9 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) {
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
@@ -32,7 +32,7 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) {
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDBrickIDTableTable::~CDBrickIDTableTable(void) { }
|
||||
CDBrickIDTableTable::~CDBrickIDTableTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDBrickIDTableTable::GetName(void) const {
|
||||
|
||||
@@ -4,33 +4,33 @@
|
||||
|
||||
//! Constructor
|
||||
CDComponentsRegistryTable::CDComponentsRegistryTable(void) {
|
||||
|
||||
#ifdef CDCLIENT_CACHE_ALL
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
//this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
|
||||
while (!tableData.eof()) {
|
||||
CDComponentsRegistry entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.component_type = tableData.getIntField(1, -1);
|
||||
entry.component_id = tableData.getIntField(2, -1);
|
||||
|
||||
this->mappedEntries.insert_or_assign(((uint64_t) entry.component_type) << 32 | ((uint64_t) entry.id), entry.component_id);
|
||||
|
||||
//this->entries.push_back(entry);
|
||||
#ifdef CDCLIENT_CACHE_ALL
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM ComponentsRegistry");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
//this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
|
||||
while (!tableData.eof()) {
|
||||
CDComponentsRegistry entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.component_type = tableData.getIntField(1, -1);
|
||||
entry.component_id = tableData.getIntField(2, -1);
|
||||
|
||||
this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id);
|
||||
|
||||
//this->entries.push_back(entry);
|
||||
|
||||
/*
|
||||
//Darwin's stuff:
|
||||
@@ -48,27 +48,25 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) {
|
||||
}
|
||||
*/
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDComponentsRegistryTable::~CDComponentsRegistryTable(void) { }
|
||||
CDComponentsRegistryTable::~CDComponentsRegistryTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDComponentsRegistryTable::GetName(void) const {
|
||||
return "ComponentsRegistry";
|
||||
return "ComponentsRegistry";
|
||||
}
|
||||
|
||||
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue)
|
||||
{
|
||||
const auto& iter = this->mappedEntries.find(((uint64_t) componentType) << 32 | ((uint64_t) id));
|
||||
int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue) {
|
||||
const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id));
|
||||
|
||||
if (iter == this->mappedEntries.end())
|
||||
{
|
||||
if (iter == this->mappedEntries.end()) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@@ -85,19 +83,19 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen
|
||||
*/
|
||||
|
||||
#ifndef CDCLIENT_CACHE_ALL
|
||||
// Now get the data
|
||||
// Now get the data
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT * FROM ComponentsRegistry WHERE id = " << std::to_string(id);
|
||||
|
||||
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
|
||||
while (!tableData.eof()) {
|
||||
CDComponentsRegistry entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.component_type = tableData.getIntField(1, -1);
|
||||
entry.component_id = tableData.getIntField(2, -1);
|
||||
|
||||
//this->entries.push_back(entry);
|
||||
while (!tableData.eof()) {
|
||||
CDComponentsRegistry entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.component_type = tableData.getIntField(1, -1);
|
||||
entry.component_id = tableData.getIntField(2, -1);
|
||||
|
||||
//this->entries.push_back(entry);
|
||||
|
||||
//Darwin's stuff:
|
||||
const auto& it = this->mappedEntries.find(entry.id);
|
||||
@@ -106,15 +104,14 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen
|
||||
if (iter == it->second.end()) {
|
||||
it->second.insert(std::make_pair(entry.component_type, entry.component_id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::map<unsigned int, unsigned int> map;
|
||||
map.insert(std::make_pair(entry.component_type, entry.component_id));
|
||||
this->mappedEntries.insert(std::make_pair(entry.id, map));
|
||||
}
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
|
||||
|
||||
@@ -8,33 +8,33 @@
|
||||
\brief Contains data for the ComponentsRegistry table
|
||||
*/
|
||||
|
||||
//! ComponentsRegistry Entry Struct
|
||||
//! ComponentsRegistry Entry Struct
|
||||
struct CDComponentsRegistry {
|
||||
unsigned int id; //!< The LOT is used as the ID
|
||||
unsigned int component_type; //!< See ComponentTypes enum for values
|
||||
unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0
|
||||
unsigned int id; //!< The LOT is used as the ID
|
||||
unsigned int component_type; //!< See ComponentTypes enum for values
|
||||
unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0
|
||||
};
|
||||
|
||||
|
||||
//! ComponentsRegistry table
|
||||
class CDComponentsRegistryTable : public CDTable {
|
||||
private:
|
||||
//std::vector<CDComponentsRegistry> entries;
|
||||
std::map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDComponentsRegistryTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDComponentsRegistryTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
//std::vector<CDComponentsRegistry> entries;
|
||||
std::map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id
|
||||
|
||||
int32_t GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue = 0);
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDComponentsRegistryTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDComponentsRegistryTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
int32_t GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue = 0);
|
||||
};
|
||||
|
||||
@@ -2,57 +2,57 @@
|
||||
|
||||
//! Constructor
|
||||
CDCurrencyTableTable::CDCurrencyTableTable(void) {
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable");
|
||||
while (!tableData.eof()) {
|
||||
CDCurrencyTable entry;
|
||||
entry.currencyIndex = tableData.getIntField(0, -1);
|
||||
entry.npcminlevel = tableData.getIntField(1, -1);
|
||||
entry.minvalue = tableData.getIntField(2, -1);
|
||||
entry.maxvalue = tableData.getIntField(3, -1);
|
||||
entry.id = tableData.getIntField(4, -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable");
|
||||
while (!tableData.eof()) {
|
||||
CDCurrencyTable entry;
|
||||
entry.currencyIndex = tableData.getIntField(0, -1);
|
||||
entry.npcminlevel = tableData.getIntField(1, -1);
|
||||
entry.minvalue = tableData.getIntField(2, -1);
|
||||
entry.maxvalue = tableData.getIntField(3, -1);
|
||||
entry.id = tableData.getIntField(4, -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDCurrencyTableTable::~CDCurrencyTableTable(void) { }
|
||||
CDCurrencyTableTable::~CDCurrencyTableTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDCurrencyTableTable::GetName(void) const {
|
||||
return "CurrencyTable";
|
||||
return "CurrencyTable";
|
||||
}
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCurrencyTable)> predicate) {
|
||||
|
||||
std::vector<CDCurrencyTable> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
|
||||
std::vector<CDCurrencyTable> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//! Gets all the entries in the table
|
||||
std::vector<CDCurrencyTable> CDCurrencyTableTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
@@ -8,44 +8,44 @@
|
||||
\brief Contains data for the CurrencyTable table
|
||||
*/
|
||||
|
||||
//! CurrencyTable Struct
|
||||
//! CurrencyTable Struct
|
||||
struct CDCurrencyTable {
|
||||
unsigned int currencyIndex; //!< The Currency Index
|
||||
unsigned int npcminlevel; //!< The minimum level of the npc
|
||||
unsigned int minvalue; //!< The minimum currency
|
||||
unsigned int maxvalue; //!< The maximum currency
|
||||
unsigned int id; //!< The ID of the currency index
|
||||
unsigned int currencyIndex; //!< The Currency Index
|
||||
unsigned int npcminlevel; //!< The minimum level of the npc
|
||||
unsigned int minvalue; //!< The minimum currency
|
||||
unsigned int maxvalue; //!< The maximum currency
|
||||
unsigned int id; //!< The ID of the currency index
|
||||
};
|
||||
|
||||
//! CurrencyTable table
|
||||
class CDCurrencyTableTable : public CDTable {
|
||||
private:
|
||||
std::vector<CDCurrencyTable> entries;
|
||||
|
||||
std::vector<CDCurrencyTable> entries;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDCurrencyTableTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDCurrencyTableTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDCurrencyTable> GetEntries(void) const;
|
||||
|
||||
|
||||
//! Constructor
|
||||
CDCurrencyTableTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDCurrencyTableTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDCurrencyTable> GetEntries(void) const;
|
||||
|
||||
};
|
||||
|
||||
@@ -2,66 +2,66 @@
|
||||
|
||||
//! Constructor
|
||||
CDDestructibleComponentTable::CDDestructibleComponentTable(void) {
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
|
||||
// First, get the size of the table
|
||||
unsigned int size = 0;
|
||||
auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM DestructibleComponent");
|
||||
while (!tableSize.eof()) {
|
||||
size = tableSize.getIntField(0, 0);
|
||||
|
||||
tableSize.nextRow();
|
||||
}
|
||||
|
||||
tableSize.finalize();
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDDestructibleComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.faction = tableData.getIntField(1, -1);
|
||||
entry.factionList = tableData.getStringField(2, "");
|
||||
entry.life = tableData.getIntField(3, -1);
|
||||
entry.imagination = tableData.getIntField(4, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(5, -1);
|
||||
entry.CurrencyIndex = tableData.getIntField(6, -1);
|
||||
entry.level = tableData.getIntField(7, -1);
|
||||
entry.armor = tableData.getFloatField(8, -1.0f);
|
||||
entry.death_behavior = tableData.getIntField(9, -1);
|
||||
entry.isnpc = tableData.getIntField(10, -1) == 1 ? true : false;
|
||||
entry.attack_priority = tableData.getIntField(11, -1);
|
||||
entry.isSmashable = tableData.getIntField(12, -1) == 1 ? true : false;
|
||||
entry.difficultyLevel = tableData.getIntField(13, -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
// Reserve the size
|
||||
this->entries.reserve(size);
|
||||
|
||||
// Now get the data
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDDestructibleComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.faction = tableData.getIntField(1, -1);
|
||||
entry.factionList = tableData.getStringField(2, "");
|
||||
entry.life = tableData.getIntField(3, -1);
|
||||
entry.imagination = tableData.getIntField(4, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(5, -1);
|
||||
entry.CurrencyIndex = tableData.getIntField(6, -1);
|
||||
entry.level = tableData.getIntField(7, -1);
|
||||
entry.armor = tableData.getFloatField(8, -1.0f);
|
||||
entry.death_behavior = tableData.getIntField(9, -1);
|
||||
entry.isnpc = tableData.getIntField(10, -1) == 1 ? true : false;
|
||||
entry.attack_priority = tableData.getIntField(11, -1);
|
||||
entry.isSmashable = tableData.getIntField(12, -1) == 1 ? true : false;
|
||||
entry.difficultyLevel = tableData.getIntField(13, -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
CDDestructibleComponentTable::~CDDestructibleComponentTable(void) { }
|
||||
CDDestructibleComponentTable::~CDDestructibleComponentTable(void) {}
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDDestructibleComponentTable::GetName(void) const {
|
||||
return "DestructibleComponent";
|
||||
return "DestructibleComponent";
|
||||
}
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::function<bool(CDDestructibleComponent)> predicate) {
|
||||
|
||||
std::vector<CDDestructibleComponent> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
|
||||
std::vector<CDDestructibleComponent> data = cpplinq::from(this->entries)
|
||||
>> cpplinq::where(predicate)
|
||||
>> cpplinq::to_vector();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//! Gets all the entries in the table
|
||||
std::vector<CDDestructibleComponent> CDDestructibleComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
@@ -8,53 +8,53 @@
|
||||
\brief Contains data for the DestructibleComponent table
|
||||
*/
|
||||
|
||||
//! ItemComponent Struct
|
||||
//! ItemComponent Struct
|
||||
struct CDDestructibleComponent {
|
||||
unsigned int id; //!< The component ID from the ComponentsRegistry Table
|
||||
int faction; //!< The Faction ID of the object
|
||||
std::string factionList; //!< A list of the faction IDs
|
||||
int life; //!< The amount of life of the object
|
||||
unsigned int imagination; //!< The amount of imagination of the object
|
||||
int LootMatrixIndex; //!< The Loot Matrix Index
|
||||
int CurrencyIndex; //!< The Currency Index
|
||||
unsigned int level; //!< ???
|
||||
float armor; //!< The amount of armor of the object
|
||||
unsigned int death_behavior; //!< The behavior ID of the death behavior
|
||||
bool isnpc; //!< Whether or not the object is an NPC
|
||||
unsigned int attack_priority; //!< ???
|
||||
bool isSmashable; //!< Whether or not the object is smashable
|
||||
int difficultyLevel; //!< ???
|
||||
unsigned int id; //!< The component ID from the ComponentsRegistry Table
|
||||
int faction; //!< The Faction ID of the object
|
||||
std::string factionList; //!< A list of the faction IDs
|
||||
int life; //!< The amount of life of the object
|
||||
unsigned int imagination; //!< The amount of imagination of the object
|
||||
int LootMatrixIndex; //!< The Loot Matrix Index
|
||||
int CurrencyIndex; //!< The Currency Index
|
||||
unsigned int level; //!< ???
|
||||
float armor; //!< The amount of armor of the object
|
||||
unsigned int death_behavior; //!< The behavior ID of the death behavior
|
||||
bool isnpc; //!< Whether or not the object is an NPC
|
||||
unsigned int attack_priority; //!< ???
|
||||
bool isSmashable; //!< Whether or not the object is smashable
|
||||
int difficultyLevel; //!< ???
|
||||
};
|
||||
|
||||
//! ItemComponent table
|
||||
class CDDestructibleComponentTable : public CDTable {
|
||||
private:
|
||||
std::vector<CDDestructibleComponent> entries;
|
||||
|
||||
std::vector<CDDestructibleComponent> entries;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CDDestructibleComponentTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDDestructibleComponentTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDDestructibleComponent> GetEntries(void) const;
|
||||
|
||||
|
||||
//! Constructor
|
||||
CDDestructibleComponentTable(void);
|
||||
|
||||
//! Destructor
|
||||
~CDDestructibleComponentTable(void);
|
||||
|
||||
//! Returns the table's name
|
||||
/*!
|
||||
\return The table name
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
//! Queries the table with a custom "where" clause
|
||||
/*!
|
||||
\param predicate The predicate
|
||||
*/
|
||||
std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate);
|
||||
|
||||
//! Gets all the entries in the table
|
||||
/*!
|
||||
\return The entries
|
||||
*/
|
||||
std::vector<CDDestructibleComponent> GetEntries(void) const;
|
||||
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user