aboutsummaryrefslogtreecommitdiff
path: root/advtrains/models/advtrains_retrosignal_off_30.b3d
blob: da258e19fee7133d672e80980a0adc11a5ad2ac7 (plain)
ofshex dumpascii
0000 42 42 33 44 1d 33 00 00 01 00 00 00 54 45 58 53 36 00 00 00 61 64 76 74 72 61 69 6e 73 5f 72 65 BB3D.3......TEXS6...advtrains_re
0020 74 72 6f 73 69 67 6e 61 6c 2e 70 6e 67 00 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 trosignal.png...................
0040 80 3f 00 00 80 3f 00 00 00 00 42 52 55 53 2e 00 00 00 01 00 00 00 42 72 75 73 68 2e 30 30 31 00 .?...?....BRUS........Brush.001.
0060 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ...?...?...?...?................
0080 4e 4f 44 45 9d 32 00 00 43 75 62 65 2e 30 30 31 00 00 00 80 b0 00 00 00 00 00 00 00 00 00 00 80 NODE.2..Cube.001................
00a0 3f 00 00 80 3f 00 00 80 3f b4 d3 e9 3e 33 9e 2f be 59 28 4f bf 84 a2 a7 3e 4d 45 53 48 64 32 00 ?...?...?...>3./.Y(O....>MESHd2.
00c0 00 ff ff ff ff 56 52 54 53 8c 2b 00 00 01 00 00 00 01 00 00 00 02 00 00 00 ae 3e cd bd bd b9 f1 .....VRTS.+...............>.....
00e0 3f 70 8a 81 bf 32 1b 19 bf 4e c1 a6 bc 9a 17 4d 3f 98 e5 52 3f f6 af 5f 3f 9e ea 63 bd 4e 0d 06 ?p...2...N.....M?..R?.._?..c.N..
0100 3f a6 cd 1b c0 6f 6d 37 bf 07 af 03 bf e2 35 f1 3e 36 c7 86 3e ff af 5f 3f 1c f1 54 bd 0e 78 37 ?....om7......5.>6..>.._?..T..x7
0120 3f 80 a6 27 c0 65 79 32 bf 03 97 01 3f 04 f1 01 bf 34 c7 86 3e 7d 38 4c 3f ed c1 c5 bd 8e 37 05 ?..'.ey2....?....4..>}8L?.....7.
0140 40 22 3c 99 bf 2a 11 15 bf a0 1d 50 3f 08 01 04 3b 96 e5 52 3f 77 38 4c 3f ed c1 c5 bd 8e 37 05 @"<..*.....P?...;..R?w8L?.....7.
0160 40 22 3c 99 bf 2a 11 15 bf a0 1d 50 3f 08 01 04 3b 96 e5 52 3f 77 38 4c 3f 6a bd ff bc c0 3d 05 @"<..*.....P?...;..R?w8L?j....=.
0180 40 ed 04 99 bf 25 6d 12 3f a4 d3 51 3f 04 21 02 3d 96 e5 52 3f 95 76 47 3f 38 d8 0e bd 20 c6 f1 @....%m.?..Q?.!.=..R?.vG?8......
01a0 3f 3a 53 81 bf 1d 63 0e 3f c0 01 60 bc a9 b7 54 3f 18 5d 66 3f 94 76 47 3f ae 3e cd bd bd b9 f1 ?:S...c.?..`...T?.]f?.vG?.>.....
01c0 3f 70 8a 81 bf 32 1b 19 bf 4e c1 a6 bc 9a 17 4d 3f 18 5d 66 3f 77 38 4c 3f 6a bd ff bc c0 3d 05 ?p...2...N.....M?.]f?w8L?j....=.
01e0 40 ed 04 99 bf 25 6d 12 3f a4 d3 51 3f 04 21 02 3d 96 e5 52 3f 59 e9 77 3f 24 d0 5a 3c d6 90 37 @....%m.?..Q?.!.=..R?Y.w?$.Z<..7
0200 3f e5 8a 27 c0 6f 6d 37 3f 07 af 03 3f e2 35 f1 be 34 c7 86 3e 4c e9 77 3f 1a ea 1e 3c 16 26 06 ?..'.om7?...?.5..4..>L.w?...<.&.
0220 3f 0c b2 1b c0 65 7b 32 3f 03 97 01 bf 04 f1 01 3f 3c c7 86 3e ce 71 64 3f 38 d8 0e bd 20 c6 f1 ?....e{2?.......?<..>.qd?8......
0240 3f 3a 53 81 bf 1d 63 0e 3f c0 01 60 bc a9 b7 54 3f 99 e5 52 3f d8 71 64 3f 9e ea 63 bd 4e 0d 06 ?:S...c.?..`...T?..R?.qd?..c.N..
0260 3f a6 cd 1b c0 6f 6d 37 bf 07 af 03 bf e2 35 f1 3e 36 c7 86 3e ff af 5f 3f ae 3e cd bd bd b9 f1 ?....om7......5.>6..>.._?.>.....
0280 3f 70 8a 81 bf 32 1b 19 bf 4e c1 a6 bc 9a 17 4d 3f 98 e5 52 3f f6 af 5f 3f 38 d8 0e bd 20 c6 f1 ?p...2...N.....M?..R?.._?8......
02a0 3f 3a 53 81 bf 1d 63 0e 3f c0 01 60 bc a9 b7 54 3f 99 e5 52 3f d8 71 64 3f 1a ea 1e 3c 16 26 06 ?:S...c.?..`...T?..R?.qd?...<.&.
02c0 3f 0c b2 1b c0 65 7b 32 3f 03 97 01 bf 04 f1 01 3f 3c c7 86 3e ce 71 64 3f 24 d0 5a 3c d6 90 37 ?....e{2?.......?<..>.qd?$.Z<..7
02e0 3f e5 8a 27 c0 6f 6d 37 3f 07 af 03 3f e2 35 f1 be 34 c7 86 3e af 76 47 3f 6a bd ff bc c0 3d 05 ?..'.om7?...?.5..4..>.vG?j....=.
0300 40 ed 04 99 bf 25 6d 12 3f a4 d3 51 3f 04 21 02 3d 96 e5 52 3f 95 76 47 3f ed c1 c5 bd 8e 37 05 @....%m.?..Q?.!.=..R?.vG?.....7.
0320 40 22 3c 99 bf 2a 11 15 bf a0 1d 50 3f 08 01 04 3b 96 e5 52 3f 77 38 4c 3f 1c f1 54 bd 0e 78 37 @"<..*.....P?...;..R?w8L?..T..x7
0340 3f 80 a6 27 c0 65 79 32 bf 03 97 01 3f 04 f1 01 bf 34 c7 86 3e 7d 38 4c 3f 3a 0e 11 3d ee e7 46 ?..'.ey2....?....4..>}8L?:..=..F
0360 3f a5 13 29 c0 70 41 38 3f 21 45 90 3e 45 69 22 bf 89 fb 95 3e 14 47 2e 3f 0e 56 8d bd 72 47 47 ?..).pA8?!E.>Ei"....>.G.?.V..rGG
0380 3f 28 60 29 c0 4d 67 26 bf 36 29 9b 3e 65 65 32 bf fb c3 86 3e c4 46 2e 3f b7 66 8d bd 7a ad 3d ?(`).Mg&.6).>ee2....>.F.?.f..z.=
03a0 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf a9 c1 86 3e e2 25 31 3f f2 ec 10 3d f6 4d 3d ?.(*.Mg&.W.+>{.=....>.%1?...=.M=
03c0 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 2f f9 95 3e 34 26 31 3f c9 9f 0f 3d 46 b6 4f ?X.).pA8?+y.>[.-./..>4&1?...=F.O
03e0 3f 13 d7 27 c0 70 eb 37 3f a0 0d d0 3e 21 83 10 bf 09 fd 95 3e f6 67 2b 3f 48 0d 8e bd c8 15 50 ?..'.p.7?...>!......>.g+?H.....P
0400 3f 94 23 28 c0 4d bf 26 bf b6 c1 da 3e 41 83 20 bf 85 c5 86 3e a6 67 2b 3f 0e 56 8d bd 72 47 47 ?.#(.M.&....>A......>.g+?.V..rGG
0420 3f 28 60 29 c0 4d 67 26 bf 36 29 9b 3e 65 65 32 bf fb c3 86 3e c4 46 2e 3f 3a 0e 11 3d ee e7 46 ?(`).Mg&.6).>ee2....>.F.?:..=..F
0440 3f a5 13 29 c0 70 41 38 3f 21 45 90 3e 45 69 22 bf 89 fb 95 3e 14 47 2e 3f b2 af 0c 3d 58 62 57 ?..).pA8?!E.>Ei"....>.G.?...=XbW
0460 3f c8 32 26 c0 6e 3f 37 3f 08 d1 03 3f e3 79 f1 be b5 fd 95 3e d8 88 28 3f 53 85 8f bd d8 c1 57 ?.2&.n?7?...?.y.....>..(?S.....W
0480 3f 4a 7f 26 c0 4f 69 27 bf 12 17 09 3f 12 cb 08 bf 2f c6 86 3e 87 88 28 3f 48 0d 8e bd c8 15 50 ?J.&.Oi'....?..../..>..(?H.....P
04a0 3f 94 23 28 c0 4d bf 26 bf b6 c1 da 3e 41 83 20 bf 85 c5 86 3e a6 67 2b 3f c9 9f 0f 3d 46 b6 4f ?.#(.M.&....>A......>.g+?...=F.O
04c0 3f 13 d7 27 c0 70 eb 37 3f a0 0d d0 3e 21 83 10 bf 09 fd 95 3e f6 67 2b 3f 7a 5a 08 3d aa a0 5d ?..'.p.7?...>!......>.g+?zZ.=..]
04e0 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 7f fd 95 3e b8 a9 25 3f ee af 91 bd 29 00 5e ?.6$.mE6?5k.?p......>..%?....).^
0500 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be f7 c5 86 3e 68 a9 25 3f 53 85 8f bd d8 c1 57 ?p.$.Qc(.?..?.A.....>h.%?S.....W
0520 3f 4a 7f 26 c0 4f 69 27 bf 12 17 09 3f 12 cb 08 bf 2f c6 86 3e 87 88 28 3f b2 af 0c 3d 58 62 57 ?J.&.Oi'....?..../..>..(?...=XbW
0540 3f c8 32 26 c0 6e 3f 37 3f 08 d1 03 3f e3 79 f1 be b5 fd 95 3e d8 88 28 3f 29 cb 02 3d d5 33 62 ?.2&.n?7?...?.y.....>..(?)..=.3b
0560 3f 08 f7 21 c0 6a 07 35 3f 56 f7 2a 3f db a9 6d be 6f fc 95 3e 9a ca 22 3f 98 77 94 bd 54 93 62 ?..!.j.5?V.*?..m.o..>.."?.w..T.b
0580 3f 8a 43 22 c0 53 9f 29 bf 60 2f 30 3f 2e 41 97 be e9 c4 86 3e 49 ca 22 3f ee af 91 bd 29 00 5e ?.C".S.).`/0?.A.....>I."?....).^
05a0 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be f7 c5 86 3e 68 a9 25 3f 7a 5a 08 3d aa a0 5d ?p.$.Qc(.?..?.A.....>h.%?zZ.=..]
05c0 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 7f fd 95 3e b8 a9 25 3f cc 70 f8 3c cd ee 64 ?.6$.mE6?5k.?p......>..%?.p.<..d
05e0 3f 38 89 1f c0 67 91 33 3f 6a d5 34 3f 84 e1 c1 bd 91 fa 95 3e 7b eb 1f 3f fa c0 97 bd 4c 4e 65 ?8...g.3?j.4?.......>{..?....LNe
0600 3f ba d5 1f c0 56 15 2b bf 74 11 3a 3f 44 21 22 be 09 c3 86 3e 2a eb 1f 3f 98 77 94 bd 54 93 62 ?....V.+.t.:?D!"....>*..?.w..T.b
0620 3f 8a 43 22 c0 53 9f 29 bf 60 2f 30 3f 2e 41 97 be e9 c4 86 3e 49 ca 22 3f 29 cb 02 3d d5 33 62 ?.C".S.).`/0?.A.....>I."?)..=.3b
0640 3f 08 f7 21 c0 6a 07 35 3f 56 f7 2a 3f db a9 6d be 6f fc 95 3e 9a ca 22 3f 2c c5 e9 3c c4 b6 65 ?..!.j.5?V.*?..m.o..>.."?,..<..e
0660 3f 62 05 1d c0 64 f1 31 3f 6f a1 37 3f 86 e1 42 3d f7 f7 95 3e 5c 0c 1d 3f e1 6b 9b bd 3f 16 66 ?b...d.1?o.7?..B=...>\..?.k..?.f
0680 3f e5 51 1d c0 59 b3 2c bf 7a eb 3c 3f 0c 01 86 bc 73 c0 86 3e 0c 0c 1d 3f fa c0 97 bd 4c 4e 65 ?.Q..Y.,.z.<?....s..>...?....LNe
06a0 3f ba d5 1f c0 56 15 2b bf 74 11 3a 3f 44 21 22 be 09 c3 86 3e 2a eb 1f 3f cc 70 f8 3c cd ee 64 ?....V.+.t.:?D!"....>*..?.p.<..d
06c0 3f 38 89 1f c0 67 91 33 3f 6a d5 34 3f 84 e1 c1 bd 91 fa 95 3e 7b eb 1f 3f 71 24 da 3c fa 83 64 ?8...g.3?j.4?.......>{..?q$.<..d
06e0 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e c1 f4 95 3e 3e 2d 1a 3f 0f 54 9f bd 7c e3 64 ?G...`70?fA3?..A>...>>-.?.T..|.d
0700 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 39 bd 86 3e ec 2c 1a 3f e1 6b 9b bd 3f 16 66 ?....]m..q.8?...>9..>.,.?.k..?.f
0720 3f e5 51 1d c0 59 b3 2c bf 7a eb 3c 3f 0c 01 86 bc 73 c0 86 3e 0c 0c 1d 3f 2c c5 e9 3c c4 b6 65 ?.Q..Y.,.z.<?....s..>...?,..<..e
0740 3f 62 05 1d c0 64 f1 31 3f 6f a1 37 3f 86 e1 42 3d f7 f7 95 3e 5c 0c 1d 3f 12 28 ca 3c 46 62 61 ?b...d.1?o.7?..B=...>\..?.(.<Fba
0760 3f 88 1e 18 c0 5d 75 2e 3f 50 e3 27 3f 4c 41 a6 3e 0f f1 95 3e 1f 4e 17 3f 2a 53 a3 bd c6 c1 61 ?....]u.?P.'?LA.>...>.N.?*S....a
0780 3f 09 6b 18 c0 60 2f 30 bf 5b 57 2d 3f 0b 5d 85 3e 87 b9 86 3e d0 4d 17 3f 0f 54 9f bd 7c e3 64 ?.k..`/0.[W-?.].>...>.M.?.T..|.d
07a0 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 39 bd 86 3e ec 2c 1a 3f 71 24 da 3c fa 83 64 ?....]m..q.8?...>9..>.,.?q$.<..d
07c0 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e c1 f4 95 3e 3e 2d 1a 3f 5a 6d ba 3c 72 70 5c ?G...`70?fA3?..A>...>>-.?Zm.<rp\
07e0 3f ba eb 15 c0 59 bb 2c 3f 2c f7 15 3f cc d5 e5 3e 09 ed 95 3e 02 6f 14 3f d8 41 a7 bd f2 cf 5c ?....Y.,?,..?...>...>.o.?.A....\
0800 3f 3c 38 16 c0 64 e7 31 bf 37 7f 1b 3f 8a 01 c5 3e 83 b5 86 3e b0 6e 14 3f 2a 53 a3 bd c6 c1 61 ?<8..d.1.7..?...>...>.n.?*S....a
0820 3f 09 6b 18 c0 60 2f 30 bf 5b 57 2d 3f 0b 5d 85 3e 87 b9 86 3e d0 4d 17 3f 12 28 ca 3c 46 62 61 ?.k..`/0.[W-?.].>...>.M.?.(.<Fba
0840 3f 88 1e 18 c0 5d 75 2e 3f 50 e3 27 3f 4c 41 a6 3e 0f f1 95 3e 1f 4e 17 3f 5b 8e ab 3c 27 df 55 ?....]u.?P.'?LA.>...>.N.?[..<'.U
0860 3f 80 01 14 c0 56 1b 2b 3f f9 59 fc 3e 1d 99 0e 3f d5 e8 95 3e e3 8f 11 3f 99 f9 aa bd a9 3e 56 ?....V.+?.Y.>...?...>...?.....>V
0880 3f 02 4e 14 c0 67 87 33 bf 08 c9 03 3f f9 75 fc 3e 4d b1 86 3e 94 8f 11 3f d8 41 a7 bd f2 cf 5c ?.N..g.3....?.u.>M..>...?.A....\
08a0 3f 3c 38 16 c0 64 e7 31 bf 37 7f 1b 3f 8a 01 c5 3e 83 b5 86 3e b0 6e 14 3f 5a 6d ba 3c 72 70 5c ?<8..d.1.7..?...>...>.n.?Zm.<rp\
08c0 3f ba eb 15 c0 59 bb 2c 3f 2c f7 15 3f cc d5 e5 3e 09 ed 95 3e 02 6f 14 3f f2 ec 10 3d f6 4d 3d ?....Y.,?,..?...>...>.o.?...=.M=
08e0 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 2f f9 95 3e 34 26 31 3f b7 66 8d bd 7a ad 3d ?X.).pA8?+y.>[.-./..>4&1?.f..z.=
0900 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf a9 c1 86 3e e2 25 31 3f bb 3e 8e bd 52 a6 33 ?.(*.Mg&.W.+>{.=....>.%1?.>..R.3
0920 3f f4 75 2a c0 4e c1 26 bf ab 81 d5 3c 84 1f 42 bf 99 be 86 3e 02 05 34 3f e8 3c 0f 3d d4 46 33 ?.u*.N.&....<..B....>..4?.<.=.F3
0940 3f 72 29 2a c0 70 e7 37 3f 10 01 88 3b 64 13 32 bf 21 f6 95 3e 52 05 34 3f e8 3c 0f 3d d4 46 33 ?r)*.p.7?...;d.2.!..>R.4?.<.=.F3
0960 3f 72 29 2a c0 70 e7 37 3f 10 01 88 3b 64 13 32 bf b5 fd 95 3e 06 43 b0 3e bb 3e 8e bd 52 a6 33 ?r)*.p.7?...;d.2....>.C.>.>..R.3
0980 3f f4 75 2a c0 4e c1 26 bf ab 81 d5 3c 84 1f 42 bf 2d c6 86 3e 66 42 b0 3e a8 d5 8f bd a8 94 29 ?.u*.N.&....<..B.-..>fB.>......)
09a0 3f 81 44 2a c0 4f 6d 27 bf db b1 ed bd 7f 5b 3f bf 81 c2 86 3e a2 00 b6 3e 06 0f 0c 3d 2a 35 29 ?.D*.Om'......[?....>...>...=*5)
09c0 3f fe f7 29 c0 6e 39 37 3f 1b 79 0d be 5e 3d 2f bf 09 fa 95 3e 44 01 b6 3e 06 0f 0c 3d 2a 35 29 ?..).n97?.y..^=/....>D..>...=*5)
09e0 3f fe f7 29 c0 6e 39 37 3f 1b 79 0d be 5e 3d 2f bf 09 fa 95 3e 44 01 b6 3e a8 d5 8f bd a8 94 29 ?..).n97?.y..^=/....>D..>......)
0a00 3f 81 44 2a c0 4f 6d 27 bf db b1 ed bd 7f 5b 3f bf 81 c2 86 3e a2 00 b6 3e eb 1b 92 bd 86 db 1f ?.D*.Om'......[?....>...>.......
0a20 3f 64 96 29 c0 51 67 28 bf 03 bd 81 be 6b 8f 35 bf 55 be 86 3e e0 be bb 3e 81 82 07 3d 08 7c 1f ?d.).Qg(.....k.5.U..>...>...=.|.
0a40 3f e2 49 29 c0 6c 3f 36 3f 1a 15 8d be 4b 5b 25 bf df f5 95 3e 82 bf bb 3e 81 82 07 3d 08 7c 1f ?.I).l?6?....K[%....>...>...=.|.
0a60 3f e2 49 29 c0 6c 3f 36 3f 1a 15 8d be 4b 5b 25 bf df f5 95 3e 82 bf bb 3e eb 1b 92 bd 86 db 1f ?.I).l?6?....K[%....>...>.......
0a80 3f 64 96 29 c0 51 67 28 bf 03 bd 81 be 6b 8f 35 bf 55 be 86 3e e0 be bb 3e 28 fb 94 bd 98 da 16 ?d.).Qg(.....k.5.U..>...>(......
0aa0 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf db b9 86 3e 1c 7d c1 3e 0d c4 01 3d 18 7b 16 ?Qr(.S.).....J.%....>.}.>...=.{.
0ac0 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf 5f f1 95 3e be 7d c1 3e 0d c4 01 3d 18 7b 16 ?.%(.j.4?.1..*..._..>.}.>...=.{.
0ae0 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf 5f f1 95 3e be 7d c1 3e 28 fb 94 bd 98 da 16 ?.%(.j.4?.1..*..._..>.}.>(......
0b00 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf db b9 86 3e 1c 7d c1 3e 3f 57 98 bd 70 ea 0e ?Qr(.S.).....J.%....>.}.>?W..p..
0b20 3f 81 e3 26 c0 56 1b 2b bf f9 59 fc be 1d 99 0e bf 2b b5 86 3e 58 3b c7 3e ba 17 f6 3c ee 8a 0e ?..&.V.+..Y......+..>X;.>...<...
0b40 3f 00 97 26 c0 67 87 33 3f 08 c9 03 bf f9 75 fc be b1 ec 95 3e f8 3b c7 3e ba 17 f6 3c ee 8a 0e ?..&.g.3?.....u.....>.;.>...<...
0b60 3f 00 97 26 c0 67 87 33 3f 08 c9 03 bf f9 75 fc be b1 ec 95 3e f8 3b c7 3e 3f 57 98 bd 70 ea 0e ?..&.g.3?.....u.....>.;.>?W..p..
0b80 3f 81 e3 26 c0 56 1b 2b bf f9 59 fc be 1d 99 0e bf 2b b5 86 3e 58 3b c7 3e c2 0e 9c bd 20 59 08 ?..&.V.+..Y......+..>X;.>.....Y.
0ba0 3f 47 f9 24 c0 59 bb 2c bf 2c f7 15 bf cc d5 e5 be 81 b0 86 3e 96 f9 cc 3e 3c 39 e7 3c a2 f9 07 ?G.$.Y.,.,..........>...><9.<...
0bc0 3f c6 ac 24 c0 64 e7 31 3f 37 7f 1b bf 8a 01 c5 be 07 e8 95 3e 36 fa cc 3e 3c 39 e7 3c a2 f9 07 ?..$.d.1?7..........>6..><9.<...
0be0 3f c6 ac 24 c0 64 e7 31 3f 37 7f 1b bf 8a 01 c5 be 07 e8 95 3e 36 fa cc 3e c2 0e 9c bd 20 59 08 ?..$.d.1?7..........>6..>.....Y.
0c00 3f 47 f9 24 c0 59 bb 2c bf 2c f7 15 bf cc d5 e5 be 81 b0 86 3e 96 f9 cc 3e 8f fd 9f bd 4e 67 03 ?G.$.Y.,.,..........>...>....Ng.
0c20 3f 7a c6 22 c0 5d 75 2e bf 50 e3 27 bf 4c 41 a6 be ff ab 86 3e cc b7 d2 3e 82 7e d7 3c ce 07 03 ?z.".]u..P.'.LA.....>...>.~.<...
0c40 3f f8 79 22 c0 60 2f 30 3f 5b 57 2d bf 0b 5d 85 be 87 e3 95 3e 76 b8 d2 3e 82 7e d7 3c ce 07 03 ?.y".`/0?[W-..].....>v..>.~.<...
0c60 3f f8 79 22 c0 60 2f 30 3f 5b 57 2d bf 0b 5d 85 be 87 e3 95 3e 76 b8 d2 3e 8f fd 9f bd 4e 67 03 ?.y".`/0?[W-..].....>v..>....Ng.
0c80 3f 7a c6 22 c0 5d 75 2e bf 50 e3 27 bf 4c 41 a6 be ff ab 86 3e cc b7 d2 3e a3 fc a3 bd 9c 45 00 ?z.".]u..P.'.LA.....>...>.....E.
0ca0 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be d3 a7 86 3e 10 76 d8 3e 24 82 c7 3c 34 cc ff ?.`..`70.gC3...A....>.v.>$..<4..
0cc0 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be 5b df 95 3e ae 76 d8 3e 24 82 c7 3c 34 cc ff >9...]m.?q.8.....[..>.v.>$..<4..
0ce0 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be 5b df 95 3e ae 76 d8 3e a3 fc a3 bd 9c 45 00 >9...]m.?q.8.....[..>.v.>.....E.
0d00 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be d3 a7 86 3e 10 76 d8 3e d4 e4 a7 bd ac 25 fe ?.`..`70.gC3...A....>.v.>.....%.
0d20 3e 9f df 1d c0 64 f1 31 bf 6f a1 37 bf 86 e1 42 bd 23 a4 86 3e 4a 34 de 3e 67 e1 b7 3c b0 66 fd >....d.1.o.7...B.#..>J4.>g..<.f.
0d40 3e 1c 93 1d c0 59 b3 2c 3f 7a eb 3c bf 0c 01 86 3c ad db 95 3e ea 34 de 3e 67 e1 b7 3c b0 66 fd >....Y.,?z.<....<...>.4.>g..<.f.
0d60 3e 1c 93 1d c0 59 b3 2c 3f 7a eb 3c bf 0c 01 86 3c ad db 95 3e ea 34 de 3e d4 e4 a7 bd ac 25 fe >....Y.,?z.<....<...>.4.>.....%.
0d80 3e 9f df 1d c0 64 f1 31 bf 6f a1 37 bf 86 e1 42 bd 23 a4 86 3e 4a 34 de 3e bd 8f ab bd 90 b5 ff >....d.1.o.7...B.#..>J4.>.......
0da0 3e ca 5b 1b c0 67 91 33 bf 6a d5 34 bf 84 e1 c1 3d 13 a1 86 3e 86 f2 e3 3e c8 35 a9 3c 94 f6 fe >.[..g.3.j.4....=...>...>.5.<...
0dc0 3e 47 0f 1b c0 56 15 2b 3f 74 11 3a bf 44 21 22 3e 99 d8 95 3e 2a f3 e3 3e c8 35 a9 3c 94 f6 fe >G...V.+?t.:.D!">...>*..>.5.<...
0de0 3e 47 0f 1b c0 56 15 2b 3f 74 11 3a bf 44 21 22 3e 99 d8 95 3e 2a f3 e3 3e bd 8f ab bd 90 b5 ff >G...V.+?t.:.D!">...>*..>.......
0e00 3e ca 5b 1b c0 67 91 33 bf 6a d5 34 bf 84 e1 c1 3d 13 a1 86 3e 86 f2 e3 3e 1d d9 ae bd c6 95 02 >.[..g.3.j.4....=...>...>.......
0e20 3f f9 ed 18 c0 6a 07 35 bf 56 f7 2a bf db a9 6d 3e bb 9e 86 3e c6 b0 e9 3e 44 10 9c 3c 46 36 02 ?....j.5.V.*...m>...>...>D..<F6.
0e40 3f 78 a1 18 c0 53 9f 29 3f 60 2f 30 bf 2e 41 97 3e 41 d6 95 3e 68 b1 e9 3e 44 10 9c 3c 46 36 02 ?x...S.)?`/0..A.>A..>h..>D..<F6.
0e60 3f 78 a1 18 c0 53 9f 29 3f 60 2f 30 bf 2e 41 97 3e 41 d6 95 3e 68 b1 e9 3e 1d d9 ae bd c6 95 02 ?x...S.)?`/0..A.>A..>h..>.......
0e80 3f f9 ed 18 c0 6a 07 35 bf 56 f7 2a bf db a9 6d 3e bb 9e 86 3e c6 b0 e9 3e c7 a0 b1 bd ec 28 07 ?....j.5.V.*...m>...>...>.....(.
0ea0 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 2f 9d 86 3e 04 6f ef 3e 8c f1 90 3c 6e c9 06 ?....mE6.5k..p..>/..>.o.>...<n..
0ec0 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e b9 d4 95 3e a8 6f ef 3e 8c f1 90 3c 6e c9 06 ?.a..Qc(??....A.>...>.o.>...<n..
0ee0 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e b9 d4 95 3e a8 6f ef 3e c7 a0 b1 bd ec 28 07 ?.a..Qc(??....A.>...>.o.>.....(.
0f00 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 2f 9d 86 3e 04 6f ef 3e 64 cb b3 bd 40 67 0d ?....mE6.5k..p..>/..>.o.>d...@g.
0f20 3f 39 b2 14 c0 6e 3f 37 bf 08 cf 03 bf e3 79 f1 3e 83 9c 86 3e 42 2d f5 3e 31 47 88 3c c0 07 0d ?9...n?7......y.>...>B-.>1G.<...
0f40 3f b7 65 14 c0 4f 69 27 3f 12 17 09 bf 12 cb 08 3f 09 d4 95 3e e2 2d f5 3e 31 47 88 3c c0 07 0d ?.e..Oi'?.......?...>.-.>1G.<...
0f60 3f b7 65 14 c0 4f 69 27 3f 12 17 09 bf 12 cb 08 3f 09 d4 95 3e e2 2d f5 3e 64 cb b3 bd 40 67 0d ?.e..Oi'?.......?...>.-.>d...@g.
0f80 3f 39 b2 14 c0 6e 3f 37 bf 08 cf 03 bf e3 79 f1 3e 83 9c 86 3e 42 2d f5 3e 6e 43 b5 bd 52 13 15 ?9...n?7......y.>...>B-.>nC..R..
0fa0 3f ee 0d 13 c0 70 eb 37 bf a0 0d d0 be 21 83 10 3f b5 9c 86 3e 82 eb fa 3e 05 67 82 3c d2 b3 14 ?....p.7.....!..?...>...>.g.<...
0fc0 3f 6d c1 12 c0 4d bf 26 3f b6 c1 da be 41 83 20 3f 39 d4 95 3e 20 ec fa 3e 05 67 82 3c d2 b3 14 ?m...M.&?....A..?9..>...>.g.<...
0fe0 3f 6d c1 12 c0 4d bf 26 3f b6 c1 da be 41 83 20 3f 39 d4 95 3e 20 ec fa 3e 6e 43 b5 bd 52 13 15 ?m...M.&?....A..?9..>...>nC..R..
1000 3f ee 0d 13 c0 70 eb 37 bf a0 0d d0 be 21 83 10 3f b5 9c 86 3e 82 eb fa 3e a4 fa b5 bd ae e1 1d ?....p.7.....!..?...>...>.......
1020 3f 5b d1 11 c0 70 41 38 bf 21 45 90 be 45 69 22 3f c5 9d 86 3e e0 54 00 3f 40 14 7f 3c 2c 82 1d ?[...pA8.!E..Ei"?...>.T.?@..<,..
1040 3f da 84 11 c0 4d 67 26 3f 36 25 9b be 65 65 32 3f 47 d5 95 3e 30 55 00 3f 40 14 7f 3c 2c 82 1d ?....Mg&?6%..ee2?G..>0U.?@..<,..
1060 3f da 84 11 c0 4d 67 26 3f 36 25 9b be 65 65 32 3f 47 d5 95 3e 30 55 00 3f a4 fa b5 bd ae e1 1d ?....Mg&?6%..ee2?G..>0U.?.......
1080 3f 5b d1 11 c0 70 41 38 bf 21 45 90 be 45 69 22 3f c5 9d 86 3e e0 54 00 3f 00 ea b5 bd a2 7b 27 ?[...pA8.!E..Ei"?...>.T.?.....{'
10a0 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 9d 9f 86 3e fe 33 03 3f 60 99 7f 3c 22 1c 27 ?....pA8.+y..[.-?...>.3.?`..<".'
10c0 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 23 d7 95 3e 4e 34 03 3f 60 99 7f 3c 22 1c 27 ?(...Mg&?W.+.{.=?#..>N4.?`..<".'
10e0 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 23 d7 95 3e 4e 34 03 3f 00 ea b5 bd a2 7b 27 ?(...Mg&?W.+.{.=?#..>N4.?.....{'
1100 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 9d 9f 86 3e fe 33 03 3f f8 11 b5 bd c8 82 31 ?....pA8.+y..[.-?...>.3.?......1
1120 3f 90 bb 10 c0 70 e7 37 bf 10 01 88 bb 64 13 32 3f 39 a2 86 3e 1c 13 06 3f c8 2c 83 3c 48 23 31 ?....p.7.....d.2?9..>...?.,.<H#1
1140 3f 0e 6f 10 c0 4e c1 26 3f aa 41 d5 bc 84 1f 42 3f bb d9 95 3e 6c 13 06 3f c8 2c 83 3c 48 23 31 ?.o..N.&?.A....B?...>l..?.,.<H#1
1160 3f 0e 6f 10 c0 4e c1 26 3f aa 41 d5 bc 84 1f 42 3f bb d9 95 3e 6c 13 06 3f f8 11 b5 bd c8 82 31 ?.o..N.&?.A....B?...>l..?......1
1180 3f 90 bb 10 c0 70 e7 37 bf 10 01 88 bb 64 13 32 3f 39 a2 86 3e 1c 13 06 3f 0d 7b b3 bd 70 94 3b ?....p.7.....d.2?9..>...?.{..p.;
11a0 3f 04 ed 10 c0 6e 39 37 bf 1b 79 0d 3e 5e 3d 2f 3f 65 a5 86 3e 3a f2 08 3f 88 88 89 3c f4 34 3b ?....n97..y.>^=/?e..>:..?...<.4;
11c0 3f 82 a0 10 c0 4f 6d 27 3f db b1 ed 3d 7f 5b 3f 3f ef dc 95 3e 8a f2 08 3f 88 88 89 3c f4 34 3b ?....Om'?...=.[??...>...?...<.4;
11e0 3f 82 a0 10 c0 4f 6d 27 3f db b1 ed 3d 7f 5b 3f 3f ef dc 95 3e 8a f2 08 3f 0d 7b b3 bd 70 94 3b ?....Om'?...=.[??...>...?.{..p.;
1200 3f 04 ed 10 c0 6e 39 37 bf 1b 79 0d 3e 5e 3d 2f 3f 65 a5 86 3e 3a f2 08 3f c7 34 b1 bd 94 4d 45 ?....n97..y.>^=/?e..>:..?.4...ME
1220 3f 20 9b 11 c0 6c 3f 36 bf 1a 15 8d 3e 4b 5b 25 3f 15 a9 86 3e 59 d1 0b 3f 92 a1 92 3c 11 ee 44 ?....l?6....>K[%?...>Y..?...<..D
1240 3f 9e 4e 11 c0 51 67 28 3f 03 bd 81 3e 6b 8f 35 3f 9d e0 95 3e a8 d1 0b 3f b7 66 8d bd 7a ad 3d ?.N..Qg(?...>k.5?...>...?.f..z.=
1260 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f a8 d5 8f bd a8 94 29 ?.(*.Mg&.W.+>{.=.!..>.o-?......)
1280 3f 81 44 2a c0 4f 6d 27 bf db b1 ed bd 7f 5b 3f bf 54 e3 b1 3e da bf 27 3f bb 3e 8e bd 52 a6 33 ?.D*.Om'......[?.T..>..'?.>..R.3
12a0 3f f4 75 2a c0 4e c1 26 bf ab 81 d5 3c 84 1f 42 bf 51 e3 b1 3e fa 9e 2a 3f 28 fb 94 bd 98 da 16 ?.u*.N.&....<..B.Q..>..*?(......
12c0 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf d0 34 b5 3e b4 47 22 3f eb 1b 92 bd 86 db 1f ?Qr(.S.).....J.%..4.>.G"?.......
12e0 3f 64 96 29 c0 51 67 28 bf 03 bd 81 be 6b 8f 35 bf 28 02 b3 3e dc ee 24 3f a8 d5 8f bd a8 94 29 ?d.).Qg(.....k.5.(..>..$?......)
1300 3f 81 44 2a c0 4f 6d 27 bf db b1 ed bd 7f 5b 3f bf 54 e3 b1 3e da bf 27 3f c2 0e 9c bd 20 59 08 ?.D*.Om'......[?.T..>..'?.....Y.
1320 3f 47 f9 24 c0 59 bb 2c bf 2c f7 15 bf cc d5 e5 be 40 75 bc 3e aa dc 1d 3f 3f 57 98 bd 70 ea 0e ?G.$.Y.,.,.......@u.>...??W..p..
1340 3f 81 e3 26 c0 56 1b 2b bf f9 59 fc be 1d 99 0e bf a2 65 b8 3e 78 e4 1f 3f 28 fb 94 bd 98 da 16 ?..&.V.+..Y.......e.>x..?(......
1360 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf d0 34 b5 3e b4 47 22 3f a3 fc a3 bd 9c 45 00 ?Qr(.S.).....J.%..4.>.G"?.....E.
1380 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f 8f fd 9f bd 4e 67 03 ?.`..`70.gC3...A....>.*.?....Ng.
13a0 3f 7a c6 22 c0 5d 75 2e bf 50 e3 27 bf 4c 41 a6 be b4 3b c1 3e 42 44 1c 3f c2 0e 9c bd 20 59 08 ?z.".]u..P.'.LA...;.>BD.?.....Y.
13c0 3f 47 f9 24 c0 59 bb 2c bf 2c f7 15 bf cc d5 e5 be 40 75 bc 3e aa dc 1d 3f bd 8f ab bd 90 b5 ff ?G.$.Y.,.,.......@u.>...?.......
13e0 3e ca 5b 1b c0 67 91 33 bf 6a d5 34 bf 84 e1 c1 3d 46 ea d1 3e 88 9b 1a 3f d4 e4 a7 bd ac 25 fe >.[..g.3.j.4....=F..>...?.....%.
1400 3e 9f df 1d c0 64 f1 31 bf 6f a1 37 bf 86 e1 42 bd 0a 2c cc 3e 88 9b 1a 3f a3 fc a3 bd 9c 45 00 >....d.1.o.7...B..,.>...?.....E.
1420 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f c7 a0 b1 bd ec 28 07 ?.`..`70.gC3...A....>.*.?.....(.
1440 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 94 da dc 3e 42 44 1c 3f 1d d9 ae bd c6 95 02 ?....mE6.5k..p..>...>BD.?.......
1460 3f f9 ed 18 c0 6a 07 35 bf 56 f7 2a bf db a9 6d 3e 44 8c d7 3e f4 2a 1b 3f bd 8f ab bd 90 b5 ff ?....j.5.V.*...m>D..>.*.?.......
1480 3e ca 5b 1b c0 67 91 33 bf 6a d5 34 bf 84 e1 c1 3d 46 ea d1 3e 88 9b 1a 3f 6e 43 b5 bd 52 13 15 >.[..g.3.j.4....=F..>...?nC..R..
14a0 3f ee 0d 13 c0 70 eb 37 bf a0 0d d0 be 21 83 10 3f a4 b0 e5 3e 7a e4 1f 3f 64 cb b3 bd 40 67 0d ?....p.7.....!..?...>z..?d...@g.
14c0 3f 39 b2 14 c0 6e 3f 37 bf 08 cf 03 bf e3 79 f1 3e 04 a1 e1 3e aa dc 1d 3f c7 a0 b1 bd ec 28 07 ?9...n?7......y.>...>...?.....(.
14e0 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 94 da dc 3e 42 44 1c 3f 00 ea b5 bd a2 7b 27 ?....mE6.5k..p..>...>BD.?.....{'
1500 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f a4 fa b5 bd ae e1 1d ?....pA8.+y..[.-?...>..$?.......
1520 3f 5b d1 11 c0 70 41 38 bf 21 45 90 be 45 69 22 3f 78 e1 e8 3e b8 47 22 3f 6e 43 b5 bd 52 13 15 ?[...pA8.!E..Ei"?x..>.G"?nC..R..
1540 3f ee 0d 13 c0 70 eb 37 bf a0 0d d0 be 21 83 10 3f a4 b0 e5 3e 7a e4 1f 3f 0d 7b b3 bd 70 94 3b ?....p.7.....!..?...>z..?.{..p.;
1560 3f 04 ed 10 c0 6e 39 37 bf 1b 79 0d 3e 5e 3d 2f 3f ec 32 ec 3e 04 9f 2a 3f f8 11 b5 bd c8 82 31 ?....n97..y.>^=/?.2.>..*?......1
1580 3f 90 bb 10 c0 70 e7 37 bf 10 01 88 bb 64 13 32 3f ec 32 ec 3e e4 bf 27 3f 00 ea b5 bd a2 7b 27 ?....p.7.....d.2?.2.>..'?.....{'
15a0 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f 71 55 ae bd 84 4e 4e ?....pA8.+y..[.-?...>..$?qU...NN
15c0 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 6e e1 e8 3e 2e 17 30 3f c7 34 b1 bd 94 4d 45 ?2...j.4..1.>*..?n..>..0?.4...ME
15e0 3f 20 9b 11 c0 6c 3f 36 bf 1a 15 8d 3e 4b 5b 25 3f 14 14 eb 3e 04 70 2d 3f 0d 7b b3 bd 70 94 3b ?....l?6....>K[%?...>.p-?.{..p.;
1600 3f 04 ed 10 c0 6e 39 37 bf 1b 79 0d 3e 5e 3d 2f 3f ec 32 ec 3e 04 9f 2a 3f d8 41 a7 bd f2 cf 5c ?....n97..y.>^=/?.2.>..*?.A....\
1620 3f 3c 38 16 c0 64 e7 31 bf 37 7f 1b 3f 8a 01 c5 3e fe a0 e1 3e 34 82 34 3f 99 f9 aa bd a9 3e 56 ?<8..d.1.7..?...>...>4.4?.....>V
1640 3f 02 4e 14 c0 67 87 33 bf 08 c9 03 3f f9 75 fc 3e 9a b0 e5 3e 66 7a 32 3f 71 55 ae bd 84 4e 4e ?.N..g.3....?.u.>...>fz2?qU...NN
1660 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 6e e1 e8 3e 2e 17 30 3f 0f 54 9f bd 7c e3 64 ?2...j.4..1.>*..?n..>..0?.T..|.d
1680 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f 2a 53 a3 bd c6 c1 61 ?....]m..q.8?...>8..>.37?*S....a
16a0 3f 09 6b 18 c0 60 2f 30 bf 5b 57 2d 3f 0b 5d 85 3e 88 da dc 3e 9c 1a 36 3f d8 41 a7 bd f2 cf 5c ?.k..`/0.[W-?.].>...>..6?.A....\
16c0 3f 3c 38 16 c0 64 e7 31 bf 37 7f 1b 3f 8a 01 c5 3e fe a0 e1 3e 34 82 34 3f fa c0 97 bd 4c 4e 65 ?<8..d.1.7..?...>...>4.4?....LNe
16e0 3f ba d5 1f c0 56 15 2b bf 74 11 3a 3f 44 21 22 be f4 2b cc 3e 54 c3 37 3f e1 6b 9b bd 3f 16 66 ?....V.+.t.:?D!"..+.>T.7?.k..?.f
1700 3f e5 51 1d c0 59 b3 2c bf 7a eb 3c 3f 0c 01 86 bc 32 ea d1 3e 56 c3 37 3f 0f 54 9f bd 7c e3 64 ?.Q..Y.,.z.<?....2..>V.7?.T..|.d
1720 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f ee af 91 bd 29 00 5e ?....]m..q.8?...>8..>.37?....).^
1740 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be a8 3b c1 3e 98 1a 36 3f 98 77 94 bd 54 93 62 ?p.$.Qc(.?..?.A...;.>..6?.w..T.b
1760 3f 8a 43 22 c0 53 9f 29 bf 60 2f 30 3f 2e 41 97 be fc 89 c6 3e ea 33 37 3f fa c0 97 bd 4c 4e 65 ?.C".S.).`/0?.A.....>.37?....LNe
1780 3f ba d5 1f c0 56 15 2b bf 74 11 3a 3f 44 21 22 be f4 2b cc 3e 54 c3 37 3f 48 0d 8e bd c8 15 50 ?....V.+.t.:?D!"..+.>T.7?H.....P
17a0 3f 94 23 28 c0 4d bf 26 bf b6 c1 da 3e 41 83 20 bf 94 65 b8 3e 5c 7a 32 3f 53 85 8f bd d8 c1 57 ?.#(.M.&....>A....e.>\z2?S.....W
17c0 3f 4a 7f 26 c0 4f 69 27 bf 12 17 09 3f 12 cb 08 bf 2c 75 bc 3e 2c 82 34 3f ee af 91 bd 29 00 5e ?J.&.Oi'....?....,u.>,.4?....).^
17e0 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be a8 3b c1 3e 98 1a 36 3f b7 66 8d bd 7a ad 3d ?p.$.Qc(.?..?.A...;.>..6?.f..z.=
1800 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f 0e 56 8d bd 72 47 47 ?.(*.Mg&.W.+>{.=.!..>.o-?.V..rGG
1820 3f 28 60 29 c0 4d 67 26 bf 36 29 9b 3e 65 65 32 bf c2 34 b5 3e 24 17 30 3f 48 0d 8e bd c8 15 50 ?(`).Mg&.6).>ee2..4.>$.0?H.....P
1840 3f 94 23 28 c0 4d bf 26 bf b6 c1 da 3e 41 83 20 bf 94 65 b8 3e 5c 7a 32 3f b7 66 8d bd 7a ad 3d ?.#(.M.&....>A....e.>\z2?.f..z.=
1860 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f 28 fb 94 bd 98 da 16 ?.(*.Mg&.W.+>{.=.!..>.o-?(......
1880 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf d0 34 b5 3e b4 47 22 3f a8 d5 8f bd a8 94 29 ?Qr(.S.).....J.%..4.>.G"?......)
18a0 3f 81 44 2a c0 4f 6d 27 bf db b1 ed bd 7f 5b 3f bf 54 e3 b1 3e da bf 27 3f a3 fc a3 bd 9c 45 00 ?.D*.Om'......[?.T..>..'?.....E.
18c0 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f c2 0e 9c bd 20 59 08 ?.`..`70.gC3...A....>.*.?.....Y.
18e0 3f 47 f9 24 c0 59 bb 2c bf 2c f7 15 bf cc d5 e5 be 40 75 bc 3e aa dc 1d 3f 28 fb 94 bd 98 da 16 ?G.$.Y.,.,.......@u.>...?(......
1900 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf d0 34 b5 3e b4 47 22 3f c7 a0 b1 bd ec 28 07 ?Qr(.S.).....J.%..4.>.G"?.....(.
1920 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 94 da dc 3e 42 44 1c 3f bd 8f ab bd 90 b5 ff ?....mE6.5k..p..>...>BD.?.......
1940 3e ca 5b 1b c0 67 91 33 bf 6a d5 34 bf 84 e1 c1 3d 46 ea d1 3e 88 9b 1a 3f a3 fc a3 bd 9c 45 00 >.[..g.3.j.4....=F..>...?.....E.
1960 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f 00 ea b5 bd a2 7b 27 ?.`..`70.gC3...A....>.*.?.....{'
1980 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f 6e 43 b5 bd 52 13 15 ?....pA8.+y..[.-?...>..$?nC..R..
19a0 3f ee 0d 13 c0 70 eb 37 bf a0 0d d0 be 21 83 10 3f a4 b0 e5 3e 7a e4 1f 3f c7 a0 b1 bd ec 28 07 ?....p.7.....!..?...>z..?.....(.
19c0 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 94 da dc 3e 42 44 1c 3f 71 55 ae bd 84 4e 4e ?....mE6.5k..p..>...>BD.?qU...NN
19e0 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 6e e1 e8 3e 2e 17 30 3f 0d 7b b3 bd 70 94 3b ?2...j.4..1.>*..?n..>..0?.{..p.;
1a00 3f 04 ed 10 c0 6e 39 37 bf 1b 79 0d 3e 5e 3d 2f 3f ec 32 ec 3e 04 9f 2a 3f 00 ea b5 bd a2 7b 27 ?....n97..y.>^=/?.2.>..*?.....{'
1a20 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f 0f 54 9f bd 7c e3 64 ?....pA8.+y..[.-?...>..$?.T..|.d
1a40 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f d8 41 a7 bd f2 cf 5c ?....]m..q.8?...>8..>.37?.A....\
1a60 3f 3c 38 16 c0 64 e7 31 bf 37 7f 1b 3f 8a 01 c5 3e fe a0 e1 3e 34 82 34 3f 71 55 ae bd 84 4e 4e ?<8..d.1.7..?...>...>4.4?qU...NN
1a80 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 6e e1 e8 3e 2e 17 30 3f ee af 91 bd 29 00 5e ?2...j.4..1.>*..?n..>..0?....).^
1aa0 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be a8 3b c1 3e 98 1a 36 3f fa c0 97 bd 4c 4e 65 ?p.$.Qc(.?..?.A...;.>..6?....LNe
1ac0 3f ba d5 1f c0 56 15 2b bf 74 11 3a 3f 44 21 22 be f4 2b cc 3e 54 c3 37 3f 0f 54 9f bd 7c e3 64 ?....V.+.t.:?D!"..+.>T.7?.T..|.d
1ae0 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f b7 66 8d bd 7a ad 3d ?....]m..q.8?...>8..>.37?.f..z.=
1b00 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f 48 0d 8e bd c8 15 50 ?.(*.Mg&.W.+>{.=.!..>.o-?H.....P
1b20 3f 94 23 28 c0 4d bf 26 bf b6 c1 da 3e 41 83 20 bf 94 65 b8 3e 5c 7a 32 3f ee af 91 bd 29 00 5e ?.#(.M.&....>A....e.>\z2?....).^
1b40 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be a8 3b c1 3e 98 1a 36 3f b7 66 8d bd 7a ad 3d ?p.$.Qc(.?..?.A...;.>..6?.f..z.=
1b60 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f a3 fc a3 bd 9c 45 00 ?.(*.Mg&.W.+>{.=.!..>.o-?.....E.
1b80 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f 28 fb 94 bd 98 da 16 ?.`..`70.gC3...A....>.*.?(......
1ba0 3f 51 72 28 c0 53 a5 29 bf 86 e1 c2 be 4a 19 25 bf d0 34 b5 3e b4 47 22 3f 00 ea b5 bd a2 7b 27 ?Qr(.S.).....J.%..4.>.G"?.....{'
1bc0 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f c7 a0 b1 bd ec 28 07 ?....pA8.+y..[.-?...>..$?.....(.
1be0 3f 13 ae 16 c0 6d 45 36 bf 35 6b 1a bf 70 01 b8 3e 94 da dc 3e 42 44 1c 3f a3 fc a3 bd 9c 45 00 ?....mE6.5k..p..>...>BD.?.....E.
1c00 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f 0f 54 9f bd 7c e3 64 ?.`..`70.gC3...A....>.*.?.T..|.d
1c20 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f 71 55 ae bd 84 4e 4e ?....]m..q.8?...>8..>.37?qU...NN
1c40 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 6e e1 e8 3e 2e 17 30 3f 00 ea b5 bd a2 7b 27 ?2...j.4..1.>*..?n..>..0?.....{'
1c60 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f b7 66 8d bd 7a ad 3d ?....pA8.+y..[.-?...>..$?.f..z.=
1c80 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f ee af 91 bd 29 00 5e ?.(*.Mg&.W.+>{.=.!..>.o-?....).^
1ca0 3f 70 83 24 c0 51 63 28 bf 3f a5 1f 3f b0 41 d8 be a8 3b c1 3e 98 1a 36 3f 0f 54 9f bd 7c e3 64 ?p.$.Qc(.?..?.A...;.>..6?.T..|.d
1cc0 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f b7 66 8d bd 7a ad 3d ?....]m..q.8?...>8..>.37?.f..z.=
1ce0 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f 00 ea b5 bd a2 7b 27 ?.(*.Mg&.W.+>{.=.!..>.o-?.....{'
1d00 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f a3 fc a3 bd 9c 45 00 ?....pA8.+y..[.-?...>..$?.....E.
1d20 3f ba 60 20 c0 60 37 30 bf 67 43 33 bf 83 b9 41 be 0c 8a c6 3e f0 2a 1b 3f b7 66 8d bd 7a ad 3d ?.`..`70.gC3...A....>.*.?.f..z.=
1d40 3f da 28 2a c0 4d 67 26 bf 57 99 2b 3e 7b bd 3d bf 21 02 b3 3e f8 6f 2d 3f 0f 54 9f bd 7c e3 64 ?.(*.Mg&.W.+>{.=.!..>.o-?.T..|.d
1d60 3f c8 d0 1a c0 5d 6d 2e bf 71 9f 38 3f 00 09 00 3e 38 8c d7 3e ee 33 37 3f 00 ea b5 bd a2 7b 27 ?....]m..q.8?...>8..>.37?.....{'
1d80 3f aa 08 11 c0 70 41 38 bf 2b 79 15 be 5b bf 2d 3f 1a 14 eb 3e e2 ee 24 3f 92 a1 92 3c 11 ee 44 ?....pA8.+y..[.-?...>..$?...<..D
1da0 3f 9e 4e 11 c0 51 67 28 3f 03 bd 81 3e 6b 8f 35 3f 9d e0 95 3e a8 d1 0b 3f c7 34 b1 bd 94 4d 45 ?.N..Qg(?...>k.5?...>...?.4...ME
1dc0 3f 20 9b 11 c0 6c 3f 36 bf 1a 15 8d 3e 4b 5b 25 3f 15 a9 86 3e 59 d1 0b 3f 71 55 ae bd 84 4e 4e ?....l?6....>K[%?...>Y..?qU...NN
1de0 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 1f ad 86 3e 76 b0 0e 3f 80 1e 9e 3c 02 ef 4d ?2...j.4..1.>*..?...>v..?...<..M
1e00 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f a3 e4 95 3e c8 b0 0e 3f 80 1e 9e 3c 02 ef 4d ?.r..S.)?...>J.%?...>...?...<..M
1e20 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f a3 e4 95 3e c8 b0 0e 3f 71 55 ae bd 84 4e 4e ?.r..S.)?...>J.%?...>...?qU...NN
1e40 3f 32 bf 12 c0 6a ff 34 bf 9c 31 ce 3e 2a cf 14 3f 1f ad 86 3e 76 b0 0e 3f 99 f9 aa bd a9 3e 56 ?2...j.4..1.>*..?...>v..?.....>V
1e60 3f 02 4e 14 c0 67 87 33 bf 08 c9 03 3f f9 75 fc 3e 4d b1 86 3e 94 8f 11 3f 5b 8e ab 3c 27 df 55 ?.N..g.3....?.u.>M..>...?[..<'.U
1e80 3f 80 01 14 c0 56 1b 2b 3f f9 59 fc 3e 1d 99 0e 3f d5 e8 95 3e e3 8f 11 3f f2 ec 10 3d f6 4d 3d ?....V.+?.Y.>...?...>...?...=.M=
1ea0 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f c9 9f 0f 3d 46 b6 4f ?X.).pA8?+y.>[.-.Z..>...?...=F.O
1ec0 3f 13 d7 27 c0 70 eb 37 3f a0 0d d0 3e 21 83 10 bf dd 80 b3 3e 6d 88 00 3f 3a 0e 11 3d ee e7 46 ?..'.p.7?...>!......>m..?:..=..F
1ee0 3f a5 13 29 c0 70 41 38 3f 21 45 90 3e 45 69 22 bf 85 b3 b5 3e 95 2f 03 3f 7a 5a 08 3d aa a0 5d ?..).pA8?!E.>Ei"....>./.?zZ.=..]
1f00 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 04 62 b2 3e 96 b0 f5 3e b2 af 0c 3d 58 62 57 ?.6$.mE6?5k.?p....b.>...>...=XbW
1f20 3f c8 32 26 c0 6e 3f 37 3f 08 d1 03 3f e3 79 f1 be 04 62 b2 3e da 6e fb 3e c9 9f 0f 3d 46 b6 4f ?.2&.n?7?...?.y...b.>.n.>...=F.O
1f40 3f 13 d7 27 c0 70 eb 37 3f a0 0d d0 3e 21 83 10 bf dd 80 b3 3e 6d 88 00 3f cc 70 f8 3c cd ee 64 ?..'.p.7?...>!......>m..?.p.<..d
1f60 3f 38 89 1f c0 67 91 33 3f 6a d5 34 3f 84 e1 c1 bd 74 b3 b5 3e 4a c0 ea 3e 29 cb 02 3d d5 33 62 ?8...g.3?j.4?....t..>J..>)..=.3b
1f80 3f 08 f7 21 c0 6a 07 35 3f 56 f7 2a 3f db a9 6d be d0 80 b3 3e a0 0e f0 3e 7a 5a 08 3d aa a0 5d ?..!.j.5?V.*?..m....>...>zZ.=..]
1fa0 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 04 62 b2 3e 96 b0 f5 3e 71 24 da 3c fa 83 64 ?.6$.mE6?5k.?p....b.>...>q$.<..d
1fc0 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e 2c c5 e9 3c c4 b6 65 ?G...`70?fA3?..A>...>...>,..<..e
1fe0 3f 62 05 1d c0 64 f1 31 3f 6f a1 37 3f 86 e1 42 3d 41 e4 b8 3e cc f9 e5 3e cc 70 f8 3c cd ee 64 ?b...d.1?o.7?..B=A..>...>.p.<..d
2000 3f 38 89 1f c0 67 91 33 3f 6a d5 34 3f 84 e1 c1 bd 74 b3 b5 3e 4a c0 ea 3e 5a 6d ba 3c 72 70 5c ?8...g.3?j.4?....t..>J..>Zm.<rp\
2020 3f ba eb 15 c0 59 bb 2c 3f 2c f7 15 3f cc d5 e5 3e a5 08 c7 3e b2 86 dc 3e 12 28 ca 3c 46 62 61 ?....Y.,?,..?...>...>...>.(.<Fba
2040 3f 88 1e 18 c0 5d 75 2e 3f 50 e3 27 3f 4c 41 a6 3e 54 ba c1 3e 58 b9 de 3e 71 24 da 3c fa 83 64 ?....]u.?P.'?LA.>T..>X..>q$.<..d
2060 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e 80 1e 9e 3c 02 ef 4d ?G...`70?fA3?..A>...>...>...<..M
2080 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f de 68 d2 3e d8 67 db 3e 5b 8e ab 3c 27 df 55 ?.r..S.)?...>J.%?.h.>.g.>[..<'.U
20a0 3f 80 01 14 c0 56 1b 2b 3f f9 59 fc 3e 1d 99 0e 3f a6 aa cc 3e da 67 db 3e 5a 6d ba 3c 72 70 5c ?....V.+?.Y.>...?...>.g.>Zm.<rp\
20c0 3f ba eb 15 c0 59 bb 2c 3f 2c f7 15 3f cc d5 e5 3e a5 08 c7 3e b2 86 dc 3e 88 88 89 3c f4 34 3b ?....Y.,?,..?...>...>...>...<.4;
20e0 3f 82 a0 10 c0 4f 6d 27 3f db b1 ed 3d 7f 5b 3f 3f 33 59 dd 3e 46 b9 de 3e 92 a1 92 3c 11 ee 44 ?....Om'?...=.[??3Y.>F..>...<..D
2100 3f 9e 4e 11 c0 51 67 28 3f 03 bd 81 3e 6b 8f 35 3f df 0a d8 3e a6 86 dc 3e 80 1e 9e 3c 02 ef 4d ?.N..Qg(?...>k.5?...>...>...<..M
2120 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f de 68 d2 3e d8 67 db 3e 60 99 7f 3c 22 1c 27 ?.r..S.)?...>J.%?.h.>.g.>`..<".'
2140 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e c8 2c 83 3c 48 23 31 ?(...Mg&?W.+.{.=?L/.>...>.,.<H#1
2160 3f 0e 6f 10 c0 4e c1 26 3f aa 41 d5 bc 84 1f 42 3f aa 1f e2 3e 18 ea e1 3e 88 88 89 3c f4 34 3b ?.o..N.&?.A....B?...>...>...<.4;
2180 3f 82 a0 10 c0 4f 6d 27 3f db b1 ed 3d 7f 5b 3f 3f 33 59 dd 3e 46 b9 de 3e 05 67 82 3c d2 b3 14 ?....Om'?...=.[??3Y.>F..>.g.<...
21a0 3f 6d c1 12 c0 4d bf 26 3f b6 c1 da be 41 83 20 3f c6 92 eb 3e 7c 0e f0 3e 40 14 7f 3c 2c 82 1d ?m...M.&?....A..?...>|..>@..<,..
21c0 3f da 84 11 c0 4d 67 26 3f 36 25 9b be 65 65 32 3f 21 60 e9 3e 28 c0 ea 3e 60 99 7f 3c 22 1c 27 ?....Mg&?6%..ee2?!`.>(..>`..<".'
21e0 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e 8c f1 90 3c 6e c9 06 ?(...Mg&?W.+.{.=?L/.>...>...<n..
2200 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e 9e b1 ec 3e b8 6e fb 3e 31 47 88 3c c0 07 0d ?.a..Qc(??....A.>...>.n.>1G.<...
2220 3f b7 65 14 c0 4f 69 27 3f 12 17 09 bf 12 cb 08 3f 9e b1 ec 3e 7a b0 f5 3e 05 67 82 3c d2 b3 14 ?.e..Oi'?.......?...>z..>.g.<...
2240 3f 6d c1 12 c0 4d bf 26 3f b6 c1 da be 41 83 20 3f c6 92 eb 3e 7c 0e f0 3e c8 35 a9 3c 94 f6 fe ?m...M.&?....A..?...>|..>.5.<...
2260 3e 47 0f 1b c0 56 15 2b 3f 74 11 3a bf 44 21 22 3e 2e 60 e9 3e 84 2f 03 3f 44 10 9c 3c 46 36 02 >G...V.+?t.:.D!">.`.>./.?D..<F6.
2280 3f 78 a1 18 c0 53 9f 29 3f 60 2f 30 bf 2e 41 97 3e ce 92 eb 3e 5a 88 00 3f 8c f1 90 3c 6e c9 06 ?x...S.)?`/0..A.>...>Z..?...<n..
22a0 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e 9e b1 ec 3e b8 6e fb 3e 24 82 c7 3c 34 cc ff ?.a..Qc(??....A.>...>.n.>$..<4..
22c0 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f 67 e1 b7 3c b0 66 fd >9...]m.?q.8........>...?g..<.f.
22e0 3e 1c 93 1d c0 59 b3 2c 3f 7a eb 3c bf 0c 01 86 3c 5c 2f e6 3e c0 92 05 3f c8 35 a9 3c 94 f6 fe >....Y.,?z.<....<\/.>...?.5.<...
2300 3e 47 0f 1b c0 56 15 2b 3f 74 11 3a bf 44 21 22 3e 2e 60 e9 3e 84 2f 03 3f 3c 39 e7 3c a2 f9 07 >G...V.+?t.:.D!">.`.>./.?<9.<...
2320 3f c6 ac 24 c0 64 e7 31 3f 37 7f 1b bf 8a 01 c5 be fa 0a d8 3e 4c 4c 0a 3f 82 7e d7 3c ce 07 03 ?..$.d.1?7..........>LL.?.~.<...
2340 3f f8 79 22 c0 60 2f 30 3f 5b 57 2d bf 0b 5d 85 be 4a 59 dd 3e fa 32 09 3f 24 82 c7 3c 34 cc ff ?.y".`/0?[W-..]..JY.>.2.?$..<4..
2360 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f 0d c4 01 3d 18 7b 16 >9...]m.?q.8........>...?...=.{.
2380 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf c1 aa cc 3e b9 db 0a 3f ba 17 f6 3c ee 8a 0e ?.%(.j.4?.1..*......>...?...<...
23a0 3f 00 97 26 c0 67 87 33 3f 08 c9 03 bf f9 75 fc be fe 68 d2 3e ba db 0a 3f 3c 39 e7 3c a2 f9 07 ?..&.g.3?.....u...h.>...?<9.<...
23c0 3f c6 ac 24 c0 64 e7 31 3f 37 7f 1b bf 8a 01 c5 be fa 0a d8 3e 4c 4c 0a 3f 06 0f 0c 3d 2a 35 29 ?..$.d.1?7..........>LL.?...=*5)
23e0 3f fe f7 29 c0 6e 39 37 3f 1b 79 0d be 5e 3d 2f bf 6f ba c1 3e 03 33 09 3f 81 82 07 3d 08 7c 1f ?..).n97?.y..^=/.o..>.3.?...=.|.
2400 3f e2 49 29 c0 6c 3f 36 3f 1a 15 8d be 4b 5b 25 bf c5 08 c7 3e 52 4c 0a 3f 0d c4 01 3d 18 7b 16 ?.I).l?6?....K[%....>RL.?...=.{.
2420 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf c1 aa cc 3e b9 db 0a 3f f2 ec 10 3d f6 4d 3d ?.%(.j.4?.1..*......>...?...=.M=
2440 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f e8 3c 0f 3d d4 46 33 ?X.).pA8?+y.>[.-.Z..>...?.<.=.F3
2460 3f 72 29 2a c0 70 e7 37 3f 10 01 88 3b 64 13 32 bf f9 f3 bc 3e 9b 9a 07 3f 06 0f 0c 3d 2a 35 29 ?r)*.p.7?...;d.2....>...?...=*5)
2480 3f fe f7 29 c0 6e 39 37 3f 1b 79 0d be 5e 3d 2f bf 6f ba c1 3e 03 33 09 3f f2 ec 10 3d f6 4d 3d ?..).n97?.y..^=/.o..>.3.?...=.M=
24a0 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f 7a 5a 08 3d aa a0 5d ?X.).pA8?+y.>[.-.Z..>...?zZ.=..]
24c0 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 04 62 b2 3e 96 b0 f5 3e c9 9f 0f 3d 46 b6 4f ?.6$.mE6?5k.?p....b.>...>...=F.O
24e0 3f 13 d7 27 c0 70 eb 37 3f a0 0d d0 3e 21 83 10 bf dd 80 b3 3e 6d 88 00 3f 71 24 da 3c fa 83 64 ?..'.p.7?...>!......>m..?q$.<..d
2500 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e cc 70 f8 3c cd ee 64 ?G...`70?fA3?..A>...>...>.p.<..d
2520 3f 38 89 1f c0 67 91 33 3f 6a d5 34 3f 84 e1 c1 bd 74 b3 b5 3e 4a c0 ea 3e 7a 5a 08 3d aa a0 5d ?8...g.3?j.4?....t..>J..>zZ.=..]
2540 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 04 62 b2 3e 96 b0 f5 3e 80 1e 9e 3c 02 ef 4d ?.6$.mE6?5k.?p....b.>...>...<..M
2560 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f de 68 d2 3e d8 67 db 3e 5a 6d ba 3c 72 70 5c ?.r..S.)?...>J.%?.h.>.g.>Zm.<rp\
2580 3f ba eb 15 c0 59 bb 2c 3f 2c f7 15 3f cc d5 e5 3e a5 08 c7 3e b2 86 dc 3e 71 24 da 3c fa 83 64 ?....Y.,?,..?...>...>...>q$.<..d
25a0 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e 60 99 7f 3c 22 1c 27 ?G...`70?fA3?..A>...>...>`..<".'
25c0 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e 88 88 89 3c f4 34 3b ?(...Mg&?W.+.{.=?L/.>...>...<.4;
25e0 3f 82 a0 10 c0 4f 6d 27 3f db b1 ed 3d 7f 5b 3f 3f 33 59 dd 3e 46 b9 de 3e 80 1e 9e 3c 02 ef 4d ?....Om'?...=.[??3Y.>F..>...<..M
2600 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f de 68 d2 3e d8 67 db 3e 8c f1 90 3c 6e c9 06 ?.r..S.)?...>J.%?.h.>.g.>...<n..
2620 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e 9e b1 ec 3e b8 6e fb 3e 05 67 82 3c d2 b3 14 ?.a..Qc(??....A.>...>.n.>.g.<...
2640 3f 6d c1 12 c0 4d bf 26 3f b6 c1 da be 41 83 20 3f c6 92 eb 3e 7c 0e f0 3e 60 99 7f 3c 22 1c 27 ?m...M.&?....A..?...>|..>`..<".'
2660 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e 24 82 c7 3c 34 cc ff ?(...Mg&?W.+.{.=?L/.>...>$..<4..
2680 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f c8 35 a9 3c 94 f6 fe >9...]m.?q.8........>...?.5.<...
26a0 3e 47 0f 1b c0 56 15 2b 3f 74 11 3a bf 44 21 22 3e 2e 60 e9 3e 84 2f 03 3f 8c f1 90 3c 6e c9 06 >G...V.+?t.:.D!">.`.>./.?...<n..
26c0 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e 9e b1 ec 3e b8 6e fb 3e 0d c4 01 3d 18 7b 16 ?.a..Qc(??....A.>...>.n.>...=.{.
26e0 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf c1 aa cc 3e b9 db 0a 3f 3c 39 e7 3c a2 f9 07 ?.%(.j.4?.1..*......>...?<9.<...
2700 3f c6 ac 24 c0 64 e7 31 3f 37 7f 1b bf 8a 01 c5 be fa 0a d8 3e 4c 4c 0a 3f 24 82 c7 3c 34 cc ff ?..$.d.1?7..........>LL.?$..<4..
2720 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f f2 ec 10 3d f6 4d 3d >9...]m.?q.8........>...?...=.M=
2740 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f 06 0f 0c 3d 2a 35 29 ?X.).pA8?+y.>[.-.Z..>...?...=*5)
2760 3f fe f7 29 c0 6e 39 37 3f 1b 79 0d be 5e 3d 2f bf 6f ba c1 3e 03 33 09 3f 0d c4 01 3d 18 7b 16 ?..).n97?.y..^=/.o..>.3.?...=.{.
2780 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf c1 aa cc 3e b9 db 0a 3f f2 ec 10 3d f6 4d 3d ?.%(.j.4?.1..*......>...?...=.M=
27a0 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f 71 24 da 3c fa 83 64 ?X.).pA8?+y.>[.-.Z..>...?q$.<..d
27c0 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e 7a 5a 08 3d aa a0 5d ?G...`70?fA3?..A>...>...>zZ.=..]
27e0 3f ee 36 24 c0 6d 45 36 3f 35 6b 1a 3f 70 01 b8 be 04 62 b2 3e 96 b0 f5 3e 60 99 7f 3c 22 1c 27 ?.6$.mE6?5k.?p....b.>...>`..<".'
2800 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e 80 1e 9e 3c 02 ef 4d ?(...Mg&?W.+.{.=?L/.>...>...<..M
2820 3f b2 72 12 c0 53 a5 29 3f 86 e1 c2 3e 4a 19 25 3f de 68 d2 3e d8 67 db 3e 71 24 da 3c fa 83 64 ?.r..S.)?...>J.%?.h.>.g.>q$.<..d
2840 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e 24 82 c7 3c 34 cc ff ?G...`70?fA3?..A>...>...>$..<4..
2860 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f 8c f1 90 3c 6e c9 06 >9...]m.?q.8........>...?...<n..
2880 3f 90 61 16 c0 51 63 28 3f 3f a5 1f bf b0 41 d8 3e 9e b1 ec 3e b8 6e fb 3e 60 99 7f 3c 22 1c 27 ?.a..Qc(??....A.>...>.n.>`..<".'
28a0 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e f2 ec 10 3d f6 4d 3d ?(...Mg&?W.+.{.=?L/.>...>...=.M=
28c0 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f 0d c4 01 3d 18 7b 16 ?X.).pA8?+y.>[.-.Z..>...?...=.{.
28e0 3f d0 25 28 c0 6a ff 34 3f 9c 31 ce be 2a cf 14 bf c1 aa cc 3e b9 db 0a 3f 24 82 c7 3c 34 cc ff ?.%(.j.4?.1..*......>...?$..<4..
2900 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f f2 ec 10 3d f6 4d 3d >9...]m.?q.8........>...?...=.M=
2920 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f 60 99 7f 3c 22 1c 27 ?X.).pA8?+y.>[.-.Z..>...?`..<".'
2940 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e 71 24 da 3c fa 83 64 ?(...Mg&?W.+.{.=?L/.>...>q$.<..d
2960 3f 47 84 1a c0 60 37 30 3f 66 41 33 3f 83 b9 41 3e e1 f3 bc 3e 2e ea e1 3e f2 ec 10 3d f6 4d 3d ?G...`70?fA3?..A>...>...>...=.M=
2980 3f 58 dc 29 c0 70 41 38 3f 2b 79 15 3e 5b bf 2d bf 5a e4 b8 3e cf 92 05 3f 24 82 c7 3c 34 cc ff ?X.).pA8?+y.>[.-.Z..>...?$..<4..
29a0 3e 39 14 20 c0 5d 6d 2e 3f 71 9f 38 bf 00 09 00 be be 1f e2 3e 93 9a 07 3f 60 99 7f 3c 22 1c 27 >9...]m.?q.8........>...?`..<".'
29c0 3f 28 bc 10 c0 4d 67 26 3f 57 99 2b be 7b bd 3d 3f 4c 2f e6 3e b6 f9 e5 3e 76 d0 01 be 75 15 eb ?(...Mg&?W.+.{.=?L/.>...>v...u..
29e0 3f 4b 47 eb bf 25 b9 12 3f b8 01 5c bb a4 c5 51 3f 90 81 20 3e f0 fc a2 3d a0 04 06 be 77 e7 f7 ?KG..%..?..\...Q?...>...=....w..
2a00 3f b3 b0 dd bf 36 09 1b 3f 97 a3 4b bf 4a c1 a4 bc 30 03 4b 3e 00 fd a2 3d 70 66 76 3c 95 8e f8 ?....6..?..K.J...0.K>...=pfv<...
2a20 3f 7b 95 dd bf 19 5f 0c bf ac f7 55 bf b5 81 da bc 30 03 4b 3e 80 f3 1b 3d 7c d4 9c 3c 93 bc eb ?{...._....U.....0.K>...=|..<...
2a40 3f 0f 2c eb bf 29 af 14 bf 66 01 33 bd a0 17 50 3f 9c 81 20 3e 60 f3 1b 3d 76 d0 01 be 75 15 eb ?.,..)...f.3...P?...>`..=v...u..
2a60 3f 4b 47 eb bf 25 b9 12 3f b8 01 5c bb a4 c5 51 3f 90 81 20 3e f0 fc a2 3d fa 69 76 bd 4f 00 d5 ?KG..%..?..\...Q?...>...=.iv.O..
2a80 be 4b 5d 94 3e 60 cf 2f 3f 05 7f 02 3f 09 a3 04 3f 98 81 20 3e 8e f3 75 3f 47 9d 83 bd 47 b8 a1 .K].>`./?...?...?...>..u?G...G..
2aa0 be a3 b7 ca 3e 74 fd 39 3f d7 b1 eb be 05 95 02 bf 0c 03 4b 3e 90 f3 75 3f a0 04 06 be 77 e7 f7 ....>t.9?..........K>..u?....w..
2ac0 3f b3 b0 dd bf 36 09 1b 3f 97 a3 4b bf 4a c1 a4 bc 30 03 4b 3e 00 fd a2 3d a0 04 06 be 77 e7 f7 ?....6..?..K.J...0.K>...=....w..
2ae0 3f b3 b0 dd bf 36 09 1b 3f 97 a3 4b bf 4a c1 a4 bc 50 f3 03 3d 10 fd a2 3d 47 9d 83 bd 47 b8 a1 ?....6..?..K.J...P..=...=G...G..
2b00 be a3 b7 ca 3e 74 fd 39 3f d7 b1 eb be 05 95 02 bf 40 f5 03 3d 90 f3 75 3f c5 38 a7 3d d7 1b 9f ....>t.9?........@..=..u?.8.=...
2b20 be 8b 24 cb 3e 60 cf 2f bf 05 7f 02 bf 09 a3 04 bf 98 fd 96 3d 8f f3 75 3f 70 66 76 3c 95 8e f8 ..$.>`./............=..u?pfv<...
2b40 3f 7b 95 dd bf 19 5f 0c bf ac f7 55 bf b5 81 da bc 50 fc 96 3d 00 fd a2 3d 70 66 76 3c 95 8e f8 ?{...._....U.....P..=...=pfv<...
2b60 3f 7b 95 dd bf 19 5f 0c bf ac f7 55 bf b5 81 da bc 50 fc 96 3d 00 fd a2 3d c5 38 a7 3d d7 1b 9f ?{...._....U.....P..=...=.8.=...
2b80 be 8b 24 cb 3e 60 cf 2f bf 05 7f 02 bf 09 a3 04 bf 98 fd 96 3d 8f f3 75 3f 15 a1 af 3d df 63 d2 ..$.>`./............=..u?...=.c.
2ba0 be 33 ca 94 3e 74 fd 39 bf d7 b1 eb 3e 05 95 02 3f 88 00 ec 3d 8f f3 75 3f 7c d4 9c 3c 93 bc eb .3..>t.9....>...?...=..u?|..<...
2bc0 3f 0f 2c eb bf 29 af 14 bf 66 01 33 bd a0 17 50 3f 28 00 ec 3d f0 fc a2 3d fa 69 76 bd 4f 00 d5 ?.,..)...f.3...P?(..=...=.iv.O..
2be0 be 4b 5d 94 3e 60 cf 2f 3f 05 7f 02 3f 09 a3 04 3f 98 81 20 3e 8e f3 75 3f 76 d0 01 be 75 15 eb .K].>`./?...?...?...>..u?v...u..
2c00 3f 4b 47 eb bf 25 b9 12 3f b8 01 5c bb a4 c5 51 3f 90 81 20 3e f0 fc a2 3d 7c d4 9c 3c 93 bc eb ?KG..%..?..\...Q?...>...=|..<...
2c20 3f 0f 2c eb bf 29 af 14 bf 66 01 33 bd a0 17 50 3f 28 00 ec 3d f0 fc a2 3d 15 a1 af 3d df 63 d2 ?.,..)...f.3...P?(..=...=...=.c.
2c40 be 33 ca 94 3e 74 fd 39 bf d7 b1 eb 3e 05 95 02 3f 88 00 ec 3d 8f f3 75 3f 54 52 49 53 c4 06 00 .3..>t.9....>...?...=..u?TRIS...
2c60 00 00 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 02 00 00 00 00 00 00 00 06 00 00 ................................
2c80 00 05 00 00 00 04 00 00 00 07 00 00 00 06 00 00 00 04 00 00 00 0a 00 00 00 09 00 00 00 08 00 00 ................................
2ca0 00 0b 00 00 00 0a 00 00 00 08 00 00 00 0e 00 00 00 0d 00 00 00 0c 00 00 00 0f 00 00 00 0e 00 00 ................................
2cc0 00 0c 00 00 00 12 00 00 00 11 00 00 00 10 00 00 00 13 00 00 00 12 00 00 00 10 00 00 00 16 00 00 ................................
2ce0 00 15 00 00 00 14 00 00 00 17 00 00 00 16 00 00 00 14 00 00 00 1a 00 00 00 19 00 00 00 18 00 00 ................................
2d00 00 1b 00 00 00 1a 00 00 00 18 00 00 00 1e 00 00 00 1d 00 00 00 1c 00 00 00 1f 00 00 00 1e 00 00 ................................
2d20 00 1c 00 00 00 22 00 00 00 21 00 00 00 20 00 00 00 23 00 00 00 22 00 00 00 20 00 00 00 26 00 00 ....."...!.......#...".......&..
2d40 00 25 00 00 00 24 00 00 00 27 00 00 00 26 00 00 00 24 00 00 00 2a 00 00 00 29 00 00 00 28 00 00 .%...$...'...&...$...*...)...(..
2d60 00 2b 00 00 00 2a 00 00 00 28 00 00 00 2e 00 00 00 2d 00 00 00 2c 00 00 00 2f 00 00 00 2e 00 00 .+...*...(.......-...,.../......
2d80 00 2c 00 00 00 32 00 00 00 31 00 00 00 30 00 00 00 33 00 00 00 32 00 00 00 30 00 00 00 36 00 00 .,...2...1...0...3...2...0...6..
2da0 00 35 00 00 00 34 00 00 00 37 00 00 00 36 00 00 00 34 00 00 00 3a 00 00 00 39 00 00 00 38 00 00 .5...4...7...6...4...:...9...8..
2dc0 00 3b 00 00 00 3a 00 00 00 38 00 00 00 3e 00 00 00 3d 00 00 00 3c 00 00 00 3f 00 00 00 3e 00 00 .;...:...8...>...=...<...?...>..
2de0 00 3c 00 00 00 42 00 00 00 41 00 00 00 40 00 00 00 43 00 00 00 42 00 00 00 40 00 00 00 46 00 00 .<...B...A...@...C...B...@...F..
2e00 00 45 00 00 00 44 00 00 00 47 00 00 00 46 00 00 00 44 00 00 00 4a 00 00 00 49 00 00 00 48 00 00 .E...D...G...F...D...J...I...H..
2e20 00 4b 00 00 00 4a 00 00 00 48 00 00 00 4e 00 00 00 4d 00 00 00 4c 00 00 00 4f 00 00 00 4e 00 00 .K...J...H...N...M...L...O...N..
2e40 00 4c 00 00 00 52 00 00 00 51 00 00 00 50 00 00 00 53 00 00 00 52 00 00 00 50 00 00 00 56 00 00 .L...R...Q...P...S...R...P...V..
2e60 00 55 00 00 00 54 00 00 00 57 00 00 00 56 00 00 00 54 00 00 00 5a 00 00 00 59 00 00 00 58 00 00 .U...T...W...V...T...Z...Y...X..
2e80 00 5b 00 00 00 5a 00 00 00 58 00 00 00 5e 00 00 00 5d 00 00 00 5c 00 00 00 5f 00 00 00 5e 00 00 .[...Z...X...^...]...\..._...^..
2ea0 00 5c 00 00 00 62 00 00 00 61 00 00 00 60 00 00 00 63 00 00 00 62 00 00 00 60 00 00 00 66 00 00 .\...b...a...`...c...b...`...f..
2ec0 00 65 00 00 00 64 00 00 00 67 00 00 00 66 00 00 00 64 00 00 00 6a 00 00 00 69 00 00 00 68 00 00 .e...d...g...f...d...j...i...h..
2ee0 00 6b 00 00 00 6a 00 00 00 68 00 00 00 6e 00 00 00 6d 00 00 00 6c 00 00 00 6f 00 00 00 6e 00 00 .k...j...h...n...m...l...o...n..
2f00 00 6c 00 00 00 72 00 00 00 71 00 00 00 70 00 00 00 73 00 00 00 72 00 00 00 70 00 00 00 76 00 00 .l...r...q...p...s...r...p...v..
2f20 00 75 00 00 00 74 00 00 00 77 00 00 00 76 00 00 00 74 00 00 00 7a 00 00 00 79 00 00 00 78 00 00 .u...t...w...v...t...z...y...x..
2f40 00 7b 00 00 00 7a 00 00 00 78 00 00 00 7e 00 00 00 7d 00 00 00 7c 00 00 00 7f 00 00 00 7e 00 00 .{...z...x...~...}...|.......~..
2f60 00 7c 00 00 00 82 00 00 00 81 00 00 00 80 00 00 00 83 00 00 00 82 00 00 00 80 00 00 00 86 00 00 .|..............................
2f80 00 85 00 00 00 84 00 00 00 87 00 00 00 86 00 00 00 84 00 00 00 8a 00 00 00 89 00 00 00 88 00 00 ................................
2fa0 00 8b 00 00 00 8a 00 00 00 88 00 00 00 8e 00 00 00 8d 00 00 00 8c 00 00 00 91 00 00 00 90 00 00 ................................
2fc0 00 8f 00 00 00 94 00 00 00 93 00 00 00 92 00 00 00 97 00 00 00 96 00 00 00 95 00 00 00 9a 00 00 ................................
2fe0 00 99 00 00 00 98 00 00 00 9d 00 00 00 9c 00 00 00 9b 00 00 00 a0 00 00 00 9f 00 00 00 9e 00 00 ................................
3000 00 a3 00 00 00 a2 00 00 00 a1 00 00 00 a6 00 00 00 a5 00 00 00 a4 00 00 00 a9 00 00 00 a8 00 00 ................................
3020 00 a7 00 00 00 ac 00 00 00 ab 00 00 00 aa 00 00 00 af 00 00 00 ae 00 00 00 ad 00 00 00 b2 00 00 ................................
3040 00 b1 00 00 00 b0 00 00 00 b5 00 00 00 b4 00 00 00 b3 00 00 00 b8 00 00 00 b7 00 00 00 b6 00 00 ................................
3060 00 bb 00 00 00 ba 00 00 00 b9 00 00 00 be 00 00 00 bd 00 00 00 bc 00 00 00 c1 00 00 00 c0 00 00 ................................
3080 00 bf 00 00 00 c4 00 00 00 c3 00 00 00 c2 00 00 00 c7 00 00 00 c6 00 00 00 c5 00 00 00 ca 00 00 ................................
30a0 00 c9 00 00 00 c8 00 00 00 cd 00 00 00 cc 00 00 00 cb 00 00 00 d0 00 00 00 cf 00 00 00 ce 00 00 ................................
30c0 00 d3 00 00 00 d2 00 00 00 d1 00 00 00 d6 00 00 00 d5 00 00 00 d4 00 00 00 d9 00 00 00 d8 00 00 ................................
30e0 00 d7 00 00 00 dc 00 00 00 db 00 00 00 da 00 00 00 df 00 00 00 de 00 00 00 dd 00 00 00 e2 00 00 ................................
3100 00 e1 00 00 00 e0 00 00 00 e5 00 00 00 e4 00 00 00 e3 00 00 00 e8 00 00 00 e7 00 00 00 e6 00 00 ................................
3120 00 e9 00 00 00 e8 00 00 00 e6 00 00 00 ec 00 00 00 eb 00 00 00 ea 00 00 00 ed 00 00 00 ec 00 00 ................................
3140 00 ea 00 00 00 f0 00 00 00 ef 00 00 00 ee 00 00 00 f3 00 00 00 f2 00 00 00 f1 00 00 00 f6 00 00 ................................
3160 00 f5 00 00 00 f4 00 00 00 f9 00 00 00 f8 00 00 00 f7 00 00 00 fc 00 00 00 fb 00 00 00 fa 00 00 ................................
3180 00 ff 00 00 00 fe 00 00 00 fd 00 00 00 02 01 00 00 01 01 00 00 00 01 00 00 05 01 00 00 04 01 00 ................................
31a0 00 03 01 00 00 08 01 00 00 07 01 00 00 06 01 00 00 0b 01 00 00 0a 01 00 00 09 01 00 00 0e 01 00 ................................
31c0 00 0d 01 00 00 0c 01 00 00 11 01 00 00 10 01 00 00 0f 01 00 00 14 01 00 00 13 01 00 00 12 01 00 ................................
31e0 00 17 01 00 00 16 01 00 00 15 01 00 00 1a 01 00 00 19 01 00 00 18 01 00 00 1d 01 00 00 1c 01 00 ................................
3200 00 1b 01 00 00 20 01 00 00 1f 01 00 00 1e 01 00 00 23 01 00 00 22 01 00 00 21 01 00 00 26 01 00 .................#..."...!...&..
3220 00 25 01 00 00 24 01 00 00 29 01 00 00 28 01 00 00 27 01 00 00 2c 01 00 00 2b 01 00 00 2a 01 00 .%...$...)...(...'...,...+...*..
3240 00 2f 01 00 00 2e 01 00 00 2d 01 00 00 32 01 00 00 31 01 00 00 30 01 00 00 35 01 00 00 34 01 00 ./.......-...2...1...0...5...4..
3260 00 33 01 00 00 38 01 00 00 37 01 00 00 36 01 00 00 3b 01 00 00 3a 01 00 00 39 01 00 00 3e 01 00 .3...8...7...6...;...:...9...>..
3280 00 3d 01 00 00 3c 01 00 00 41 01 00 00 40 01 00 00 3f 01 00 00 44 01 00 00 43 01 00 00 42 01 00 .=...<...A...@...?...D...C...B..
32a0 00 47 01 00 00 46 01 00 00 45 01 00 00 4a 01 00 00 49 01 00 00 48 01 00 00 4b 01 00 00 4a 01 00 .G...F...E...J...I...H...K...J..
32c0 00 48 01 00 00 4e 01 00 00 4d 01 00 00 4c 01 00 00 4f 01 00 00 4e 01 00 00 4c 01 00 00 52 01 00 .H...N...M...L...O...N...L...R..
32e0 00 51 01 00 00 50 01 00 00 53 01 00 00 52 01 00 00 50 01 00 00 56 01 00 00 55 01 00 00 54 01 00 .Q...P...S...R...P...V...U...T..
3300 00 57 01 00 00 56 01 00 00 54 01 00 00 5a 01 00 00 59 01 00 00 58 01 00 00 5b 01 00 00 5a 01 00 .W...V...T...Z...Y...X...[...Z..
3320 00 58 01 00 00 .X...
a id='n2529' href='#n2529'>2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833
/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "server.h"
#include <iostream>
#include <queue>
#include <algorithm>
#include "network/connection.h"
#include "network/networkprotocol.h"
#include "network/serveropcodes.h"
#include "ban.h"
#include "environment.h"
#include "map.h"
#include "threading/mutex_auto_lock.h"
#include "constants.h"
#include "voxel.h"
#include "config.h"
#include "version.h"
#include "filesys.h"
#include "mapblock.h"
#include "server/serveractiveobject.h"
#include "settings.h"
#include "profiler.h"
#include "log.h"
#include "scripting_server.h"
#include "nodedef.h"
#include "itemdef.h"
#include "craftdef.h"
#include "emerge.h"
#include "mapgen/mapgen.h"
#include "mapgen/mg_biome.h"
#include "content_mapnode.h"
#include "content_nodemeta.h"
#include "content/mods.h"
#include "modchannels.h"
#include "serverlist.h"
#include "util/string.h"
#include "rollback.h"
#include "util/serialize.h"
#include "util/thread.h"
#include "defaultsettings.h"
#include "server/mods.h"
#include "util/base64.h"
#include "util/sha1.h"
#include "util/hex.h"
#include "database/database.h"
#include "chatmessage.h"
#include "chat_interface.h"
#include "remoteplayer.h"
#include "server/player_sao.h"
#include "server/serverinventorymgr.h"
#include "translation.h"

class ClientNotFoundException : public BaseException
{
public:
	ClientNotFoundException(const char *s):
		BaseException(s)
	{}
};

class ServerThread : public Thread
{
public:

	ServerThread(Server *server):
		Thread("Server"),
		m_server(server)
	{}

	void *run();

private:
	Server *m_server;
};

void *ServerThread::run()
{
	BEGIN_DEBUG_EXCEPTION_HANDLER

	/*
	 * The real business of the server happens on the ServerThread.
	 * How this works:
	 * AsyncRunStep() runs an actual server step as soon as enough time has
	 * passed (dedicated_server_loop keeps track of that).
	 * Receive() blocks at least(!) 30ms waiting for a packet (so this loop
	 * doesn't busy wait) and will process any remaining packets.
	 */

	m_server->AsyncRunStep(true);

	while (!stopRequested()) {
		try {
			m_server->AsyncRunStep();

			m_server->Receive();

		} catch (con::PeerNotFoundException &e) {
			infostream<<"Server: PeerNotFoundException"<<std::endl;
		} catch (ClientNotFoundException &e) {
		} catch (con::ConnectionBindFailed &e) {
			m_server->setAsyncFatalError(e.what());
		} catch (LuaError &e) {
			m_server->setAsyncFatalError(
					"ServerThread::run Lua: " + std::string(e.what()));
		}
	}

	END_DEBUG_EXCEPTION_HANDLER

	return nullptr;
}

v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
{
	if(pos_exists) *pos_exists = false;
	switch(type){
	case SSP_LOCAL:
		return v3f(0,0,0);
	case SSP_POSITIONAL:
		if(pos_exists) *pos_exists = true;
		return pos;
	case SSP_OBJECT: {
		if(object == 0)
			return v3f(0,0,0);
		ServerActiveObject *sao = env->getActiveObject(object);
		if(!sao)
			return v3f(0,0,0);
		if(pos_exists) *pos_exists = true;
		return sao->getBasePosition(); }
	}
	return v3f(0,0,0);
}

void Server::ShutdownState::reset()
{
	m_timer = 0.0f;
	message.clear();
	should_reconnect = false;
	is_requested = false;
}

void Server::ShutdownState::trigger(float delay, const std::string &msg, bool reconnect)
{
	m_timer = delay;
	message = msg;
	should_reconnect = reconnect;
}

void Server::ShutdownState::tick(float dtime, Server *server)
{
	if (m_timer <= 0.0f)
		return;

	// Timed shutdown
	static const float shutdown_msg_times[] =
	{
		1, 2, 3, 4, 5, 10, 20, 40, 60, 120, 180, 300, 600, 1200, 1800, 3600
	};

	// Automated messages
	if (m_timer < shutdown_msg_times[ARRLEN(shutdown_msg_times) - 1]) {
		for (float t : shutdown_msg_times) {
			// If shutdown timer matches an automessage, shot it
			if (m_timer > t && m_timer - dtime < t) {
				std::wstring periodicMsg = getShutdownTimerMessage();

				infostream << wide_to_utf8(periodicMsg).c_str() << std::endl;
				server->SendChatMessage(PEER_ID_INEXISTENT, periodicMsg);
				break;
			}
		}
	}

	m_timer -= dtime;
	if (m_timer < 0.0f) {
		m_timer = 0.0f;
		is_requested = true;
	}
}

std::wstring Server::ShutdownState::getShutdownTimerMessage() const
{
	std::wstringstream ws;
	ws << L"*** Server shutting down in "
		<< duration_to_string(myround(m_timer)).c_str() << ".";
	return ws.str();
}

/*
	Server
*/

Server::Server(
		const std::string &path_world,
		const SubgameSpec &gamespec,
		bool simple_singleplayer_mode,
		Address bind_addr,
		bool dedicated,
		ChatInterface *iface
	):
	m_bind_addr(bind_addr),
	m_path_world(path_world),
	m_gamespec(gamespec),
	m_simple_singleplayer_mode(simple_singleplayer_mode),
	m_dedicated(dedicated),
	m_async_fatal_error(""),
	m_con(std::make_shared<con::Connection>(PROTOCOL_ID,
			512,
			CONNECTION_TIMEOUT,
			m_bind_addr.isIPv6(),
			this)),
	m_itemdef(createItemDefManager()),
	m_nodedef(createNodeDefManager()),
	m_craftdef(createCraftDefManager()),
	m_thread(new ServerThread(this)),
	m_clients(m_con),
	m_admin_chat(iface),
	m_modchannel_mgr(new ModChannelMgr())
{
	if (m_path_world.empty())
		throw ServerError("Supplied empty world path");

	if (!gamespec.isValid())
		throw ServerError("Supplied invalid gamespec");

#if USE_PROMETHEUS
	m_metrics_backend = std::unique_ptr<MetricsBackend>(createPrometheusMetricsBackend());
#else
	m_metrics_backend = std::unique_ptr<MetricsBackend>(new MetricsBackend());
#endif

	m_uptime_counter = m_metrics_backend->addCounter("minetest_core_server_uptime", "Server uptime (in seconds)");
	m_player_gauge = m_metrics_backend->addGauge("minetest_core_player_number", "Number of connected players");

	m_timeofday_gauge = m_metrics_backend->addGauge(
			"minetest_core_timeofday",
			"Time of day value");

	m_lag_gauge = m_metrics_backend->addGauge(
			"minetest_core_latency",
			"Latency value (in seconds)");

	m_aom_buffer_counter = m_metrics_backend->addCounter(
			"minetest_core_aom_generated_count",
			"Number of active object messages generated");

	m_packet_recv_counter = m_metrics_backend->addCounter(
			"minetest_core_server_packet_recv",
			"Processable packets received");

	m_packet_recv_processed_counter = m_metrics_backend->addCounter(
			"minetest_core_server_packet_recv_processed",
			"Valid received packets processed");

	m_lag_gauge->set(g_settings->getFloat("dedicated_server_step"));
}

Server::~Server()
{

	// Send shutdown message
	SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE,
			L"*** Server shutting down"));

	if (m_env) {
		MutexAutoLock envlock(m_env_mutex);

		infostream << "Server: Saving players" << std::endl;
		m_env->saveLoadedPlayers();

		infostream << "Server: Kicking players" << std::endl;
		std::string kick_msg;
		bool reconnect = false;
		if (isShutdownRequested()) {
			reconnect = m_shutdown_state.should_reconnect;
			kick_msg = m_shutdown_state.message;
		}
		if (kick_msg.empty()) {
			kick_msg = g_settings->get("kick_msg_shutdown");
		}
		m_env->saveLoadedPlayers(true);
		m_env->kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
			kick_msg, reconnect);
	}

	actionstream << "Server: Shutting down" << std::endl;

	// Do this before stopping the server in case mapgen callbacks need to access
	// server-controlled resources (like ModStorages). Also do them before
	// shutdown callbacks since they may modify state that is finalized in a
	// callback.
	if (m_emerge)
		m_emerge->stopThreads();

	if (m_env) {
		MutexAutoLock envlock(m_env_mutex);

		// Execute script shutdown hooks
		infostream << "Executing shutdown hooks" << std::endl;
		m_script->on_shutdown();

		infostream << "Server: Saving environment metadata" << std::endl;
		m_env->saveMeta();
	}

	// Stop threads
	if (m_thread) {
		stop();
		delete m_thread;
	}

	// Delete things in the reverse order of creation
	delete m_emerge;
	delete m_env;
	delete m_rollback;
	delete m_banmanager;
	delete m_itemdef;
	delete m_nodedef;
	delete m_craftdef;

	// Deinitialize scripting
	infostream << "Server: Deinitializing scripting" << std::endl;
	delete m_script;

	while (!m_unsent_map_edit_queue.empty()) {
		delete m_unsent_map_edit_queue.front();
		m_unsent_map_edit_queue.pop();
	}
}

void Server::init()
{
	infostream << "Server created for gameid \"" << m_gamespec.id << "\"";
	if (m_simple_singleplayer_mode)
		infostream << " in simple singleplayer mode" << std::endl;
	else
		infostream << std::endl;
	infostream << "- world:  " << m_path_world << std::endl;
	infostream << "- game:   " << m_gamespec.path << std::endl;

	// Create world if it doesn't exist
	if (!loadGameConfAndInitWorld(m_path_world, m_gamespec))
		throw ServerError("Failed to initialize world");

	// Create emerge manager
	m_emerge = new EmergeManager(this);

	// Create ban manager
	std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
	m_banmanager = new BanManager(ban_path);

	m_modmgr = std::unique_ptr<ServerModManager>(new ServerModManager(m_path_world));
	std::vector<ModSpec> unsatisfied_mods = m_modmgr->getUnsatisfiedMods();
	// complain about mods with unsatisfied dependencies
	if (!m_modmgr->isConsistent()) {
		m_modmgr->printUnsatisfiedModsError();
	}

	//lock environment
	MutexAutoLock envlock(m_env_mutex);

	// Create the Map (loads map_meta.txt, overriding configured mapgen params)
	ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge, m_metrics_backend.get());

	// Initialize scripting
	infostream << "Server: Initializing Lua" << std::endl;

	m_script = new ServerScripting(this);

	// Must be created before mod loading because we have some inventory creation
	m_inventory_mgr = std::unique_ptr<ServerInventoryManager>(new ServerInventoryManager());

	m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);

	m_modmgr->loadMods(m_script);

	// Read Textures and calculate sha1 sums
	fillMediaCache();

	// Apply item aliases in the node definition manager
	m_nodedef->updateAliases(m_itemdef);

	// Apply texture overrides from texturepack/override.txt
	std::vector<std::string> paths;
	fs::GetRecursiveDirs(paths, g_settings->get("texture_path"));
	fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
	for (const std::string &path : paths) {
		TextureOverrideSource override_source(path + DIR_DELIM + "override.txt");
		m_nodedef->applyTextureOverrides(override_source.getNodeTileOverrides());
		m_itemdef->applyTextureOverrides(override_source.getItemTextureOverrides());
	}

	m_nodedef->setNodeRegistrationStatus(true);

	// Perform pending node name resolutions
	m_nodedef->runNodeResolveCallbacks();

	// unmap node names in cross-references
	m_nodedef->resolveCrossrefs();

	// init the recipe hashes to speed up crafting
	m_craftdef->initHashes(this);

	// Initialize Environment
	m_env = new ServerEnvironment(servermap, m_script, this, m_path_world);

	m_inventory_mgr->setEnv(m_env);
	m_clients.setEnv(m_env);

	if (!servermap->settings_mgr.makeMapgenParams())
		FATAL_ERROR("Couldn't create any mapgen type");

	// Initialize mapgens
	m_emerge->initMapgens(servermap->getMapgenParams());

	if (g_settings->getBool("enable_rollback_recording")) {
		// Create rollback manager
		m_rollback = new RollbackManager(m_path_world, this);
	}

	// Give environment reference to scripting api
	m_script->initializeEnvironment(m_env);

	// Register us to receive map edit events
	servermap->addEventReceiver(this);

	m_env->loadMeta();

	// Those settings can be overwritten in world.mt, they are
	// intended to be cached after environment loading.
	m_liquid_transform_every = g_settings->getFloat("liquid_update");
	m_max_chatmessage_length = g_settings->getU16("chat_message_max_size");
	m_csm_restriction_flags = g_settings->getU64("csm_restriction_flags");
	m_csm_restriction_noderange = g_settings->getU32("csm_restriction_noderange");
}

void Server::start()
{
	init();

	infostream << "Starting server on " << m_bind_addr.serializeString()
			<< "..." << std::endl;

	// Stop thread if already running
	m_thread->stop();

	// Initialize connection
	m_con->SetTimeoutMs(30);
	m_con->Serve(m_bind_addr);

	// Start thread
	m_thread->start();

	// ASCII art for the win!
	std::cerr
		<< "        .__               __                   __   " << std::endl
		<< "  _____ |__| ____   _____/  |_  ____   _______/  |_ " << std::endl
		<< " /     \\|  |/    \\_/ __ \\   __\\/ __ \\ /  ___/\\   __\\" << std::endl
		<< "|  Y Y  \\  |   |  \\  ___/|  | \\  ___/ \\___ \\  |  |  " << std::endl
		<< "|__|_|  /__|___|  /\\___  >__|  \\___  >____  > |__|  " << std::endl
		<< "      \\/        \\/     \\/          \\/     \\/        " << std::endl;
	actionstream << "World at [" << m_path_world << "]" << std::endl;
	actionstream << "Server for gameid=\"" << m_gamespec.id
			<< "\" listening on " << m_bind_addr.serializeString() << ":"
			<< m_bind_addr.getPort() << "." << std::endl;
}

void Server::stop()
{
	infostream<<"Server: Stopping and waiting threads"<<std::endl;

	// Stop threads (set run=false first so both start stopping)
	m_thread->stop();
	//m_emergethread.setRun(false);
	m_thread->wait();
	//m_emergethread.stop();

	infostream<<"Server: Threads stopped"<<std::endl;
}

void Server::step(float dtime)
{
	// Limit a bit
	if (dtime > 2.0)
		dtime = 2.0;
	{
		MutexAutoLock lock(m_step_dtime_mutex);
		m_step_dtime += dtime;
	}
	// Throw if fatal error occurred in thread
	std::string async_err = m_async_fatal_error.get();
	if (!async_err.empty()) {
		if (!m_simple_singleplayer_mode) {
			m_env->kickAllPlayers(SERVER_ACCESSDENIED_CRASH,
				g_settings->get("kick_msg_crash"),
				g_settings->getBool("ask_reconnect_on_crash"));
		}
		throw ServerError("AsyncErr: " + async_err);
	}
}

void Server::AsyncRunStep(bool initial_step)
{

	float dtime;
	{
		MutexAutoLock lock1(m_step_dtime_mutex);
		dtime = m_step_dtime;
	}

	{
		// Send blocks to clients
		SendBlocks(dtime);
	}

	if((dtime < 0.001) && !initial_step)
		return;

	ScopeProfiler sp(g_profiler, "Server::AsyncRunStep()", SPT_AVG);

	{
		MutexAutoLock lock1(m_step_dtime_mutex);
		m_step_dtime -= dtime;
	}

	/*
		Update uptime
	*/
	m_uptime_counter->increment(dtime);

	handlePeerChanges();

	/*
		Update time of day and overall game time
	*/
	m_env->setTimeOfDaySpeed(g_settings->getFloat("time_speed"));

	/*
		Send to clients at constant intervals
	*/

	m_time_of_day_send_timer -= dtime;
	if (m_time_of_day_send_timer < 0.0) {
		m_time_of_day_send_timer = g_settings->getFloat("time_send_interval");
		u16 time = m_env->getTimeOfDay();
		float time_speed = g_settings->getFloat("time_speed");
		SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed);

		m_timeofday_gauge->set(time);
	}

	{
		MutexAutoLock lock(m_env_mutex);
		// Figure out and report maximum lag to environment
		float max_lag = m_env->getMaxLagEstimate();
		max_lag *= 0.9998; // Decrease slowly (about half per 5 minutes)
		if(dtime > max_lag){
			if(dtime > 0.1 && dtime > max_lag * 2.0)
				infostream<<"Server: Maximum lag peaked to "<<dtime
						<<" s"<<std::endl;
			max_lag = dtime;
		}
		m_env->reportMaxLagEstimate(max_lag);
		// Step environment
		m_env->step(dtime);
	}

	static const float map_timer_and_unload_dtime = 2.92;
	if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
	{
		MutexAutoLock lock(m_env_mutex);
		// Run Map's timers and unload unused data
		ScopeProfiler sp(g_profiler, "Server: map timer and unload");
		m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
			g_settings->getFloat("server_unload_unused_data_timeout"),
			U32_MAX);
	}

	/*
		Listen to the admin chat, if available
	*/
	if (m_admin_chat) {
		if (!m_admin_chat->command_queue.empty()) {
			MutexAutoLock lock(m_env_mutex);
			while (!m_admin_chat->command_queue.empty()) {
				ChatEvent *evt = m_admin_chat->command_queue.pop_frontNoEx();
				handleChatInterfaceEvent(evt);
				delete evt;
			}
		}
		m_admin_chat->outgoing_queue.push_back(
			new ChatEventTimeInfo(m_env->getGameTime(), m_env->getTimeOfDay()));
	}

	/*
		Do background stuff
	*/

	/* Transform liquids */
	m_liquid_transform_timer += dtime;
	if(m_liquid_transform_timer >= m_liquid_transform_every)
	{
		m_liquid_transform_timer -= m_liquid_transform_every;

		MutexAutoLock lock(m_env_mutex);

		ScopeProfiler sp(g_profiler, "Server: liquid transform");

		std::map<v3s16, MapBlock*> modified_blocks;
		m_env->getMap().transformLiquids(modified_blocks, m_env);

		/*
			Set the modified blocks unsent for all the clients
		*/
		if (!modified_blocks.empty()) {
			SetBlocksNotSent(modified_blocks);
		}
	}
	m_clients.step(dtime);

	m_lag_gauge->increment((m_lag_gauge->get() > dtime ? -1 : 1) * dtime/100);
#if USE_CURL
	// send masterserver announce
	{
		float &counter = m_masterserver_timer;
		if (!isSingleplayer() && (!counter || counter >= 300.0) &&
				g_settings->getBool("server_announce")) {
			ServerList::sendAnnounce(counter ? ServerList::AA_UPDATE :
						ServerList::AA_START,
					m_bind_addr.getPort(),
					m_clients.getPlayerNames(),
					m_uptime_counter->get(),
					m_env->getGameTime(),
					m_lag_gauge->get(),
					m_gamespec.id,
					Mapgen::getMapgenName(m_emerge->mgparams->mgtype),
					m_modmgr->getMods(),
					m_dedicated);
			counter = 0.01;
		}
		counter += dtime;
	}
#endif

	/*
		Check added and deleted active objects
	*/
	{
		//infostream<<"Server: Checking added and deleted active objects"<<std::endl;
		MutexAutoLock envlock(m_env_mutex);

		m_clients.lock();
		const RemoteClientMap &clients = m_clients.getClientList();
		ScopeProfiler sp(g_profiler, "Server: update objects within range");

		m_player_gauge->set(clients.size());
		for (const auto &client_it : clients) {
			RemoteClient *client = client_it.second;

			if (client->getState() < CS_DefinitionsSent)
				continue;

			// This can happen if the client times out somehow
			if (!m_env->getPlayer(client->peer_id))
				continue;

			PlayerSAO *playersao = getPlayerSAO(client->peer_id);
			if (!playersao)
				continue;

			SendActiveObjectRemoveAdd(client, playersao);
		}
		m_clients.unlock();

		// Save mod storages if modified
		m_mod_storage_save_timer -= dtime;
		if (m_mod_storage_save_timer <= 0.0f) {
			m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
			int n = 0;
			for (std::unordered_map<std::string, ModMetadata *>::const_iterator
				it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
				if (it->second->isModified()) {
					it->second->save(getModStoragePath());
					n++;
				}
			}
			if (n > 0)
				infostream << "Saved " << n << " modified mod storages." << std::endl;
		}
	}

	/*
		Send object messages
	*/
	{
		MutexAutoLock envlock(m_env_mutex);
		ScopeProfiler sp(g_profiler, "Server: send SAO messages");

		// Key = object id
		// Value = data sent by object
		std::unordered_map<u16, std::vector<ActiveObjectMessage>*> buffered_messages;

		// Get active object messages from environment
		ActiveObjectMessage aom(0);
		u32 aom_count = 0;
		for(;;) {
			if (!m_env->getActiveObjectMessage(&aom))
				break;

			std::vector<ActiveObjectMessage>* message_list = nullptr;
			auto n = buffered_messages.find(aom.id);
			if (n == buffered_messages.end()) {
				message_list = new std::vector<ActiveObjectMessage>;
				buffered_messages[aom.id] = message_list;
			} else {
				message_list = n->second;
			}
			message_list->push_back(std::move(aom));
			aom_count++;
		}

		m_aom_buffer_counter->increment(aom_count);

		m_clients.lock();
		const RemoteClientMap &clients = m_clients.getClientList();
		// Route data to every client
		std::string reliable_data, unreliable_data;
		for (const auto &client_it : clients) {
			reliable_data.clear();
			unreliable_data.clear();
			RemoteClient *client = client_it.second;
			PlayerSAO *player = getPlayerSAO(client->peer_id);
			// Go through all objects in message buffer
			for (const auto &buffered_message : buffered_messages) {
				// If object does not exist or is not known by client, skip it
				u16 id = buffered_message.first;
				ServerActiveObject *sao = m_env->getActiveObject(id);
				if (!sao || client->m_known_objects.find(id) == client->m_known_objects.end())
					continue;

				// Get message list of object
				std::vector<ActiveObjectMessage>* list = buffered_message.second;
				// Go through every message
				for (const ActiveObjectMessage &aom : *list) {
					// Send position updates to players who do not see the attachment
					if (aom.datastring[0] == AO_CMD_UPDATE_POSITION) {
						if (sao->getId() == player->getId())
							continue;

						// Do not send position updates for attached players
						// as long the parent is known to the client
						ServerActiveObject *parent = sao->getParent();
						if (parent && client->m_known_objects.find(parent->getId()) !=
								client->m_known_objects.end())
							continue;
					}

					// Add full new data to appropriate buffer
					std::string &buffer = aom.reliable ? reliable_data : unreliable_data;
					char idbuf[2];
					writeU16((u8*) idbuf, aom.id);
					// u16 id
					// std::string data
					buffer.append(idbuf, sizeof(idbuf));
					buffer.append(serializeString(aom.datastring));
				}
			}
			/*
				reliable_data and unreliable_data are now ready.
				Send them.
			*/
			if (!reliable_data.empty()) {
				SendActiveObjectMessages(client->peer_id, reliable_data);
			}

			if (!unreliable_data.empty()) {
				SendActiveObjectMessages(client->peer_id, unreliable_data, false);
			}
		}
		m_clients.unlock();

		// Clear buffered_messages
		for (auto &buffered_message : buffered_messages) {
			delete buffered_message.second;
		}
	}

	/*
		Send queued-for-sending map edit events.
	*/
	{
		// We will be accessing the environment
		MutexAutoLock lock(m_env_mutex);

		// Don't send too many at a time
		//u32 count = 0;

		// Single change sending is disabled if queue size is not small
		bool disable_single_change_sending = false;
		if(m_unsent_map_edit_queue.size() >= 4)
			disable_single_change_sending = true;

		int event_count = m_unsent_map_edit_queue.size();

		// We'll log the amount of each
		Profiler prof;

		std::list<v3s16> node_meta_updates;

		while (!m_unsent_map_edit_queue.empty()) {
			MapEditEvent* event = m_unsent_map_edit_queue.front();
			m_unsent_map_edit_queue.pop();

			// Players far away from the change are stored here.
			// Instead of sending the changes, MapBlocks are set not sent
			// for them.
			std::unordered_set<u16> far_players;

			switch (event->type) {
			case MEET_ADDNODE:
			case MEET_SWAPNODE:
				prof.add("MEET_ADDNODE", 1);
				sendAddNode(event->p, event->n, &far_players,
						disable_single_change_sending ? 5 : 30,
						event->type == MEET_ADDNODE);
				break;
			case MEET_REMOVENODE:
				prof.add("MEET_REMOVENODE", 1);
				sendRemoveNode(event->p, &far_players,
						disable_single_change_sending ? 5 : 30);
				break;
			case MEET_BLOCK_NODE_METADATA_CHANGED: {
				prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1);
				if (!event->is_private_change) {
					// Don't send the change yet. Collect them to eliminate dupes.
					node_meta_updates.remove(event->p);
					node_meta_updates.push_back(event->p);
				}

				if (MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(
						getNodeBlockPos(event->p))) {
					block->raiseModified(MOD_STATE_WRITE_NEEDED,
						MOD_REASON_REPORT_META_CHANGE);
				}
				break;
			}
			case MEET_OTHER:
				prof.add("MEET_OTHER", 1);
				for (const v3s16 &modified_block : event->modified_blocks) {
					m_clients.markBlockposAsNotSent(modified_block);
				}
				break;
			default:
				prof.add("unknown", 1);
				warningstream << "Server: Unknown MapEditEvent "
						<< ((u32)event->type) << std::endl;
				break;
			}

			/*
				Set blocks not sent to far players
			*/
			if (!far_players.empty()) {
				// Convert list format to that wanted by SetBlocksNotSent
				std::map<v3s16, MapBlock*> modified_blocks2;
				for (const v3s16 &modified_block : event->modified_blocks) {
					modified_blocks2[modified_block] =
							m_env->getMap().getBlockNoCreateNoEx(modified_block);
				}

				// Set blocks not sent
				for (const u16 far_player : far_players) {
					if (RemoteClient *client = getClient(far_player))
						client->SetBlocksNotSent(modified_blocks2);
				}
			}

			delete event;
		}

		if (event_count >= 5) {
			infostream << "Server: MapEditEvents:" << std::endl;
			prof.print(infostream);
		} else if (event_count != 0) {
			verbosestream << "Server: MapEditEvents:" << std::endl;
			prof.print(verbosestream);
		}

		// Send all metadata updates
		if (node_meta_updates.size())
			sendMetadataChanged(node_meta_updates);
	}

	/*
		Trigger emergethread (it somehow gets to a non-triggered but
		bysy state sometimes)
	*/
	{
		float &counter = m_emergethread_trigger_timer;
		counter += dtime;
		if (counter >= 2.0) {
			counter = 0.0;

			m_emerge->startThreads();
		}
	}

	// Save map, players and auth stuff
	{
		float &counter = m_savemap_timer;
		counter += dtime;
		static thread_local const float save_interval =
			g_settings->getFloat("server_map_save_interval");
		if (counter >= save_interval) {
			counter = 0.0;
			MutexAutoLock lock(m_env_mutex);

			ScopeProfiler sp(g_profiler, "Server: map saving (sum)");

			// Save ban file
			if (m_banmanager->isModified()) {
				m_banmanager->save();
			}

			// Save changed parts of map
			m_env->getMap().save(MOD_STATE_WRITE_NEEDED);

			// Save players
			m_env->saveLoadedPlayers();

			// Save environment metadata
			m_env->saveMeta();
		}
	}

	m_shutdown_state.tick(dtime, this);
}

void Server::Receive()
{
	NetworkPacket pkt;
	session_t peer_id;
	bool first = true;
	for (;;) {
		pkt.clear();
		peer_id = 0;
		try {
			/*
				In the first iteration *wait* for a packet, afterwards process
				all packets that are immediately available (no waiting).
			*/
			if (first) {
				m_con->Receive(&pkt);
				first = false;
			} else {
				if (!m_con->TryReceive(&pkt))
					return;
			}

			peer_id = pkt.getPeerId();
			m_packet_recv_counter->increment();
			ProcessData(&pkt);
			m_packet_recv_processed_counter->increment();
		} catch (const con::InvalidIncomingDataException &e) {
			infostream << "Server::Receive(): InvalidIncomingDataException: what()="
					<< e.what() << std::endl;
		} catch (const SerializationError &e) {
			infostream << "Server::Receive(): SerializationError: what()="
					<< e.what() << std::endl;
		} catch (const ClientStateError &e) {
			errorstream << "ProcessData: peer=" << peer_id << " what()="
					 << e.what() << std::endl;
			DenyAccess_Legacy(peer_id, L"Your client sent something server didn't expect."
					L"Try reconnecting or updating your client");
		} catch (const con::PeerNotFoundException &e) {
			// Do nothing
		} catch (const con::NoIncomingDataException &e) {
			return;
		}
	}
}

PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
{
	std::string playername;
	PlayerSAO *playersao = NULL;
	m_clients.lock();
	try {
		RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
		if (client) {
			playername = client->getName();
			playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version);
		}
	} catch (std::exception &e) {
		m_clients.unlock();
		throw;
	}
	m_clients.unlock();

	RemotePlayer *player = m_env->getPlayer(playername.c_str());

	// If failed, cancel
	if (!playersao || !player) {
		if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
			actionstream << "Server: Failed to emerge player \"" << playername
					<< "\" (player allocated to an another client)" << std::endl;
			DenyAccess_Legacy(peer_id, L"Another client is connected with this "
					L"name. If your client closed unexpectedly, try again in "
					L"a minute.");
		} else {
			errorstream << "Server: " << playername << ": Failed to emerge player"
					<< std::endl;
			DenyAccess_Legacy(peer_id, L"Could not allocate player.");
		}
		return NULL;
	}

	/*
		Send complete position information
	*/
	SendMovePlayer(peer_id);

	// Send privileges
	SendPlayerPrivileges(peer_id);

	// Send inventory formspec
	SendPlayerInventoryFormspec(peer_id);

	// Send inventory
	SendInventory(playersao, false);

	// Send HP or death screen
	if (playersao->isDead())
		SendDeathscreen(peer_id, false, v3f(0,0,0));
	else
		SendPlayerHPOrDie(playersao,
				PlayerHPChangeReason(PlayerHPChangeReason::SET_HP));

	// Send Breath
	SendPlayerBreath(playersao);

	/*
		Print out action
	*/
	{
		Address addr = getPeerAddress(player->getPeerId());
		std::string ip_str = addr.serializeString();
		const std::vector<std::string> &names = m_clients.getPlayerNames();

		actionstream << player->getName() << " [" << ip_str << "] joins game. List of players: ";

		for (const std::string &name : names) {
			actionstream << name << " ";
		}

		actionstream << player->getName() <<std::endl;
	}
	return playersao;
}

inline void Server::handleCommand(NetworkPacket *pkt)
{
	const ToServerCommandHandler &opHandle = toServerCommandTable[pkt->getCommand()];
	(this->*opHandle.handler)(pkt);
}

void Server::ProcessData(NetworkPacket *pkt)
{
	// Environment is locked first.
	MutexAutoLock envlock(m_env_mutex);

	ScopeProfiler sp(g_profiler, "Server: Process network packet (sum)");
	u32 peer_id = pkt->getPeerId();

	try {
		Address address = getPeerAddress(peer_id);
		std::string addr_s = address.serializeString();

		if(m_banmanager->isIpBanned(addr_s)) {
			std::string ban_name = m_banmanager->getBanName(addr_s);
			infostream << "Server: A banned client tried to connect from "
					<< addr_s << "; banned name was "
					<< ban_name << std::endl;
			// This actually doesn't seem to transfer to the client
			DenyAccess_Legacy(peer_id, L"Your ip is banned. Banned name was "
					+ utf8_to_wide(ban_name));
			return;
		}
	}
	catch(con::PeerNotFoundException &e) {
		/*
		 * no peer for this packet found
		 * most common reason is peer timeout, e.g. peer didn't
		 * respond for some time, your server was overloaded or
		 * things like that.
		 */
		infostream << "Server::ProcessData(): Canceling: peer "
				<< peer_id << " not found" << std::endl;
		return;
	}

	try {
		ToServerCommand command = (ToServerCommand) pkt->getCommand();

		// Command must be handled into ToServerCommandHandler
		if (command >= TOSERVER_NUM_MSG_TYPES) {
			infostream << "Server: Ignoring unknown command "
					 << command << std::endl;
			return;
		}

		if (toServerCommandTable[command].state == TOSERVER_STATE_NOT_CONNECTED) {
			handleCommand(pkt);
			return;
		}

		u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version;

		if(peer_ser_ver == SER_FMT_VER_INVALID) {
			errorstream << "Server::ProcessData(): Cancelling: Peer"
					" serialization format invalid or not initialized."
					" Skipping incoming command=" << command << std::endl;
			return;
		}

		/* Handle commands related to client startup */
		if (toServerCommandTable[command].state == TOSERVER_STATE_STARTUP) {
			handleCommand(pkt);
			return;
		}

		if (m_clients.getClientState(peer_id) < CS_Active) {
			if (command == TOSERVER_PLAYERPOS) return;

			errorstream << "Got packet command: " << command << " for peer id "
					<< peer_id << " but client isn't active yet. Dropping packet "
					<< std::endl;
			return;
		}

		handleCommand(pkt);
	} catch (SendFailedException &e) {
		errorstream << "Server::ProcessData(): SendFailedException: "
				<< "what=" << e.what()
				<< std::endl;
	} catch (PacketError &e) {
		actionstream << "Server::ProcessData(): PacketError: "
				<< "what=" << e.what()
				<< std::endl;
	}
}

void Server::setTimeOfDay(u32 time)
{
	m_env->setTimeOfDay(time);
	m_time_of_day_send_timer = 0;
}

void Server::onMapEditEvent(const MapEditEvent &event)
{
	if (m_ignore_map_edit_events_area.contains(event.getArea()))
		return;

	m_unsent_map_edit_queue.push(new MapEditEvent(event));
}

void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
{
	std::vector<session_t> clients = m_clients.getClientIDs();
	m_clients.lock();
	// Set the modified blocks unsent for all the clients
	for (const session_t client_id : clients) {
			if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
				client->SetBlocksNotSent(block);
	}
	m_clients.unlock();
}

void Server::peerAdded(con::Peer *peer)
{
	verbosestream<<"Server::peerAdded(): peer->id="
			<<peer->id<<std::endl;

	m_peer_change_queue.push(con::PeerChange(con::PEER_ADDED, peer->id, false));
}

void Server::deletingPeer(con::Peer *peer, bool timeout)
{
	verbosestream<<"Server::deletingPeer(): peer->id="
			<<peer->id<<", timeout="<<timeout<<std::endl;

	m_clients.event(peer->id, CSE_Disconnect);
	m_peer_change_queue.push(con::PeerChange(con::PEER_REMOVED, peer->id, timeout));
}

bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float* retval)
{
	*retval = m_con->getPeerStat(peer_id,type);
	return *retval != -1;
}

bool Server::getClientInfo(
		session_t    peer_id,
		ClientState* state,
		u32*         uptime,
		u8*          ser_vers,
		u16*         prot_vers,
		u8*          major,
		u8*          minor,
		u8*          patch,
		std::string* vers_string,
		std::string* lang_code
	)
{
	*state = m_clients.getClientState(peer_id);
	m_clients.lock();
	RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);

	if (!client) {
		m_clients.unlock();
		return false;
	}

	*uptime = client->uptime();
	*ser_vers = client->serialization_version;
	*prot_vers = client->net_proto_version;

	*major = client->getMajor();
	*minor = client->getMinor();
	*patch = client->getPatch();
	*vers_string = client->getFull();
	*lang_code = client->getLangCode();

	m_clients.unlock();

	return true;
}

void Server::handlePeerChanges()
{
	while(!m_peer_change_queue.empty())
	{
		con::PeerChange c = m_peer_change_queue.front();
		m_peer_change_queue.pop();

		verbosestream<<"Server: Handling peer change: "
				<<"id="<<c.peer_id<<", timeout="<<c.timeout
				<<std::endl;

		switch(c.type)
		{
		case con::PEER_ADDED:
			m_clients.CreateClient(c.peer_id);
			break;

		case con::PEER_REMOVED:
			DeleteClient(c.peer_id, c.timeout?CDR_TIMEOUT:CDR_LEAVE);
			break;

		default:
			FATAL_ERROR("Invalid peer change event received!");
			break;
		}
	}
}

void Server::printToConsoleOnly(const std::string &text)
{
	if (m_admin_chat) {
		m_admin_chat->outgoing_queue.push_back(
			new ChatEventChat("", utf8_to_wide(text)));
	} else {
		std::cout << text << std::endl;
	}
}

void Server::Send(NetworkPacket *pkt)
{
	Send(pkt->getPeerId(), pkt);
}

void Server::Send(session_t peer_id, NetworkPacket *pkt)
{
	m_clients.send(peer_id,
		clientCommandFactoryTable[pkt->getCommand()].channel,
		pkt,
		clientCommandFactoryTable[pkt->getCommand()].reliable);
}

void Server::SendMovement(session_t peer_id)
{
	std::ostringstream os(std::ios_base::binary);

	NetworkPacket pkt(TOCLIENT_MOVEMENT, 12 * sizeof(float), peer_id);

	pkt << g_settings->getFloat("movement_acceleration_default");
	pkt << g_settings->getFloat("movement_acceleration_air");
	pkt << g_settings->getFloat("movement_acceleration_fast");
	pkt << g_settings->getFloat("movement_speed_walk");
	pkt << g_settings->getFloat("movement_speed_crouch");
	pkt << g_settings->getFloat("movement_speed_fast");
	pkt << g_settings->getFloat("movement_speed_climb");
	pkt << g_settings->getFloat("movement_speed_jump");
	pkt << g_settings->getFloat("movement_liquid_fluidity");
	pkt << g_settings->getFloat("movement_liquid_fluidity_smooth");
	pkt << g_settings->getFloat("movement_liquid_sink");
	pkt << g_settings->getFloat("movement_gravity");

	Send(&pkt);
}

void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
{
	if (playersao->isImmortal())
		return;

	session_t peer_id = playersao->getPeerID();
	bool is_alive = playersao->getHP() > 0;

	if (is_alive)
		SendPlayerHP(peer_id);
	else
		DiePlayer(peer_id, reason);
}

void Server::SendHP(session_t peer_id, u16 hp)
{
	NetworkPacket pkt(TOCLIENT_HP, 1, peer_id);
	pkt << hp;
	Send(&pkt);
}

void Server::SendBreath(session_t peer_id, u16 breath)
{
	NetworkPacket pkt(TOCLIENT_BREATH, 2, peer_id);
	pkt << (u16) breath;
	Send(&pkt);
}

void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
		const std::string &custom_reason, bool reconnect)
{
	assert(reason < SERVER_ACCESSDENIED_MAX);

	NetworkPacket pkt(TOCLIENT_ACCESS_DENIED, 1, peer_id);
	pkt << (u8)reason;
	if (reason == SERVER_ACCESSDENIED_CUSTOM_STRING)
		pkt << custom_reason;
	else if (reason == SERVER_ACCESSDENIED_SHUTDOWN ||
			reason == SERVER_ACCESSDENIED_CRASH)
		pkt << custom_reason << (u8)reconnect;
	Send(&pkt);
}

void Server::SendAccessDenied_Legacy(session_t peer_id,const std::wstring &reason)
{
	NetworkPacket pkt(TOCLIENT_ACCESS_DENIED_LEGACY, 0, peer_id);
	pkt << reason;
	Send(&pkt);
}

void Server::SendDeathscreen(session_t peer_id, bool set_camera_point_target,
		v3f camera_point_target)
{
	NetworkPacket pkt(TOCLIENT_DEATHSCREEN, 1 + sizeof(v3f), peer_id);
	pkt << set_camera_point_target << camera_point_target;
	Send(&pkt);
}

void Server::SendItemDef(session_t peer_id,
		IItemDefManager *itemdef, u16 protocol_version)
{
	NetworkPacket pkt(TOCLIENT_ITEMDEF, 0, peer_id);

	/*
		u16 command
		u32 length of the next item
		zlib-compressed serialized ItemDefManager
	*/
	std::ostringstream tmp_os(std::ios::binary);
	itemdef->serialize(tmp_os, protocol_version);
	std::ostringstream tmp_os2(std::ios::binary);
	compressZlib(tmp_os.str(), tmp_os2);
	pkt.putLongString(tmp_os2.str());

	// Make data buffer
	verbosestream << "Server: Sending item definitions to id(" << peer_id
			<< "): size=" << pkt.getSize() << std::endl;

	Send(&pkt);
}

void Server::SendNodeDef(session_t peer_id,
	const NodeDefManager *nodedef, u16 protocol_version)
{
	NetworkPacket pkt(TOCLIENT_NODEDEF, 0, peer_id);

	/*
		u16 command
		u32 length of the next item
		zlib-compressed serialized NodeDefManager
	*/
	std::ostringstream tmp_os(std::ios::binary);
	nodedef->serialize(tmp_os, protocol_version);
	std::ostringstream tmp_os2(std::ios::binary);
	compressZlib(tmp_os.str(), tmp_os2);

	pkt.putLongString(tmp_os2.str());

	// Make data buffer
	verbosestream << "Server: Sending node definitions to id(" << peer_id
			<< "): size=" << pkt.getSize() << std::endl;

	Send(&pkt);
}

/*
	Non-static send methods
*/

void Server::SendInventory(PlayerSAO *sao, bool incremental)
{
	RemotePlayer *player = sao->getPlayer();

	// Do not send new format to old clients
	incremental &= player->protocol_version >= 38;

	UpdateCrafting(player);

	/*
		Serialize it
	*/

	NetworkPacket pkt(TOCLIENT_INVENTORY, 0, sao->getPeerID());

	std::ostringstream os(std::ios::binary);
	sao->getInventory()->serialize(os, incremental);
	sao->getInventory()->setModified(false);
	player->setModified(true);

	const std::string &s = os.str();
	pkt.putRawString(s.c_str(), s.size());
	Send(&pkt);
}

void Server::SendChatMessage(session_t peer_id, const ChatMessage &message)
{
	NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id);
	u8 version = 1;
	u8 type = message.type;
	pkt << version << type << std::wstring(L"") << message.message << (u64)message.timestamp;

	if (peer_id != PEER_ID_INEXISTENT) {
		RemotePlayer *player = m_env->getPlayer(peer_id);
		if (!player)
			return;

		Send(&pkt);
	} else {
		m_clients.sendToAll(&pkt);
	}
}

void Server::SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
	const std::string &formname)
{
	NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0, peer_id);
	if (formspec.empty()){
		//the client should close the formspec
		//but make sure there wasn't another one open in meantime
		const auto it = m_formspec_state_data.find(peer_id);
		if (it != m_formspec_state_data.end() && it->second == formname) {
			m_formspec_state_data.erase(peer_id);
		}
		pkt.putLongString("");
	} else {
		m_formspec_state_data[peer_id] = formname;
		pkt.putLongString(formspec);
	}
	pkt << formname;

	Send(&pkt);
}

// Spawns a particle on peer with peer_id
void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version,
	const ParticleParameters &p)
{
	static thread_local const float radius =
			g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS;

	if (peer_id == PEER_ID_INEXISTENT) {
		std::vector<session_t> clients = m_clients.getClientIDs();
		const v3f pos = p.pos * BS;
		const float radius_sq = radius * radius;

		for (const session_t client_id : clients) {
			RemotePlayer *player = m_env->getPlayer(client_id);
			if (!player)
				continue;

			PlayerSAO *sao = player->getPlayerSAO();
			if (!sao)
				continue;

			// Do not send to distant clients
			if (sao->getBasePosition().getDistanceFromSQ(pos) > radius_sq)
				continue;

			SendSpawnParticle(client_id, player->protocol_version, p);
		}
		return;
	}
	assert(protocol_version != 0);

	NetworkPacket pkt(TOCLIENT_SPAWN_PARTICLE, 0, peer_id);

	{
		// NetworkPacket and iostreams are incompatible...
		std::ostringstream oss(std::ios_base::binary);
		p.serialize(oss, protocol_version);
		pkt.putRawString(oss.str());
	}

	Send(&pkt);
}

// Adds a ParticleSpawner on peer with peer_id
void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
	const ParticleSpawnerParameters &p, u16 attached_id, u32 id)
{
	static thread_local const float radius =
			g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS;

	if (peer_id == PEER_ID_INEXISTENT) {
		std::vector<session_t> clients = m_clients.getClientIDs();
		const v3f pos = (p.minpos + p.maxpos) / 2.0f * BS;
		const float radius_sq = radius * radius;
		/* Don't send short-lived spawners to distant players.
		 * This could be replaced with proper tracking at some point. */
		const bool distance_check = !attached_id && p.time <= 1.0f;

		for (const session_t client_id : clients) {
			RemotePlayer *player = m_env->getPlayer(client_id);
			if (!player)
				continue;

			if (distance_check) {
				PlayerSAO *sao = player->getPlayerSAO();
				if (!sao)
					continue;
				if (sao->getBasePosition().getDistanceFromSQ(pos) > radius_sq)
					continue;
			}

			SendAddParticleSpawner(client_id, player->protocol_version,
				p, attached_id, id);
		}
		return;
	}
	assert(protocol_version != 0);

	NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 100, peer_id);

	pkt << p.amount << p.time << p.minpos << p.maxpos << p.minvel
		<< p.maxvel << p.minacc << p.maxacc << p.minexptime << p.maxexptime
		<< p.minsize << p.maxsize << p.collisiondetection;

	pkt.putLongString(p.texture);

	pkt << id << p.vertical << p.collision_removal << attached_id;
	{
		std::ostringstream os(std::ios_base::binary);
		p.animation.serialize(os, protocol_version);
		pkt.putRawString(os.str());
	}
	pkt << p.glow << p.object_collision;
	pkt << p.node.param0 << p.node.param2 << p.node_tile;

	Send(&pkt);
}

void Server::SendDeleteParticleSpawner(session_t peer_id, u32 id)
{
	NetworkPacket pkt(TOCLIENT_DELETE_PARTICLESPAWNER, 4, peer_id);

	pkt << id;

	if (peer_id != PEER_ID_INEXISTENT)
		Send(&pkt);
	else
		m_clients.sendToAll(&pkt);

}

void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form)
{
	NetworkPacket pkt(TOCLIENT_HUDADD, 0 , peer_id);

	pkt << id << (u8) form->type << form->pos << form->name << form->scale
			<< form->text << form->number << form->item << form->dir
			<< form->align << form->offset << form->world_pos << form->size
			<< form->z_index << form->text2;

	Send(&pkt);
}

void Server::SendHUDRemove(session_t peer_id, u32 id)
{
	NetworkPacket pkt(TOCLIENT_HUDRM, 4, peer_id);
	pkt << id;
	Send(&pkt);
}

void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value)
{
	NetworkPacket pkt(TOCLIENT_HUDCHANGE, 0, peer_id);
	pkt << id << (u8) stat;

	switch (stat) {
		case HUD_STAT_POS:
		case HUD_STAT_SCALE:
		case HUD_STAT_ALIGN:
		case HUD_STAT_OFFSET:
			pkt << *(v2f *) value;
			break;
		case HUD_STAT_NAME:
		case HUD_STAT_TEXT:
		case HUD_STAT_TEXT2:
			pkt << *(std::string *) value;
			break;
		case HUD_STAT_WORLD_POS:
			pkt << *(v3f *) value;
			break;
		case HUD_STAT_SIZE:
			pkt << *(v2s32 *) value;
			break;
		case HUD_STAT_NUMBER:
		case HUD_STAT_ITEM:
		case HUD_STAT_DIR:
		default:
			pkt << *(u32 *) value;
			break;
	}

	Send(&pkt);
}

void Server::SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask)
{
	NetworkPacket pkt(TOCLIENT_HUD_SET_FLAGS, 4 + 4, peer_id);

	flags &= ~(HUD_FLAG_HEALTHBAR_VISIBLE | HUD_FLAG_BREATHBAR_VISIBLE);

	pkt << flags << mask;

	Send(&pkt);
}

void Server::SendHUDSetParam(session_t peer_id, u16 param, const std::string &value)
{
	NetworkPacket pkt(TOCLIENT_HUD_SET_PARAM, 0, peer_id);
	pkt << param << value;
	Send(&pkt);
}

void Server::SendSetSky(session_t peer_id, const SkyboxParams &params)
{
	NetworkPacket pkt(TOCLIENT_SET_SKY, 0, peer_id);

	// Handle prior clients here
	if (m_clients.getProtocolVersion(peer_id) < 39) {
		pkt << params.bgcolor << params.type << (u16) params.textures.size();

		for (const std::string& texture : params.textures)
			pkt << texture;

		pkt << params.clouds;
	} else { // Handle current clients and future clients
		pkt << params.bgcolor << params.type
		<< params.clouds << params.fog_sun_tint
		<< params.fog_moon_tint << params.fog_tint_type;

		if (params.type == "skybox") {
			pkt << (u16) params.textures.size();
			for (const std::string &texture : params.textures)
				pkt << texture;
		} else if (params.type == "regular") {
			pkt << params.sky_color.day_sky << params.sky_color.day_horizon
				<< params.sky_color.dawn_sky << params.sky_color.dawn_horizon
				<< params.sky_color.night_sky << params.sky_color.night_horizon
				<< params.sky_color.indoors;
		}
	}

	Send(&pkt);
}

void Server::SendSetSun(session_t peer_id, const SunParams &params)
{
	NetworkPacket pkt(TOCLIENT_SET_SUN, 0, peer_id);
	pkt << params.visible << params.texture
		<< params.tonemap << params.sunrise
		<< params.sunrise_visible << params.scale;

	Send(&pkt);
}
void Server::SendSetMoon(session_t peer_id, const MoonParams &params)
{
	NetworkPacket pkt(TOCLIENT_SET_MOON, 0, peer_id);

	pkt << params.visible << params.texture
		<< params.tonemap << params.scale;

	Send(&pkt);
}
void Server::SendSetStars(session_t peer_id, const StarParams &params)
{
	NetworkPacket pkt(TOCLIENT_SET_STARS, 0, peer_id);

	pkt << params.visible << params.count
		<< params.starcolor << params.scale;

	Send(&pkt);
}

void Server::SendCloudParams(session_t peer_id, const CloudParams &params)
{
	NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id);
	pkt << params.density << params.color_bright << params.color_ambient
			<< params.height << params.thickness << params.speed;
	Send(&pkt);
}

void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override,
		float ratio)
{
	NetworkPacket pkt(TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO,
			1 + 2, peer_id);

	pkt << do_override << (u16) (ratio * 65535);

	Send(&pkt);
}

void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
{
	NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
	pkt << time << time_speed;

	if (peer_id == PEER_ID_INEXISTENT) {
		m_clients.sendToAll(&pkt);
	}
	else {
		Send(&pkt);
	}
}

void Server::SendPlayerHP(session_t peer_id)
{
	PlayerSAO *playersao = getPlayerSAO(peer_id);
	assert(playersao);

	SendHP(peer_id, playersao->getHP());
	m_script->player_event(playersao,"health_changed");

	// Send to other clients
	playersao->sendPunchCommand();
}

void Server::SendPlayerBreath(PlayerSAO *sao)
{
	assert(sao);

	m_script->player_event(sao, "breath_changed");
	SendBreath(sao->getPeerID(), sao->getBreath());
}

void Server::SendMovePlayer(session_t peer_id)
{
	RemotePlayer *player = m_env->getPlayer(peer_id);
	assert(player);
	PlayerSAO *sao = player->getPlayerSAO();
	assert(sao);

	NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id);
	pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y;

	{
		v3f pos = sao->getBasePosition();
		verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER"
				<< " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")"
				<< " pitch=" << sao->getLookPitch()
				<< " yaw=" << sao->getRotation().Y
				<< std::endl;
	}

	Send(&pkt);
}

void Server::SendPlayerFov(session_t peer_id)
{
	NetworkPacket pkt(TOCLIENT_FOV, 4 + 1 + 4, peer_id);

	PlayerFovSpec fov_spec = m_env->getPlayer(peer_id)->getFov();
	pkt << fov_spec.fov << fov_spec.is_multiplier << fov_spec.transition_time;

	Send(&pkt);
}

void Server::SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
		f32 animation_speed)
{
	NetworkPacket pkt(TOCLIENT_LOCAL_PLAYER_ANIMATIONS, 0,
		peer_id);

	pkt << animation_frames[0] << animation_frames[1] << animation_frames[2]
			<< animation_frames[3] << animation_speed;

	Send(&pkt);
}

void Server::SendEyeOffset(session_t peer_id, v3f first, v3f third)
{
	NetworkPacket pkt(TOCLIENT_EYE_OFFSET, 0, peer_id);
	pkt << first << third;
	Send(&pkt);
}

void Server::SendPlayerPrivileges(session_t peer_id)
{
	RemotePlayer *player = m_env->getPlayer(peer_id);
	assert(player);
	if(player->getPeerId() == PEER_ID_INEXISTENT)
		return;

	std::set<std::string> privs;
	m_script->getAuth(player->getName(), NULL, &privs);

	NetworkPacket pkt(TOCLIENT_PRIVILEGES, 0, peer_id);
	pkt << (u16) privs.size();

	for (const std::string &priv : privs) {
		pkt << priv;
	}

	Send(&pkt);
}

void Server::SendPlayerInventoryFormspec(session_t peer_id)
{
	RemotePlayer *player = m_env->getPlayer(peer_id);
	assert(player);
	if (player->getPeerId() == PEER_ID_INEXISTENT)
		return;

	NetworkPacket pkt(TOCLIENT_INVENTORY_FORMSPEC, 0, peer_id);
	pkt.putLongString(player->inventory_formspec);

	Send(&pkt);
}

void Server::SendPlayerFormspecPrepend(session_t peer_id)
{
	RemotePlayer *player = m_env->getPlayer(peer_id);
	assert(player);
	if (player->getPeerId() == PEER_ID_INEXISTENT)
		return;

	NetworkPacket pkt(TOCLIENT_FORMSPEC_PREPEND, 0, peer_id);
	pkt << player->formspec_prepend;
	Send(&pkt);
}

void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao)
{
	// Radius inside which objects are active
	static thread_local const s16 radius =
		g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;

	// Radius inside which players are active
	static thread_local const bool is_transfer_limited =
		g_settings->exists("unlimited_player_transfer_distance") &&
		!g_settings->getBool("unlimited_player_transfer_distance");

	static thread_local const s16 player_transfer_dist =
		g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;

	s16 player_radius = player_transfer_dist == 0 && is_transfer_limited ?
		radius : player_transfer_dist;

	s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
	if (my_radius <= 0)
		my_radius = radius;

	std::queue<u16> removed_objects, added_objects;
	m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
		client->m_known_objects, removed_objects);
	m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
		client->m_known_objects, added_objects);

	int removed_count = removed_objects.size();
	int added_count   = added_objects.size();

	if (removed_objects.empty() && added_objects.empty())
		return;

	char buf[4];
	std::string data;

	// Handle removed objects
	writeU16((u8*)buf, removed_objects.size());
	data.append(buf, 2);
	while (!removed_objects.empty()) {
		// Get object
		u16 id = removed_objects.front();
		ServerActiveObject* obj = m_env->getActiveObject(id);

		// Add to data buffer for sending
		writeU16((u8*)buf, id);
		data.append(buf, 2);

		// Remove from known objects
		client->m_known_objects.erase(id);

		if (obj && obj->m_known_by_count > 0)
			obj->m_known_by_count--;

		removed_objects.pop();
	}

	// Handle added objects
	writeU16((u8*)buf, added_objects.size());
	data.append(buf, 2);
	while (!added_objects.empty()) {
		// Get object
		u16 id = added_objects.front();
		ServerActiveObject *obj = m_env->getActiveObject(id);
		added_objects.pop();

		if (!obj) {
			warningstream << FUNCTION_NAME << ": NULL object id="
				<< (int)id << std::endl;
			continue;
		}

		// Get object type
		u8 type = obj->getSendType();

		// Add to data buffer for sending
		writeU16((u8*)buf, id);
		data.append(buf, 2);
		writeU8((u8*)buf, type);
		data.append(buf, 1);

		data.append(serializeLongString(
			obj->getClientInitializationData(client->net_proto_version)));

		// Add to known objects
		client->m_known_objects.insert(id);

		obj->m_known_by_count++;
	}

	NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, data.size(), client->peer_id);
	pkt.putRawString(data.c_str(), data.size());
	Send(&pkt);

	verbosestream << "Server::SendActiveObjectRemoveAdd: "
		<< removed_count << " removed, " << added_count << " added, "
		<< "packet size is " << pkt.getSize() << std::endl;
}

void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas,
		bool reliable)
{
	NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_MESSAGES,
			datas.size(), peer_id);

	pkt.putRawString(datas.c_str(), datas.size());

	m_clients.send(pkt.getPeerId(),
			reliable ? clientCommandFactoryTable[pkt.getCommand()].channel : 1,
			&pkt, reliable);
}

void Server::SendCSMRestrictionFlags(session_t peer_id)
{
	NetworkPacket pkt(TOCLIENT_CSM_RESTRICTION_FLAGS,
		sizeof(m_csm_restriction_flags) + sizeof(m_csm_restriction_noderange), peer_id);
	pkt << m_csm_restriction_flags << m_csm_restriction_noderange;
	Send(&pkt);
}

void Server::SendPlayerSpeed(session_t peer_id, const v3f &added_vel)
{
	NetworkPacket pkt(TOCLIENT_PLAYER_SPEED, 0, peer_id);
	pkt << added_vel;
	Send(&pkt);
}

inline s32 Server::nextSoundId()
{
	s32 ret = m_next_sound_id;
	if (m_next_sound_id == INT32_MAX)
		m_next_sound_id = 0; // signed overflow is undefined
	else
		m_next_sound_id++;
	return ret;
}

s32 Server::playSound(const SimpleSoundSpec &spec,
		const ServerSoundParams &params, bool ephemeral)
{
	// Find out initial position of sound
	bool pos_exists = false;
	v3f pos = params.getPos(m_env, &pos_exists);
	// If position is not found while it should be, cancel sound
	if(pos_exists != (params.type != ServerSoundParams::SSP_LOCAL))
		return -1;

	// Filter destination clients
	std::vector<session_t> dst_clients;
	if (!params.to_player.empty()) {
		RemotePlayer *player = m_env->getPlayer(params.to_player.c_str());
		if(!player){
			infostream<<"Server::playSound: Player \""<<params.to_player
					<<"\" not found"<<std::endl;
			return -1;
		}
		if (player->getPeerId() == PEER_ID_INEXISTENT) {
			infostream<<"Server::playSound: Player \""<<params.to_player
					<<"\" not connected"<<std::endl;
			return -1;
		}
		dst_clients.push_back(player->getPeerId());
	} else {
		std::vector<session_t> clients = m_clients.getClientIDs();

		for (const session_t client_id : clients) {
			RemotePlayer *player = m_env->getPlayer(client_id);
			if (!player)
				continue;
			if (!params.exclude_player.empty() &&
					params.exclude_player == player->getName())
				continue;

			PlayerSAO *sao = player->getPlayerSAO();
			if (!sao)
				continue;

			if (pos_exists) {
				if(sao->getBasePosition().getDistanceFrom(pos) >
						params.max_hear_distance)
					continue;
			}
			dst_clients.push_back(client_id);
		}
	}

	if(dst_clients.empty())
		return -1;

	// Create the sound
	s32 id;
	ServerPlayingSound *psound = nullptr;
	if (ephemeral) {
		id = -1; // old clients will still use this, so pick a reserved ID
	} else {
		id = nextSoundId();
		// The sound will exist as a reference in m_playing_sounds
		m_playing_sounds[id] = ServerPlayingSound();
		psound = &m_playing_sounds[id];
		psound->params = params;
		psound->spec = spec;
	}

	float gain = params.gain * spec.gain;
	NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0);
	pkt << id << spec.name << gain
			<< (u8) params.type << pos << params.object
			<< params.loop << params.fade << params.pitch
			<< ephemeral;

	bool as_reliable = !ephemeral;

	for (const u16 dst_client : dst_clients) {
		if (psound)
			psound->clients.insert(dst_client);
		m_clients.send(dst_client, 0, &pkt, as_reliable);
	}
	return id;
}
void Server::stopSound(s32 handle)
{
	// Get sound reference
	std::unordered_map<s32, ServerPlayingSound>::iterator i =
		m_playing_sounds.find(handle);
	if (i == m_playing_sounds.end())
		return;
	ServerPlayingSound &psound = i->second;

	NetworkPacket pkt(TOCLIENT_STOP_SOUND, 4);
	pkt << handle;

	for (std::unordered_set<session_t>::const_iterator si = psound.clients.begin();
			si != psound.clients.end(); ++si) {
		// Send as reliable
		m_clients.send(*si, 0, &pkt, true);
	}
	// Remove sound reference
	m_playing_sounds.erase(i);
}

void Server::fadeSound(s32 handle, float step, float gain)
{
	// Get sound reference
	std::unordered_map<s32, ServerPlayingSound>::iterator i =
		m_playing_sounds.find(handle);
	if (i == m_playing_sounds.end())
		return;

	ServerPlayingSound &psound = i->second;
	psound.params.gain = gain;

	NetworkPacket pkt(TOCLIENT_FADE_SOUND, 4);
	pkt << handle << step << gain;

	// Backwards compability
	bool play_sound = gain > 0;
	ServerPlayingSound compat_psound = psound;
	compat_psound.clients.clear();

	NetworkPacket compat_pkt(TOCLIENT_STOP_SOUND, 4);
	compat_pkt << handle;

	for (std::unordered_set<u16>::iterator it = psound.clients.begin();
			it != psound.clients.end();) {
		if (m_clients.getProtocolVersion(*it) >= 32) {
			// Send as reliable
			m_clients.send(*it, 0, &pkt, true);
			++it;
		} else {
			compat_psound.clients.insert(*it);
			// Stop old sound
			m_clients.send(*it, 0, &compat_pkt, true);
			psound.clients.erase(it++);
		}
	}

	// Remove sound reference
	if (!play_sound || psound.clients.empty())
		m_playing_sounds.erase(i);

	if (play_sound && !compat_psound.clients.empty()) {
		// Play new sound volume on older clients
		playSound(compat_psound.spec, compat_psound.params);
	}
}

void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
		float far_d_nodes)
{
	float maxd = far_d_nodes * BS;
	v3f p_f = intToFloat(p, BS);
	v3s16 block_pos = getNodeBlockPos(p);

	NetworkPacket pkt(TOCLIENT_REMOVENODE, 6);
	pkt << p;

	std::vector<session_t> clients = m_clients.getClientIDs();
	m_clients.lock();

	for (session_t client_id : clients) {
		RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
		if (!client)
			continue;

		RemotePlayer *player = m_env->getPlayer(client_id);
		PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;

		// If player is far away, only set modified blocks not sent
		if (!client->isBlockSent(block_pos) || (sao &&
				sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
			if (far_players)
				far_players->emplace(client_id);
			else
				client->SetBlockNotSent(block_pos);
			continue;
		}

		// Send as reliable
		m_clients.send(client_id, 0, &pkt, true);
	}

	m_clients.unlock();
}

void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
		float far_d_nodes, bool remove_metadata)
{
	float maxd = far_d_nodes * BS;
	v3f p_f = intToFloat(p, BS);
	v3s16 block_pos = getNodeBlockPos(p);

	NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1);
	pkt << p << n.param0 << n.param1 << n.param2
			<< (u8) (remove_metadata ? 0 : 1);

	std::vector<session_t> clients = m_clients.getClientIDs();
	m_clients.lock();

	for (session_t client_id : clients) {
		RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
		if (!client)
			continue;

		RemotePlayer *player = m_env->getPlayer(client_id);
		PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;

		// If player is far away, only set modified blocks not sent
		if (!client->isBlockSent(block_pos) || (sao &&
				sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
			if (far_players)
				far_players->emplace(client_id);
			else
				client->SetBlockNotSent(block_pos);
			continue;
		}

		// Send as reliable
		m_clients.send(client_id, 0, &pkt, true);
	}

	m_clients.unlock();
}

void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far_d_nodes)
{
	float maxd = far_d_nodes * BS;
	NodeMetadataList meta_updates_list(false);
	std::vector<session_t> clients = m_clients.getClientIDs();

	m_clients.lock();

	for (session_t i : clients) {
		RemoteClient *client = m_clients.lockedGetClientNoEx(i);
		if (!client)
			continue;

		ServerActiveObject *player = m_env->getActiveObject(i);
		v3f player_pos = player ? player->getBasePosition() : v3f();

		for (const v3s16 &pos : meta_updates) {
			NodeMetadata *meta = m_env->getMap().getNodeMetadata(pos);

			if (!meta)
				continue;

			v3s16 block_pos = getNodeBlockPos(pos);
			if (!client->isBlockSent(block_pos) || (player &&
					player_pos.getDistanceFrom(intToFloat(pos, BS)) > maxd)) {
				client->SetBlockNotSent(block_pos);
				continue;
			}

			// Add the change to send list
			meta_updates_list.set(pos, meta);
		}
		if (meta_updates_list.size() == 0)
			continue;

		// Send the meta changes
		std::ostringstream os(std::ios::binary);
		meta_updates_list.serialize(os, client->net_proto_version, false, true);
		std::ostringstream oss(std::ios::binary);
		compressZlib(os.str(), oss);

		NetworkPacket pkt(TOCLIENT_NODEMETA_CHANGED, 0);
		pkt.putLongString(oss.str());
		m_clients.send(i, 0, &pkt, true);

		meta_updates_list.clear();
	}

	m_clients.unlock();
}

void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
		u16 net_proto_version)
{
	/*
		Create a packet with the block in the right format
	*/

	std::ostringstream os(std::ios_base::binary);
	block->serialize(os, ver, false);
	block->serializeNetworkSpecific(os);
	std::string s = os.str();

	NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + 2 + s.size(), peer_id);

	pkt << block->getPos();
	pkt.putRawString(s.c_str(), s.size());
	Send(&pkt);
}

void Server::SendBlocks(float dtime)
{
	MutexAutoLock envlock(m_env_mutex);
	//TODO check if one big lock could be faster then multiple small ones

	std::vector<PrioritySortedBlockTransfer> queue;

	u32 total_sending = 0;

	{
		ScopeProfiler sp2(g_profiler, "Server::SendBlocks(): Collect list");

		std::vector<session_t> clients = m_clients.getClientIDs();

		m_clients.lock();
		for (const session_t client_id : clients) {
			RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);

			if (!client)
				continue;

			total_sending += client->getSendingCount();
			client->GetNextBlocks(m_env,m_emerge, dtime, queue);
		}
		m_clients.unlock();
	}

	// Sort.
	// Lowest priority number comes first.
	// Lowest is most important.
	std::sort(queue.begin(), queue.end());

	m_clients.lock();

	// Maximal total count calculation
	// The per-client block sends is halved with the maximal online users
	u32 max_blocks_to_send = (m_env->getPlayerCount() + g_settings->getU32("max_users")) *
		g_settings->getU32("max_simultaneous_block_sends_per_client") / 4 + 1;

	ScopeProfiler sp(g_profiler, "Server::SendBlocks(): Send to clients");
	Map &map = m_env->getMap();

	for (const PrioritySortedBlockTransfer &block_to_send : queue) {
		if (total_sending >= max_blocks_to_send)
			break;

		MapBlock *block = map.getBlockNoCreateNoEx(block_to_send.pos);
		if (!block)
			continue;

		RemoteClient *client = m_clients.lockedGetClientNoEx(block_to_send.peer_id,
				CS_Active);
		if (!client)
			continue;

		SendBlockNoLock(block_to_send.peer_id, block, client->serialization_version,
				client->net_proto_version);

		client->SentBlock(block_to_send.pos);
		total_sending++;
	}
	m_clients.unlock();
}

bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
{
	MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
	if (!block)
		return false;

	m_clients.lock();
	RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active);
	if (!client || client->isBlockSent(blockpos)) {
		m_clients.unlock();
		return false;
	}
	SendBlockNoLock(peer_id, block, client->serialization_version,
			client->net_proto_version);
	m_clients.unlock();

	return true;
}

void Server::fillMediaCache()
{
	infostream<<"Server: Calculating media file checksums"<<std::endl;

	// Collect all media file paths
	std::vector<std::string> paths;
	m_modmgr->getModsMediaPaths(paths);
	fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
	fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server");

	// Collect media file information from paths into cache
	for (const std::string &mediapath : paths) {
		std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
		for (const fs::DirListNode &dln : dirlist) {
			if (dln.dir) // Ignode dirs
				continue;
			std::string filename = dln.name;
			// If name contains illegal characters, ignore the file
			if (!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) {
				infostream<<"Server: ignoring illegal file name: \""
						<< filename << "\"" << std::endl;
				continue;
			}
			// If name is not in a supported format, ignore it
			const char *supported_ext[] = {
				".png", ".jpg", ".bmp", ".tga",
				".pcx", ".ppm", ".psd", ".wal", ".rgb",
				".ogg",
				".x", ".b3d", ".md2", ".obj",
				// Custom translation file format
				".tr",
				NULL
			};
			if (removeStringEnd(filename, supported_ext).empty()){
				infostream << "Server: ignoring unsupported file extension: \""
						<< filename << "\"" << std::endl;
				continue;
			}
			// Ok, attempt to load the file and add to cache
			std::string filepath;
			filepath.append(mediapath).append(DIR_DELIM).append(filename);

			// Read data
			std::ifstream fis(filepath.c_str(), std::ios_base::binary);
			if (!fis.good()) {
				errorstream << "Server::fillMediaCache(): Could not open \""
						<< filename << "\" for reading" << std::endl;
				continue;
			}
			std::ostringstream tmp_os(std::ios_base::binary);
			bool bad = false;
			for(;;) {
				char buf[1024];
				fis.read(buf, 1024);
				std::streamsize len = fis.gcount();
				tmp_os.write(buf, len);
				if (fis.eof())
					break;
				if (!fis.good()) {
					bad = true;
					break;
				}
			}
			if(bad) {
				errorstream<<"Server::fillMediaCache(): Failed to read \""
						<< filename << "\"" << std::endl;
				continue;
			}
			if(tmp_os.str().length() == 0) {
				errorstream << "Server::fillMediaCache(): Empty file \""
						<< filepath << "\"" << std::endl;
				continue;
			}

			SHA1 sha1;
			sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());

			unsigned char *digest = sha1.getDigest();
			std::string sha1_base64 = base64_encode(digest, 20);
			std::string sha1_hex = hex_encode((char*)digest, 20);
			free(digest);

			// Put in list
			m_media[filename] = MediaInfo(filepath, sha1_base64);
			verbosestream << "Server: " << sha1_hex << " is " << filename
					<< std::endl;
		}
	}
}

void Server::sendMediaAnnouncement(session_t peer_id, const std::string &lang_code)
{
	// Make packet
	NetworkPacket pkt(TOCLIENT_ANNOUNCE_MEDIA, 0, peer_id);

	u16 media_sent = 0;
	std::string lang_suffix;
	lang_suffix.append(".").append(lang_code).append(".tr");
	for (const auto &i : m_media) {
		if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix))
			continue;
		media_sent++;
	}

	pkt << media_sent;

	for (const auto &i : m_media) {
		if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix))
			continue;
		pkt << i.first << i.second.sha1_digest;
	}

	pkt << g_settings->get("remote_media");
	Send(&pkt);

	verbosestream << "Server: Announcing files to id(" << peer_id
		<< "): count=" << media_sent << " size=" << pkt.getSize() << std::endl;
}

