Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
220e010193 | ||
|
|
865888824c | ||
|
|
583df110fd | ||
|
|
f204bd693e | ||
|
|
b6be1ca045 | ||
|
|
beb403a9f7 | ||
|
|
00f1187200 | ||
|
|
7ee490cc1b | ||
|
|
3dc0ae7a47 | ||
|
|
994a8b5c4a | ||
|
|
5cd2e7affe | ||
|
|
f29ffe4cd2 | ||
|
|
6c7d2ab3ad | ||
|
|
ab7b20871a | ||
|
|
6883418e22 | ||
|
|
32f7266a5f | ||
|
|
35db76e9cd | ||
|
|
4f6aa87b9f | ||
|
|
f5816e20dd | ||
|
|
e72ae59e49 | ||
|
|
f0c2fd82ca | ||
|
|
5a588c8268 | ||
|
|
2adc030d6f | ||
|
|
b0ca8ed2b7 | ||
|
|
f9d5c861ce | ||
|
|
9aaaa71ce9 | ||
|
|
73a971bde3 | ||
|
|
5942eb7b15 | ||
|
|
b97fea1841 | ||
|
|
33637229d6 | ||
|
|
af366fcdb2 | ||
|
|
c9089c5d51 | ||
|
|
3afc6a2da9 | ||
|
|
12d22e78bf | ||
|
|
bcf969e56f | ||
|
|
b3a95c0310 | ||
|
|
ae863ab6e4 | ||
|
|
688ca4e31d | ||
|
|
724b6dddd6 | ||
|
|
bf3b30eb2c | ||
|
|
4f0545dfc1 | ||
|
|
c1b9a81e12 | ||
|
|
029b6ed691 | ||
|
|
4fdefca33d | ||
|
|
e90ca145be | ||
|
|
bf3d3c308d | ||
|
|
bee2f3c6ef | ||
|
|
d4e13e4578 | ||
|
|
66486b019f | ||
|
|
6510204fe6 | ||
|
|
b4b736c0c4 | ||
|
|
c4e8c5811c | ||
|
|
804b2fc610 | ||
|
|
0a7487a144 | ||
|
|
4ae9de0628 | ||
|
|
04d0f717d8 | ||
|
|
b3ddda78a1 | ||
|
|
066e74be5f | ||
|
|
f9c2cf8e31 | ||
|
|
d3fc625299 | ||
|
|
905763b6e3 | ||
|
|
877b7bc217 | ||
|
|
d8b7f6a8de | ||
|
|
579d3b529f | ||
|
|
065a79adc3 | ||
|
|
5ed45ef414 | ||
|
|
ba671b3370 | ||
|
|
e975f20a6b | ||
|
|
70bdebd4a0 | ||
|
|
409078801e | ||
|
|
06fed7de52 | ||
|
|
da2428a9f9 | ||
|
|
83b6ae5229 | ||
|
|
4b7804cdfd | ||
|
|
d075b5212f | ||
|
|
636c8ce219 | ||
|
|
091d7fa3ec | ||
|
|
59356e5b52 | ||
|
|
882bf29e63 | ||
|
|
f3eef4dd6b | ||
|
|
898983c6e5 | ||
|
|
dae5d032fa | ||
|
|
ff76622796 | ||
|
|
a6fd11a243 | ||
|
|
cf983be44c | ||
|
|
1a72de0e85 | ||
|
|
bf70a1e80e | ||
|
|
512d797d4d | ||
|
|
4a46dd1dde | ||
|
|
7494cdc071 | ||
|
|
608184ef9e | ||
|
|
eb4d8a9b68 | ||
|
|
6b92ae383c | ||
|
|
5fee857c4a | ||
|
|
53b7139c30 | ||
|
|
83e864d667 | ||
|
|
b88297e6de | ||
|
|
4aa2f46011 | ||
|
|
1fb3c757e2 | ||
|
|
3f640b6c14 | ||
|
|
49eb57af00 | ||
|
|
6bd6a80e71 | ||
|
|
38b84f0fa5 | ||
|
|
1f46debd0c | ||
|
|
37998e76d1 | ||
|
|
80b5508533 | ||
|
|
a646cc8227 | ||
|
|
92692adf52 | ||
|
|
b2cfc2b99b | ||
|
|
86e08f6151 | ||
|
|
8d852eb2d1 | ||
|
|
8bef018911 | ||
|
|
5e13419c28 | ||
|
|
503a7ae18f | ||
|
|
dfb9638a38 | ||
|
|
8452b0675b | ||
|
|
930643706a | ||
|
|
a2eac1f721 | ||
|
|
6e994cd694 | ||
|
|
c82869c631 | ||
|
|
f5a94868c4 | ||
|
|
c5628d613b | ||
|
|
9509b1ffa8 | ||
|
|
c1dac8a21e | ||
|
|
950846df45 | ||
|
|
31d96e2dc6 | ||
|
|
031e96075e | ||
|
|
bf2caeac6c | ||
|
|
12e523b37e | ||
|
|
576c985d8f | ||
|
|
9365807f47 | ||
|
|
25ce10fa61 | ||
|
|
09c333501f | ||
|
|
c51b09ee3a | ||
|
|
4d82eace86 | ||
|
|
385b03a163 | ||
|
|
4b438afa69 | ||
|
|
66961b94da | ||
|
|
39b62e5942 | ||
|
|
5bb8ab3d95 | ||
|
|
8dfc23b61d | ||
|
|
c8769808b5 | ||
|
|
2fc106aa26 | ||
|
|
da0b725ff8 | ||
|
|
15703d66fb | ||
|
|
c68beeaa51 | ||
|
|
5ef8868916 | ||
|
|
24488cc985 | ||
|
|
1c9faaa1e6 | ||
|
|
ac32875b14 | ||
|
|
07c1dd29e0 | ||
|
|
bd93233c34 | ||
|
|
20aec2fbcf | ||
|
|
a149139143 | ||
|
|
c857d1abb7 | ||
|
|
dde9da7006 | ||
|
|
d18a1970e5 | ||
|
|
66b9aeec17 | ||
|
|
ea301a3923 | ||
|
|
ced272a783 | ||
|
|
c9f320da31 | ||
|
|
025873e66b | ||
|
|
ecddc40aa5 | ||
|
|
cb13a02b75 | ||
|
|
5714a9a1d3 | ||
|
|
d0671c1682 | ||
|
|
88b3ac42bb | ||
|
|
4ecf3dec76 | ||
|
|
b4b70ca7e5 | ||
|
|
d3aa68df05 | ||
|
|
36aa0518ed | ||
|
|
b1c5692322 | ||
|
|
db24edf7d5 | ||
|
|
798a576d0b | ||
|
|
b49225fbf7 | ||
|
|
439cf82fcc | ||
|
|
7527bf4761 | ||
|
|
a9abda9ae9 | ||
|
|
757186d77b | ||
|
|
3e769c885c | ||
|
|
af4d73a0d5 | ||
|
|
331c38cc98 | ||
|
|
fbd1a7f5dc | ||
|
|
675025c0ec | ||
|
|
3e1efe4c4c | ||
|
|
679e76a5f6 | ||
|
|
5a338cdba1 | ||
|
|
3ef973ffc5 | ||
|
|
d36c3f4f77 | ||
|
|
79bd0c3304 | ||
|
|
721abfe3a5 | ||
|
|
77a5d61861 | ||
|
|
34aee2290c | ||
|
|
4b93157816 | ||
|
|
d66b01c681 | ||
|
|
939dfc2c9b | ||
|
|
1578c4c77d | ||
|
|
640a4fa47c | ||
|
|
3d50b65ad9 | ||
|
|
3f9eef9538 | ||
|
|
f655f519d0 | ||
|
|
59add35703 | ||
|
|
0ff21e70b5 | ||
|
|
cfc97e602e | ||
|
|
4661b8c856 | ||
|
|
e955153d53 | ||
|
|
911dcb99ec | ||
|
|
40ff829c72 | ||
|
|
729f3485de | ||
|
|
84db868244 | ||
|
|
126a9af2ac | ||
|
|
c9dc33d285 | ||
|
|
49ee1d1d57 | ||
|
|
1a477068fb | ||
|
|
d633830f7a | ||
|
|
b2bc616e18 | ||
|
|
934f8ba4d7 | ||
|
|
477616ce38 | ||
|
|
f66d0e5cd7 | ||
|
|
2bb6de1198 | ||
|
|
6570d71234 | ||
|
|
64c7da70e7 | ||
|
|
a2eadf5a78 | ||
|
|
7fb040ac1a | ||
|
|
b575274680 | ||
|
|
8bfe3583b9 | ||
|
|
ab3882e1d4 | ||
|
|
0cbb9fd1a4 | ||
|
|
115a597038 | ||
|
|
a8fde271ea | ||
|
|
b0143bb5bf | ||
|
|
025af5eae0 | ||
|
|
ce16f87e12 | ||
|
|
b47084f61f | ||
|
|
936e3581b4 | ||
|
|
cc756842c4 | ||
|
|
9aa29685ef | ||
|
|
c1bb45fe14 | ||
|
|
928555b36e | ||
|
|
744d516932 | ||
|
|
8721c80a9f | ||
|
|
06698a54e1 | ||
|
|
7f48b54b73 | ||
|
|
cf619ebeee | ||
|
|
9fdc6c2e1b | ||
|
|
1d309816ba | ||
|
|
21aa248d49 | ||
|
|
90c8e49808 | ||
|
|
2326850538 | ||
|
|
cef0cb1076 | ||
|
|
9b34e51494 | ||
|
|
61dc1e2c2d | ||
|
|
2458782c73 | ||
|
|
0f05d63a3b | ||
|
|
b82f7dea3d | ||
|
|
6df626afd3 | ||
|
|
ac2d2a530a | ||
|
|
99a0590c7e | ||
|
|
58c98bbbfa | ||
|
|
9560b9c202 | ||
|
|
24ebe429cc | ||
|
|
8ef92d0c1b | ||
|
|
e3e122edc4 | ||
|
|
ab0e51feac | ||
|
|
c6c981f4aa | ||
|
|
cc82c5b420 | ||
|
|
0f15a3840e | ||
|
|
f9781363ff | ||
|
|
ea5e7c7eb9 | ||
|
|
25a4a54e52 | ||
|
|
abd6668a7a | ||
|
|
a98e95a49c | ||
|
|
d3d24f2ce6 | ||
|
|
a9386ea275 | ||
|
|
773bf2c255 | ||
|
|
71d58dd99a | ||
|
|
ec8cc14aa6 | ||
|
|
cab3ca0916 | ||
|
|
e59217bd10 | ||
|
|
26e43c519e | ||
|
|
b827ad446d | ||
|
|
8bd0dc7852 | ||
|
|
3f7c8fe3ea | ||
|
|
ee8dc65b2a | ||
|
|
d7a2decf32 | ||
|
|
5620f091bb | ||
|
|
c6040446db | ||
|
|
9a13c50e91 | ||
|
|
07e6ab324f | ||
|
|
ea063159f0 | ||
|
|
1de5322a00 | ||
|
|
2416347bea | ||
|
|
b4418c040c | ||
|
|
3080050c4d | ||
|
|
213851335a | ||
|
|
80daadff47 | ||
|
|
f3daad5c28 | ||
|
|
af624557c8 | ||
|
|
4bd41aa135 | ||
|
|
724b26aab4 | ||
|
|
f165fd968f | ||
|
|
9df60774a7 | ||
|
|
626d6e786f | ||
|
|
c4d928bbd7 | ||
|
|
1141e9f7a1 | ||
|
|
cfa478067e | ||
|
|
a36d926460 | ||
|
|
1ba9eb3613 | ||
|
|
58fd90d33d | ||
|
|
8f7b7df124 | ||
|
|
8e17e99428 | ||
|
|
284417ef50 | ||
|
|
9ceb26307e | ||
|
|
11bb0c6fa1 | ||
|
|
dd8bad7480 | ||
|
|
e10619813a | ||
|
|
24e9d9f83c | ||
|
|
5efbe8e8bf | ||
|
|
176b986c47 | ||
|
|
a2266e5bbe | ||
|
|
0ad6ffdd3c | ||
|
|
0f3b3f9ee6 | ||
|
|
5d6435cf40 | ||
|
|
ba8ad02289 | ||
|
|
7546a509da | ||
|
|
baecbbcb31 | ||
|
|
6bba40ff1c | ||
|
|
8a03dd8131 | ||
|
|
241a659f35 | ||
|
|
5afc874eed | ||
|
|
add5e8968e | ||
|
|
5e4c70edce | ||
|
|
1aa6d9ca93 | ||
|
|
ce018fe6a0 | ||
|
|
88e0ccf20e | ||
|
|
99226aadbd | ||
|
|
ea0ad14374 | ||
|
|
a6f133e058 | ||
|
|
bb52d2c6d5 | ||
|
|
96703690e6 | ||
|
|
b761928654 | ||
|
|
d50a291366 | ||
|
|
0fae292946 | ||
|
|
63e27c2700 | ||
|
|
e824a22ae6 | ||
|
|
0bf35a7b8d | ||
|
|
08d3e8d278 | ||
|
|
ed7d596f12 | ||
|
|
0186de26c2 | ||
|
|
3c9cc5fa8e | ||
|
|
b1aa0019b2 | ||
|
|
34a2aca45e | ||
|
|
6bbeba1612 | ||
|
|
99f0612209 | ||
|
|
d8e5998f21 | ||
|
|
513d4d7996 | ||
|
|
cf5d619d34 | ||
|
|
fc59b51558 | ||
|
|
c839c9eadd | ||
|
|
5456431dd4 | ||
|
|
08949370e6 | ||
|
|
033a428184 | ||
|
|
1a6dd8a259 | ||
|
|
4307a90333 | ||
|
|
7267264503 | ||
|
|
2fb475ae95 | ||
|
|
b780b71e5e | ||
|
|
5d02ecdf94 | ||
|
|
f8c1a95b63 | ||
|
|
95a8b313e5 | ||
|
|
1bc6bdbbce | ||
|
|
3293478dd7 | ||
|
|
ba2b8b44d3 | ||
|
|
f7b213a677 | ||
|
|
a49792adf5 | ||
|
|
1b272e5849 | ||
|
|
6bacce6cec | ||
|
|
6f533d23c6 | ||
|
|
c367100e6b | ||
|
|
e8b105fa90 | ||
|
|
7c4f902dbd | ||
|
|
4d59a54ad0 | ||
|
|
dbd1310eb3 | ||
|
|
52415c5561 | ||
|
|
ed87abaaaa | ||
|
|
89174178c6 | ||
|
|
d6aca1d2a1 | ||
|
|
898ebab6d8 | ||
|
|
a62f0aa6f3 | ||
|
|
55168e24db | ||
|
|
d7023ae81b | ||
|
|
c81fab62e6 | ||
|
|
fcfce6f2ea | ||
|
|
14091f142d | ||
|
|
67412b082f | ||
|
|
23b903e2f2 | ||
|
|
03c4874a50 | ||
|
|
83be327bd3 | ||
|
|
4e14655f45 | ||
|
|
8e8a295200 | ||
|
|
458840a0d7 | ||
|
|
0480260a56 | ||
|
|
ae9c6c7a48 | ||
|
|
3ff3d44d35 | ||
|
|
c243d518a9 | ||
|
|
ec951738b5 | ||
|
|
04a82c4a63 | ||
|
|
53ec8e5b60 | ||
|
|
1f3d39f4b1 | ||
|
|
fb9765304c | ||
|
|
555893d287 | ||
|
|
e0104d99f9 | ||
|
|
16a9a0ccd0 | ||
|
|
e848ecf9bc | ||
|
|
949e531448 | ||
|
|
f4afd451ab | ||
|
|
d5a8e3f7b4 | ||
|
|
fcb7870a38 | ||
|
|
46a215bd2c | ||
|
|
d9ff81131c | ||
|
|
c18c915dd2 | ||
|
|
29ef00f24e | ||
|
|
76c2857d48 | ||
|
|
2f25863578 | ||
|
|
85a787993c | ||
|
|
406ffd10db | ||
|
|
67ab24570e | ||
|
|
0247cfef9e | ||
|
|
44a7c4d000 | ||
|
|
3a0eb3bea1 | ||
|
|
ce0265c7e7 | ||
|
|
c1694ec6e2 | ||
|
|
a5a56e59c7 | ||
|
|
9d23bf934e | ||
|
|
9221a87812 | ||
|
|
6dc762f47f | ||
|
|
5c6889fbd5 | ||
|
|
7ffb8fb43b | ||
|
|
9440352e56 | ||
|
|
f8282eff7e | ||
|
|
dd106434ce | ||
|
|
6ca8108f1e | ||
|
|
451b5db941 | ||
|
|
76fb5cee72 | ||
|
|
c659a54158 | ||
|
|
22b1fa2b0e | ||
|
|
63d2f2dd69 | ||
|
|
ec6ec09cee | ||
|
|
96fb6301a8 | ||
|
|
46d27e3bea | ||
|
|
e5c46e7a55 | ||
|
|
b0095aa3fd | ||
|
|
a2e51b2c31 | ||
|
|
44fecb3b5a | ||
|
|
97f57a9322 | ||
|
|
8688a9d098 | ||
|
|
e2bcd3aac7 | ||
|
|
80c9448c71 | ||
|
|
b7207e2c2b | ||
|
|
065ad04699 | ||
|
|
725220a99b | ||
|
|
ab282cea23 | ||
|
|
324721e155 | ||
|
|
42dca4a42e | ||
|
|
e42e1257c9 | ||
|
|
2b9a21d475 | ||
|
|
9e6cfe4002 | ||
|
|
3351b92ea6 | ||
|
|
a946357ea3 | ||
|
|
f4120433d9 | ||
|
|
25f9bdd9b6 | ||
|
|
a0a758949e | ||
|
|
5125132f23 | ||
|
|
5206cc3df7 | ||
|
|
65faa69852 | ||
|
|
83dc0f99b6 | ||
|
|
edc2515caa | ||
|
|
be8a2f4ca4 | ||
|
|
0bf059afcf | ||
|
|
47c76fafc1 | ||
|
|
3ebb9c7d48 | ||
|
|
e68c5ce4b0 | ||
|
|
0fc231909c | ||
|
|
fde2a77aae | ||
|
|
6d4f076969 | ||
|
|
6f2796f851 | ||
|
|
478ec61cb0 | ||
|
|
667505b13a | ||
|
|
4f810fc7fd | ||
|
|
dab5efea30 | ||
|
|
5823bdae46 | ||
|
|
139db5e5b8 | ||
|
|
4e9e7a8bc1 | ||
|
|
7b57f04db9 | ||
|
|
42bd234c76 | ||
|
|
59af0f34ec | ||
|
|
57aaac8a8f | ||
|
|
dd41de430e | ||
|
|
ae43010da3 | ||
|
|
00d7480e9b | ||
|
|
687c66d7ec | ||
|
|
997da1f497 | ||
|
|
f2011e5032 | ||
|
|
dbefe8e33a | ||
|
|
a279863e80 | ||
|
|
f85d45f796 | ||
|
|
47101ca894 | ||
|
|
4db4663274 | ||
|
|
fdf5a83386 | ||
|
|
3bbec46585 | ||
|
|
92f4492fc3 | ||
|
|
04fdb31ef6 | ||
|
|
64694a4409 | ||
|
|
2257ae6919 | ||
|
|
579cdafb77 | ||
|
|
fae67394a3 | ||
|
|
b020580a40 | ||
|
|
f21f0ba54d | ||
|
|
9b911339d7 | ||
|
|
609cd5c8f8 | ||
|
|
127894b2f9 | ||
|
|
b7f3e1beba | ||
|
|
a7d476589a | ||
|
|
e23ac97e8e | ||
|
|
db31f77f9b | ||
|
|
6eb635f437 | ||
|
|
a308780acd | ||
|
|
91ca7fd1c2 | ||
|
|
0655f20543 | ||
|
|
4167861071 | ||
|
|
c19f15ae14 | ||
|
|
d684726ea7 | ||
|
|
12b2819e45 | ||
|
|
d2d77eb608 | ||
|
|
fdcc0f810b | ||
|
|
c2655df12d | ||
|
|
b6949ead26 | ||
|
|
f75e140ddf | ||
|
|
30da8c043d | ||
|
|
74edc3031f | ||
|
|
723a1caf05 | ||
|
|
745f36bea3 | ||
|
|
2bb362825d | ||
|
|
01cef587ec | ||
|
|
539427ddd2 | ||
|
|
798fe1e171 | ||
|
|
3ff03ef50e | ||
|
|
8a7175b011 | ||
|
|
2adee4054c | ||
|
|
4483e554e9 | ||
|
|
4d15d92e46 | ||
|
|
c29249a7de | ||
|
|
f8f1e83986 | ||
|
|
03f103bcff | ||
|
|
0b4c812e43 | ||
|
|
a1dd613232 | ||
|
|
f5d74d8d0e | ||
|
|
19a200707b | ||
|
|
a156a1d084 | ||
|
|
4236bc2af5 | ||
|
|
36c09c02ab | ||
|
|
5c9d0808dd | ||
|
|
6821548d50 | ||
|
|
a198247d13 | ||
|
|
255eed49a7 | ||
|
|
6cdcee0c58 | ||
|
|
96df597507 | ||
|
|
5054c72b32 | ||
|
|
16ee560f4c | ||
|
|
73bce495e1 | ||
|
|
25bb6f50a5 | ||
|
|
fdce1bbc59 | ||
|
|
48afd160d5 | ||
|
|
c48534b0ba | ||
|
|
e81f8ff96c | ||
|
|
2d9f93bdf8 | ||
|
|
65ba222b89 | ||
|
|
1d89578ab5 | ||
|
|
852a87a516 | ||
|
|
8aa4a77c4a | ||
|
|
d72b2611d7 | ||
|
|
4ea5d290c7 | ||
|
|
3e27beb825 | ||
|
|
526bcc61cf | ||
|
|
0e7cbd76aa | ||
|
|
e2aa30d139 | ||
|
|
99fea68bb8 | ||
|
|
682e905c49 | ||
|
|
ff4c5dff3b | ||
|
|
acc00863a4 | ||
|
|
94d5afbff7 | ||
|
|
191387f42d | ||
|
|
bdaac34a33 | ||
|
|
94475d2b04 | ||
|
|
f25af642b0 | ||
|
|
c5b7fd52c5 | ||
|
|
f460d6a230 | ||
|
|
504ac3055e | ||
|
|
1bc4ff4581 | ||
|
|
8bfe79ae87 | ||
|
|
1f12a9e529 | ||
|
|
a309361a2e | ||
|
|
abef299633 | ||
|
|
2c291fc1fc | ||
|
|
1c64186a00 | ||
|
|
07093ab0cb | ||
|
|
43b73501d7 | ||
|
|
e3c4360b62 | ||
|
|
01e7465f0c | ||
|
|
6f7011c9f2 | ||
|
|
716c9ac0a0 | ||
|
|
e295fcf9f2 | ||
|
|
60c28f1ecb | ||
|
|
9b164019ec | ||
|
|
e777c54414 | ||
|
|
97ddd1cd8b | ||
|
|
ebdee0bb44 | ||
|
|
d4f977c0af | ||
|
|
aed1a80532 | ||
|
|
e7f26e402b | ||
|
|
d7d97a74d8 | ||
|
|
964efd341e | ||
|
|
03ae299e36 | ||
|
|
a7b8c07d1a | ||
|
|
4162aae3a0 | ||
|
|
8b3f158a43 | ||
|
|
aac5b37485 | ||
|
|
731c7859ce | ||
|
|
953e038223 | ||
|
|
8be6e1e86b | ||
|
|
1f1bfff4f7 | ||
|
|
4512eeff23 | ||
|
|
e7ba2aee8e | ||
|
|
4ae6893f81 | ||
|
|
1592a0676c | ||
|
|
7666a1634a | ||
|
|
63d106e414 | ||
|
|
8481fada93 | ||
|
|
933763486c | ||
|
|
c90893d817 | ||
|
|
aea4f3709a | ||
|
|
46fcdc0894 | ||
|
|
1d75a25aa3 | ||
|
|
0786de54b2 | ||
|
|
ac8a11fefa | ||
|
|
081631242f | ||
|
|
3f0ab75efb | ||
|
|
12a3c65c9b | ||
|
|
480e36579c | ||
|
|
2c43c74fe3 | ||
|
|
4029ddd2b1 | ||
|
|
0f41c9ea08 | ||
|
|
a146ffb30e | ||
|
|
ac93f04dde | ||
|
|
c36ebc648b | ||
|
|
dd61be59b3 | ||
|
|
ac2086a0e0 | ||
|
|
ea043bc743 | ||
|
|
3dce95cc50 | ||
|
|
1ad5f4aef9 | ||
|
|
db7a597bcc | ||
|
|
d3116dc685 | ||
|
|
9bf909b4db | ||
|
|
be42cfaae1 | ||
|
|
4e2a0dbf28 | ||
|
|
8aa683452a | ||
|
|
642fa4a4aa | ||
|
|
686c5f4c65 | ||
|
|
43f56a8f39 | ||
|
|
68a4093e1a | ||
|
|
631049877e | ||
|
|
7b97855a3b | ||
|
|
08b5cd8333 | ||
|
|
e812efd6b7 | ||
|
|
dfd985da95 | ||
|
|
1831560bd6 | ||
|
|
f7e8da93d8 | ||
|
|
57586ce7c0 | ||
|
|
633365672c | ||
|
|
32244e9482 | ||
|
|
012e0687a8 | ||
|
|
1c6cbd5d30 | ||
|
|
3100d835df | ||
|
|
da94a6a014 | ||
|
|
2640a5354c | ||
|
|
57d9eeef64 | ||
|
|
0bfdc88e21 | ||
|
|
0e0afe7c9b | ||
|
|
c76db85ae7 | ||
|
|
2b554ca475 | ||
|
|
b58cd086ea | ||
|
|
968e021711 | ||
|
|
105a06537c | ||
|
|
5d02239dc1 | ||
|
|
5b254cfe75 | ||
|
|
a54b122094 | ||
|
|
1e04292ba2 | ||
|
|
1c2fe8c8fe | ||
|
|
a53772f094 | ||
|
|
e6bb883334 | ||
|
|
a9f53a4a95 | ||
|
|
d65886343b | ||
|
|
81a447dce9 | ||
|
|
12ed805737 | ||
|
|
c62f549176 | ||
|
|
296af8b4f6 | ||
|
|
3355e7c334 | ||
|
|
c727ee87d3 | ||
|
|
c28673b83b | ||
|
|
5ca48ddd73 | ||
|
|
8df43991a6 | ||
|
|
558b4a4c64 | ||
|
|
b6239b3c5c | ||
|
|
3ac692a7c7 | ||
|
|
9a7e643742 | ||
|
|
18fa8f4baf | ||
|
|
38746ad0dd | ||
|
|
40de41adc8 | ||
|
|
9c62e3d05c | ||
|
|
2bc5df8703 | ||
|
|
7508275cf7 | ||
|
|
8e43f75f70 | ||
|
|
b51b3214ba | ||
|
|
b7dec8f65e | ||
|
|
ccdb50e760 | ||
|
|
e136caef91 | ||
|
|
502deb840b | ||
|
|
3e89bc5d2c | ||
|
|
b1850e1dfe | ||
|
|
03c0097641 | ||
|
|
0c5f0f293f | ||
|
|
90998c447b | ||
|
|
81a1d8d2b2 | ||
|
|
cf67d5ac52 | ||
|
|
912a88ec0a | ||
|
|
8215e89d77 | ||
|
|
ac419adbd6 | ||
|
|
ac5a4daa6f | ||
|
|
4d637a349b | ||
|
|
d664227436 | ||
|
|
5efad350d8 | ||
|
|
4790325f0e | ||
|
|
181303b58b | ||
|
|
55ea2d7c12 | ||
|
|
40f2d87434 | ||
|
|
36daf153db | ||
|
|
8b7458a6c4 | ||
|
|
3c614910e5 | ||
|
|
807debb622 | ||
|
|
bc6525e431 | ||
|
|
32b6b9b1da | ||
|
|
8cc588d766 | ||
|
|
29fd6d03b9 | ||
|
|
81100e13b4 | ||
|
|
3085ee54d8 | ||
|
|
fedd2965cc | ||
|
|
7886bf7103 | ||
|
|
6a4aa28489 | ||
|
|
486b4fe8ba | ||
|
|
3d2e69cc21 | ||
|
|
ed9d91e527 | ||
|
|
1ef2a4fd3c | ||
|
|
2dd18c2b70 | ||
|
|
eec4dc1779 | ||
|
|
8fceb20a9e | ||
|
|
d622adb4ef | ||
|
|
693a9a454f | ||
|
|
0c4f7fa393 | ||
|
|
d5399995c3 | ||
|
|
e41e55f5aa | ||
|
|
04303eda75 | ||
|
|
4bf2f60f42 | ||
|
|
b5b16b5dff | ||
|
|
5f003ccb05 | ||
|
|
d396edad12 | ||
|
|
4bcecd5aa3 | ||
|
|
cad1165071 | ||
|
|
d24f14a8f2 | ||
|
|
9fec341589 | ||
|
|
dbe9c7bcaa | ||
|
|
5029da8763 | ||
|
|
ae734ded8e | ||
|
|
ed6ad315d1 | ||
|
|
1e7f6d98e7 | ||
|
|
1b77e43b61 | ||
|
|
7dab8a367f | ||
|
|
f44283d5f0 | ||
|
|
0b883d1f9a | ||
|
|
48031dd6da | ||
|
|
f32c8f5fe6 | ||
|
|
9b75a6a0a9 | ||
|
|
cd908f7e44 | ||
|
|
4e8f72a34b | ||
|
|
6cadaebb0c | ||
|
|
efbfab7914 | ||
|
|
7bb02d9a2a | ||
|
|
1604c71c33 | ||
|
|
f5a3d57afd | ||
|
|
368100f77c | ||
|
|
04f6878696 | ||
|
|
62c5985a34 | ||
|
|
91505c9350 | ||
|
|
5487303095 | ||
|
|
5c7e2b357f | ||
|
|
d36de24349 | ||
|
|
a19af18a61 | ||
|
|
69c1219f2b | ||
|
|
8c14efb7d8 | ||
|
|
25b6413be1 | ||
|
|
dfa75e145f | ||
|
|
43f7223a15 | ||
|
|
3be2667844 | ||
|
|
43371d3068 | ||
|
|
aa94d47148 | ||
|
|
7b1db3e1db | ||
|
|
beb556c73c | ||
|
|
c7e82497dd | ||
|
|
ff93fcdc9c | ||
|
|
5b6d0ced6e | ||
|
|
a44d6b09a8 | ||
|
|
4c1f36cf67 | ||
|
|
5daf1362cc | ||
|
|
cf252da519 | ||
|
|
5f83465529 | ||
|
|
9c8e96df16 | ||
|
|
163858e47b | ||
|
|
571eaa1378 | ||
|
|
4a2b25e5cc | ||
|
|
71d811c031 | ||
|
|
8e891da49f | ||
|
|
4f65a59324 | ||
|
|
446c846572 | ||
|
|
f44518ff27 | ||
|
|
51627ea2f6 | ||
|
|
b280089225 | ||
|
|
db66f19109 | ||
|
|
6cb67eb6c8 | ||
|
|
16a5556fa3 | ||
|
|
6805cf89ee | ||
|
|
8c88567c78 | ||
|
|
f41f7dafb9 | ||
|
|
5a1cd97b71 | ||
|
|
80569d5dfe | ||
|
|
585bf7523e | ||
|
|
9ce9a6597f | ||
|
|
490c6a763d | ||
|
|
7325c8e7bc | ||
|
|
1cc1807aec | ||
|
|
810d8a1af8 | ||
|
|
e3b6391653 | ||
|
|
72f628888e | ||
|
|
371c740321 | ||
|
|
f438ef7f49 | ||
|
|
892eecfa2b | ||
|
|
9f9d01ec58 | ||
|
|
faf1abb896 | ||
|
|
fdf5b03983 | ||
|
|
9236def453 | ||
|
|
dbf86c9408 | ||
|
|
7fb9198373 | ||
|
|
02b23ef926 | ||
|
|
2cd6077287 | ||
|
|
191a94e19d | ||
|
|
ce1618cb52 | ||
|
|
608a72d3ac | ||
|
|
19dac6e32b | ||
|
|
635c87389d | ||
|
|
9a18739a7f | ||
|
|
c793ded63e | ||
|
|
0b5c95ee57 | ||
|
|
874141e13b | ||
|
|
165a0aebd5 | ||
|
|
1d25839f53 | ||
|
|
a7aba651b8 | ||
|
|
c96ce9d37e | ||
|
|
afd710fccc | ||
|
|
770b93d275 | ||
|
|
85872eec19 | ||
|
|
ef9af6edae | ||
|
|
b35eb9ec81 | ||
|
|
54c68a61c0 | ||
|
|
6ab413de68 | ||
|
|
7fb9d2d55a | ||
|
|
f45c0a76e1 | ||
|
|
46f9a38056 | ||
|
|
b7169271ac | ||
|
|
9effc1edb5 | ||
|
|
a697e77e6c | ||
|
|
db6d296c20 | ||
|
|
3e37df1275 | ||
|
|
76bdd00a18 | ||
|
|
a9404bdf31 | ||
|
|
cc4b3715c5 | ||
|
|
ea2daa688f | ||
|
|
4e32988661 | ||
|
|
767e2ba4b7 | ||
|
|
5e397ea6d9 | ||
|
|
ca99a00ac2 | ||
|
|
33bc23b4e1 | ||
|
|
67087a6a7e | ||
|
|
fae4685082 | ||
|
|
f7466fd968 | ||
|
|
56f122b8b9 | ||
|
|
709f6d7c4a | ||
|
|
573bf273ff | ||
|
|
6e1524817e | ||
|
|
f1e2aff331 | ||
|
|
e68a485e16 | ||
|
|
e08cf95135 | ||
|
|
9a7ec7fd62 | ||
|
|
05446ddf1a | ||
|
|
de642bf3e6 | ||
|
|
fc1ac5973f | ||
|
|
d8e432b4cf | ||
|
|
d8875dd8b9 | ||
|
|
560559fad2 | ||
|
|
b6554eb0ac | ||
|
|
fdbee3a21f | ||
|
|
28b7529516 | ||
|
|
96c63b5e6f | ||
|
|
89790291a5 | ||
|
|
bafcca4c58 | ||
|
|
74aaf603e2 | ||
|
|
c3224c2a5b | ||
|
|
68ac417f65 | ||
|
|
0c114d3dab | ||
|
|
ccc5ceb3b9 | ||
|
|
dc55ff4078 | ||
|
|
9daff2b738 | ||
|
|
f876ae49ad | ||
|
|
b644d560d8 | ||
|
|
8a3fa2956c | ||
|
|
67ed07549e | ||
|
|
58f6191a8e | ||
|
|
66ce5b6e0e | ||
|
|
5bfc73fafb | ||
|
|
8b48a82968 | ||
|
|
fd1df47fec | ||
|
|
14f14e20df | ||
|
|
4a7c90e5bc | ||
|
|
90cf8eabd8 | ||
|
|
e690f97c8d | ||
|
|
5860a5a027 | ||
|
|
5a362aa8f9 | ||
|
|
9e7f2b76f7 | ||
|
|
f0a8346ef4 | ||
|
|
a1fb2115cd | ||
|
|
0423dd32c4 | ||
|
|
ea98ccb8f1 | ||
|
|
44f51e5e60 | ||
|
|
f4ec180d85 | ||
|
|
4663fa507b | ||
|
|
f2410f962b | ||
|
|
ac2eb6dce0 | ||
|
|
b8af814940 | ||
|
|
5416a87149 | ||
|
|
7dece38b57 | ||
|
|
336c452ef3 | ||
|
|
78b3f1faf8 | ||
|
|
932d2fb4cb | ||
|
|
3deb903f3c | ||
|
|
867d78b650 | ||
|
|
c4ebd75008 | ||
|
|
92a76c9de1 | ||
|
|
d20940f110 | ||
|
|
a3f06f7e33 | ||
|
|
5f73cded22 | ||
|
|
e699d5ff2b | ||
|
|
3f4a5586de | ||
|
|
3ceabfabdd | ||
|
|
47d1f94a13 | ||
|
|
0602325974 | ||
|
|
1eb47dec6a | ||
|
|
d1a8a79525 | ||
|
|
53aa74b493 | ||
|
|
78eddadac4 | ||
|
|
db4b7ca192 | ||
|
|
092e30a552 | ||
|
|
059fd89b69 | ||
|
|
9a97b00750 | ||
|
|
443bf7ab85 | ||
|
|
1aecc3d922 | ||
|
|
75e67dcbd0 | ||
|
|
302f3a96ce | ||
|
|
8b8058dc47 | ||
|
|
f3ed351c61 | ||
|
|
6d3fbc4591 | ||
|
|
6519691e79 | ||
|
|
c150a89d13 | ||
|
|
29bdd2f8fb | ||
|
|
1cd044ffda | ||
|
|
a4ef26b1a6 | ||
|
|
dcaf90e394 | ||
|
|
e6098e0cf5 | ||
|
|
8822a7baf7 | ||
|
|
d60b4d7363 | ||
|
|
9dc457125e | ||
|
|
9d8e9df44e | ||
|
|
966e6399f6 | ||
|
|
bd1b804026 | ||
|
|
87ee72ad9d | ||
|
|
546117253d | ||
|
|
1a2dade994 | ||
|
|
8574299ed5 | ||
|
|
647773cd2e | ||
|
|
fc046003d5 | ||
|
|
d850262e6c | ||
|
|
94e0e3778e | ||
|
|
331244ddd2 | ||
|
|
0aad3cbbf3 | ||
|
|
34c668714a | ||
|
|
9fa667845e | ||
|
|
d388ae01bb | ||
|
|
d215ba8c8b | ||
|
|
a661a94d80 | ||
|
|
d7f2493811 | ||
|
|
6cc5b0edb9 | ||
|
|
8aad95525c | ||
|
|
ea4b5b057a | ||
|
|
8943445efa | ||
|
|
4195b0d62c | ||
|
|
a94cfe92d3 | ||
|
|
85d8f1c0d5 | ||
|
|
bf3fcadd28 | ||
|
|
715937a394 | ||
|
|
262b712d5b | ||
|
|
a8d60ab38a | ||
|
|
d271e23f99 | ||
|
|
65e3e77a59 | ||
|
|
c5b3bb05dd | ||
|
|
5267ef0fb7 | ||
|
|
56eea049e6 | ||
|
|
4baf407657 | ||
|
|
443682f24f | ||
|
|
f5f9b793c4 | ||
|
|
528c263930 | ||
|
|
50e1005b29 | ||
|
|
24845e6077 | ||
|
|
3ea9e3f6e0 | ||
|
|
fb39e64417 | ||
|
|
08506617b6 | ||
|
|
f6b044ebdd | ||
|
|
1bc2fe75ed | ||
|
|
bbe1acb143 | ||
|
|
4b836b441c | ||
|
|
c30e053ab1 | ||
|
|
fffa9afbfa | ||
|
|
d731fddaf1 | ||
|
|
9562f56a3a | ||
|
|
97dd07e1d4 | ||
|
|
155daa0335 | ||
|
|
aa79fe3145 | ||
|
|
b56d94d0bf | ||
|
|
a3d505dd97 | ||
|
|
72c8445693 | ||
|
|
5fe9554965 | ||
|
|
95107e1624 | ||
|
|
1e63652d32 | ||
|
|
6bde0e7c9b | ||
|
|
405f800908 | ||
|
|
62edfd19f9 | ||
|
|
176ebf9409 | ||
|
|
275d63de18 | ||
|
|
11c6c89c7d | ||
|
|
e6dba99aa8 | ||
|
|
5b4a45a487 | ||
|
|
aac84677e4 | ||
|
|
99148db07a | ||
|
|
e4e5e7c681 | ||
|
|
263b59dae2 | ||
|
|
5dbd71b565 | ||
|
|
7bcd437664 | ||
|
|
a599c38537 | ||
|
|
af79794300 | ||
|
|
acc1167fe1 | ||
|
|
fa5b953010 | ||
|
|
10081b3880 | ||
|
|
d944a0e7c6 | ||
|
|
0940ac84a0 | ||
|
|
cc45b87ebe | ||
|
|
1a66bc4645 | ||
|
|
359556909c | ||
|
|
2e4e060b46 | ||
|
|
c624c040b7 | ||
|
|
bae1987704 | ||
|
|
04f6150399 | ||
|
|
fe66116dde | ||
|
|
24282fe0ab | ||
|
|
26ff8070ac | ||
|
|
7040567aab | ||
|
|
d581db23f8 | ||
|
|
b792e3695d | ||
|
|
27c5d75871 | ||
|
|
f3e6b71e09 | ||
|
|
c83baae50d | ||
|
|
7314dbee73 | ||
|
|
2be0fd84fe | ||
|
|
0593b19d51 | ||
|
|
c0ebbb0b44 | ||
|
|
81a084984b | ||
|
|
5c5e640b04 | ||
|
|
aee85a7cb0 | ||
|
|
98f04859ab | ||
|
|
4fe7b6754c | ||
|
|
43d19e02a6 | ||
|
|
2c90b1386d | ||
|
|
b737cde803 | ||
|
|
9f3d7baf05 | ||
|
|
0e729b51bf | ||
|
|
5446d25528 | ||
|
|
43677cca89 | ||
|
|
dbe270539b | ||
|
|
e724a1ee9e | ||
|
|
161421a00c | ||
|
|
e40e19cd1e | ||
|
|
b7fc92e343 | ||
|
|
f343ce3094 | ||
|
|
d1b54eb8cf | ||
|
|
53f87a6e4f | ||
|
|
b0ef8114b6 | ||
|
|
d4ef81a7ef | ||
|
|
482ffe0c65 | ||
|
|
bd3c4cb40c | ||
|
|
8185811188 | ||
|
|
465d7123f6 | ||
|
|
d4e13e8543 | ||
|
|
c79f2d0a96 | ||
|
|
aa24b19d2b | ||
|
|
883ac4590c | ||
|
|
6e360bef93 | ||
|
|
5df734fcf7 | ||
|
|
bfb2b56599 | ||
|
|
08e12494ec | ||
|
|
d8ec0f2e94 | ||
|
|
665e60a646 | ||
|
|
90cfe1ac23 | ||
|
|
1afa7601c9 | ||
|
|
d22ec1cf7a | ||
|
|
fdc7f6237e | ||
|
|
17d2ab505c | ||
|
|
666cc29d47 | ||
|
|
0bbe719f16 | ||
|
|
c23147185e | ||
|
|
4191ea8a18 | ||
|
|
4358c4e64c | ||
|
|
97a2bd3854 | ||
|
|
7bba7c321b | ||
|
|
e6353b5d44 | ||
|
|
775acff846 | ||
|
|
cd771f1432 | ||
|
|
80eb7d7cea | ||
|
|
b8a15d9a5d | ||
|
|
6755723e0b | ||
|
|
17548eeff7 | ||
|
|
8a7db6ee15 | ||
|
|
4d2bf38a66 | ||
|
|
01bbbd3bda | ||
|
|
1897154cfd | ||
|
|
b5eb75d607 | ||
|
|
1ad5acef7c | ||
|
|
b0d9bc2d6a | ||
|
|
16ccfeda1d | ||
|
|
37ec617801 | ||
|
|
6be1f99cf9 | ||
|
|
3ba72cbad5 | ||
|
|
9624815c82 | ||
|
|
bbb9924c4b | ||
|
|
6da45fc139 | ||
|
|
e73a2a8b9e | ||
|
|
5163b094ae | ||
|
|
4ff6b2aeae | ||
|
|
56a178c786 | ||
|
|
c9dbf58737 | ||
|
|
95d276f7a0 | ||
|
|
a1448597af | ||
|
|
99e161b05b | ||
|
|
03ea5d4e3b | ||
|
|
adf41722f5 | ||
|
|
c69ff17048 | ||
|
|
ccbfe04988 | ||
|
|
b027e49f33 | ||
|
|
39f048910a | ||
|
|
df6140c282 | ||
|
|
7790ab1b53 | ||
|
|
ba155feb6c | ||
|
|
1d9e2ccad2 | ||
|
|
a7619e889b | ||
|
|
a6118b2942 | ||
|
|
373b9657c2 | ||
|
|
06c0eb3e87 | ||
|
|
3f0724d1dc | ||
|
|
a6f94cb0a3 | ||
|
|
5be2fa9cfe | ||
|
|
224bcc1721 | ||
|
|
33705c52e0 | ||
|
|
2c28c0b771 | ||
|
|
ffeb794303 | ||
|
|
06eb509bc3 | ||
|
|
6428d39ce5 | ||
|
|
7695c14598 | ||
|
|
d259d7c5e7 | ||
|
|
42311b2c54 | ||
|
|
a020d83c8a | ||
|
|
9639639420 | ||
|
|
d59f5b9473 | ||
|
|
7e3b6a841f | ||
|
|
ee3aab938a | ||
|
|
43ce8d6372 | ||
|
|
0ac76e3452 | ||
|
|
a50cabc572 | ||
|
|
072c4fef86 | ||
|
|
4226f4134f | ||
|
|
6c3deb392d | ||
|
|
e9adffec54 | ||
|
|
3ce82c5150 | ||
|
|
233a466dd6 | ||
|
|
527e045c69 | ||
|
|
bd3a1f6c4d | ||
|
|
215b85c407 | ||
|
|
f592db516f | ||
|
|
d9d2d13d0d | ||
|
|
e9bb34898b | ||
|
|
d596e41716 | ||
|
|
101a1060e7 | ||
|
|
f649ebff24 | ||
|
|
d4cc804624 | ||
|
|
56ad66c04f | ||
|
|
9a27304a9e | ||
|
|
a1b1417acb | ||
|
|
9603310b4e | ||
|
|
056ab10121 | ||
|
|
9cec0af484 | ||
|
|
1fa810362f | ||
|
|
817ca8e176 | ||
|
|
7a7c5cc53e | ||
|
|
49d1b2c948 | ||
|
|
2c18ee92c7 | ||
|
|
136b7e25c3 | ||
|
|
af8c0e3b9a | ||
|
|
f4162c2868 | ||
|
|
64e332f3d5 | ||
|
|
7bcaadf6ee | ||
|
|
56faccd2fc | ||
|
|
04478e77e1 | ||
|
|
1e83f3c035 | ||
|
|
4e27ee638a | ||
|
|
a6164f7464 | ||
|
|
81b6516cac | ||
|
|
f09fcd6cd5 | ||
|
|
1dfc6ff77c | ||
|
|
ecfe3e0936 | ||
|
|
576704562e | ||
|
|
8f10f3ed15 | ||
|
|
3d3432762e | ||
|
|
ac5fb3c9ac | ||
|
|
63842088a4 | ||
|
|
3ce369ab43 | ||
|
|
6269330364 | ||
|
|
466e0946d6 | ||
|
|
51f0ba7e1c | ||
|
|
30e165c8ce | ||
|
|
70befbcd77 | ||
|
|
5382a9c467 | ||
|
|
8ade5f68aa | ||
|
|
6fb4682d8b | ||
|
|
47bdb27261 | ||
|
|
dcffda5c4f | ||
|
|
fa8a12a6f2 | ||
|
|
3066cfdd04 | ||
|
|
3fa3705d55 | ||
|
|
ef8f794b93 | ||
|
|
52402536d9 | ||
|
|
daa637c557 | ||
|
|
58017f45a1 | ||
|
|
2c9858c261 | ||
|
|
9f2497e0f9 | ||
|
|
c3f5a69d68 | ||
|
|
1b1cc715be | ||
|
|
facec04ac2 | ||
|
|
28b37f68ea | ||
|
|
4dd633cef8 | ||
|
|
4335a566f1 | ||
|
|
ecfc5e645a | ||
|
|
1baa16b8e3 | ||
|
|
93859d1a63 | ||
|
|
22fe25da32 | ||
|
|
6afaa46cf4 | ||
|
|
24e34278aa | ||
|
|
103d772533 | ||
|
|
3f44eaee39 | ||
|
|
557c682a5e | ||
|
|
2ee84797ba | ||
|
|
2886aa0bab | ||
|
|
d9131b4b07 | ||
|
|
23b4958592 | ||
|
|
779a0a9d26 | ||
|
|
13b211e813 | ||
|
|
78daf36418 | ||
|
|
0694f28f32 | ||
|
|
2c11cade06 | ||
|
|
ff0139d809 | ||
|
|
2b7858de7c | ||
|
|
e579180abf | ||
|
|
635d37112e | ||
|
|
63333b11ad | ||
|
|
d2554788ea | ||
|
|
22269ccfb1 | ||
|
|
fb7c137a11 | ||
|
|
dd4ca33ed0 | ||
|
|
90e2277490 | ||
|
|
b3293a031f | ||
|
|
353b70d6c7 | ||
|
|
e74f6d5655 | ||
|
|
7d0cb70584 | ||
|
|
82e998e939 | ||
|
|
49de06e500 | ||
|
|
55beac9386 | ||
|
|
0cf31ae364 | ||
|
|
693f498d05 | ||
|
|
f46cce493f | ||
|
|
8c04526c62 | ||
|
|
cdf76080c5 | ||
|
|
bc513dcba9 | ||
|
|
016d7e8926 | ||
|
|
2cc1878cd6 | ||
|
|
81b4c3fb8d | ||
|
|
76a889f160 | ||
|
|
a8758b7f04 | ||
|
|
2259c115c4 | ||
|
|
54af962ea3 | ||
|
|
53cb3dda73 | ||
|
|
a010371a8b | ||
|
|
afcc20f483 | ||
|
|
b1ee353ea8 | ||
|
|
4037a0c0b0 | ||
|
|
2cc474dd26 | ||
|
|
9df2669839 | ||
|
|
ecea97f409 | ||
|
|
522a0ecb4a | ||
|
|
74dfdc7702 | ||
|
|
501c3fffe6 | ||
|
|
34e5177da6 | ||
|
|
fe022cb19c | ||
|
|
ea62a684d0 | ||
|
|
3410f0f0ce | ||
|
|
48b0b95e58 | ||
|
|
633688f184 | ||
|
|
b7c2585742 | ||
|
|
c4f186b3c8 | ||
|
|
87a51cf4c2 | ||
|
|
db161599e9 | ||
|
|
de2937d4dd | ||
|
|
d9d58e498f | ||
|
|
562c99b9ed | ||
|
|
2f67532fdd | ||
|
|
fd0c336600 | ||
|
|
0e3e1bf80b | ||
|
|
ff5c60a608 | ||
|
|
1dafa02f53 | ||
|
|
d1d7c9d9df | ||
|
|
2cc30e6ce1 | ||
|
|
fc223d0b0b | ||
|
|
59c7a85355 | ||
|
|
8fdec31c35 | ||
|
|
481b8a5fff | ||
|
|
626f12e619 | ||
|
|
37916f7cbe | ||
|
|
f00e5494fb | ||
|
|
8f3041fe56 | ||
|
|
0e1a3cef6c | ||
|
|
70ad0c0475 | ||
|
|
ddc835d1f3 | ||
|
|
d6f6892d37 | ||
|
|
598efd26f3 | ||
|
|
342a6a6187 | ||
|
|
bfc4193b76 | ||
|
|
a52845a4c2 | ||
|
|
e56662fbef | ||
|
|
7d5e91afae | ||
|
|
ab65cd250c | ||
|
|
588374646e | ||
|
|
1337d8dd5f | ||
|
|
9d0aaa0eb5 | ||
|
|
870eb12390 | ||
|
|
a2c5c83a48 | ||
|
|
babad2942a | ||
|
|
bddd8e0745 | ||
|
|
41f11a14e3 | ||
|
|
cfa0e19205 | ||
|
|
c69802ef91 | ||
|
|
217e754de2 | ||
|
|
21d6d5880c | ||
|
|
3c99be6d25 | ||
|
|
8519b47dc2 | ||
|
|
a5d28b67e9 | ||
|
|
ae8a2afb8b | ||
|
|
6f88060ffe | ||
|
|
b092d15c12 | ||
|
|
2ed87b2c1a | ||
|
|
2f9c957310 | ||
|
|
2c2539e457 | ||
|
|
25efc898a0 | ||
|
|
9285691c62 | ||
|
|
9276ea8c98 | ||
|
|
42c04b074c | ||
|
|
e5fbf5c655 | ||
|
|
599afa76e6 | ||
|
|
4ef628d0e6 | ||
|
|
5644b8e048 | ||
|
|
ba7f5284cf | ||
|
|
3be2ccca8f | ||
|
|
04872e07f7 | ||
|
|
c889a4ef45 | ||
|
|
65e34ddc40 | ||
|
|
cb95ecc7cb | ||
|
|
60a79ba9b7 | ||
|
|
585008e29d | ||
|
|
376140cab8 | ||
|
|
90259d4148 | ||
|
|
043b1b2095 | ||
|
|
6ab4560887 | ||
|
|
2b77aa1b54 | ||
|
|
ecaf50a1a8 | ||
|
|
1b683328e0 | ||
|
|
6888d37fb6 | ||
|
|
824cc56802 | ||
|
|
802d07c894 | ||
|
|
87791963b6 | ||
|
|
323811adb2 | ||
|
|
bb3e8170d5 | ||
|
|
f2220e664a | ||
|
|
a8773c3331 | ||
|
|
d34201d0d9 | ||
|
|
739f63bc40 | ||
|
|
56431a161e | ||
|
|
f0064357f5 | ||
|
|
d2940741f8 | ||
|
|
719b8f1894 | ||
|
|
ce7bf469f3 | ||
|
|
758301149a | ||
|
|
b5e673d209 | ||
|
|
1ee08d4847 | ||
|
|
57137da4bc | ||
|
|
61f0e261bf | ||
|
|
ed78372fd0 | ||
|
|
fcc37cc3d2 | ||
|
|
d0677f1c44 | ||
|
|
4122f1861b | ||
|
|
f691767fd5 | ||
|
|
54e0b1520d | ||
|
|
0fb5d8f7a0 | ||
|
|
34af828653 | ||
|
|
96f24bf8d4 | ||
|
|
0c084ec463 | ||
|
|
aef6991eb4 | ||
|
|
7b0ac3a373 | ||
|
|
02e9f8dadc | ||
|
|
8cde7e24f2 | ||
|
|
10e9d4ce37 | ||
|
|
2f9931eb6e | ||
|
|
e8efbfce42 | ||
|
|
6c8fa400d9 | ||
|
|
af9fff2911 | ||
|
|
d2a667ef9e | ||
|
|
025b5c77ff | ||
|
|
389c906d8f | ||
|
|
943a962bb9 | ||
|
|
8a21aae034 | ||
|
|
bc6189c65e | ||
|
|
1fcd0290d5 | ||
|
|
2dbf10d905 | ||
|
|
732031a624 | ||
|
|
8e3f83403f | ||
|
|
5be34ec932 | ||
|
|
e15e5721fb | ||
|
|
a0139317e8 | ||
|
|
50724aa7fd | ||
|
|
5540805570 | ||
|
|
937a7b7060 | ||
|
|
343f36c4f5 | ||
|
|
c1af1d9c31 | ||
|
|
1173406b0a | ||
|
|
2ec0c76ba2 | ||
|
|
372af61076 | ||
|
|
b9d4356487 | ||
|
|
fdedfecfba | ||
|
|
f8d75bf004 | ||
|
|
bf1db7b207 | ||
|
|
3be3f614c2 | ||
|
|
c54b35c79c | ||
|
|
279b16fd26 | ||
|
|
03ff484702 | ||
|
|
5a5f723d5f | ||
|
|
c70163f7ef | ||
|
|
147ef71e06 | ||
|
|
8ded145b96 | ||
|
|
e6756b3c06 | ||
|
|
f18ba2e248 | ||
|
|
41f03b2d3e | ||
|
|
f0dd3f1f2e | ||
|
|
3ad7366077 | ||
|
|
683ac4e6f6 | ||
|
|
ae404f047e | ||
|
|
80466f6c5f | ||
|
|
3169ac165a | ||
|
|
b32bbe4629 | ||
|
|
397aea8e6a | ||
|
|
a65026dd03 | ||
|
|
c3176256dc | ||
|
|
13c905ec48 | ||
|
|
1e4541c784 | ||
|
|
5ca7d18f7d | ||
|
|
530704d31e | ||
|
|
275b6fc1e1 | ||
|
|
b5070a160a | ||
|
|
5eecc1f78d | ||
|
|
be9d70855f | ||
|
|
4cd366e634 | ||
|
|
a17c07ad46 | ||
|
|
98b9d5ce90 | ||
|
|
11ff2fa0a1 | ||
|
|
6d1d4a9bb1 | ||
|
|
51a6ea6164 | ||
|
|
0e787e758a | ||
|
|
949a00de14 | ||
|
|
a7ad0720bc | ||
|
|
b5903bbf84 | ||
|
|
061985a336 | ||
|
|
911286ab14 | ||
|
|
a95a633586 | ||
|
|
2cbf237887 | ||
|
|
0dc403d278 | ||
|
|
8d48e37aa0 | ||
|
|
aec70c8250 | ||
|
|
17e8e55b08 | ||
|
|
ee76a1c360 | ||
|
|
463aa25693 | ||
|
|
aadff9c9bd | ||
|
|
45ae42c4fc | ||
|
|
556eec95d8 | ||
|
|
422fbc4d2c |
@@ -0,0 +1,16 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length=120
|
||||
|
||||
[*.gradle]
|
||||
indent_size = 2
|
||||
@@ -0,0 +1,2 @@
|
||||
*.cpp linguist-language=java
|
||||
*.cc linguist-language=java
|
||||
@@ -0,0 +1,13 @@
|
||||
### Expected behavior
|
||||
|
||||
### Actual behavior
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
### Minimal yet complete reproducer code (or URL to code) or complete log file
|
||||
|
||||
### Moquette MQTT version
|
||||
|
||||
### JVM version (e.g. `java -version`)
|
||||
|
||||
### OS version (e.g. `uname -a`)
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/build
|
||||
*/build/
|
||||
/target/
|
||||
/parser/target/
|
||||
/benchmarking/target/
|
||||
.idea/
|
||||
*.iml
|
||||
broker/target/
|
||||
client/target/
|
||||
parser_commons/target/
|
||||
netty_parser/target/
|
||||
netty_parser/target/
|
||||
parser_commons/target/
|
||||
distribution/target/
|
||||
broker/moquette.log
|
||||
broker/runner
|
||||
/bundle/target/
|
||||
/bundle/runner/
|
||||
/osgi_test/target/
|
||||
/perf/target/
|
||||
/mapdb_storage/target/
|
||||
*~
|
||||
*.log*
|
||||
.DS_Store
|
||||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
/*/bin/
|
||||
*.swp
|
||||
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
broker/*moquette_store.*
|
||||
embedding_moquette/target/
|
||||
broker/nb-configuration.xml
|
||||
broker/nbactions-Server.xml
|
||||
|
||||
maven-metadata.xml
|
||||
/.gradle/
|
||||
/bin/
|
||||
broker/config/git.properties
|
||||
distribution/src/main/resources/git.properties
|
||||
license/target
|
||||
server/target
|
||||
broker/h2db
|
||||
broker/media
|
||||
common/target
|
||||
server/target
|
||||
sdk/target
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
|
||||
script:
|
||||
- ./gradlew install test
|
||||
@@ -0,0 +1,55 @@
|
||||
Creative Commons Attribution-NoDerivs 3.0 Unported
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
a. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
|
||||
b. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
|
||||
c. "Distribute" means to make available to the public the original and copies of the Work through sale or other transfer of ownership.
|
||||
d. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
|
||||
e. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
|
||||
f. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
|
||||
g. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
|
||||
h. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
|
||||
i. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
|
||||
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
|
||||
a. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; and,
|
||||
b. to Distribute and Publicly Perform the Work including as incorporated in Collections.
|
||||
c. For the avoidance of doubt:
|
||||
i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
|
||||
ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
|
||||
iii. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
|
||||
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats, but otherwise you have no rights to make Adaptations. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
|
||||
a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested.
|
||||
b. If You Distribute, or Publicly Perform the Work or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work. The credit required by this Section 4(b) may be implemented in any reasonable manner; provided, however, that in the case of a Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
|
||||
c. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation.
|
||||
5. Representations, Warranties and Disclaimer
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
7. Termination
|
||||
a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
|
||||
b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
|
||||
8. Miscellaneous
|
||||
a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
|
||||
b. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
c. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
|
||||
d. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
|
||||
e. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
|
||||
Creative Commons Notice
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
Copyright (c) <2019> <wildfirechat>
|
||||
|
||||
Anti 996 License Version 1.0 (Draft)
|
||||
|
||||
Permission is hereby granted to any individual or legal entity
|
||||
obtaining a copy of this licensed work (including the source code,
|
||||
documentation and/or related items, hereinafter collectively referred
|
||||
to as the "licensed work"), free of charge, to deal with the licensed
|
||||
work for any purpose, including without limitation, the rights to use,
|
||||
reproduce, modify, prepare derivative works of, distribute, publish
|
||||
and sublicense the licensed work, subject to the following conditions:
|
||||
|
||||
1. The individual or the legal entity must conspicuously display,
|
||||
without modification, this License and the notice on each redistributed
|
||||
or derivative copy of the Licensed Work.
|
||||
|
||||
2. The individual or the legal entity must strictly comply with all
|
||||
applicable laws, regulations, rules and standards of the jurisdiction
|
||||
relating to labor and employment where the individual is physically
|
||||
located or where the individual was born or naturalized; or where the
|
||||
legal entity is registered or is operating (whichever is stricter). In
|
||||
case that the jurisdiction has no such laws, regulations, rules and
|
||||
standards or its laws, regulations, rules and standards are
|
||||
unenforceable, the individual or the legal entity are required to
|
||||
comply with Core International Labor Standards.
|
||||
|
||||
3. The individual or the legal entity shall not induce or force its
|
||||
employee(s), whether full-time or part-time, or its independent
|
||||
contractor(s), in any methods, to agree in oral or written form, to
|
||||
directly or indirectly restrict, weaken or relinquish his or her
|
||||
rights or remedies under such laws, regulations, rules and standards
|
||||
relating to labor and employment as mentioned above, no matter whether
|
||||
such written or oral agreement are enforceable under the laws of the
|
||||
said jurisdiction, nor shall such individual or the legal entity
|
||||
limit, in any methods, the rights of its employee(s) or independent
|
||||
contractor(s) from reporting or complaining to the copyright holder or
|
||||
relevant authorities monitoring the compliance of the license about
|
||||
its violation(s) of the said license.
|
||||
|
||||
THE LICENSED WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN ANY WAY CONNECTION WITH THE
|
||||
LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK.
|
||||
Executable
+201
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,2 +1,92 @@
|
||||
## 野火IM解决方案
|
||||
|
||||
野火IM是一套跨平台、核心功能开源的即时通讯解决方案,主要包含以下内容。
|
||||
|
||||
| 仓库 | 说明 | 备注 |
|
||||
| ------------------------------------------------------------ | ------------------------------------------------------- | ---- |
|
||||
| [android-chat](https://github.com/wildfirechat/android-chat) | 野火IM Android SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 |
|
||||
| [ios-chat](https://github.com/wildfirechat/ios-chat) | 野火IM iOS SDK源码和App源码 |可以很方便地进行二次开发,或集成到现有应用当中 |
|
||||
| [pc-chat](https://github.com/wildfirechat/pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC平台应用 | |
|
||||
| [web-chat](https://github.com/wildfirechat/web-chat) | Web平台的Demo, [体验地址](http://web.wildfirechat.cn) | |
|
||||
| [wx-chat](https://github.com/wildfirechat/wx-chat) | 微信小程序平台的Demo | |
|
||||
| [server](https://github.com/wildfirechat/server) | IM server | |
|
||||
| [app server](https://github.com/wildfirechat/app_server) | 应用服务端 | |
|
||||
| [robot_server](https://github.com/wildfirechat/robot_server) | 机器人服务端 | |
|
||||
| [push_server](https://github.com/wildfirechat/push_server) | 推送服务器 | |
|
||||
| [docs](https://github.com/wildfirechat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明 | | | |
|
||||
|
||||
# server
|
||||
本系统有4部分组成,[服务器](https://github.com/wildfirechat/server)/[iOS客户端](https://github.com/wildfirechat/ios-chat)/[Android客户端](https://github.com/wildfirechat/android-chat)/[协议栈库](https://github.com/wildfirechat/proto)。其中iOS和Android都依赖于协议栈库。本工程为服务器的发布工程,请阅读[docs](http://docs.wildfirechat.cn)或下载服务器[发布版本](https://github.com/wildfirechat/server/releases)
|
||||
本工程为野火IM 社区版IM服务软件。野火IM作为一个通用的即时通讯解决方案,可以集成到各种应用中。请阅读[docs](http://docs.wildfirechat.cn)或下载服务器[发布版本](https://github.com/wildfirechat/server/releases)
|
||||
|
||||
|
||||
开发一套IM系统真的很艰辛,请路过的朋友们给点个star,支持我们坚持下去🙏🙏🙏🙏🙏
|
||||
|
||||
### 联系我们
|
||||
|
||||
> 商务合作请优先采用邮箱和我们联系。技术问题请到[野火IM论坛](http://bbs.wildfirechat.cn/)发帖交流
|
||||
|
||||
1. heavyrain.lee 邮箱: heavyrain.lee@wildfirechat.cn 微信:wildfirechat
|
||||
2. imndx 邮箱: imndx@wildfirechat.cn 微信:wfchat
|
||||
|
||||
### 问题交流
|
||||
|
||||
1. 如果大家发现bug,请在GitHub提issue
|
||||
2. 其他问题,请到[野火IM论坛](http://bbs.wildfirechat.cn/)进行交流学习
|
||||
3. 微信公众号
|
||||
|
||||
<img src="http://static.wildfirechat.cn/wx_wfc_qrcode.jpg" width = 50% height = 50% />
|
||||
|
||||
> 强烈建议关注我们的公众号。我们有新版本发布或者有重大更新会通过公众号通知大家,另外我们也会不定期的发布一些关于野火IM的技术介绍。
|
||||
|
||||
#### 体验Demo
|
||||
我们提供了体验demo,请使用微信扫码下载安装体验
|
||||
|
||||

|
||||
|
||||
#### 加入野火官方体验交流群
|
||||
使用野火IM移动客户端扫码下面二维码(不是使用微信扫码),和野火IM的爱好者一起畅谈野火IM的问题和经验:
|
||||
|
||||

|
||||
|
||||
#### 应用截图
|
||||

|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-message-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-contact-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-discover-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-settings-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-messagelist-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-chat-setting-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-takephoto-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-record-voice-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-location-view.png" width = 50% height = 50% />
|
||||
|
||||
<img src="http://static.wildfirechat.cn/ios-voip-view.png" width = 50% height = 50% />
|
||||
|
||||
## 编译
|
||||
在安装JDK1.8以上及maven的前提下,在命令行中执行```mvn clean compile package```,生成的目标文件在```./distribution/target/distribution-xxxx-bundle-tar.tar.gz```
|
||||
|
||||
## 捐赠者名单
|
||||
|
||||
| 捐赠者 | 商标 | 金额 | 简介 |
|
||||
| ----- | ---- | -------- | --- |
|
||||
| [SAMOS](http://samos.io) |  | 保密 | 一站式区块链解决方案服务商(http://samos.io) |
|
||||
|
||||
## 特别感谢
|
||||
1. [moquette](https://github.com/moquette-io/moquette) 本项目是基于此项目二次开发而来,处理MQTT相关业务。
|
||||
2. [loServer](https://github.com/looly/loServer) 本项目使用loServer处理HTTP相关业务。
|
||||
|
||||
*** 对他们表示诚挚的感谢🙏 ***
|
||||
|
||||
## License
|
||||
|
||||
1. Under the Creative Commons Attribution-NoDerivs 3.0 Unported license. See the [LICENSE](https://github.com/wildfirechat/server/blob/wildfirechat/LICENSE) file for details.
|
||||
2. Under the Anti 996 License. See the [Anti 996 LICENSE](https://github.com/wildfirechat/server/blob/wildfirechat/LICENSE_996) file for details.
|
||||
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
|
||||
<!-- # 本配置文件为debug使用,修改这里不会在Release包中生效。Release中包含的配置文件在 ${Porject_Path}/distribution/src/main/resources目录下-->
|
||||
|
||||
|
||||
<hazelcast
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.hazelcast.com/schema/config
|
||||
http://www.hazelcast.com/schema/config/hazelcast-config-3.5.xsd"
|
||||
xmlns="http://www.hazelcast.com/schema/config">
|
||||
<network>
|
||||
<join>
|
||||
<multicast enabled="false"/>
|
||||
</join>
|
||||
</network>
|
||||
|
||||
<!-- map eviction -->
|
||||
<!-- http://docs.hazelcast.org/docs/latest-development/manual/html/Distributed_Data_Structures/Map/Map_Eviction.html -->
|
||||
<map name="messages_map">
|
||||
<!-- 7 days -->
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<max-size policy="PER_NODE">1000000</max-size>
|
||||
<eviction-percentage>10</eviction-percentage>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.MessageLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<map name="groups_map">
|
||||
<!-- 7 days -->
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<max-size policy="PER_NODE">1000000</max-size>
|
||||
<eviction-percentage>10</eviction-percentage>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.GroupLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<map name="users">
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<max-size policy="PER_NODE">1000000</max-size>
|
||||
<eviction-percentage>10</eviction-percentage>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.UserLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<map name="user_status">
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<max-size policy="PER_NODE">1000000</max-size>
|
||||
<eviction-percentage>10</eviction-percentage>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.UserStatusLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<set name="node_ids"/>
|
||||
|
||||
<multimap name="user_setting">
|
||||
</multimap>
|
||||
|
||||
<multimap name="group_members">
|
||||
</multimap>
|
||||
|
||||
<map name="chatrooms">
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.ChatroomLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<map name="user_chatroom">
|
||||
</map>
|
||||
|
||||
<map name="robots">
|
||||
<!-- 7 days -->
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<max-size policy="PER_NODE">1000000</max-size>
|
||||
<eviction-percentage>10</eviction-percentage>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.RobotLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<map name="things">
|
||||
</map>
|
||||
|
||||
<multimap name="user_robots">
|
||||
</multimap>
|
||||
|
||||
<multimap name="user_things">
|
||||
</multimap>
|
||||
|
||||
<multimap name="chatroom_members">
|
||||
</multimap>
|
||||
|
||||
<multimap name="user_friends">
|
||||
</multimap>
|
||||
|
||||
<multimap name="user_friends_request">
|
||||
</multimap>
|
||||
|
||||
<map name="channels_map">
|
||||
<!-- 7 days -->
|
||||
<time-to-live-seconds>604800</time-to-live-seconds>
|
||||
<eviction-policy>LRU</eviction-policy>
|
||||
<max-size policy="PER_NODE">1000000</max-size>
|
||||
<eviction-percentage>10</eviction-percentage>
|
||||
<map-store enabled="true">
|
||||
<class-name>io.moquette.persistence.ChannelLoader</class-name>
|
||||
<write-delay-seconds>0</write-delay-seconds>
|
||||
</map-store>
|
||||
</map>
|
||||
|
||||
<multimap name="channel_listeners">
|
||||
</multimap>
|
||||
</hazelcast>
|
||||
Executable
+140
@@ -0,0 +1,140 @@
|
||||
#
|
||||
#
|
||||
# 本配置文件为debug使用,修改这里不会在Release包中生效。Release中包含的配置文件在 ${Porject_Path}/distribution/src/main/resources目录下
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
|
||||
#*********************************************************************
|
||||
# Server configuration
|
||||
#*********************************************************************
|
||||
#服务器的接入IP。给客户端提供是${server.ip}和${http_port}。
|
||||
#客户端会从${http_port}端口获取到长链接端口。这个地址一定要改成客户端可以访问到的IP地址
|
||||
# (如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址)
|
||||
server.ip 0.0.0.0
|
||||
|
||||
##原生客户端长链接端口
|
||||
port 1883
|
||||
|
||||
##客户端短链接端口
|
||||
http_port 80
|
||||
|
||||
##WEB客户端长链接端口
|
||||
websocket_port 8083
|
||||
|
||||
#管理端口
|
||||
http.admin.port 18080
|
||||
|
||||
##节点ID,当集群部署时,一定不能有重复。
|
||||
node_id 1
|
||||
|
||||
##绑定IP,保持不变即可
|
||||
host 0.0.0.0
|
||||
|
||||
##本地绑定端口
|
||||
local_port 80
|
||||
|
||||
##是否使用内置DB。0使用mysql;1使用h2db;2使用mysql+mongodb。社区版只支持0和1,专业版支持2
|
||||
embed.db 0
|
||||
|
||||
##服务器管理接口密钥
|
||||
http.admin.secret_key 123456
|
||||
|
||||
##服务器API接口参数是否检查时间。当设置为false时,所有的请求会检查时间的有效性;当设置为true时,可以在http.admin.secret_key保持不变的情况下,使用固定的服务API签名
|
||||
##nonce = "76616", timestamp = "1558350862502", sign = "b98f9b0717f59febccf1440067a7f50d9b31bdde"
|
||||
##这个地方上线前要改为false
|
||||
http.admin.no_check_time true
|
||||
|
||||
##客户端协议栈密钥,需要与客户端协议栈文件libemqq.cc文件中的aes_key值保持一致,16进制byte用逗号分割。这个密钥对安全性帮助不大,客户不要修改
|
||||
client.proto.secret_key 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F
|
||||
|
||||
##用来生产im token的私钥,只在服务器使用,客户端不用。正式使用时为了安全一定要修改这个值,切记切记
|
||||
token.key testim
|
||||
|
||||
##首次登录,是否接收之前的历史消息。0 不接收;1接收。
|
||||
message.roaming 0
|
||||
|
||||
##是否开启拉取远程历史消息
|
||||
message.remote_history_message 0
|
||||
|
||||
##服务器为每个用户缓存的消息数量。这个值改得太大,拉取消息时间变长,另外会占用大量内存。
|
||||
message.max_queue 1024
|
||||
|
||||
#*********************************************************************
|
||||
# hazelcase configuration
|
||||
#*********************************************************************
|
||||
hazelcast.configuration config/hazelcast.xml
|
||||
|
||||
#*********************************************************************
|
||||
# Media server configuration
|
||||
#*********************************************************************
|
||||
##是否使用七牛云存储。1使用七牛;0使用内存文件服务器。
|
||||
media.server.use_qiniu 0
|
||||
|
||||
##媒体类型分类
|
||||
#Media_Type_GENERAL = 0,
|
||||
#Media_Type_IMAGE = 1,
|
||||
#Media_Type_VOICE = 2,
|
||||
#Media_Type_VIDEO = 3,
|
||||
#Media_Type_FILE = 4,
|
||||
#Media_Type_PORTRAIT = 5,
|
||||
#Media_Type_FAVORITE = 6
|
||||
|
||||
# qiniu media server configuration
|
||||
qiniu.server_url http://up.qbox.me
|
||||
qiniu.access_key tU3vdBK5BL5j4N7jI5N5uZgq_HQDo170w5C9Amnn
|
||||
qiniu.secret_key YfQIJdgp5YGhwEw14vGpaD2HJZsuJldWtqens7i5
|
||||
qiniu.bucket_general_name media
|
||||
qiniu.bucket_general_domain http://pghnpyzos.bkt.clouddn.com
|
||||
qiniu.bucket_image_name media
|
||||
qiniu.bucket_image_domain http://pghnpyzos.bkt.clouddn.com
|
||||
qiniu.bucket_voice_name media
|
||||
qiniu.bucket_voice_domain http://pghnpyzos.bkt.clouddn.com
|
||||
qiniu.bucket_video_name media
|
||||
qiniu.bucket_video_domain http://pghnpyzos.bkt.clouddn.com
|
||||
qiniu.bucket_file_name media
|
||||
qiniu.bucket_file_domain http://pghnpyzos.bkt.clouddn.com
|
||||
qiniu.bucket_portrait_name storage
|
||||
qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
|
||||
qiniu.bucket_favorite_name storage
|
||||
qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
|
||||
|
||||
|
||||
# local media server configuration
|
||||
# 本地媒体服务器配置。
|
||||
local.media.storage.root media
|
||||
|
||||
# 是否支持多端登陆
|
||||
server.multi_endpoint false
|
||||
|
||||
#*********************************************************************
|
||||
# Push server configuration
|
||||
#*********************************************************************
|
||||
##安卓推送服务器地址
|
||||
push.android.server.address http://localhost:8085/android/push
|
||||
##苹果推送服务器地址
|
||||
push.ios.server.address http://localhost:8085/ios/push
|
||||
|
||||
|
||||
#*********************************************************************
|
||||
# MongoDB configuration
|
||||
#*********************************************************************
|
||||
#专业版支持,社区版请忽略
|
||||
#mongodb.client_uri mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
|
||||
#mongodb.client_uri mongodb://host1:27017,host2:27017,host3:27017/wfchat?replicaSet=myReplicaSet
|
||||
mongodb.client_uri mongodb://wfc:123456@localhost:27017/wfchat
|
||||
mongodb.database wfchat
|
||||
mongodb.data_expire_days 1096
|
||||
|
||||
#*********************************************************************
|
||||
# Sensitive configuration
|
||||
#*********************************************************************
|
||||
##文本敏感词过滤处理方法,0 发送失败;1 发送成功但消息被服务器直接丢弃;2 命中的敏感词被替换成***;3 记录并继续发送
|
||||
sensitive.filter.type 0
|
||||
|
||||
#*********************************************************************
|
||||
# Message forward configuration
|
||||
#*********************************************************************
|
||||
##消息转发地址
|
||||
#message.forward.url http://localhost:8087/message/forward
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
insert into t_user (`_uid`,`_name`,`_display_name`,`_type`,`_dt`) values ('admin','admin','系统管理员',3,1);
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
ALTER TABLE t_user_session MODIFY _token VARCHAR(240) DEFAULT NULL;
|
||||
@@ -0,0 +1,4 @@
|
||||
alter table `t_group` add column `_mute` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_join_type` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_private_chat` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_searchable` tinyint NOT NULL DEFAULT 0;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_settings`;
|
||||
CREATE TABLE `t_settings` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY,
|
||||
`value` varchar(64) NOT NULL,
|
||||
`desc` varchar(128) NOT NULL
|
||||
);
|
||||
|
||||
|
||||
insert into t_settings(`id`, `value`,`desc`) values (1, '3000', '最大群成员数量');
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_sensitiveword` add column `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
alter table `t_user_session` modify column `_voip_token` varchar(240) DEFAULT '';
|
||||
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
alter table t_friend add column `_blacked` tinyint DEFAULT 0;
|
||||
update t_friend set `_blacked` = 1 where `_state` = 2;
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_user_session` ADD INDEX `session_token_index` ( `_token` );
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table t_friend_request add index `friend_request_uid_index` (`_friend_uid`);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_user_session` ADD INDEX `session_uid_index` ( `_uid` );
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
alter table `t_user_session` add column `_deleted` tinyint DEFAULT 0;
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
alter table `t_user` add column `_deleted` tinyint DEFAULT 0;
|
||||
Executable
+200
@@ -0,0 +1,200 @@
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_group`;
|
||||
CREATE TABLE `t_group` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_name` varchar(64) DEFAULT '',
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_type` tinyint NOT NULL DEFAULT 0,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_member_count` int(11) DEFAULT 0,
|
||||
`_member_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `group_gid_index` (`_gid` ASC),
|
||||
INDEX `group_name_index` (`_name` ASC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_group_member`;
|
||||
CREATE TABLE `t_group_member` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) DEFAULT '',
|
||||
`_alias` varchar(64) DEFAULT '',
|
||||
`_type` tinyint DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_gid_mid_index` (`_gid`, `_mid`)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_user`;
|
||||
CREATE TABLE `t_user` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_name` varchar(64) DEFAULT '',
|
||||
`_display_name` varchar(64) DEFAULT '',
|
||||
`_gender` int(11) NOT NULL DEFAULT 0,
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_mobile` varchar(64) DEFAULT '',
|
||||
`_email` varchar(64) DEFAULT '',
|
||||
`_address` varchar(64) DEFAULT '',
|
||||
`_company` varchar(64) DEFAULT '',
|
||||
`_social` varchar(64) DEFAULT '',
|
||||
`_passwd_md5` varchar(64) DEFAULT '',
|
||||
`_salt` varchar(64) DEFAULT '',
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_type` tinyint DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_uid_index` (`_uid` ASC),
|
||||
UNIQUE INDEX `user_name_index` (`_name` ASC),
|
||||
INDEX `user_display_name_index` (`_display_name` ASC),
|
||||
INDEX `user_mobile_index` (`_mobile` ASC),
|
||||
INDEX `user_email_index` (`_email` ASC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_status`;
|
||||
CREATE TABLE `t_user_status` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_status` int(11) NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_status_uid_index` (`_uid` ASC),
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_friend_request`;
|
||||
CREATE TABLE `t_friend_request` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_friend_uid` varchar(64) NOT NULL,
|
||||
`_reason` TEXT DEFAULT NULL,
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_from_read_status` tinyint DEFAULT 0,
|
||||
`_to_read_status` tinyint DEFAULT 0,
|
||||
UNIQUE INDEX `fr_user_target_index` (`_uid` ASC, `_friend_uid` ASC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_friend`;
|
||||
CREATE TABLE `t_friend` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_friend_uid` varchar(64) NOT NULL,
|
||||
`_state` tinyint DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `f_user_target_index` (`_uid` ASC, `_friend_uid` ASC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_setting`;
|
||||
CREATE TABLE `t_user_setting` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_scope` int NOT NULL,
|
||||
`_key` varchar(64) NOT NULL,
|
||||
`_value` varchar(4096) NOT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_setting_index` (`_uid` ASC, `_scope` ASC, `_key` ASC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_id_generator`;
|
||||
CREATE TABLE `t_id_generator` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT
|
||||
)
|
||||
AUTO_INCREMENT = 3;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_channel`;
|
||||
CREATE TABLE `t_channel` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_name` varchar(64) DEFAULT '',
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_desc` TEXT DEFAULT NULL,
|
||||
`_secret` varchar(64) DEFAULT '',
|
||||
`_callback` varchar(1024) DEFAULT '',
|
||||
`_automatic` tinyint NOT NULL DEFAULT 0,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `channel_cid_index` (`_cid` DESC),
|
||||
INDEX `channel_name_index` (`_name` DESC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_channel_listener`;
|
||||
CREATE TABLE `t_channel_listener` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) DEFAULT '',
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `channel_cid_mid_index` (`_cid`, `_mid`)
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_session`;
|
||||
CREATE TABLE `t_user_session` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_token` varchar(64) DEFAULT '',
|
||||
`_voip_token` varchar(64) DEFAULT '',
|
||||
`_secret` varchar(64) NOT NULL,
|
||||
`_db_secret` varchar(64) NOT NULL,
|
||||
`_platform` tinyint DEFAULT 0,
|
||||
`_push_type` tinyint DEFAULT 0,
|
||||
`_package_name` varchar(64) DEFAULT '',
|
||||
`_device_name` varchar(64) DEFAULT '',
|
||||
`_device_version` varchar(64) DEFAULT '',
|
||||
`_phone_name` varchar(64) DEFAULT '',
|
||||
`_language` varchar(64) DEFAULT '',
|
||||
`_carrier_name` varchar(64) DEFAULT '',
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `session_uid_cid_index` (`_cid`, `_uid`)
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_robot`;
|
||||
CREATE TABLE `t_robot` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_secret` varchar(64) DEFAULT '',
|
||||
`_callback` varchar(1024) DEFAULT '',
|
||||
`_state` tinyint DEFAULT 0,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `robot_uid_index` (`_uid` ASC),
|
||||
INDEX `robot_owner_index` (`_owner` ASC)
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_thing`;
|
||||
CREATE TABLE `t_thing` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_token` varchar(64) DEFAULT '',
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `thing_uid_index` (`_uid` ASC),
|
||||
INDEX `thing_owner_index` (`_owner` ASC)
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_chatroom`;
|
||||
CREATE TABLE `t_chatroom` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_title` varchar(64) DEFAULT '',
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_state` tinyint NOT NULL DEFAULT 0,
|
||||
`_desc` TEXT DEFAULT NULL,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `chatroom_cid_index` (`_cid` DESC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_sensitiveword`;
|
||||
CREATE TABLE `t_sensitiveword` (
|
||||
`_word` TEXT DEFAULT NULL
|
||||
);
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_messages`;
|
||||
CREATE TABLE `t_messages` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_mid` bigint(20) NOT NULL,
|
||||
`_from` varchar(64) NOT NULL,
|
||||
`_type` tinyint NOT NULL DEFAULT 0,
|
||||
`_target` varchar(64) NOT NULL,
|
||||
`_line` int(11) NOT NULL DEFAULT 0,
|
||||
`_data` BLOB NOT NULL,
|
||||
`_searchable_key` TEXT DEFAULT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
UNIQUE INDEX `message_uid_index` (`_mid` ASC)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_messages`;
|
||||
CREATE TABLE `t_user_messages` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_mid` bigint(20) NOT NULL,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_seq` bigint(20) NOT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
UNIQUE INDEX `message_seq_uid_index` (`_uid` DESC, `_seq` DESC)
|
||||
);
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
|
||||
insert into t_chatroom (`_cid`, `_title`, `_desc`,`_dt`) values ('chatroom1','火信聊天室1','火信测试聊天室1,用来演示聊天室功能', 1);
|
||||
|
||||
insert into t_chatroom (`_cid`, `_title`, `_desc`,`_dt`) values ('chatroom2','火信聊天室2','火信测试聊天室2,用来演示聊天室功能', 1);
|
||||
|
||||
insert into t_chatroom (`_cid`, `_title`, `_desc`,`_dt`) values ('chatroom3','火信聊天室3','火信测试聊天室3,用来演示聊天室功能', 1);
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
insert into t_user (`_uid`,`_name`,`_display_name`,`_portrait`,`_type`,`_dt`) values ('FireRobot','FireRobot','小火','http://cdn2.wildfirechat.cn/robot.png',1,1);
|
||||
|
||||
insert into t_robot (`_uid`,`_owner`,`_secret`,`_callback`,`_state`,`_dt`) values ('FireRobot', 'FireRobot', '123456', 'http://127.0.0.1:8883/robot/recvmsg', 0, 1);
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
|
||||
alter table t_friend add column `_alias` varchar(64) DEFAULT NULL;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table t_user add column `_createTime` TIMESTAMP default CURRENT_TIMESTAMP;
|
||||
alter table t_group add column `_createTime` TIMESTAMP default CURRENT_TIMESTAMP;
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_messages` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_sensitive_messages`;
|
||||
CREATE TABLE `t_sensitive_messages` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_mid` bigint(20) NOT NULL,
|
||||
`_from` varchar(64) NOT NULL,
|
||||
`_type` tinyint NOT NULL DEFAULT 0,
|
||||
`_target` varchar(64) NOT NULL,
|
||||
`_line` int(11) NOT NULL DEFAULT 0,
|
||||
`_data` BLOB NOT NULL,
|
||||
`_searchable_key` TEXT DEFAULT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
`_content_type` int(11) NOT NULL DEFAULT 0,
|
||||
UNIQUE INDEX `sensitive_message_uid_index` (`_mid` ASC)
|
||||
);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
insert into t_user (`_uid`,`_name`,`_display_name`,`_type`,`_dt`) values ('admin','admin','系统管理员',3,1);
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
ALTER TABLE t_user_session MODIFY _token VARCHAR(240) DEFAULT NULL;
|
||||
@@ -0,0 +1,4 @@
|
||||
alter table `t_group` add column `_mute` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_join_type` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_private_chat` tinyint NOT NULL DEFAULT 0;
|
||||
alter table `t_group` add column `_searchable` tinyint NOT NULL DEFAULT 0;
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_session`;
|
||||
CREATE TABLE `t_session` (
|
||||
`row_id` varchar(50) not null primary key,
|
||||
`del_flag` tinyint(1) default 0 null,
|
||||
`create_time` timestamp null,
|
||||
`update_time` timestamp null,
|
||||
`expire_time` timestamp null,
|
||||
`user_id` int null,
|
||||
constraint `t_session_pk_2` unique (`user_id`, `expire_time`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table t_user MODIFY column `_createTime` DATETIME NOT NULL DEFAULT NOW();
|
||||
alter table t_group MODIFY column `_createTime` DATETIME NOT NULL DEFAULT NOW();
|
||||
@@ -0,0 +1,4 @@
|
||||
alter table t_session MODIFY column `create_time` DATETIME NOT NULL DEFAULT NOW();
|
||||
alter table t_session MODIFY column `update_time` DATETIME NOT NULL DEFAULT NOW();
|
||||
alter table t_session MODIFY column `expire_time` DATETIME NOT NULL DEFAULT NOW();
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
update t_messages_0 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_1 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_2 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_3 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_4 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_5 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_6 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_7 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_8 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_9 set _dt = date_add(_dt, interval 8 hour);
|
||||
|
||||
update t_messages_10 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_11 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_12 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_13 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_14 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_15 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_16 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_17 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_18 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_19 set _dt = date_add(_dt, interval 8 hour);
|
||||
|
||||
update t_messages_20 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_21 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_22 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_23 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_24 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_25 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_26 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_27 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_28 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_29 set _dt = date_add(_dt, interval 8 hour);
|
||||
|
||||
|
||||
update t_messages_30 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_31 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_32 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_33 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_34 set _dt = date_add(_dt, interval 8 hour);
|
||||
update t_messages_35 set _dt = date_add(_dt, interval 8 hour);
|
||||
+4038
File diff suppressed because it is too large
Load Diff
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_settings`;
|
||||
CREATE TABLE `t_settings` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY,
|
||||
`value` varchar(64) NOT NULL,
|
||||
`desc` varchar(128) NOT NULL default ""
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
insert into t_settings(`id`, `value`,`desc`) values (1, "3000", "最大群成员数量");
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_sensitiveword` add column `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT;
|
||||
Executable
@@ -0,0 +1,3 @@
|
||||
alter table `t_user_session` modify column `_voip_token` varchar(240) DEFAULT '';
|
||||
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
alter table t_friend add column `_blacked` tinyint DEFAULT 0 COMMENT "0, normal; 1, blacked";
|
||||
update t_friend set `_blacked` = 1 where `_state` = 2;
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_user_session` ADD INDEX `session_token_index` ( `_token` );
|
||||
@@ -0,0 +1 @@
|
||||
alter table t_friend_request add index `friend_request_uid_index` (`_friend_uid`);
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_user_session` ADD INDEX `session_uid_index` ( `_uid` );
|
||||
@@ -0,0 +1 @@
|
||||
alter table `t_user_session` add column `_deleted` tinyint DEFAULT 0;
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table `t_user` add column `_deleted` tinyint DEFAULT 0;
|
||||
Executable
+275
@@ -0,0 +1,275 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_messages`;
|
||||
CREATE TABLE `t_messages` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_mid` bigint(20) NOT NULL,
|
||||
`_from` varchar(64) NOT NULL,
|
||||
`_type` tinyint NOT NULL DEFAULT 0,
|
||||
`_target` varchar(64) NOT NULL,
|
||||
`_line` int(11) NOT NULL DEFAULT 0,
|
||||
`_data` BLOB NOT NULL,
|
||||
`_searchable_key` TEXT DEFAULT NULL,
|
||||
`_dt` DATETIME NOT NULL,
|
||||
UNIQUE INDEX `message_uid_index` (`_mid` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_messages`;
|
||||
CREATE TABLE `t_user_messages` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_mid` bigint(20) NOT NULL,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_seq` bigint(20) NOT NULL,
|
||||
`_dt` DATETIME NOT NULL DEFAULT NOW(),
|
||||
INDEX `message_seq_uid_index` (`_uid` DESC, `_seq` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_group`;
|
||||
CREATE TABLE `t_group` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_name` varchar(64) DEFAULT '',
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_type` tinyint NOT NULL DEFAULT 0,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_member_count` int(11) DEFAULT 0,
|
||||
`_member_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `group_gid_index` (`_gid` DESC),
|
||||
INDEX `group_name_index` (`_name` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_group_member`;
|
||||
CREATE TABLE `t_group_member` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) DEFAULT '',
|
||||
`_alias` varchar(64) DEFAULT '',
|
||||
`_type` tinyint DEFAULT 0 COMMENT "0普通成员;1,管理员;2,群主,与Owner相同",
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_gid_mid_index` (`_gid`, `_mid`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_user`;
|
||||
CREATE TABLE `t_user` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_name` varchar(64) DEFAULT '',
|
||||
`_display_name` varchar(64) DEFAULT '',
|
||||
`_gender` int(11) NOT NULL DEFAULT 0,
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_mobile` varchar(64) DEFAULT '',
|
||||
`_email` varchar(64) DEFAULT '',
|
||||
`_address` varchar(64) DEFAULT '',
|
||||
`_company` varchar(64) DEFAULT '',
|
||||
`_social` varchar(64) DEFAULT '',
|
||||
`_passwd_md5` varchar(64) DEFAULT '',
|
||||
`_salt` varchar(64) DEFAULT '',
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_type` tinyint DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_uid_index` (`_uid` ASC),
|
||||
UNIQUE INDEX `user_name_index` (`_name` ASC),
|
||||
INDEX `user_display_name_index` (`_display_name` ASC),
|
||||
INDEX `user_mobile_index` (`_mobile` ASC),
|
||||
INDEX `user_email_index` (`_email` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_status`;
|
||||
CREATE TABLE `t_user_status` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_status` int(11) NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_status_uid_index` (`_uid` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_friend_request`;
|
||||
CREATE TABLE `t_friend_request` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_friend_uid` varchar(64) NOT NULL,
|
||||
`_reason` TEXT DEFAULT NULL,
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_from_read_status` tinyint DEFAULT 0,
|
||||
`_to_read_status` tinyint DEFAULT 0,
|
||||
UNIQUE INDEX `fr_user_target_index` (`_uid` ASC, `_friend_uid` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_friend`;
|
||||
CREATE TABLE `t_friend` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_friend_uid` varchar(64) NOT NULL,
|
||||
`_state` tinyint DEFAULT 0 COMMENT "0, normal; 1, deleted; 2, blacked",
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `f_user_target_index` (`_uid` ASC, `_friend_uid` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_setting`;
|
||||
CREATE TABLE `t_user_setting` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_scope` int NOT NULL,
|
||||
`_key` varchar(64) NOT NULL,
|
||||
`_value` varchar(4096) NOT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `user_setting_index` (`_uid` ASC, `_scope` ASC, `_key` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_id_generator`;
|
||||
CREATE TABLE `t_id_generator` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci
|
||||
AUTO_INCREMENT = 3;
|
||||
|
||||
DROP TABLE IF EXISTS `t_channel`;
|
||||
CREATE TABLE `t_channel` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_name` varchar(64) DEFAULT '',
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_desc` TEXT DEFAULT NULL,
|
||||
`_secret` varchar(64) DEFAULT '',
|
||||
`_callback` varchar(1024) DEFAULT '',
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_automatic` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `channel_cid_index` (`_cid` DESC),
|
||||
INDEX `channel_name_index` (`_name` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_channel_listener`;
|
||||
CREATE TABLE `t_channel_listener` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) DEFAULT '',
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `channel_cid_mid_index` (`_cid`, `_mid`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_user_session`;
|
||||
CREATE TABLE `t_user_session` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_token` varchar(64) DEFAULT '',
|
||||
`_voip_token` varchar(64) DEFAULT '',
|
||||
`_secret` varchar(64) NOT NULL,
|
||||
`_db_secret` varchar(64) NOT NULL,
|
||||
`_platform` tinyint DEFAULT 0,
|
||||
`_push_type` tinyint DEFAULT 0,
|
||||
`_package_name` varchar(64) DEFAULT '',
|
||||
`_device_name` varchar(64) DEFAULT '',
|
||||
`_device_version` varchar(64) DEFAULT '',
|
||||
`_phone_name` varchar(64) DEFAULT '',
|
||||
`_language` varchar(64) DEFAULT '',
|
||||
`_carrier_name` varchar(64) DEFAULT '',
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `session_uid_cid_index` (`_cid`, `_uid`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_robot`;
|
||||
CREATE TABLE `t_robot` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_secret` varchar(64) DEFAULT '',
|
||||
`_callback` varchar(1024) DEFAULT '',
|
||||
`_state` tinyint DEFAULT 0,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `robot_uid_index` (`_uid` ASC),
|
||||
INDEX `robot_owner_index` (`_owner` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_thing`;
|
||||
CREATE TABLE `t_thing` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_owner` varchar(64) DEFAULT '',
|
||||
`_token` varchar(64) DEFAULT '',
|
||||
`_state` tinyint DEFAULT 0,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `thing_uid_index` (`_uid` ASC),
|
||||
INDEX `thing_owner_index` (`_owner` ASC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `t_chatroom`;
|
||||
CREATE TABLE `t_chatroom` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_cid` varchar(64) NOT NULL,
|
||||
`_title` varchar(64) DEFAULT '',
|
||||
`_portrait` varchar(1024) DEFAULT '',
|
||||
`_state` tinyint NOT NULL DEFAULT 0,
|
||||
`_desc` TEXT DEFAULT NULL,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
UNIQUE INDEX `chatroom_cid_index` (`_cid` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
DROP TABLE IF EXISTS `t_sensitiveword`;
|
||||
CREATE TABLE `t_sensitiveword` (
|
||||
`_word` TEXT DEFAULT NULL
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
+2353
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
insert into t_chatroom (`_cid`, `_title`, `_desc`,`_dt`) values ('chatroom1','火信聊天室1','火信测试聊天室1,用来演示聊天室功能', 1);
|
||||
|
||||
insert into t_chatroom (`_cid`, `_title`, `_desc`,`_dt`) values ('chatroom2','火信聊天室2','火信测试聊天室2,用来演示聊天室功能', 1);
|
||||
|
||||
insert into t_chatroom (`_cid`, `_title`, `_desc`,`_dt`) values ('chatroom3','火信聊天室3','火信测试聊天室3,用来演示聊天室功能', 1);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
insert into t_user (`_uid`,`_name`,`_display_name`,`_portrait`,`_type`,`_dt`) values ('FireRobot','FireRobot','小火','http://cdn2.wildfirechat.cn/robot.png',1,1);
|
||||
|
||||
insert into t_robot (`_uid`,`_owner`,`_secret`,`_callback`,`_state`,`_dt`) values ('FireRobot', 'FireRobot', '123456', 'http://127.0.0.1:8883/robot/recvmsg', 0, 1);
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table t_friend add column `_alias` varchar(64) DEFAULT NULL;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table t_user add column `_createTime` TIMESTAMP default CURRENT_TIMESTAMP;
|
||||
alter table t_group add column `_createTime` TIMESTAMP default CURRENT_TIMESTAMP;
|
||||
@@ -0,0 +1,36 @@
|
||||
alter table `t_messages_0` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_1` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_2` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_3` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_4` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_5` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_6` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_7` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_8` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_9` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_10` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_11` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_12` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_13` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_14` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_15` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_16` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_17` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_18` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_19` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_20` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_21` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_22` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_23` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_24` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_25` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_26` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_27` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_28` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_29` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_30` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_31` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_32` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_33` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_34` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
alter table `t_messages_35` add column `_content_type` int(11) NOT NULL DEFAULT '0';
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_sensitive_messages`;
|
||||
CREATE TABLE `t_sensitive_messages` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_mid` bigint(20) NOT NULL,
|
||||
`_from` varchar(64) NOT NULL,
|
||||
`_type` tinyint NOT NULL DEFAULT 0,
|
||||
`_target` varchar(64) NOT NULL,
|
||||
`_line` int(11) NOT NULL DEFAULT 0,
|
||||
`_data` BLOB NOT NULL,
|
||||
`_searchable_key` TEXT DEFAULT NULL,
|
||||
`_dt` DATETIME NOT NULL,
|
||||
`_content_type` int(11) NOT NULL DEFAULT '0',
|
||||
INDEX `message_uid_index` (`_mid` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,27 @@
|
||||
upstream imserver {
|
||||
server 127.0.0.1:8080; #Apache
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.wildfirechat.cn;
|
||||
|
||||
root html;
|
||||
index index.html index.htm index.php;
|
||||
|
||||
## send request back to im server ##
|
||||
location /im {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
location /route {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://imserver;
|
||||
}
|
||||
location / {
|
||||
proxy_pass https://wildfirechat.github.io/docs/;
|
||||
}
|
||||
}
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>0.35</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Moquette - broker</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<bintray.package>io.moquette.moquette-broker</bintray.package>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.7.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.11</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-common</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-buffer</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-handler</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec-http</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
<!--
|
||||
<classifier>${os.detected.name}-${os.detected.arch}</classifier>
|
||||
-->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast</artifactId>
|
||||
<version>3.9.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.xiaoleilu/hutool -->
|
||||
<dependency>
|
||||
<groupId>com.xiaoleilu</groupId>
|
||||
<artifactId>hutool</artifactId>
|
||||
<version>2.15.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
|
||||
<dependency>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.5.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- needs extra dependencies: objenesis & hamcrest -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.fusesource.mqtt-client</groupId>
|
||||
<artifactId>mqtt-client</artifactId>
|
||||
<version>1.12</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-client</artifactId>
|
||||
<version>9.2.0.M1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<!-- use 2.6.0 for Java 7 projects -->
|
||||
<version>2.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.191</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
<artifactId>qiniu-java-sdk</artifactId>
|
||||
<version>7.1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.46</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.197</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.13.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-core -->
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>5.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Generate the test-jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Includes to generate OSGi headers -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
<version>2.1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>revision</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<!--日期格式;默认值:dd.MM.yyyy '@' HH:mm:ss z;-->
|
||||
<dateFormat>yyyyMMddHHmmss</dateFormat>
|
||||
<!--,构建过程中,是否打印详细信息;默认值:false;-->
|
||||
<verbose>true</verbose>
|
||||
<!-- ".git"文件路径;默认值:${project.basedir}/.git; -->
|
||||
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
|
||||
<!--若项目打包类型为pom,是否取消构建;默认值:true;-->
|
||||
<skipPoms>false</skipPoms>
|
||||
<!--是否生成"git.properties"文件;默认值:false;-->
|
||||
<generateGitPropertiesFile>true</generateGitPropertiesFile>
|
||||
<!--指定"git.properties"文件的存放路径(相对于${project.basedir}的一个路径);-->
|
||||
<generateGitPropertiesFilename>config/git.properties</generateGitPropertiesFilename>
|
||||
<!--".git"文件夹未找到时,构建是否失败;若设置true,则构建失败;若设置false,则跳过执行该目标;默认值:true;-->
|
||||
<failOnNoGitDirectory>false</failOnNoGitDirectory>
|
||||
|
||||
<!--git描述配置,可选;由JGit提供实现;-->
|
||||
<gitDescribe>
|
||||
<!--是否生成描述属性-->
|
||||
<skip>false</skip>
|
||||
<!--提交操作未发现tag时,仅打印提交操作ID,-->
|
||||
<always>false</always>
|
||||
<!--提交操作ID显式字符长度,最大值为:40;默认值:7;
|
||||
0代表特殊意义;后面有解释;
|
||||
-->
|
||||
<abbrev>7</abbrev>
|
||||
<!--构建触发时,代码有修改时(即"dirty state"),添加指定后缀;默认值:"";-->
|
||||
<dirty>-dirty</dirty>
|
||||
<!--always print using the "tag-commits_from_tag-g_commit_id-maybe_dirty" format, even if "on" a tag.
|
||||
The distance will always be 0 if you're "on" the tag.
|
||||
-->
|
||||
<forceLongFormat>false</forceLongFormat>
|
||||
</gitDescribe>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.push;
|
||||
|
||||
|
||||
public class PushMessage {
|
||||
public String sender;
|
||||
public String senderName;
|
||||
public int convType;
|
||||
public String target;
|
||||
public String targetName;
|
||||
public int line;
|
||||
public int cntType;
|
||||
public long serverTime;
|
||||
//消息的类型,普通消息通知栏;voip要透传。
|
||||
public int pushMessageType;
|
||||
//推送类型,android推送分为小米/华为/魅族等。ios分别为开发和发布。
|
||||
public int pushType;
|
||||
public String pushContent;
|
||||
public int unReceivedMsg;
|
||||
public int mentionedType;
|
||||
public String packageName;
|
||||
public String deviceToken;
|
||||
public String voipDeviceToken;
|
||||
public boolean isHiddenDetail;
|
||||
public String language;
|
||||
|
||||
public PushMessage(String sender, int conversationType, String target, int line, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionedType, boolean isHiddenDetail, String language) {
|
||||
this.sender = sender;
|
||||
this.convType = conversationType;
|
||||
this.target = target;
|
||||
this.senderName = senderName;
|
||||
this.targetName = targetName;
|
||||
this.line = line;
|
||||
this.cntType = messageContentType;
|
||||
this.serverTime = serverTime;
|
||||
this.unReceivedMsg = unReceivedMsg;
|
||||
this.pushMessageType = (cntType == 400 ? PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_INVITE : (cntType == 402 ? PushServer.PushMessageType.PUSH_MESSAGE_TYPE_VOIP_BYE : PushServer.PushMessageType.PUSH_MESSAGE_TYPE_NORMAL));
|
||||
this.mentionedType = mentionedType;
|
||||
this.isHiddenDetail = isHiddenDetail;
|
||||
this.language = language;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.push;
|
||||
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.server.config.IConfig;
|
||||
import io.moquette.spi.ClientSession;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.HttpUtils;
|
||||
import win.liyufan.im.Utility;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static io.moquette.BrokerConstants.PUSH_ANDROID_SERVER_ADDRESS;
|
||||
import static io.moquette.BrokerConstants.PUSH_IOS_SERVER_ADDRESS;
|
||||
|
||||
public class PushServer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PushServer.class);
|
||||
|
||||
public interface PushMessageType {
|
||||
int PUSH_MESSAGE_TYPE_NORMAL = 0;
|
||||
int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1;
|
||||
int PUSH_MESSAGE_TYPE_VOIP_BYE = 2;
|
||||
}
|
||||
|
||||
private static PushServer INSTANCE = new PushServer();
|
||||
private ISessionsStore sessionsStore;
|
||||
private static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*5);
|
||||
|
||||
private String androidPushServerUrl;
|
||||
private String iOSPushServerUrl;
|
||||
|
||||
private PushServer() {
|
||||
}
|
||||
|
||||
public static PushServer getServer() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void init(IConfig config, ISessionsStore sessionsStore) {
|
||||
this.sessionsStore = sessionsStore;
|
||||
this.androidPushServerUrl = config.getProperty(PUSH_ANDROID_SERVER_ADDRESS);
|
||||
this.iOSPushServerUrl = config.getProperty(PUSH_IOS_SERVER_ADDRESS);
|
||||
}
|
||||
|
||||
public void pushMessage(PushMessage pushMessage, String deviceId, String pushContent) {
|
||||
LOG.info("try to delivery push diviceId = {}, pushContent = {}", deviceId, pushContent);
|
||||
executorService.execute(() ->{
|
||||
try {
|
||||
pushMessageInternel(pushMessage, deviceId, pushContent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void pushMessageInternel(PushMessage pushMessage, String deviceId, String pushContent) {
|
||||
if (pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL && StringUtil.isNullOrEmpty(pushContent)) {
|
||||
LOG.info("push content empty, deviceId {}", deviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
MemorySessionStore.Session session = sessionsStore.getSession(deviceId);
|
||||
int badge = session.getUnReceivedMsgs();
|
||||
if (badge <= 0) {
|
||||
badge = 1;
|
||||
}
|
||||
if (StringUtil.isNullOrEmpty(session.getDeviceToken())) {
|
||||
LOG.warn("Device token is empty for device {}", deviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
pushMessage.packageName = session.getAppName();
|
||||
pushMessage.pushType = session.getPushType();
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.deviceToken = session.getDeviceToken();
|
||||
pushMessage.unReceivedMsg = badge;
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_Android) {
|
||||
String url = androidPushServerUrl;
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS) {
|
||||
url = iOSPushServerUrl;
|
||||
pushMessage.voipDeviceToken = session.getVoipDeviceToken();
|
||||
}
|
||||
HttpUtils.httpJsonPost(url, new Gson().toJson(pushMessage, pushMessage.getClass()));
|
||||
} else {
|
||||
LOG.info("Not mobile platform {}", session.getPlatform());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.server;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Server {
|
||||
public static void main(String[] args) throws IOException {
|
||||
io.moquette.server.Server.start(args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.server;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ThreadPoolExecutorWrapper {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ThreadPoolExecutorWrapper.class);
|
||||
private final ScheduledExecutorService executor;
|
||||
private final int count;
|
||||
private final AtomicInteger runCounter;
|
||||
private final String name;
|
||||
|
||||
public ThreadPoolExecutorWrapper(ScheduledExecutorService executor, int count, String name) {
|
||||
this.executor = executor;
|
||||
this.count = count;
|
||||
this.runCounter = new AtomicInteger();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void execute(Runnable task) {
|
||||
int startCount = runCounter.incrementAndGet();
|
||||
LOG.debug("Submit task and current task count {}", startCount);
|
||||
final long startTime = System.currentTimeMillis();
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
task.run();
|
||||
} finally {
|
||||
int endCount = runCounter.decrementAndGet();
|
||||
LOG.debug("Finish task and current task count {} use time {}", endCount, System.currentTimeMillis()-startTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.xiaoleilu.loServer;
|
||||
|
||||
import com.xiaoleilu.hutool.log.Log;
|
||||
import com.xiaoleilu.hutool.log.StaticLog;
|
||||
import com.xiaoleilu.hutool.util.DateUtil;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.action.ClassUtil;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.ActionHandler;
|
||||
import com.xiaoleilu.loServer.handler.HttpFileServerHandler;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* LoServer starter<br>
|
||||
* 用于启动服务器的主对象<br>
|
||||
* 使用LoServer.start()启动服务器<br>
|
||||
* 服务的Action类和端口等设置在ServerSetting中设置
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class LoFileServer {
|
||||
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(LoFileServer.class);
|
||||
private int port;
|
||||
private IMessagesStore messagesStore;
|
||||
private Channel channel;
|
||||
|
||||
public LoFileServer(int port, IMessagesStore messagesStore) {
|
||||
this.port = port;
|
||||
this.messagesStore = messagesStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动服务
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void start() throws InterruptedException {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// Configure the server.
|
||||
final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
final EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
final ServerBootstrap b = new ServerBootstrap();
|
||||
b.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.option(ChannelOption.SO_BACKLOG, 1024) // 服务端可连接队列大小
|
||||
.option(ChannelOption.SO_KEEPALIVE, true)
|
||||
.option(ChannelOption.SO_REUSEADDR, true)
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.option(ChannelOption.SO_SNDBUF, 1024*1024*10)
|
||||
.option(ChannelOption.SO_RCVBUF, 1024*1024*10)
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
socketChannel.pipeline().addLast(new HttpRequestDecoder());
|
||||
socketChannel.pipeline().addLast(new HttpResponseEncoder());
|
||||
socketChannel.pipeline().addLast(new ChunkedWriteHandler());
|
||||
socketChannel.pipeline().addLast(new HttpObjectAggregator(100 * 1024 * 1024));
|
||||
socketChannel.pipeline().addLast(new HttpFileServerHandler());
|
||||
}
|
||||
});
|
||||
|
||||
channel = b.bind(port).sync().channel();
|
||||
Logger.info("***** Welcome To LoServer on port [{}], startting spend {}ms *****", port, DateUtil.spendMs(start));
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
public void shutdown() {
|
||||
if (this.channel != null) {
|
||||
this.channel.close();
|
||||
try {
|
||||
this.channel.closeFuture().sync();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
package com.xiaoleilu.loServer;
|
||||
|
||||
import com.xiaoleilu.hutool.util.DateUtil;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.AdminActionHandler;
|
||||
import com.xiaoleilu.loServer.handler.IMActionHandler;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import com.xiaoleilu.loServer.action.ClassUtil;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* LoServer starter<br>
|
||||
* 用于启动服务器的主对象<br>
|
||||
* 使用LoServer.start()启动服务器<br>
|
||||
* 服务的Action类和端口等设置在ServerSetting中设置
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class LoServer {
|
||||
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(LoServer.class);
|
||||
private int port;
|
||||
private int adminPort;
|
||||
private IMessagesStore messagesStore;
|
||||
private ISessionsStore sessionsStore;
|
||||
private Channel channel;
|
||||
private Channel adminChannel;
|
||||
|
||||
public LoServer(int port, int adminPort, IMessagesStore messagesStore, ISessionsStore sessionsStore) {
|
||||
this.port = port;
|
||||
this.adminPort = adminPort;
|
||||
this.messagesStore = messagesStore;
|
||||
this.sessionsStore = sessionsStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动服务
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void start() throws InterruptedException {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// Configure the server.
|
||||
final EventLoopGroup bossGroup = new NioEventLoopGroup(2);
|
||||
final EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
|
||||
registerAllAction();
|
||||
|
||||
try {
|
||||
final ServerBootstrap b = new ServerBootstrap();
|
||||
final ServerBootstrap adminB = new ServerBootstrap();
|
||||
b.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true)
|
||||
.option(ChannelOption.SO_REUSEADDR, true)
|
||||
.childOption(ChannelOption.TCP_NODELAY, true)
|
||||
.childOption(ChannelOption.SO_SNDBUF, 1024*64)
|
||||
.childOption(ChannelOption.SO_RCVBUF, 1024*64)
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
socketChannel.pipeline().addLast(new HttpRequestDecoder());
|
||||
socketChannel.pipeline().addLast(new HttpResponseEncoder());
|
||||
socketChannel.pipeline().addLast(new ChunkedWriteHandler());
|
||||
socketChannel.pipeline().addLast(new HttpObjectAggregator(100 * 1024 * 1024));
|
||||
socketChannel.pipeline().addLast(new IMActionHandler(messagesStore, sessionsStore));
|
||||
}
|
||||
});
|
||||
|
||||
channel = b.bind(port).sync().channel();
|
||||
|
||||
|
||||
adminB.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true)
|
||||
.option(ChannelOption.SO_REUSEADDR, true)
|
||||
.childOption(ChannelOption.TCP_NODELAY, true)
|
||||
.childOption(ChannelOption.SO_SNDBUF, 1024*64)
|
||||
.childOption(ChannelOption.SO_RCVBUF, 1024*64)
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
socketChannel.pipeline().addLast(new HttpRequestDecoder());
|
||||
socketChannel.pipeline().addLast(new HttpResponseEncoder());
|
||||
socketChannel.pipeline().addLast(new ChunkedWriteHandler());
|
||||
socketChannel.pipeline().addLast(new HttpObjectAggregator(100 * 1024 * 1024));
|
||||
socketChannel.pipeline().addLast(new AdminActionHandler(messagesStore, sessionsStore));
|
||||
}
|
||||
});
|
||||
|
||||
adminChannel = adminB.bind(adminPort).sync().channel();
|
||||
Logger.info("***** Welcome To LoServer on port [{},{}], startting spend {}ms *****", port, adminPort, DateUtil.spendMs(start));
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
public void shutdown() {
|
||||
if (this.channel!= null) {
|
||||
this.channel.close();
|
||||
try {
|
||||
this.channel.closeFuture().sync();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.adminChannel != null) {
|
||||
this.adminChannel.close();
|
||||
try {
|
||||
this.adminChannel.closeFuture().sync();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerAllAction() {
|
||||
try {
|
||||
for (Class cls:ClassUtil.getAllAssignedClass(Action.class)
|
||||
) {
|
||||
if(cls.getAnnotation(Route.class) != null) {
|
||||
ServerSetting.setAction((Class<? extends Action>)cls);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
public class RestResult {
|
||||
|
||||
|
||||
int code;
|
||||
String msg;
|
||||
Object result;
|
||||
|
||||
public static RestResult ok(Object object) {
|
||||
return resultOf(ErrorCode.ERROR_CODE_SUCCESS, ErrorCode.ERROR_CODE_SUCCESS.getMsg(), object);
|
||||
}
|
||||
|
||||
public static RestResult ok() {
|
||||
return resultOf(ErrorCode.ERROR_CODE_SUCCESS, ErrorCode.ERROR_CODE_SUCCESS.getMsg(), null);
|
||||
}
|
||||
|
||||
public static RestResult resultOf(ErrorCode errorCode) {
|
||||
return resultOf(errorCode, errorCode.msg, null);
|
||||
}
|
||||
|
||||
public static RestResult resultOf(ErrorCode errorCode, String msg) {
|
||||
return resultOf(errorCode, msg, null);
|
||||
}
|
||||
|
||||
public static RestResult resultOf(ErrorCode errorCode, String msg, Object object) {
|
||||
RestResult result = new RestResult();
|
||||
result.code = errorCode.code;
|
||||
result.msg = msg;
|
||||
result.result = object;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setErrorCode(ErrorCode errorCode) {
|
||||
setCode(errorCode.code);
|
||||
}
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
package com.xiaoleilu.loServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.xiaoleilu.hutool.lang.Singleton;
|
||||
import com.xiaoleilu.hutool.log.Log;
|
||||
import com.xiaoleilu.hutool.log.StaticLog;
|
||||
import com.xiaoleilu.hutool.util.FileUtil;
|
||||
import com.xiaoleilu.hutool.util.StrUtil;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.action.DefaultIndexAction;
|
||||
import com.xiaoleilu.loServer.action.UnknownErrorAction;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.exception.ServerSettingException;
|
||||
import com.xiaoleilu.loServer.filter.Filter;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 全局设定文件
|
||||
* @author xiaoleilu
|
||||
*
|
||||
*/
|
||||
public class ServerSetting {
|
||||
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(ServerSetting.class);
|
||||
|
||||
//-------------------------------------------------------- Default value start
|
||||
/** 默认的字符集编码 */
|
||||
public final static String DEFAULT_CHARSET = "utf-8";
|
||||
|
||||
public final static String MAPPING_ALL = "/*";
|
||||
|
||||
public final static String MAPPING_ERROR = "/_error";
|
||||
//-------------------------------------------------------- Default value end
|
||||
|
||||
/** 字符编码 */
|
||||
private static String charset = DEFAULT_CHARSET;
|
||||
/** 端口 */
|
||||
private static int port = 8090;
|
||||
/** 根目录 */
|
||||
private static File root;
|
||||
/** Filter映射表 */
|
||||
private static Map<String, Filter> filterMap;
|
||||
/** Action映射表 */
|
||||
private static Map<String, Action> getActionMap;
|
||||
private static Map<String, Action> postActionMap;
|
||||
private static Map<String, Action> putActionMap;
|
||||
private static Map<String, Action> deleteActionMap;
|
||||
private static Map<String, Action> errorActionMap;
|
||||
|
||||
static{
|
||||
filterMap = new ConcurrentHashMap<String, Filter>();
|
||||
|
||||
getActionMap = new ConcurrentHashMap<String, Action>();
|
||||
postActionMap = new ConcurrentHashMap<String, Action>();
|
||||
|
||||
putActionMap = new ConcurrentHashMap<String, Action>();
|
||||
|
||||
deleteActionMap = new ConcurrentHashMap<String, Action>();
|
||||
|
||||
errorActionMap = new ConcurrentHashMap<String, Action>();
|
||||
errorActionMap.put(StrUtil.SLASH, new DefaultIndexAction());
|
||||
errorActionMap.put(MAPPING_ERROR, new UnknownErrorAction());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 获取编码
|
||||
*/
|
||||
public static String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
/**
|
||||
* @return 字符集
|
||||
*/
|
||||
public static Charset charset() {
|
||||
return Charset.forName(getCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置编码
|
||||
* @param charset 编码
|
||||
*/
|
||||
public static void setCharset(String charset) {
|
||||
ServerSetting.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 监听端口
|
||||
*/
|
||||
public static int getPort() {
|
||||
return port;
|
||||
}
|
||||
/**
|
||||
* 设置监听端口
|
||||
* @param port 端口
|
||||
*/
|
||||
public static void setPort(int port) {
|
||||
ServerSetting.port = port;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------- Root start
|
||||
/**
|
||||
* @return 根目录
|
||||
*/
|
||||
public static File getRoot() {
|
||||
return root;
|
||||
}
|
||||
/**
|
||||
* @return 根目录
|
||||
*/
|
||||
public static boolean isRootAvailable() {
|
||||
if(root != null && root.isDirectory() && root.isHidden() == false && root.canRead()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @return 根目录
|
||||
*/
|
||||
public static String getRootPath() {
|
||||
return FileUtil.getAbsolutePath(root);
|
||||
}
|
||||
/**
|
||||
* 根目录
|
||||
* @param root 根目录绝对路径
|
||||
*/
|
||||
public static void setRoot(String root) {
|
||||
ServerSetting.root = FileUtil.mkdir(root);
|
||||
Logger.debug("Set root to [{}]", ServerSetting.root.getAbsolutePath());
|
||||
}
|
||||
/**
|
||||
* 根目录
|
||||
* @param root 根目录绝对路径
|
||||
*/
|
||||
public static void setRoot(File root) {
|
||||
if(root.exists() == false){
|
||||
root.mkdirs();
|
||||
}else if(root.isDirectory() == false){
|
||||
throw new ServerSettingException(StrUtil.format("{} is not a directory!", root.getPath()));
|
||||
}
|
||||
ServerSetting.root = root;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------- Root end
|
||||
|
||||
//----------------------------------------------------------------------------------------------- Filter start
|
||||
/**
|
||||
* @return 获取FilterMap
|
||||
*/
|
||||
public static Map<String, Filter> getFilterMap() {
|
||||
return filterMap;
|
||||
}
|
||||
/**
|
||||
* 获得路径对应的Filter
|
||||
* @param path 路径,为空时将获得 根目录对应的Action
|
||||
* @return Filter
|
||||
*/
|
||||
public static Filter getFilter(String path){
|
||||
if(StrUtil.isBlank(path)){
|
||||
path = StrUtil.SLASH;
|
||||
}
|
||||
return getFilterMap().get(path.trim());
|
||||
}
|
||||
/**
|
||||
* 设置FilterMap
|
||||
* @param filterMap FilterMap
|
||||
*/
|
||||
public static void setFilterMap(Map<String, Filter> filterMap) {
|
||||
ServerSetting.filterMap = filterMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Filter类,已有的Filter类将被覆盖
|
||||
* @param path 拦截路径(必须以"/"开头)
|
||||
* @param filter Action类
|
||||
*/
|
||||
public static void setFilter(String path, Filter filter) {
|
||||
if(StrUtil.isBlank(path)){
|
||||
path = StrUtil.SLASH;
|
||||
}
|
||||
|
||||
if(null == filter) {
|
||||
Logger.warn("Added blank action, pass it.");
|
||||
return;
|
||||
}
|
||||
//所有路径必须以 "/" 开头,如果没有则补全之
|
||||
if(false == path.startsWith(StrUtil.SLASH)) {
|
||||
path = StrUtil.SLASH + path;
|
||||
}
|
||||
|
||||
ServerSetting.filterMap.put(path, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Filter类,已有的Filter类将被覆盖
|
||||
* @param path 拦截路径(必须以"/"开头)
|
||||
* @param filterClass Filter类
|
||||
*/
|
||||
public static void setFilter(String path, Class<? extends Filter> filterClass) {
|
||||
setFilter(path, (Filter)Singleton.get(filterClass));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------- Filter end
|
||||
|
||||
//----------------------------------------------------------------------------------------------- Action start
|
||||
/**
|
||||
* @return 获取ActionMap
|
||||
*/
|
||||
public static Map<String, Action> getActionMap(String method) {
|
||||
if (method.equals("GET")) {
|
||||
return getActionMap;
|
||||
} else if(method.equals("POST")) {
|
||||
return postActionMap;
|
||||
} else if(method.equals("PUT")) {
|
||||
return putActionMap;
|
||||
} else if(method.equals("DELETE")) {
|
||||
return deleteActionMap;
|
||||
}
|
||||
return getActionMap;
|
||||
}
|
||||
|
||||
public static Action getErrorAction(String path) {
|
||||
return errorActionMap.get(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得路径对应的Action
|
||||
* @param path 路径,为空时将获得 根目录对应的Action
|
||||
* @return Action
|
||||
*/
|
||||
public static Action getAction(String path, String method){
|
||||
if(StrUtil.isBlank(path)){
|
||||
path = StrUtil.SLASH;
|
||||
}
|
||||
return getActionMap(method).get(path.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Action类,已有的Action类将被覆盖
|
||||
* @param path 拦截路径(必须以"/"开头)
|
||||
* @param action Action类
|
||||
*/
|
||||
public static void setAction(String path, Action action) {
|
||||
if(StrUtil.isBlank(path)){
|
||||
path = StrUtil.SLASH;
|
||||
}
|
||||
|
||||
if(null == action) {
|
||||
Logger.warn("Added blank action, pass it.");
|
||||
return;
|
||||
}
|
||||
//所有路径必须以 "/" 开头,如果没有则补全之
|
||||
if(false == path.startsWith(StrUtil.SLASH)) {
|
||||
path = StrUtil.SLASH + path;
|
||||
}
|
||||
String method = "GET";
|
||||
HttpMethod methodAnnotation = action.getClass().getAnnotation(HttpMethod.class);
|
||||
if (methodAnnotation != null) {
|
||||
method = methodAnnotation.value();
|
||||
}
|
||||
ServerSetting.getActionMap(method).put(path, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加Action类,已有的Action类将被覆盖<br>
|
||||
* 所有Action都是以单例模式存在的!
|
||||
* @param path 拦截路径(必须以"/"开头)
|
||||
* @param actionClass Action类
|
||||
*/
|
||||
public static void setAction(String path, Class<? extends Action> actionClass) {
|
||||
setAction(path, (Action)Singleton.get(actionClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加Action类,已有的Action类将被覆盖<br>
|
||||
* 自动读取Route的注解来获得Path路径
|
||||
* @param action 带注解的Action对象
|
||||
*/
|
||||
public static void setAction(Action action) {
|
||||
final Route route = action.getClass().getAnnotation(Route.class);
|
||||
if(route != null){
|
||||
final String path = route.value();
|
||||
if(StrUtil.isNotBlank(path)){
|
||||
setAction(path, action);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ServerSettingException("Can not find Route annotation,please add annotation to Action class!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加Action类,已有的Action类将被覆盖<br>
|
||||
* 所有Action都是以单例模式存在的!
|
||||
* @param actionClass 带注解的Action类
|
||||
*/
|
||||
public static void setAction(Class<? extends Action> actionClass) {
|
||||
setAction((Action)Singleton.get(actionClass));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------- Action start
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.moquette.spi.ISessionsStore;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
/**
|
||||
* 请求处理接口<br>
|
||||
* 当用户请求某个Path,则调用相应Action的doAction方法
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
|
||||
abstract public class Action {
|
||||
public static IMessagesStore messagesStore = null;
|
||||
public static ISessionsStore sessionsStore = null;
|
||||
|
||||
public ChannelHandlerContext ctx;
|
||||
|
||||
public ErrorCode preAction(Request request, Response response) {
|
||||
if (getClass().getAnnotation(RequireAuthentication.class) != null) {
|
||||
//do authentication
|
||||
}
|
||||
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
public boolean doAction(Request request, Response response) {
|
||||
ErrorCode errorCode = preAction(request, response);
|
||||
boolean isSync = true;
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
//事务逻辑有缺陷,先注释掉
|
||||
// if (isTransactionAction() && !(this instanceof IMAction)) {
|
||||
// DBUtil.beginTransaction();
|
||||
// try {
|
||||
// action(request, response);
|
||||
// DBUtil.commit();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// DBUtil.roolback();
|
||||
// throw e;
|
||||
// }
|
||||
// } else {
|
||||
isSync = action(request, response);
|
||||
// }
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (errorCode == null) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), RestResult.resultOf(errorCode));
|
||||
response.setContent(new Gson().toJson(result));
|
||||
response.send();
|
||||
}
|
||||
|
||||
return isSync;
|
||||
}
|
||||
public boolean isTransactionAction() {
|
||||
return false;
|
||||
}
|
||||
abstract public boolean action(Request request, Response response);
|
||||
|
||||
protected <T> T getRequestBody(HttpRequest request, Class<T> cls) {
|
||||
if (request instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);//contribute by JiaRG from github
|
||||
Gson gson = new Gson();
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public class ClassUtil {
|
||||
|
||||
/**
|
||||
* 获取同一路径下所有子类或接口实现类
|
||||
*
|
||||
* @param cls
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public static List<Class<?>> getAllAssignedClass(Class<?> cls) throws IOException,
|
||||
ClassNotFoundException {
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
for (Class<?> c : getClasses(cls)) {
|
||||
if (cls.isAssignableFrom(c) && !cls.equals(c)) {
|
||||
classes.add(c);
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前类路径下的所有类
|
||||
*
|
||||
* @param cls
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public static List<Class<?>> getClasses(Class<?> cls) throws IOException,
|
||||
ClassNotFoundException {
|
||||
String pk = cls.getPackage().getName();
|
||||
// String path = pk.replace('.', '/');
|
||||
// ClassLoader classloader = Thread.currentThread().getContextClassLoader();
|
||||
// URL url = classloader.getResource(path);
|
||||
// String type = url.getProtocol();
|
||||
//
|
||||
// System.out.println("the type is " + type);
|
||||
// System.out.println(url.getPath());
|
||||
//
|
||||
// return getClasses(new File(url.getFile()), pk);
|
||||
List<String> classNames = getClassName(pk, true);
|
||||
List<Class<?>> classes = new ArrayList<>();
|
||||
for (String className :
|
||||
classNames) {
|
||||
if (className.endsWith(".class")) {
|
||||
className = className.substring(0, className.length() - 6);
|
||||
className = className.substring(className.lastIndexOf("/")+1, className.length());
|
||||
}
|
||||
|
||||
classes.add(Class.forName(className));
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 迭代查找类
|
||||
*
|
||||
* @param dir
|
||||
* @param pk
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private static List<Class<?>> getClasses(File dir, String pk) throws ClassNotFoundException {
|
||||
System.out.println(dir.getAbsolutePath());
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
if (!dir.exists()) {
|
||||
return classes;
|
||||
}
|
||||
for (File f : dir.listFiles()) {
|
||||
if (f.isDirectory()) {
|
||||
classes.addAll(getClasses(f, pk + "." + f.getName()));
|
||||
}
|
||||
String name = f.getName();
|
||||
if (name.endsWith(".class")) {
|
||||
classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6)));
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取某包下所有类
|
||||
* @param packageName 包名
|
||||
* @param childPackage 是否遍历子包
|
||||
* @return 类的完整名称
|
||||
*/
|
||||
public static List<String> getClassName(String packageName, boolean childPackage) {
|
||||
List<String> fileNames = null;
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
String packagePath = packageName.replace(".", "/");
|
||||
URL url = loader.getResource(packagePath);
|
||||
if (url != null) {
|
||||
String type = url.getProtocol();
|
||||
if (type.equals("file")) {
|
||||
fileNames = getClassNameByFile(url.getPath(), null, childPackage);
|
||||
} else if (type.equals("jar")) {
|
||||
fileNames = getClassNameByJar(url.getPath(), childPackage);
|
||||
}
|
||||
} else {
|
||||
fileNames = getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage);
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从项目文件获取某包下所有类
|
||||
* @param filePath 文件路径
|
||||
* @param className 类名集合
|
||||
* @param childPackage 是否遍历子包
|
||||
* @return 类的完整名称
|
||||
*/
|
||||
private static List<String> getClassNameByFile(String filePath, List<String> className, boolean childPackage) {
|
||||
List<String> myClassName = new ArrayList<String>();
|
||||
File file = new File(filePath);
|
||||
File[] childFiles = file.listFiles();
|
||||
for (File childFile : childFiles) {
|
||||
if (childFile.isDirectory()) {
|
||||
if (childPackage) {
|
||||
myClassName.addAll(getClassNameByFile(childFile.getPath(), myClassName, childPackage));
|
||||
}
|
||||
} else {
|
||||
String childFilePath = childFile.getPath();
|
||||
if (childFilePath.endsWith(".class")) {
|
||||
if (childFilePath.indexOf("\\classes") >= 0 || childFilePath.indexOf("/classes") >= 0) {
|
||||
int start = childFilePath.indexOf("\\classes");
|
||||
if (start == -1) {
|
||||
start = childFilePath.indexOf("/classes");
|
||||
}
|
||||
childFilePath = childFilePath.substring(start + 9, childFilePath.lastIndexOf("."));
|
||||
}
|
||||
childFilePath = childFilePath.replace("\\", ".");
|
||||
childFilePath = childFilePath.replace("/", ".");
|
||||
myClassName.add(childFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从jar获取某包下所有类
|
||||
* @param jarPath jar文件路径
|
||||
* @param childPackage 是否遍历子包
|
||||
* @return 类的完整名称
|
||||
*/
|
||||
private static List<String> getClassNameByJar(String jarPath, boolean childPackage) {
|
||||
List<String> myClassName = new ArrayList<String>();
|
||||
String[] jarInfo = jarPath.split("!");
|
||||
String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
|
||||
String packagePath = jarInfo[1].substring(1);
|
||||
try {
|
||||
JarFile jarFile = new JarFile(jarFilePath);
|
||||
Enumeration<JarEntry> entrys = jarFile.entries();
|
||||
while (entrys.hasMoreElements()) {
|
||||
JarEntry jarEntry = entrys.nextElement();
|
||||
String entryName = jarEntry.getName();
|
||||
|
||||
if (entryName.endsWith(".class")) {
|
||||
if (childPackage) {
|
||||
if (entryName.startsWith(packagePath)) {
|
||||
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
|
||||
myClassName.add(entryName);
|
||||
}
|
||||
} else {
|
||||
int index = entryName.lastIndexOf("/");
|
||||
String myPackagePath;
|
||||
if (index != -1) {
|
||||
myPackagePath = entryName.substring(0, index);
|
||||
} else {
|
||||
myPackagePath = entryName;
|
||||
}
|
||||
if (myPackagePath.equals(packagePath)) {
|
||||
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
|
||||
myClassName.add(entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从所有jar中搜索该包,并获取该包下所有类
|
||||
* @param urls URL集合
|
||||
* @param packagePath 包路径
|
||||
* @param childPackage 是否遍历子包
|
||||
* @return 类的完整名称
|
||||
*/
|
||||
private static List<String> getClassNameByJars(URL[] urls, String packagePath, boolean childPackage) {
|
||||
List<String> myClassName = new ArrayList<String>();
|
||||
if (urls != null) {
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
URL url = urls[i];
|
||||
String urlPath = url.getPath();
|
||||
// 不必搜索classes文件夹
|
||||
if (urlPath.endsWith("classes/")) {
|
||||
continue;
|
||||
}
|
||||
String jarPath = urlPath + "!/" + packagePath;
|
||||
myClassName.addAll(getClassNameByJar(jarPath, childPackage));
|
||||
}
|
||||
}
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
|
||||
/**
|
||||
* 默认的主页Action,当访问主页且没有定义主页Action时,调用此Action
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class DefaultIndexAction extends Action{
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
response.setContent("Welcome to LoServer.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.xiaoleilu.hutool.log.Log;
|
||||
import com.xiaoleilu.hutool.log.StaticLog;
|
||||
import com.xiaoleilu.hutool.util.DateUtil;
|
||||
import com.xiaoleilu.hutool.util.FileUtil;
|
||||
import com.xiaoleilu.hutool.util.ReUtil;
|
||||
import com.xiaoleilu.hutool.util.StrUtil;
|
||||
import com.xiaoleilu.loServer.ServerSetting;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 默认的主页Action,当访问主页且没有定义主页Action时,调用此Action
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class FileAction extends Action {
|
||||
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(FileAction.class);
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (false == Request.METHOD_GET.equalsIgnoreCase(request.getMethod())) {
|
||||
response.sendError(HttpResponseStatus.METHOD_NOT_ALLOWED, "Please use GET method to request file!");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ServerSetting.isRootAvailable() == false){
|
||||
response.sendError(HttpResponseStatus.NOT_FOUND, "404 Root dir not avaliable!");
|
||||
return true;
|
||||
}
|
||||
|
||||
final File file = getFileByPath(request.getPath());
|
||||
Logger.debug("Client [{}] get file [{}]", request.getIp(), file.getPath());
|
||||
|
||||
// 隐藏文件,跳过
|
||||
if (file.isHidden() || !file.exists()) {
|
||||
response.sendError(HttpResponseStatus.NOT_FOUND, "404 File not found!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 非文件,跳过
|
||||
if (false == file.isFile()) {
|
||||
response.sendError(HttpResponseStatus.FORBIDDEN, "403 Forbidden!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cache Validation
|
||||
String ifModifiedSince = request.getHeader(HttpHeaderNames.IF_MODIFIED_SINCE.toString());
|
||||
if (StrUtil.isNotBlank(ifModifiedSince)) {
|
||||
Date ifModifiedSinceDate = null;
|
||||
try {
|
||||
ifModifiedSinceDate = DateUtil.parse(ifModifiedSince, HTTP_DATE_FORMATER);
|
||||
} catch (Exception e) {
|
||||
Logger.warn("If-Modified-Since header parse error: {}", e.getMessage());
|
||||
}
|
||||
if(ifModifiedSinceDate != null) {
|
||||
// 只对比到秒一级别
|
||||
long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
|
||||
long fileLastModifiedSeconds = file.lastModified() / 1000;
|
||||
if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
|
||||
Logger.debug("File {} not modified.", file.getPath());
|
||||
response.sendNotModified();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response.setContent(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*");
|
||||
private static final SimpleDateFormat HTTP_DATE_FORMATER = new SimpleDateFormat(DateUtil.HTTP_DATETIME_PATTERN, Locale.US);
|
||||
|
||||
|
||||
/**
|
||||
* 通过URL中的path获得文件的绝对路径
|
||||
*
|
||||
* @param httpPath Http请求的Path
|
||||
* @return 文件绝对路径
|
||||
*/
|
||||
public static File getFileByPath(String httpPath) {
|
||||
// Decode the path.
|
||||
try {
|
||||
httpPath = URLDecoder.decode(httpPath, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
|
||||
if (httpPath.isEmpty() || httpPath.charAt(0) != '/') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 路径安全检查
|
||||
if (httpPath.contains("/.") || httpPath.contains("./") || httpPath.charAt(0) == '.' || httpPath.charAt(httpPath.length() - 1) == '.' || ReUtil.isMatch(INSECURE_URI, httpPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 转换为绝对路径
|
||||
return FileUtil.file(ServerSetting.getRoot(), httpPath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
import io.moquette.spi.impl.security.AES;
|
||||
import io.moquette.spi.security.Tokenor;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route("/im")
|
||||
@HttpMethod("POST")
|
||||
public class IMAction extends Action {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest)request.getNettyRequest();
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
|
||||
String str = new String(bytes);
|
||||
try {
|
||||
bytes = Base64.getDecoder().decode(str);
|
||||
} catch (IllegalArgumentException e) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
String cid = fullHttpRequest.headers().get("cid");
|
||||
byte[] cbytes = Base64.getDecoder().decode(cid);
|
||||
cbytes = AES.AESDecrypt(cbytes, "", true);
|
||||
if (cbytes == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
|
||||
return true;
|
||||
}
|
||||
cid = new String(cbytes);
|
||||
|
||||
MemorySessionStore.Session session = sessionsStore.getSession(cid);
|
||||
|
||||
if (session != null) {
|
||||
bytes = AES.AESDecrypt(bytes, session.getSecret(), true);
|
||||
} else {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (bytes == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
WFCMessage.IMHttpWrapper wrapper = WFCMessage.IMHttpWrapper.parseFrom(bytes);
|
||||
String token = wrapper.getToken();
|
||||
String userId = Tokenor.getUserId(token.getBytes());
|
||||
if (userId == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null);
|
||||
} else {
|
||||
RPCCenter.getInstance().sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), userId, TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
sendResponse(response, null, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, false);
|
||||
return false;
|
||||
}
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendResponse(Response response, ErrorCode errorCode, byte[] contents) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if(contents == null) {
|
||||
ByteBuf ackPayload = Unpooled.buffer();
|
||||
ackPayload.ensureWritable(1).writeByte(errorCode.getCode());
|
||||
response.setContent(ackPayload);
|
||||
} else {
|
||||
response.setContent(contents);
|
||||
}
|
||||
response.send();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.xiaoleilu.hutool.log.Log;
|
||||
import com.xiaoleilu.hutool.log.StaticLog;
|
||||
import com.xiaoleilu.hutool.util.StrUtil;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* 错误堆栈Action类
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class NotFoundAction extends Action{
|
||||
|
||||
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(NotFoundAction.class);
|
||||
|
||||
public final static String ERROR_PARAM_NAME = "_e";
|
||||
|
||||
private final static String TEMPLATE_ERROR = "<!DOCTYPE html><html><head><title>LoServer - Error report</title><style>h1,h3 {color:white; background-color: gray;}</style></head><body><h1>HTTP Status {} - {}</h1><hr size=\"1\" noshade=\"noshade\" /><p>{}</p><hr size=\"1\" noshade=\"noshade\" /><h3>LoServer</h3></body></html>";
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
response.sendError(HttpResponseStatus.NOT_FOUND, "404 Not found!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
import io.moquette.spi.impl.security.AES;
|
||||
import io.moquette.spi.security.Tokenor;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route("/route")
|
||||
@HttpMethod("POST")
|
||||
public class RouteAction extends Action {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RouteAction.class);
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request.getNettyRequest();
|
||||
boolean b = false;
|
||||
if ("web".equalsIgnoreCase(fullHttpRequest.headers().get("p"))) {
|
||||
b = true;
|
||||
}
|
||||
|
||||
final boolean base64Response = b;
|
||||
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
|
||||
String str = new String(bytes);
|
||||
try {
|
||||
bytes = Base64.getDecoder().decode(str);
|
||||
} catch (IllegalArgumentException e) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response);
|
||||
return true;
|
||||
}
|
||||
|
||||
String cid = fullHttpRequest.headers().get("cid");
|
||||
byte[] cbytes = Base64.getDecoder().decode(cid);
|
||||
cbytes = AES.AESDecrypt(cbytes, "", true);
|
||||
if (cbytes == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response);
|
||||
return true;
|
||||
}
|
||||
cid = new String(cbytes);
|
||||
|
||||
String uid = fullHttpRequest.headers().get("uid");
|
||||
byte[] ubytes = Base64.getDecoder().decode(uid);
|
||||
ubytes = AES.AESDecrypt(ubytes, "", true);
|
||||
if (ubytes == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response);
|
||||
return true;
|
||||
}
|
||||
uid = new String(ubytes);
|
||||
|
||||
|
||||
MemorySessionStore.Session session = sessionsStore.sessionForClientAndUser(uid, cid);
|
||||
if (session == null) {
|
||||
ErrorCode errorCode = sessionsStore.loadActiveSession(uid, cid);
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, errorCode, null, base64Response);
|
||||
return true;
|
||||
}
|
||||
session = sessionsStore.sessionForClientAndUser(uid, cid);
|
||||
}
|
||||
|
||||
|
||||
if (session != null) {
|
||||
bytes = AES.AESDecrypt(bytes, session.getSecret(), true);
|
||||
} else {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (bytes == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
WFCMessage.IMHttpWrapper wrapper = WFCMessage.IMHttpWrapper.parseFrom(bytes);
|
||||
String token = wrapper.getToken();
|
||||
String userId = Tokenor.getUserId(token.getBytes());
|
||||
LOG.info("RouteAction token={}, userId={}", token, userId);
|
||||
if (userId == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null, base64Response);
|
||||
} else {
|
||||
RPCCenter.getInstance().sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), userId, TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
sendResponse(response, null, result, base64Response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null, base64Response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null, base64Response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, false);
|
||||
return false;
|
||||
}
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null, false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendResponse(Response response, ErrorCode errorCode, byte[] contents, boolean base64Response) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (contents == null) {
|
||||
ByteBuf ackPayload = Unpooled.buffer();
|
||||
ackPayload.ensureWritable(1).writeByte(errorCode.getCode());
|
||||
contents = ackPayload.array();
|
||||
}
|
||||
if (base64Response) {
|
||||
byte[] base64Data = Base64.getEncoder().encode(contents);
|
||||
response.setContent(base64Data);
|
||||
} else {
|
||||
response.setContent(contents);
|
||||
}
|
||||
response.send();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.xiaoleilu.hutool.log.Log;
|
||||
import com.xiaoleilu.hutool.log.StaticLog;
|
||||
import com.xiaoleilu.hutool.util.StrUtil;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
|
||||
import io.moquette.spi.IMessagesStore;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 错误堆栈Action类
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class UnknownErrorAction extends Action{
|
||||
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(UnknownErrorAction.class);
|
||||
|
||||
public final static String ERROR_PARAM_NAME = "_e";
|
||||
|
||||
private final static String TEMPLATE_ERROR = "<!DOCTYPE html><html><head><title>LoServer - Error report</title><style>h1,h3 {color:white; background-color: gray;}</style></head><body><h1>HTTP Status {} - {}</h1><hr size=\"1\" noshade=\"noshade\" /><p>{}</p><hr size=\"1\" noshade=\"noshade\" /><h3>LoServer</h3></body></html>";
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
response.setStatus(HttpResponseStatus.NOT_FOUND);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.*;
|
||||
import io.moquette.server.config.MediaServerConfig;
|
||||
import io.moquette.spi.impl.security.AES;
|
||||
import io.moquette.spi.security.DES;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.handler.codec.http.*;
|
||||
import io.netty.handler.codec.http.multipart.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.xiaoleilu.loServer.handler.HttpResponseHelper.getFileExt;
|
||||
|
||||
@Route("/fs")
|
||||
@HttpMethod("POST")
|
||||
@RequireAuthentication
|
||||
public class UploadFileAction extends Action {
|
||||
private static final String KEY = "imfile";
|
||||
private static final Logger logger = LoggerFactory.getLogger(UploadFileAction.class);
|
||||
private static final HttpDataFactory factory = new DefaultHttpDataFactory(false);
|
||||
|
||||
public static class InvalidateTokenExecption extends Exception {
|
||||
|
||||
}
|
||||
|
||||
public static String getToken(int type) {
|
||||
String signKey = KEY + "|" + (System.currentTimeMillis()) + "|" + type;
|
||||
try {
|
||||
return DES.encryptDES(signKey);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int validateToken(String token) throws InvalidateTokenExecption {
|
||||
try {
|
||||
String signKey = DES.decryptDES(token);
|
||||
String[] parts = signKey.split("\\|");
|
||||
if(parts.length == 3) {
|
||||
if(parts[0].equals(KEY)) {
|
||||
long timestamp = Long.parseLong(parts[1]);
|
||||
if(Math.abs(System.currentTimeMillis() - timestamp) < 2 * 60 * 60 * 1000) {
|
||||
return Integer.parseInt(parts[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
//e.printStackTrace();
|
||||
}
|
||||
throw new InvalidateTokenExecption();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request r, Response response) {
|
||||
if (r.getNettyRequest() instanceof FullHttpRequest) {
|
||||
|
||||
FullHttpRequest request = (FullHttpRequest) r.getNettyRequest();
|
||||
String requestId = UUID.randomUUID().toString().replace("-", "");
|
||||
logger.info("HttpFileServerHandler received a request: method=" + request.getMethod() + ", uri=" + request.getUri() + ", requestId=" + requestId);
|
||||
|
||||
if (!request.getDecoderResult().isSuccess()) {
|
||||
logger.warn("http decode failed!");
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("http decode failed");
|
||||
return true;
|
||||
}
|
||||
|
||||
multipartUpload(request, requestId, response);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* multipart上传
|
||||
*/
|
||||
private void multipartUpload(FullHttpRequest request, String requestId, Response response) {
|
||||
HttpPostRequestDecoder decoder = null;
|
||||
try {
|
||||
decoder = new HttpPostRequestDecoder(factory, request);
|
||||
} catch (HttpPostRequestDecoder.ErrorDataDecoderException e1) {
|
||||
logger.error("Failed to decode file data!", e1);
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("Failed to decode file data!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (decoder != null) {
|
||||
if (request instanceof HttpContent) {
|
||||
HttpContent chunk = (HttpContent) request;
|
||||
try {
|
||||
decoder.offer(chunk);
|
||||
} catch (HttpPostRequestDecoder.ErrorDataDecoderException e1) {
|
||||
logger.warn("BAD_REQUEST, Failed to decode file data");
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("Failed to decode file data!");
|
||||
return;
|
||||
}
|
||||
|
||||
long fileTotalSize = 0;
|
||||
if (request.headers().contains("X-File-Total-Size")) {
|
||||
try {
|
||||
fileTotalSize = Integer.parseInt(request.headers().get("X-File-Total-Size"));
|
||||
} catch (Exception e) {
|
||||
logger.warn("invalid X-File-Total-Size value!");
|
||||
}
|
||||
}
|
||||
|
||||
readHttpDataChunkByChunk(response, decoder, requestId, HttpHeaders.isKeepAlive(request));
|
||||
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
|
||||
}
|
||||
} else {
|
||||
logger.warn("BAD_REQUEST, Not a http request");
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("Not a http request");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readHttpDataChunkByChunk
|
||||
*/
|
||||
private void readHttpDataChunkByChunk(Response response, HttpPostRequestDecoder decoder, String requestId, boolean isKeepAlive) {
|
||||
try {
|
||||
int[] bucket = new int[1];
|
||||
bucket[0] = -1;
|
||||
while (decoder.hasNext()) {
|
||||
InterfaceHttpData data = decoder.next();
|
||||
if (data != null) {
|
||||
try {
|
||||
if(!writeFileUploadData(data, response, requestId, isKeepAlive, bucket)) {
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
data.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.info("chunk end");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* writeFileUploadData
|
||||
*/
|
||||
private boolean writeFileUploadData(InterfaceHttpData data, Response response, String requestId, boolean isKeepAlive, int[] bucket) {
|
||||
try {
|
||||
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
|
||||
FileUpload fileUpload = (FileUpload) data;
|
||||
|
||||
String remoteFileName = fileUpload.getFilename();
|
||||
long remoteFileSize = fileUpload.length();
|
||||
|
||||
if(bucket[0] == -1) {
|
||||
logger.warn("Not authenticated!");
|
||||
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("Not authenticated!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(remoteFileName)) {
|
||||
logger.warn("remoteFileName is empty!");
|
||||
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("file name is empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(requestId)) {
|
||||
logger.warn("requestId is empty!");
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("requestId is empty!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remoteFileSize > 50 * 1024 * 1024) {
|
||||
logger.warn("file over limite!(" + remoteFileSize + ")");
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("file over limite!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
String remoteFileExt = "";
|
||||
if (remoteFileName.lastIndexOf(".") == -1) {
|
||||
remoteFileExt = "octetstream";
|
||||
remoteFileName = remoteFileName + "." + remoteFileExt;
|
||||
|
||||
} else {
|
||||
remoteFileExt = getFileExt(remoteFileName);
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(remoteFileExt) || remoteFileExt.equals("ing")) {
|
||||
logger.warn("Invalid file extention name");
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("Invalid file extention name");
|
||||
return false;
|
||||
}
|
||||
|
||||
int remoteFileTotalSize = (int) remoteFileSize;
|
||||
|
||||
|
||||
ByteBuf byteBuf = null;
|
||||
int savedThunkSize = 0; // 分片接收保存的大小
|
||||
int offset = 0; // 断点续传开始位置
|
||||
|
||||
Date nowTime=new Date();
|
||||
SimpleDateFormat time=new SimpleDateFormat("yyyy/MM/dd/HH");
|
||||
String datePath = time.format(nowTime);
|
||||
|
||||
datePath = "fs/" + bucket[0] + "/" + datePath; //add bucket
|
||||
|
||||
String dir = "./" + MediaServerConfig.FILE_STROAGE_ROOT + "/" + datePath;
|
||||
|
||||
File dirFile = new File(dir);
|
||||
boolean bFile = dirFile.exists();
|
||||
|
||||
if(!bFile) {
|
||||
bFile = dirFile.mkdirs();
|
||||
if (!bFile) {
|
||||
response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
|
||||
response.setContent("服务器错误:无法创建文件");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String filePath = dir + "/" + requestId;
|
||||
logger.info("the file path is " + filePath);
|
||||
|
||||
File tmpFile = new File(filePath);
|
||||
|
||||
logger.info("before write the file");
|
||||
boolean isError = false;
|
||||
while (true) {
|
||||
byte[] thunkData;
|
||||
try {
|
||||
byteBuf = fileUpload.getChunk(128 * 1024);
|
||||
int readableBytesSize = byteBuf.readableBytes();
|
||||
thunkData = new byte[readableBytesSize];
|
||||
byteBuf.readBytes(thunkData);
|
||||
|
||||
put(tmpFile, offset, thunkData);
|
||||
|
||||
savedThunkSize += readableBytesSize;
|
||||
offset += readableBytesSize;
|
||||
|
||||
if (savedThunkSize >= remoteFileSize) {
|
||||
byteBuf.release();
|
||||
fileUpload.release();
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
String relativePath = datePath + "/" + requestId;
|
||||
response.setContent("{\"key\":\"" + relativePath + "\"}");
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("save thunckData error!", e);
|
||||
if (fileUpload != null)
|
||||
fileUpload.release();
|
||||
|
||||
if (byteBuf != null)
|
||||
byteBuf.release();
|
||||
|
||||
response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
|
||||
response.setContent("服务器错误:" + e.getMessage());
|
||||
isError = true;
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
thunkData = null;
|
||||
if (isError) {
|
||||
tmpFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
|
||||
Attribute attribute = (Attribute)data;
|
||||
if(attribute.getName().equals("token")) {
|
||||
String token = attribute.getValue();
|
||||
|
||||
try {
|
||||
bucket[0] = validateToken(token);
|
||||
} catch (InvalidateTokenExecption e) {
|
||||
logger.error("无效的token!", e);
|
||||
response.setStatus(HttpResponseStatus.BAD_REQUEST);
|
||||
response.setContent("无效的token:" + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("writeHttpData error!", e);
|
||||
response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
|
||||
response.setContent("服务器错误:" + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void put(File file, long pos, byte[] data) throws Exception {
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(file, "rwd");
|
||||
raf.seek(pos);
|
||||
raf.write(data);
|
||||
} finally {
|
||||
try {
|
||||
if (raf != null)
|
||||
raf.close();
|
||||
} catch (Exception e) {
|
||||
logger.warn("release error!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputUserLogin;
|
||||
import cn.wildfirechat.pojos.OutputLoginData;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import win.liyufan.im.GitRepositoryState;
|
||||
import win.liyufan.im.Utility;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Route("/api/version")
|
||||
@HttpMethod("GET")
|
||||
public class VersionAction extends Action {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
|
||||
try {
|
||||
|
||||
response.setContent(Utility.formatJson(new Gson().toJson(GitRepositoryState.getGitRepositoryState())));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
response.setContent("{\"version\":\"unknown\"}");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputAddGroupMember;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Group_Member_Add)
|
||||
@HttpMethod("POST")
|
||||
public class AddGroupMemberAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputAddGroupMember inputAddGroupMember = getRequestBody(request.getNettyRequest(), InputAddGroupMember.class);
|
||||
if (inputAddGroupMember.isValide()) {
|
||||
RPCCenter.getInstance().sendRequest(inputAddGroupMember.getOperator(), null, IMTopic.AddGroupMemberTopic, inputAddGroupMember.toProtoGroupRequest().toByteArray(), inputAddGroupMember.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, null, null);
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.Action;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.RateLimiter;
|
||||
|
||||
abstract public class AdminAction extends Action {
|
||||
private static String SECRET_KEY = "123456";
|
||||
private static boolean NO_CHECK_TIME = false;
|
||||
private final RateLimiter mLimitCounter = new RateLimiter(10, 500);
|
||||
public static void setSecretKey(String secretKey) {
|
||||
SECRET_KEY = secretKey;
|
||||
}
|
||||
|
||||
public static void setNoCheckTime(String noCheckTime) {
|
||||
try {
|
||||
NO_CHECK_TIME = Boolean.parseBoolean(noCheckTime);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode preAction(Request request, Response response) {
|
||||
if (!mLimitCounter.isGranted("admin")) {
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
String nonce = request.getHeader("nonce");
|
||||
String timestamp = request.getHeader("timestamp");
|
||||
String sign = request.getHeader("sign");
|
||||
if (StringUtil.isNullOrEmpty(nonce) || StringUtil.isNullOrEmpty(timestamp) || StringUtil.isNullOrEmpty(sign)) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Long ts;
|
||||
try {
|
||||
ts = Long.parseLong(timestamp);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!NO_CHECK_TIME && System.currentTimeMillis() - ts > 2 * 60 * 60 * 1000) {
|
||||
return ErrorCode.ERROR_CODE_SIGN_EXPIRED;
|
||||
}
|
||||
|
||||
String str = nonce + "|" + SECRET_KEY + "|" + timestamp;
|
||||
String localSign = DigestUtils.sha1Hex(str);
|
||||
return localSign.equals(sign) ? ErrorCode.ERROR_CODE_SUCCESS : ErrorCode.ERROR_CODE_AUTH_FAILURE;
|
||||
}
|
||||
|
||||
protected void sendResponse(Response response, ErrorCode errorCode, Object data) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (errorCode == null) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), data);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
response.send();
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputOutputUserBlockStatus;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
@Route(APIPath.User_Update_Block_Status)
|
||||
@HttpMethod("POST")
|
||||
public class BlockUserAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputOutputUserBlockStatus inputUserBlock = getRequestBody(request.getNettyRequest(), InputOutputUserBlockStatus.class);
|
||||
if (inputUserBlock != null
|
||||
&& !StringUtil.isNullOrEmpty(inputUserBlock.getUserId())) {
|
||||
|
||||
ErrorCode errorCode = messagesStore.modifyUserStatus(inputUserBlock.getUserId(), inputUserBlock.getStatus());
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
result = RestResult.resultOf(errorCode);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
if (inputUserBlock.getStatus() == 2) {
|
||||
RPCCenter.getInstance().sendRequest(null, null, RPCCenter.KICKOFF_USER_REQUEST, inputUserBlock.getUserId().getBytes(), inputUserBlock.getUserId(), TargetEntry.Type.TARGET_TYPE_USER, null, true);
|
||||
}
|
||||
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, null);
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.BroadMessageData;
|
||||
import cn.wildfirechat.pojos.BroadMessageResult;
|
||||
import cn.wildfirechat.pojos.SendMessageData;
|
||||
import cn.wildfirechat.pojos.SendMessageResult;
|
||||
import com.google.gson.Gson;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Msg_Broadcast)
|
||||
@HttpMethod("POST")
|
||||
public class BroadcastMessageAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
BroadMessageData sendMessageData = getRequestBody(request.getNettyRequest(), BroadMessageData.class);
|
||||
if (BroadMessageData.isValide(sendMessageData) && !StringUtil.isNullOrEmpty(sendMessageData.getSender())) {
|
||||
RPCCenter.getInstance().sendRequest(sendMessageData.getSender(), null, IMTopic.BroadcastMessageTopic, sendMessageData.toProtoMessage().toByteArray(), sendMessageData.getSender(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
long messageId = byteBuf.readLong();
|
||||
long count = byteBuf.readLong();
|
||||
sendResponse(response, null, new BroadMessageResult(messageId, count));
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
@Route(APIPath.User_Get_Online_Status)
|
||||
@HttpMethod("POST")
|
||||
public class CheckUserOnlineAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetUserInfo inputUserId = getRequestBody(request.getNettyRequest(), InputGetUserInfo.class);
|
||||
if (inputUserId == null || !StringUtil.isNullOrEmpty(inputUserId.getUserId())) {
|
||||
RPCCenter.getInstance().sendRequest(null, null, RPCCenter.CHECK_USER_ONLINE_REQUEST, inputUserId.getUserId().getBytes(), inputUserId.getUserId(), TargetEntry.Type.TARGET_TYPE_USER, null, true);
|
||||
return true;
|
||||
} else {
|
||||
sendResponse(response, ErrorCode.INVALID_PARAMETER, null);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import win.liyufan.im.UUIDGenerator;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Create_Channel)
|
||||
@HttpMethod("POST")
|
||||
public class CreateChannelAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputCreateChannel inputCreateChannel = getRequestBody(request.getNettyRequest(), InputCreateChannel.class);
|
||||
if (inputCreateChannel != null
|
||||
&& !StringUtil.isNullOrEmpty(inputCreateChannel.getName())) {
|
||||
|
||||
|
||||
if(StringUtil.isNullOrEmpty(inputCreateChannel.getTargetId())) {
|
||||
inputCreateChannel.setTargetId(messagesStore.getShortUUID());
|
||||
}
|
||||
|
||||
RPCCenter.getInstance().sendRequest(inputCreateChannel.getOwner(), null, IMTopic.CreateChannelTopic, inputCreateChannel.toProtoChannelInfo().toByteArray(), inputCreateChannel.getOwner(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, null, new OutputCreateChannel(inputCreateChannel.getTargetId()));
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputCreateChatroom;
|
||||
import cn.wildfirechat.pojos.OutputCreateChatroom;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
@Route(APIPath.Create_Chatroom)
|
||||
@HttpMethod("POST")
|
||||
public class CreateChatroomAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest)request.getNettyRequest();
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes);
|
||||
Gson gson = new Gson();
|
||||
InputCreateChatroom inputCreateChatroom = gson.fromJson(content, InputCreateChatroom.class);
|
||||
if (inputCreateChatroom != null
|
||||
&& !StringUtil.isNullOrEmpty(inputCreateChatroom.getTitle())) {
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputCreateChatroom.getChatroomId())) {
|
||||
inputCreateChatroom.setChatroomId(messagesStore.getShortUUID());
|
||||
}
|
||||
|
||||
if (inputCreateChatroom.getPortrait() == null || inputCreateChatroom.getPortrait().length() == 0) {
|
||||
inputCreateChatroom.setPortrait("https://avatars.io/gravatar/" + inputCreateChatroom.getChatroomId());
|
||||
}
|
||||
|
||||
WFCMessage.ChatroomInfo info = inputCreateChatroom.toChatroomInfo();
|
||||
|
||||
messagesStore.createChatroom(inputCreateChatroom.getChatroomId(), info);
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok(new OutputCreateChatroom(inputCreateChatroom.getChatroomId()));
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputCreateGroup;
|
||||
import cn.wildfirechat.pojos.OutputCreateGroupResult;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Create_Group)
|
||||
@HttpMethod("POST")
|
||||
public class CreateGroupAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputCreateGroup inputCreateGroup = getRequestBody(request.getNettyRequest(), InputCreateGroup.class);
|
||||
if (inputCreateGroup.isValide()) {
|
||||
RPCCenter.getInstance().sendRequest(inputCreateGroup.getOperator(), null, IMTopic.CreateGroupTopic, inputCreateGroup.toProtoGroupRequest().toByteArray(), inputCreateGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String groupId = new String(data);
|
||||
sendResponse(response, null, new OutputCreateGroupResult(groupId));
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputCreateRobot;
|
||||
import cn.wildfirechat.pojos.OutputCreateRobot;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.UUIDGenerator;
|
||||
|
||||
@Route(APIPath.Create_Robot)
|
||||
@HttpMethod("POST")
|
||||
public class CreateRobotAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputCreateRobot inputCreateRobot = getRequestBody(request.getNettyRequest(), InputCreateRobot.class);
|
||||
if (inputCreateRobot != null
|
||||
&& !StringUtil.isNullOrEmpty(inputCreateRobot.getName())) {
|
||||
|
||||
if(StringUtil.isNullOrEmpty(inputCreateRobot.getPassword())) {
|
||||
inputCreateRobot.setPassword(UUIDGenerator.getUUID());
|
||||
}
|
||||
|
||||
if(StringUtil.isNullOrEmpty(inputCreateRobot.getUserId())) {
|
||||
inputCreateRobot.setUserId(messagesStore.getShortUUID());
|
||||
}
|
||||
|
||||
if (inputCreateRobot.getPortrait() == null || inputCreateRobot.getPortrait().length() == 0) {
|
||||
inputCreateRobot.setPortrait("https://avatars.io/gravatar/" + inputCreateRobot.getUserId());
|
||||
}
|
||||
|
||||
WFCMessage.User newUser = inputCreateRobot.toUser();
|
||||
|
||||
|
||||
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword());
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputCreateRobot.getOwner())) {
|
||||
inputCreateRobot.setOwner(inputCreateRobot.getUserId());
|
||||
}
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputCreateRobot.getSecret())) {
|
||||
inputCreateRobot.setSecret(UUIDGenerator.getUUID());
|
||||
}
|
||||
|
||||
messagesStore.addRobot(inputCreateRobot.toRobot());
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok(new OutputCreateRobot(inputCreateRobot.getUserId(), inputCreateRobot.getSecret()));
|
||||
response.setContent(new Gson().toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputCreateUser;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.UUIDGenerator;
|
||||
|
||||
@Route(APIPath.Create_User)
|
||||
@HttpMethod("POST")
|
||||
public class CreateUserAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputOutputUserInfo inputCreateUser = getRequestBody(request.getNettyRequest(), InputOutputUserInfo.class);
|
||||
if (inputCreateUser != null
|
||||
&& !StringUtil.isNullOrEmpty(inputCreateUser.getName())) {
|
||||
|
||||
if(StringUtil.isNullOrEmpty(inputCreateUser.getPassword())) {
|
||||
inputCreateUser.setPassword(UUIDGenerator.getUUID());
|
||||
}
|
||||
|
||||
if(StringUtil.isNullOrEmpty(inputCreateUser.getUserId())) {
|
||||
inputCreateUser.setUserId(messagesStore.getShortUUID());
|
||||
}
|
||||
|
||||
WFCMessage.User.Builder newUserBuilder = WFCMessage.User.newBuilder()
|
||||
.setUid(StringUtil.isNullOrEmpty(inputCreateUser.getUserId()) ? "" : inputCreateUser.getUserId());
|
||||
if (inputCreateUser.getName() != null)
|
||||
newUserBuilder.setName(inputCreateUser.getName());
|
||||
if (inputCreateUser.getDisplayName() != null)
|
||||
newUserBuilder.setDisplayName(StringUtil.isNullOrEmpty(inputCreateUser.getDisplayName()) ? inputCreateUser.getName() : inputCreateUser.getDisplayName());
|
||||
if (inputCreateUser.getPortrait() != null)
|
||||
newUserBuilder.setPortrait(inputCreateUser.getPortrait());
|
||||
if (inputCreateUser.getEmail() != null)
|
||||
newUserBuilder.setEmail(inputCreateUser.getEmail());
|
||||
if (inputCreateUser.getAddress() != null)
|
||||
newUserBuilder.setAddress(inputCreateUser.getAddress());
|
||||
if (inputCreateUser.getCompany() != null)
|
||||
newUserBuilder.setCompany(inputCreateUser.getCompany());
|
||||
|
||||
if (inputCreateUser.getSocial() != null)
|
||||
newUserBuilder.setSocial(inputCreateUser.getSocial());
|
||||
|
||||
|
||||
if (inputCreateUser.getMobile() != null)
|
||||
newUserBuilder.setMobile(inputCreateUser.getMobile());
|
||||
newUserBuilder.setGender(inputCreateUser.getGender());
|
||||
if (inputCreateUser.getExtra() != null)
|
||||
newUserBuilder.setExtra(inputCreateUser.getExtra());
|
||||
|
||||
newUserBuilder.setUpdateDt(System.currentTimeMillis());
|
||||
|
||||
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword());
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok(new OutputCreateUser(inputCreateUser.getUserId(), inputCreateUser.getName()));
|
||||
response.setContent(new Gson().toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputDestoryChatroom;
|
||||
import io.moquette.spi.impl.Utils;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
@Route(APIPath.Chatroom_Destroy)
|
||||
@HttpMethod("POST")
|
||||
public class DestoryChatroomAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest)request.getNettyRequest();
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes);
|
||||
Gson gson = new Gson();
|
||||
InputDestoryChatroom inputDestoryChatroom = gson.fromJson(content, InputDestoryChatroom.class);
|
||||
if (inputDestoryChatroom != null
|
||||
&& !StringUtil.isNullOrEmpty(inputDestoryChatroom.getChatroomId())) {
|
||||
|
||||
messagesStore.destoryChatroom(inputDestoryChatroom.getChatroomId());
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok();
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputDestroyUser;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputCreateUser;
|
||||
import cn.wildfirechat.pojos.OutputGetIMTokenData;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import win.liyufan.im.UUIDGenerator;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Destroy_User)
|
||||
@HttpMethod("POST")
|
||||
public class DestroyUserAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputDestroyUser inputDestroyUser = getRequestBody(request.getNettyRequest(), InputDestroyUser.class);
|
||||
if (inputDestroyUser != null
|
||||
&& !StringUtil.isNullOrEmpty(inputDestroyUser.getUserId())) {
|
||||
|
||||
WFCMessage.IDBuf idBuf = WFCMessage.IDBuf.newBuilder().setId(inputDestroyUser.getUserId()).build();
|
||||
RPCCenter.getInstance().sendRequest(inputDestroyUser.getUserId(), null, IMTopic.DestroyUserTopic, idBuf.toByteArray(), inputDestroyUser.getUserId(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ErrorCode errorCode1 = ErrorCode.fromCode(result[0]);
|
||||
if (errorCode1 == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
//ba errorcode qudiao
|
||||
byte[] data = new byte[result.length -1];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = result[i+1];
|
||||
}
|
||||
String token = Base64.getEncoder().encodeToString(data);
|
||||
|
||||
sendResponse(response, null, null);
|
||||
} else {
|
||||
sendResponse(response, errorCode1, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputDismissGroup;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Group_Dismiss)
|
||||
@HttpMethod("POST")
|
||||
public class DismissGroupAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputDismissGroup inputDismissGroup = getRequestBody(request.getNettyRequest(), InputDismissGroup.class);
|
||||
if (inputDismissGroup.isValide()) {
|
||||
RPCCenter.getInstance().sendRequest(inputDismissGroup.getOperator(), null, IMTopic.DismissGroupTopic, inputDismissGroup.toProtoGroupRequest().toByteArray(), inputDismissGroup.getOperator(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, null, null);
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputFriendRequest;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.Friend_Update_Status)
|
||||
@HttpMethod("POST")
|
||||
public class FriendRelationAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputFriendRequest friendAdd = getRequestBody(request.getNettyRequest(), InputFriendRequest.class);
|
||||
if (friendAdd != null
|
||||
&& !StringUtil.isNullOrEmpty(friendAdd.getUserId())
|
||||
&& !StringUtil.isNullOrEmpty(friendAdd.getFriendUid())
|
||||
) {
|
||||
WFCMessage.HandleFriendRequest friendRequest = WFCMessage.HandleFriendRequest.newBuilder().setTargetUid(friendAdd.getFriendUid()).setStatus(friendAdd.getStatus()).build();
|
||||
RPCCenter.getInstance().sendRequest(friendAdd.getUserId(), null, IMTopic.HandleFriendRequestTopic, friendRequest.toByteArray(), friendAdd.getFriendUid(), TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
sendResponse(response, null, null);
|
||||
} else {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> ctx.executor().execute(command);
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import cn.wildfirechat.pojos.InputGetFriendList;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Friend_Get_List)
|
||||
@HttpMethod("POST")
|
||||
public class FriendRelationGetAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetFriendList inputGetFriendList = getRequestBody(request.getNettyRequest(), InputGetFriendList.class);
|
||||
List<FriendData> dataList = messagesStore.getFriendList(inputGetFriendList.getUserId(), null, 0);
|
||||
List<String> list = new ArrayList<>();
|
||||
for (FriendData data : dataList) {
|
||||
if (data.getState() == inputGetFriendList.getStatus()) {
|
||||
list.add(data.getFriendUid());
|
||||
}
|
||||
}
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok(list);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
@Route(APIPath.Chatroom_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetChatroomInfoAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetChatroomInfo getChatroomInfo = getRequestBody(request.getNettyRequest(), InputGetChatroomInfo.class);
|
||||
String chatroomid = getChatroomInfo.getChatroomId();
|
||||
if (!StringUtil.isNullOrEmpty(chatroomid)) {
|
||||
|
||||
WFCMessage.ChatroomInfo info = messagesStore.getChatroomInfo(chatroomid);
|
||||
|
||||
RestResult result;
|
||||
if (info != null) {
|
||||
result = RestResult.ok(new OutputGetChatroomInfo(chatroomid, messagesStore.getChatroomMemberCount(chatroomid), info));
|
||||
} else {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
}
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
|
||||
response.setContent(new Gson().toJson(result));
|
||||
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetGroup;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Group_Get_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetGroupInfoAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetGroup inputGetGroup = getRequestBody(request.getNettyRequest(), InputGetGroup.class);
|
||||
if (inputGetGroup != null
|
||||
&& (!StringUtil.isNullOrEmpty(inputGetGroup.getGroupId()))) {
|
||||
|
||||
WFCMessage.GroupInfo groupInfo = messagesStore.getGroupInfo(inputGetGroup.getGroupId());
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
if (groupInfo == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
pojoGroupInfo.setExtra(groupInfo.getExtra());
|
||||
pojoGroupInfo.setName(groupInfo.getName());
|
||||
pojoGroupInfo.setOwner(groupInfo.getOwner());
|
||||
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
|
||||
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
|
||||
pojoGroupInfo.setType(groupInfo.getType());
|
||||
result = RestResult.ok(pojoGroupInfo);
|
||||
}
|
||||
|
||||
response.setContent(new Gson().toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetGroup;
|
||||
import cn.wildfirechat.pojos.OutputGroupMemberList;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfo;
|
||||
import cn.wildfirechat.pojos.PojoGroupMember;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Group_Member_List)
|
||||
@HttpMethod("POST")
|
||||
public class GetGroupMembersAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetGroup inputGetGroup = getRequestBody(request.getNettyRequest(), InputGetGroup.class);
|
||||
if (inputGetGroup != null
|
||||
&& (!StringUtil.isNullOrEmpty(inputGetGroup.getGroupId()))) {
|
||||
|
||||
List<WFCMessage.GroupMember> members = new ArrayList<>();
|
||||
ErrorCode errorCode = messagesStore.getGroupMembers(inputGetGroup.getGroupId(), 0, members);
|
||||
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
result = RestResult.resultOf(errorCode);
|
||||
} else {
|
||||
OutputGroupMemberList out = new OutputGroupMemberList();
|
||||
out.setMembers(new ArrayList<>());
|
||||
for (WFCMessage.GroupMember member : members) {
|
||||
PojoGroupMember pm = new PojoGroupMember();
|
||||
pm.setMember_id(member.getMemberId());
|
||||
pm.setAlias(member.getAlias());
|
||||
pm.setType(member.getType());
|
||||
out.getMembers().add(pm);
|
||||
}
|
||||
result = RestResult.ok(out);
|
||||
}
|
||||
|
||||
response.setContent(new Gson().toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputGetToken;
|
||||
import cn.wildfirechat.pojos.OutputGetIMTokenData;
|
||||
import io.moquette.persistence.RPCCenter;
|
||||
import io.moquette.persistence.TargetEntry;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route(APIPath.User_Get_Token)
|
||||
@HttpMethod("POST")
|
||||
public class GetIMTokenAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetToken input = getRequestBody(request.getNettyRequest(), InputGetToken.class);
|
||||
String userId = input.getUserId();
|
||||
|
||||
|
||||
WFCMessage.GetTokenRequest getTokenRequest = WFCMessage.GetTokenRequest.newBuilder().setUserId(userId).setClientId(input.getClientId()).setPlatform(input.getPlatform() == null ? 0 : input.getPlatform()).build();
|
||||
RPCCenter.getInstance().sendRequest(userId, input.getClientId(), IMTopic.GetTokenTopic, getTokenRequest.toByteArray(), userId, TargetEntry.Type.TARGET_TYPE_USER, new RPCCenter.Callback() {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
ErrorCode errorCode1 = ErrorCode.fromCode(result[0]);
|
||||
if (errorCode1 == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
//ba errorcode qudiao
|
||||
byte[] data = new byte[result.length -1];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = result[i+1];
|
||||
}
|
||||
String token = Base64.getEncoder().encodeToString(data);
|
||||
|
||||
sendResponse(response, null, new OutputGetIMTokenData(userId, token));
|
||||
} else {
|
||||
sendResponse(response, errorCode1, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorCode errorCode) {
|
||||
sendResponse(response, errorCode, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout() {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getResponseExecutor() {
|
||||
return command -> {
|
||||
ctx.executor().execute(command);
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.SystemSettingPojo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Get_System_Setting)
|
||||
@HttpMethod("POST")
|
||||
public class GetSystemSettingAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
SystemSettingPojo inputUserId = getRequestBody(request.getNettyRequest(), SystemSettingPojo.class);
|
||||
if (inputUserId != null) {
|
||||
SystemSettingPojo output = messagesStore.getSystemSetting(inputUserId.id);
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
if (output == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(output);
|
||||
}
|
||||
|
||||
response.setContent(new Gson().toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
@Route(APIPath.User_Get_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetUserAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetUserInfo inputUserId = getRequestBody(request.getNettyRequest(), InputGetUserInfo.class);
|
||||
if (inputUserId != null
|
||||
&& (!StringUtil.isNullOrEmpty(inputUserId.getUserId()) || !StringUtil.isNullOrEmpty(inputUserId.getName()) || !StringUtil.isNullOrEmpty(inputUserId.getMobile()))) {
|
||||
|
||||
WFCMessage.User user = null;
|
||||
if(!StringUtil.isNullOrEmpty(inputUserId.getUserId())) {
|
||||
user = messagesStore.getUserInfo(inputUserId.getUserId());
|
||||
} else if(!StringUtil.isNullOrEmpty(inputUserId.getName())) {
|
||||
user = messagesStore.getUserInfoByName(inputUserId.getName());
|
||||
} else if(!StringUtil.isNullOrEmpty(inputUserId.getMobile())) {
|
||||
user = messagesStore.getUserInfoByMobile(inputUserId.getMobile());
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
if (user == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(InputOutputUserInfo.fromPbUser(user));
|
||||
}
|
||||
|
||||
response.setContent(new Gson().toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.OutputUserBlockStatusList;
|
||||
import com.google.gson.Gson;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
@Route(APIPath.User_Get_Blocked_List)
|
||||
@HttpMethod("POST")
|
||||
public class GetUserBlockListAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
OutputUserBlockStatusList list = new OutputUserBlockStatusList();
|
||||
list.setStatusList(messagesStore.getUserStatusList());
|
||||
RestResult result = RestResult.ok(list);
|
||||
response.setContent(new Gson().toJson(result));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user