struct SendableMedia
{
	std::string name;
	std::string path;
	std::string data;

	SendableMedia(const std::string &name_="", const std::string &path_="",
	              const std::string &data_=""):
		name(name_),
		path(path_),
		data(data_)
	{}
};

void Server::sendRequestedMedia(session_t peer_id,
		const std::vector<std::string> &tosend)
{
	verbosestream<<"Server::sendRequestedMedia(): "
			<<"Sending files to client"<<std::endl;

	/* Read files */

	// Put 5kB in one bunch (this is not accurate)
	u32 bytes_per_bunch = 5000;

	std::vector< std::vector<SendableMedia> > file_bunches;
	file_bunches.emplace_back();

	u32 file_size_bunch_total = 0;

	for (const std::string &name : tosend) {
		if (m_media.find(name) == m_media.end()) {
			errorstream<<"Server::sendRequestedMedia(): Client asked for "
					<<"unknown file \""<<(name)<<"\""<<std::endl;
			continue;
		}

		//TODO get path + name
		std::string tpath = m_media[name].path;

		// Read data
		std::ifstream fis(tpath.c_str(), std::ios_base::binary);
		if(!fis.good()){
			errorstream<<"Server::sendRequestedMedia(): Could not open \""
					<<tpath<<"\" for reading"<<std::endl;
			continue;
		}
		std::ostringstream tmp_os(std::ios_base::binary);
		bool bad = false;
		for(;;) {
			char buf[1024];
			fis.read(buf, 1024);
			std::streamsize len = fis.gcount();
			tmp_os.write(buf, len);
			file_size_bunch_total += len;
			if(fis.eof())
				break;
			if(!fis.good()) {
				bad = true;
				break;
			}
		}
		if (bad) {
			errorstream<<"Server::sendRequestedMedia(): Failed to read \""
					<<name<<"\""<<std::endl;
			continue;
		}
		/*infostream<<"Server::sendRequestedMedia(): Loaded \""
				<<tname<<"\""<<std::endl;*/
		// Put in list
		file_bunches[file_bunches.size()-1].emplace_back(name, tpath, tmp_os.str());

		// Start next bunch if got enough data
		if(file_size_bunch_total >= bytes_per_bunch) {
			file_bunches.emplace_back();
			file_size_bunch_total = 0;
		}

	}

	/* Create and send packets */

	u16 num_bunches = file_bunches.size();
	for (u16 i = 0; i < num_bunches; i++) {
		/*
			u16 command
			u16 total number of texture bunches
			u16 index of this bunch
			u32 number of files in this bunch
			for each file {
				u16 length of name
				string name
				u32 length of data
				data
			}
		*/

		NetworkPacket pkt(TOCLIENT_MEDIA, 4 + 0, peer_id);
		pkt << num_bunches << i << (u32) file_bunches[i].size();

		for (const SendableMedia &j : file_bunches[i]) {
			pkt << j.name;
			pkt.putLongString(j.data);
		}

		verbosestream << "Server::sendRequestedMedia(): bunch "
				<< i << "/" << num_bunches
				<< " files=" << file_bunches[i].size()
				<< " size="  << pkt.getSize() << std::endl;
		Send(&pkt);
	}
}

void Server::sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id)
{
	NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id);
	pkt << name;

	if (!inventory) {
		pkt << false; // Remove inventory
	} else {
		pkt << true; // Update inventory

		// Serialization & NetworkPacket isn't a love story
		std::ostringstream os(std::ios_base::binary);
		inventory->serialize(os);
		inventory->setModified(false);

		const std::string &os_str = os.str();
		pkt << static_cast<u16>(os_str.size()); // HACK: to keep compatibility with 5.0.0 clients
		pkt.putRawString(os_str);
	}

	if (peer_id == PEER_ID_INEXISTENT)
		m_clients.sendToAll(&pkt);
	else
		Send(&pkt);
}

void Server::sendDetachedInventories(session_t peer_id, bool incremental)
{
	// Lookup player name, to filter detached inventories just after
	std::string peer_name;
	if (peer_id != PEER_ID_INEXISTENT) {
		peer_name = getClient(peer_id, CS_Created)->getName();
	}

	auto send_cb = [this, peer_id](const std::string &name, Inventory *inv) {
		sendDetachedInventory(inv, name, peer_id);
	};

	m_inventory_mgr->sendDetachedInventories(peer_name, incremental, send_cb);
}

/*
	Something random
*/

void Server::DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason)
{
	PlayerSAO *playersao = getPlayerSAO(peer_id);
	assert(playersao);

	infostream << "Server::DiePlayer(): Player "
			<< playersao->getPlayer()->getName()
			<< " dies" << std::endl;

	playersao->setHP(0, reason);
	playersao->clearParentAttachment();

	// Trigger scripted stuff
	m_script->on_dieplayer(playersao, reason);

	SendPlayerHP(peer_id);
	SendDeathscreen(peer_id, false, v3f(0,0,0));
}

void Server::RespawnPlayer(session_t peer_id)
{
	PlayerSAO *playersao = getPlayerSAO(peer_id);
	assert(playersao);

	infostream << "Server::RespawnPlayer(): Player "
			<< playersao->getPlayer()->getName()
			<< " respawns" << std::endl;

	playersao->setHP(playersao->accessObjectProperties()->hp_max,
			PlayerHPChangeReason(PlayerHPChangeReason::RESPAWN));
	playersao->setBreath(playersao->accessObjectProperties()->breath_max);

	bool repositioned = m_script->on_respawnplayer(playersao);
	if (!repositioned) {
		// setPos will send the new position to client
		playersao->setPos(findSpawnPos());
	}

	SendPlayerHP(peer_id);
}


void Server::DenySudoAccess(session_t peer_id)
{
	NetworkPacket pkt(TOCLIENT_DENY_SUDO_MODE, 0, peer_id);
	Send(&pkt);
}


void Server::DenyAccessVerCompliant(session_t peer_id, u16 proto_ver, AccessDeniedCode reason,
		const std::string &str_reason, bool reconnect)
{
	SendAccessDenied(peer_id, reason, str_reason, reconnect);

	m_clients.event(peer_id, CSE_SetDenied);
	DisconnectPeer(peer_id);
}


void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason,
		const std::string &custom_reason)
{
	SendAccessDenied(peer_id, reason, custom_reason);
	m_clients.event(peer_id, CSE_SetDenied);
	DisconnectPeer(peer_id);
}

// 13/03/15: remove this function when protocol version 25 will become
// the minimum version for MT users, maybe in 1 year
void Server::DenyAccess_Legacy(session_t peer_id, const std::wstring &reason)
{
	SendAccessDenied_Legacy(peer_id, reason);
	m_clients.event(peer_id, CSE_SetDenied);
	DisconnectPeer(peer_id);
}

void Server::DisconnectPeer(session_t peer_id)
{
	m_modchannel_mgr->leaveAllChannels(peer_id);
	m_con->DisconnectPeer(peer_id);
}

void Server::acceptAuth(session_t peer_id, bool forSudoMode)
{
	if (!forSudoMode) {
		RemoteClient* client = getClient(peer_id, CS_Invalid);

		NetworkPacket resp_pkt(TOCLIENT_AUTH_ACCEPT, 1 + 6 + 8 + 4, peer_id);

		// Right now, the auth mechs don't change between login and sudo mode.
		u32 sudo_auth_mechs = client->allowed_auth_mechs;
		client->allowed_sudo_mechs = sudo_auth_mechs;

		resp_pkt << v3f(0,0,0) << (u64) m_env->getServerMap().getSeed()
				<< g_settings->getFloat("dedicated_server_step")
				<< sudo_auth_mechs;

		Send(&resp_pkt);
		m_clients.event(peer_id, CSE_AuthAccept);
	} else {
		NetworkPacket resp_pkt(TOCLIENT_ACCEPT_SUDO_MODE, 1 + 6 + 8 + 4, peer_id);

		// We only support SRP right now
		u32 sudo_auth_mechs = AUTH_MECHANISM_FIRST_SRP;

		resp_pkt << sudo_auth_mechs;
		Send(&resp_pkt);
		m_clients.event(peer_id, CSE_SudoSuccess);
	}
}

void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason)
{
	std::wstring message;
	{
		/*
			Clear references to playing sounds
		*/
		for (std::unordered_map<s32, ServerPlayingSound>::iterator
				 i = m_playing_sounds.begin(); i != m_playing_sounds.end();) {
			ServerPlayingSound &psound = i->second;
			psound.clients.erase(peer_id);
			if (psound.clients.empty())
				m_playing_sounds.erase(i++);
			else
				++i;
		}

		// clear formspec info so the next client can't abuse the current state
		m_formspec_state_data.erase(peer_id);

		RemotePlayer *player = m_env->getPlayer(peer_id);

		/* Run scripts and remove from environment */
		if (player) {
			PlayerSAO *playersao = player->getPlayerSAO();
			assert(playersao);

			playersao->clearChildAttachments();
			playersao->clearParentAttachment();

			// inform connected clients
			const std::string &player_name = player->getName();
			NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
			// (u16) 1 + std::string represents a vector serialization representation
			notice << (u8) PLAYER_LIST_REMOVE  << (u16) 1 << player_name;
			m_clients.sendToAll(&notice);
			// run scripts
			m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT);

			playersao->disconnected();
		}

		/*
			Print out action
		*/
		{
			if (player && reason != CDR_DENY) {
				std::ostringstream os(std::ios_base::binary);
				std::vector<session_t> clients = m_clients.getClientIDs();

				for (const session_t client_id : clients) {
					// Get player
					RemotePlayer *player = m_env->getPlayer(client_id);
					if (!player)
						continue;

					// Get name of player
					os << player->getName() << " ";
				}

				std::string name = player->getName();
				actionstream << name << " "
						<< (reason == CDR_TIMEOUT ? "times out." : "leaves game.")
						<< " List of players: " << os.str() << std::endl;
				if (m_admin_chat)
					m_admin_chat->outgoing_queue.push_back(
						new ChatEventNick(CET_NICK_REMOVE, name));
			}
		}
		{
			MutexAutoLock env_lock(m_env_mutex);
			m_clients.DeleteClient(peer_id);
		}
	}

	// Send leave chat message to all remaining clients
	if (!message.empty()) {
		SendChatMessage(PEER_ID_INEXISTENT,
				ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, message));
	}
}

void Server::UpdateCrafting(RemotePlayer *player)
{
	InventoryList *clist = player->inventory.getList("craft");
	if (!clist || clist->getSize() == 0)
		return;

	if (!clist->checkModified())
		return;

	// Get a preview for crafting
	ItemStack preview;
	InventoryLocation loc;
	loc.setPlayer(player->getName());
	std::vector<ItemStack> output_replacements;
	getCraftingResult(&player->inventory, preview, output_replacements, false, this);
	m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(),
			clist, loc);

	InventoryList *plist = player->inventory.getList("craftpreview");
	if (plist && plist->getSize() >= 1) {
		// Put the new preview in
		plist->changeItem(0, preview);
	}
}

void Server::handleChatInterfaceEvent(ChatEvent *evt)
{
	if (evt->type == CET_NICK_ADD) {
		// The terminal informed us of its nick choice
		m_admin_nick = ((ChatEventNick *)evt)->nick;
		if (!m_script->getAuth(m_admin_nick, NULL, NULL)) {
			errorstream << "You haven't set up an account." << std::endl
				<< "Please log in using the client as '"
				<< m_admin_nick << "' with a secure password." << std::endl
				<< "Until then, you can't execute admin tasks via the console," << std::endl
				<< "and everybody can claim the user account instead of you," << std::endl
				<< "giving them full control over this server." << std::endl;
		}
	} else {
		assert(evt->type == CET_CHAT);
		handleAdminChat((ChatEventChat *)evt);
	}
}

std::wstring Server::handleChat(const std::string &name, const std::wstring &wname,
	std::wstring wmessage, bool check_shout_priv, RemotePlayer *player)
{
	// If something goes wrong, this player is to blame
	RollbackScopeActor rollback_scope(m_rollback,
			std::string("player:") + name);

	if (g_settings->getBool("strip_color_codes"))
		wmessage = unescape_enriched(wmessage);

	if (player) {
		switch (player->canSendChatMessage()) {
		case RPLAYER_CHATRESULT_FLOODING: {
			std::wstringstream ws;
			ws << L"You cannot send more messages. You are limited to "
					<< g_settings->getFloat("chat_message_limit_per_10sec")
					<< L" messages per 10 seconds.";
			return ws.str();
		}
		case RPLAYER_CHATRESULT_KICK:
			DenyAccess_Legacy(player->getPeerId(),
					L"You have been kicked due to message flooding.");
			return L"";
		case RPLAYER_CHATRESULT_OK:
			break;
		default:
			FATAL_ERROR("Unhandled chat filtering result found.");
		}
	}

	if (m_max_chatmessage_length > 0
			&& wmessage.length() > m_max_chatmessage_length) {
		return L"Your message exceed the maximum chat message limit set on the server. "
				L"It was refused. Send a shorter message";
	}

	auto message = trim(wide_to_utf8(wmessage));
	if (message.find_first_of("\n\r") != std::wstring::npos) {
		return L"New lines are not permitted in chat messages";
	}

	// Run script hook, exit if script ate the chat message
	if (m_script->on_chat_message(name, message))
		return L"";

	// Line to send
	std::wstring line;
	// Whether to send line to the player that sent the message, or to all players
	bool broadcast_line = true;

	if (check_shout_priv && !checkPriv(name, "shout")) {
		line += L"-!- You don't have permission to shout.";
		broadcast_line = false;
	} else {
		/*
			Workaround for fixing chat on Android. Lua doesn't handle
			the Cyrillic alphabet and some characters on older Android devices
		*/
#ifdef __ANDROID__
		line += L"<" + wname + L"> " + wmessage;
#else
		line += narrow_to_wide(m_script->formatChatMessage(name,
				wide_to_narrow(wmessage)));
#endif
	}

	/*
		Tell calling method to send the message to sender
	*/
	if (!broadcast_line)
		return line;

	/*
		Send the message to others
	*/
	actionstream << "CHAT: " << wide_to_narrow(unescape_enriched(line)) << std::endl;

	std::vector<session_t> clients = m_clients.getClientIDs();

	/*
		Send the message back to the inital sender
		if they are using protocol version >= 29
	*/

	session_t peer_id_to_avoid_sending =
		(player ? player->getPeerId() : PEER_ID_INEXISTENT);

	if (player && player->protocol_version >= 29)
		peer_id_to_avoid_sending = PEER_ID_INEXISTENT;

	for (u16 cid : clients) {
		if (cid != peer_id_to_avoid_sending)
			SendChatMessage(cid, ChatMessage(line));
	}
	return L"";
}

void Server::handleAdminChat(const ChatEventChat *evt)
{
	std::string name = evt->nick;
	std::wstring wname = utf8_to_wide(name);
	std::wstring wmessage = evt->evt_msg;

	std::wstring answer = handleChat(name, wname, wmessage);

	// If asked to send answer to sender
	if (!answer.empty()) {
		m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", answer));
	}
}

RemoteClient *Server::getClient(session_t peer_id, ClientState state_min)
{
	RemoteClient *client = getClientNoEx(peer_id,state_min);
	if(!client)
		throw ClientNotFoundException("Client not found");

	return client;
}
RemoteClient *Server::getClientNoEx(session_t peer_id, ClientState state_min)
{
	return m_clients.getClientNoEx(peer_id, state_min);
}

std::string Server::getPlayerName(session_t peer_id)
{
	RemotePlayer *player = m_env->getPlayer(peer_id);
	if (!player)
		return "[id="+itos(peer_id)+"]";
	return player->getName();
}

PlayerSAO *Server::getPlayerSAO(session_t peer_id)
{
	RemotePlayer *player = m_env->getPlayer(peer_id);
	if (!player)
		return NULL;
	return player->getPlayerSAO();
}

std::wstring Server::getStatusString()
{
	std::wostringstream os(std::ios_base::binary);
	os << L"# Server: ";
	// Version
	os << L"version=" << narrow_to_wide(g_version_string);
	// Uptime
	os << L", uptime=" << m_uptime_counter->get();
	// Max lag estimate
	os << L", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0);

	// Information about clients
	bool first = true;
	os << L", clients={";
	if (m_env) {
		std::vector<session_t> clients = m_clients.getClientIDs();
		for (session_t client_id : clients) {
			RemotePlayer *player = m_env->getPlayer(client_id);

			// Get name of player
			std::wstring name = L"unknown";
			if (player)
				name = narrow_to_wide(player->getName());

			// Add name to information string
			if (!first)
				os << L", ";
			else
				first = false;

			os << name;
		}
	}
	os << L"}";

	if (m_env && !((ServerMap*)(&m_env->getMap()))->isSavingEnabled())
		os << std::endl << L"# Server: " << " WARNING: Map saving is disabled.";

	if (!g_settings->get("motd").empty())
		os << std::endl << L"# Server: " << narrow_to_wide(g_settings->get("motd"));

	return os.str();
}

std::set<std::string> Server::getPlayerEffectivePrivs(const std::string &name)
{
	std::set<std::string> privs;
	m_script->getAuth(name, NULL, &privs);
	return privs;
}

bool Server::checkPriv(const std::string &name, const std::string &priv)
{
	std::set<std::string> privs = getPlayerEffectivePrivs(name);
	return (privs.count(priv) != 0);
}

void Server::reportPrivsModified(const std::string &name)
{
	if (name.empty()) {
		std::vector<session_t> clients = m_clients.getClientIDs();
		for (const session_t client_id : clients) {
			RemotePlayer *player = m_env->getPlayer(client_id);
			reportPrivsModified(player->getName());
		}
	} else {
		RemotePlayer *player = m_env->getPlayer(name.c_str());
		if (!player)
			return;
		SendPlayerPrivileges(player->getPeerId());
		PlayerSAO *sao = player->getPlayerSAO();
		if(!sao)
			return;
		sao->updatePrivileges(
				getPlayerEffectivePrivs(name),
				isSingleplayer());
	}
}

void Server::reportInventoryFormspecModified(const std::string &name)
{
	RemotePlayer *player = m_env->getPlayer(name.c_str());
	if (!player)
		return;
	SendPlayerInventoryFormspec(player->getPeerId());
}

void Server::reportFormspecPrependModified(const std::string &name)
{
	RemotePlayer *player = m_env->getPlayer(name.c_str());
	if (!player)
		return;
	SendPlayerFormspecPrepend(player->getPeerId());
}

void Server::setIpBanned(const std::string &ip, const std::string &name)
{
	m_banmanager->add(ip, name);
}

void Server::unsetIpBanned(const std::string &ip_or_name)
{
	m_banmanager->remove(ip_or_name);
}

std::string Server::getBanDescription(const std::string &ip_or_name)
{
	return m_banmanager->getBanDescription(ip_or_name);
}

void Server::notifyPlayer(const char *name, const std::wstring &msg)
{
	// m_env will be NULL if the server is initializing
	if (!m_env)
		return;

	if (m_admin_nick == name && !m_admin_nick.empty()) {
		m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", msg));
	}

	RemotePlayer *player = m_env->getPlayer(name);
	if (!player) {
		return;
	}

	if (player->getPeerId() == PEER_ID_INEXISTENT)
		return;

	SendChatMessage(player->getPeerId(), ChatMessage(msg));
}

bool Server::showFormspec(const char *playername, const std::string &formspec,
	const std::string &formname)
{
	// m_env will be NULL if the server is initializing
	if (!m_env)
		return false;

	RemotePlayer *player = m_env->getPlayer(playername);
	if (!player)
		return false;

	SendShowFormspecMessage(player->getPeerId(), formspec, formname);
	return true;
}

u32 Server::hudAdd(RemotePlayer *player, HudElement *form)
{
	if (!player)
		return -1;

	u32 id = player->addHud(form);

	SendHUDAdd(player->getPeerId(), id, form);

	return id;
}

bool Server::hudRemove(RemotePlayer *player, u32 id) {
	if (!player)
		return false;

	HudElement* todel = player->removeHud(id);

	if (!todel)
		return false;

	delete todel;

	SendHUDRemove(player->getPeerId(), id);
	return true;
}

bool Server::hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *data)
{
	if (!player)
		return false;

	SendHUDChange(player->getPeerId(), id, stat, data);
	return true;
}

bool Server::hudSetFlags(RemotePlayer *player, u32 flags, u32 mask)
{
	if (!player)
		return false;

	SendHUDSetFlags(player->getPeerId(), flags, mask);
	player->hud_flags &= ~mask;
	player->hud_flags |= flags;

	PlayerSAO* playersao = player->getPlayerSAO();

	if (!playersao)
		return false;

	m_script->player_event(playersao, "hud_changed");
	return true;
}

bool Server::hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount)
{
	if (!player)
		return false;

	if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX)
		return false;

	player->setHotbarItemcount(hotbar_itemcount);
	std::ostringstream os(std::ios::binary);
	writeS32(os, hotbar_itemcount);
	SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_ITEMCOUNT, os.str());
	return true;
}

void Server::hudSetHotbarImage(RemotePlayer *player, const std::string &name)
{
	if (!player)
		return;

	player->setHotbarImage(name);
	SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_IMAGE, name);
}

void Server::hudSetHotbarSelectedImage(RemotePlayer *player, const std::string &name)
{
	if (!player)
		return;

	player->setHotbarSelectedImage(name);
	SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
}

Address Server::getPeerAddress(session_t peer_id)
{
	return m_con->GetPeerAddress(peer_id);
}

void Server::setLocalPlayerAnimations(RemotePlayer *player,
		v2s32 animation_frames[4], f32 frame_speed)
{
	sanity_check(player);
	player->setLocalAnimations(animation_frames, frame_speed);
	SendLocalPlayerAnimations(player->getPeerId(), animation_frames, frame_speed);
}

void Server::setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third)
{
	sanity_check(player);
	player->eye_offset_first = first;
	player->eye_offset_third = third;
	SendEyeOffset(player->getPeerId(), first, third);
}

void Server::setSky(RemotePlayer *player, const SkyboxParams &params)
{
	sanity_check(player);
	player->setSky(params);
	SendSetSky(player->getPeerId(), params);
}

void Server::setSun(RemotePlayer *player, const SunParams &params)
{
	sanity_check(player);
	player->setSun(params);
	SendSetSun(player->getPeerId(), params);
}

void Server::setMoon(RemotePlayer *player, const MoonParams &params)
{
	sanity_check(player);
	player->setMoon(params);
	SendSetMoon(player->getPeerId(), params);
}

void Server::setStars(RemotePlayer *player, const StarParams &params)
{
	sanity_check(player);
	player->setStars(params);
	SendSetStars(player->getPeerId(), params);
}

void Server::setClouds(RemotePlayer *player, const CloudParams &params)
{
	sanity_check(player);
	player->setCloudParams(params);
	SendCloudParams(player->getPeerId(), params);
}

void Server::overrideDayNightRatio(RemotePlayer *player, bool do_override,
	float ratio)
{
	sanity_check(player);
	player->overrideDayNightRatio(do_override, ratio);
	SendOverrideDayNightRatio(player->getPeerId(), do_override, ratio);
}

void Server::notifyPlayers(const std::wstring &msg)
{
	SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
}

void Server::spawnParticle(const std::string &playername,
	const ParticleParameters &p)
{
	// m_env will be NULL if the server is initializing
	if (!m_env)
		return;

	session_t peer_id = PEER_ID_INEXISTENT;
	u16 proto_ver = 0;
	if (!playername.empty()) {
		RemotePlayer *player = m_env->getPlayer(playername.c_str());
		if (!player)
			return;
		peer_id = player->getPeerId();
		proto_ver = player->protocol_version;
	}

	SendSpawnParticle(peer_id, proto_ver, p);
}

u32 Server::addParticleSpawner(const ParticleSpawnerParameters &p,
	ServerActiveObject *attached, const std::string &playername)
{
	// m_env will be NULL if the server is initializing
	if (!m_env)
		return -1;

	session_t peer_id = PEER_ID_INEXISTENT;
	u16 proto_ver = 0;
	if (!playername.empty()) {
		RemotePlayer *player = m_env->getPlayer(playername.c_str());
		if (!player)
			return -1;
		peer_id = player->getPeerId();
		proto_ver = player->protocol_version;
	}

	u16 attached_id = attached ? attached->getId() : 0;

	u32 id;
	if (attached_id == 0)
		id = m_env->addParticleSpawner(p.time);
	else
		id = m_env->addParticleSpawner(p.time, attached_id);

	SendAddParticleSpawner(peer_id, proto_ver, p, attached_id, id);
	return id;
}

void Server::deleteParticleSpawner(const std::string &playername, u32 id)
{
	// m_env will be NULL if the server is initializing
	if (!m_env)
		throw ServerError("Can't delete particle spawners during initialisation!");

	session_t peer_id = PEER_ID_INEXISTENT;
	if (!playername.empty()) {
		RemotePlayer *player = m_env->getPlayer(playername.c_str());
		if (!player)
			return;
		peer_id = player->getPeerId();
	}

	m_env->deleteParticleSpawner(id);
	SendDeleteParticleSpawner(peer_id, id);
}

// actions: time-reversed list
// Return value: success/failure
bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
		std::list<std::string> *log)
{
	infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
	ServerMap *map = (ServerMap*)(&m_env->getMap());

	// Fail if no actions to handle
	if (actions.empty()) {
		assert(log);
		log->push_back("Nothing to do.");
		return false;
	}

	int num_tried = 0;
	int num_failed = 0;

	for (const RollbackAction &action : actions) {
		num_tried++;
		bool success = action.applyRevert(map, m_inventory_mgr.get(), this);
		if(!success){
			num_failed++;
			std::ostringstream os;
			os<<"Revert of step ("<<num_tried<<") "<<action.toString()<<" failed";
			infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
			if (log)
				log->push_back(os.str());
		}else{
			std::ostringstream os;
			os<<"Successfully reverted step ("<<num_tried<<") "<<action.toString();
			infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
			if (log)
				log->push_back(os.str());
		}
	}

	infostream<<"Map::rollbackRevertActions(): "<<num_failed<<"/"<<num_tried
			<<" failed"<<std::endl;

	// Call it done if less than half failed
	return num_failed <= num_tried/2;
}

// IGameDef interface
// Under envlock
IItemDefManager *Server::getItemDefManager()
{
	return m_itemdef;
}

const NodeDefManager *Server::getNodeDefManager()
{
	return m_nodedef;
}

ICraftDefManager *Server::getCraftDefManager()
{
	return m_craftdef;
}

u16 Server::allocateUnknownNodeId(const std::string &name)
{
	return m_nodedef->allocateDummy(name);
}

IWritableItemDefManager *Server::getWritableItemDefManager()
{
	return m_itemdef;
}

NodeDefManager *Server::getWritableNodeDefManager()
{
	return m_nodedef;
}

IWritableCraftDefManager *Server::getWritableCraftDefManager()
{
	return m_craftdef;
}

const std::vector<ModSpec> & Server::getMods() const
{
	return m_modmgr->getMods();
}

const ModSpec *Server::getModSpec(const std::string &modname) const
{
	return m_modmgr->getModSpec(modname);
}

void Server::getModNames(std::vector<std::string> &modlist)
{
	m_modmgr->getModNames(modlist);
}

std::string Server::getBuiltinLuaPath()
{
	return porting::path_share + DIR_DELIM + "builtin";
}

std::string Server::getModStoragePath() const
{
	return m_path_world + DIR_DELIM + "mod_storage";
}

v3f Server::findSpawnPos()
{
	ServerMap &map = m_env->getServerMap();
	v3f nodeposf;
	if (g_settings->getV3FNoEx("static_spawnpoint", nodeposf))
		return nodeposf * BS;

	bool is_good = false;
	// Limit spawn range to mapgen edges (determined by 'mapgen_limit')
	s32 range_max = map.getMapgenParams()->getSpawnRangeMax();

	// Try to find a good place a few times
	for (s32 i = 0; i < 4000 && !is_good; i++) {
		s32 range = MYMIN(1 + i, range_max);
		// We're going to try to throw the player to this position
		v2s16 nodepos2d = v2s16(
			-range + (myrand() % (range * 2)),
			-range + (myrand() % (range * 2)));
		// Get spawn level at point
		s16 spawn_level = m_emerge->getSpawnLevelAtPoint(nodepos2d);
		// Continue if MAX_MAP_GENERATION_LIMIT was returned by the mapgen to
		// signify an unsuitable spawn position, or if outside limits.
		if (spawn_level >= MAX_MAP_GENERATION_LIMIT ||
				spawn_level <= -MAX_MAP_GENERATION_LIMIT)
			continue;

		v3s16 nodepos(nodepos2d.X, spawn_level, nodepos2d.Y);
		// Consecutive empty nodes
		s32 air_count = 0;

		// Search upwards from 'spawn level' for 2 consecutive empty nodes, to
		// avoid obstructions in already-generated mapblocks.
		// In ungenerated mapblocks consisting of 'ignore' nodes, there will be
		// no obstructions, but mapgen decorations are generated after spawn so
		// the player may end up inside one.
		for (s32 i = 0; i < 8; i++) {
			v3s16 blockpos = getNodeBlockPos(nodepos);
			map.emergeBlock(blockpos, true);
			content_t c = map.getNode(nodepos).getContent();

			// In generated mapblocks allow spawn in all 'airlike' drawtype nodes.
			// In ungenerated mapblocks allow spawn in 'ignore' nodes.
			if (m_nodedef->get(c).drawtype == NDT_AIRLIKE || c == CONTENT_IGNORE) {
				air_count++;
				if (air_count >= 2) {
					// Spawn in lower empty node
					nodepos.Y--;
					nodeposf = intToFloat(nodepos, BS);
					// Don't spawn the player outside map boundaries
					if (objectpos_over_limit(nodeposf))
						// Exit this loop, positions above are probably over limit
						break;

					// Good position found, cause an exit from main loop
					is_good = true;
					break;
				}
			} else {
				air_count = 0;
			}
			nodepos.Y++;
		}
	}

	if (is_good)
		return nodeposf;

	// No suitable spawn point found, return fallback 0,0,0
	return v3f(0.0f, 0.0f, 0.0f);
}

void Server::requestShutdown(const std::string &msg, bool reconnect, float delay)
{
	if (delay == 0.0f) {
	// No delay, shutdown immediately
		m_shutdown_state.is_requested = true;
		// only print to the infostream, a chat message saying
		// "Server Shutting Down" is sent when the server destructs.
		infostream << "*** Immediate Server shutdown requested." << std::endl;
	} else if (delay < 0.0f && m_shutdown_state.isTimerRunning()) {