From 03073f5436c95ca6fee54b5544d593628656f1b2 Mon Sep 17 00:00:00 2001 From: HardiReady Date: Sat, 9 Feb 2019 20:42:24 +0100 Subject: [PATCH] Add parsing and persisting for FPS logs (CC-80) --- docs/mongo-db-schema.odg | Bin 16432 -> 16708 bytes server/models/logs/budget.js | 2 +- server/models/logs/flag.js | 2 +- server/models/logs/kill.js | 2 +- server/models/logs/player-count.js | 2 +- server/models/logs/points.js | 2 +- server/models/logs/respawn.js | 2 +- server/models/logs/revive.js | 2 +- server/models/logs/server-fps.js | 14 ++++- server/models/logs/transport.js | 2 +- server/models/logs/vehicle.js | 2 +- server/models/player.js | 5 ++ server/routes/wars.js | 84 ++++++++++++++++------------- server/tools/log-parse-tool.js | 48 ++++++++++++++++- 14 files changed, 122 insertions(+), 47 deletions(-) diff --git a/docs/mongo-db-schema.odg b/docs/mongo-db-schema.odg index 26737ec27baa5749636652a6110e00c17cb026d1..90557e0221037d82e3cd992ccdb9bc98c22eefba 100644 GIT binary patch delta 12620 zcmZX*1yCHp(>{E6xVt+9_dswD5Zo;gf=iG9!SxPz3j}v}cXxMpcXyXB`MqDgQva^n z?V0Z0XQy_zs%M_*t$+Y~e1OPGvQW_2002AyfSnqRtO)vh)};fp`vt;;%}8jf)~cu$ zHU}-Fh2`s0Ez3={vvN^Trxt|tz^>b$@!qQoraiH^Y%jr6AG1X$;oC~%U|lH%3fHBJ zVhC}OG2Ff|(b39HR_;&vq%CtL6ih|&ss(1piPuWvQ!b|w8PY35#UuHbO!gp+vgRuc z=s7+Zo{EqQkVb+h*@I(+IvSW{53-SBCy{>QJMJroiLKe?>+2Ku+II2<-Y5N9sLd6% z=aA4jPX47A@yRSzmfn&5)Z8Ab#W73?asM60+HG>R_@Dw(zjiY)Kch53QhUV~w;1E$oF{KDY5c8y9aeZdsu%K+FXmj%&2z{6mH~yW$QNLvF(s zVh`a0t(d3HhKHB~?Wq_MW7x_Do zmZE?9%q&{tw2D&;=;W(Wo}wM36iF%+o@GSNJNz=r!}u*?wxN_$W1^$IxOJG#dW_DR z#FWQR9;RFy%_i0T8csiFFy zZ@OZ`%iY26YU(Wzhufc_R5MkxAU_g6j zhPWR#&e8a*F$LjVi2IfY6A^JB>cS3I@7~pV&cGpHzdx%)r~Pak-<_hAzXT2!bKI;N zFY)$#f3B-{M@y&4ddZ+HpJ#a|z7d4o+~0LjXCv8a>X_jE=>H5ht^D37C8X|o7ih*^ z@ck!^*=uwkX5-SAF|PPe{l&2#zkW5uZgEkx&}`RxmaCY+(zk_X+RII|8Tym|(~v=R z)}bu+^=bFxHSXc(16|G-{!P}lSj5Un8}`^x-HTo^dYv$obxD`D1?hIR79LXJQxI!7 zy?7-2&tJ7ryIZevJ1E0pblB)~9Dhs}*4((PO z0Yw%ip%38;IH!XIqe(2X6FM)8if}|T<{RyTYsEyil~@ZmLO(keVF4>3l`5t*5;32f zgA$*TU1Y_$^XyYY5Wd%J$%z((ZAS9j+`I1;3w22g)s`i-mKg-8Cf<{U=o9!2sV&`I z;3iH55*XC~S!jTduO`lu;;^}mPt=~AKygCyGfBf|FiLg*5Q5dpJKT1IqA4*6#*w6T zo^HR6fBHry-esG0M$BfRkyz#dkUm+(oZjD^iO;=+5K_wZ@+Wf{#<)4?0W24c0JAD2VxhCD5QDDfr%m@cI~`KamUO4gJ^6FD-8Ci8ap90>{utz+`Cz2x zRa!^xdfRUYi)D=fhb!oEdqgv>vsvGaWj66~_-8tg7#`~wloACEJC~|*+Q&m{C5?OE z!`mAJH}2cB>uob41NVd9>8gxGGt$-t4J-70p_{i)f!!w8MRH3vGul470; zE@!GgM8cqw_IfW}B+>I7r}z!(Ulzi3&^iAK3jkQt{O>IEcY+af08bA7z17B2+r{L@EaNwfhQ-1QgXP{QbQl4!rWLcrc0MYUVnXq#a+Lu`A&vXcjp{py)2zZ~+OncArimhDi@4A!EzZqIALt)QtfbM> z^+{_uPROjlN7duwNG4km-KpZ2GE2+{pF4+OI*#yWa){AXgFPXr?diYf4sSZXalz7L zKiNmJWi~PMJOU>6)$+2iKB`3qFn-mnbM$wPPQU+*O70eiBcbt+SFo%vP+Nj5l|KX@}qi0bF?c=!G`SGE( zNEnH)^A&-lA9WB0y~N;*M@!lpMjy{>WWcxYJgK(ws*j6=643BsjtFaAK`}wTBUF9* zXfcrRw#EjFoWVa)Kh-XHW1lfz5#KBM!@tT)isas~kAf%eC{rpthPvbyNsc8rtFnebc3K+g@T_w0{%1h zi0r}YUhRh9JXe%j!ktvxx=!f}qCA=(u-*FdO#S7}oJbmx@|}X#3;ZD_JS^gL0o9H^ zXw@i)b3}%v8f^<7zy~s;~#!h4yb|FBE(#rJ5VEbY!jXO1Ng{uLDaodf4p-A4P6BtIrE`pRXG9; z4#TwWj1Ez|r${Puw46rmRP6%{8eLGg8~q0bWlZTPy>IUk9_xNox6J67UCXo%>PCE) zS^_&jKf&+aVjm=}1@9S>CmESXu`lomCU~E~rlAwH2(ukdI3N=k*@vlJRm`3cCJ%e- zM`R+>*M1s4B1~)&V$%W|)l4DnUsUo2Fk*HRZ{q~(3sLC1g7t?!iW=cNSQszOb@(5! zqw^U|GVl4IdfSKjx#c(Uy2KcV`R!chU4s31%pZ!rCQ(16{p9R&;3&l#H6Oga`HY@f z9`JVi^Tq93snUde|eKix|lJdXr&A(EwxC_^7`8(hmdn(;ZsjHl0@tNvZ(R73J zl!}O@Tn!4*^t3%{2IEQF8%p4%_2#x5U(rfpyL2drnohL{#f1nA9-n*KTO~l_7pEEL z%bnL=?v`V7?ShI>L}G^5_551DTEC){f0PZ;U&K`7>l(xj=+~%%mi&=snXD?ZHpY_c zf%WL;v3L!m@U^N~d|}(~u3!u2(|i$l0nQ{D`g|@qh4WFf#=ok+fuehDH6~rdOPlaT zvdA05thVaP@ufeH=wSNWY8)ZIk4cxqCN^_2KlZ9hou-yTtcjl%LZjqKhA2sj%q4*w z!i8s{!k4d4IJs7D%(pV8ze2RX2Pb*aLMPC0Hgbuhy&f8%STj75dKNu-g}aG^@%PM$ zZ1mS$OIZ|^@H5oEeA)EW6m~?wrn=*CgR79S#IV6H#&7K!()^2;|X_i!U zx-rfjtBj-NAFEvB#Wn81yI)%b6Eg}Q-Hudxg|8hDTkg_@*`F*Y8D*2G3iWFjGHw&Q ztJ{YOe5Re?%M7fEY{2+)ty^t}+ZOnBVaWBj0FtysBSm(#u#Nd#IK~oBzQPFolL+&? zPqHS{_7)v_mLOv2dE2so&M~bkH8U-|{59Ei5kYItzS|S{{aJWcpyZPZI63@;Ac+j4 zi(f@G7sNxk9JuT8p3=E5PKySWM z7|VQyH}7i}ANUPC!EY>t2TFjw4fjaG5` zy6HE0)jF>7d=ZkK`+Xmb4MUlcI zCqDK!Sjt1d6$&5ELMUk`LlhTdM8!0zTfM&u%-rlFp;BYk%)g-LV@nP z|IB#^Y9^+c|1?Dx-Db}9dp~W>r!jNcqjuOXLi8VcRiM3_J%xu?aeOq4fI;*h;GhfE z&wi?$;(U+C)3tF^6bQswA`ZghPfo((e6cTfxQC%&Bu0Id#36AlVlK*)(EF;~oOq5) zSH+zA&wkN7g~}4JV3c~%ke(|8EHaGJ`{5n31e7Cm6E~0a!N7-ObeOiYTt>F?Pu;}G z*wzQBV{caB7q}*aRM&V1yFJ4CTapJ@o`!%gtZyu-S>)2TD*P}SrAzb0!%&hQCT*PQ zXWkKlTXbFm9s&<5Ch|Qcvy)8a4JC>!R0>{W?3P5{ z`_L4XH!3(v3B;_ars9k>&XEZ9W? z7FwejV-^E`ux!|=T*T=JZO=%4!f5Yn(J!!`{KytR_IN?e z5-gjFI$^@r5yGd}FNv(>^8_;ncxUnyk> z(WW8?0udAVdi^-EZWT{7UBd(PIiY_eck;S9_8iP^fe&u|O6d-27uHYn=RZEhjg(yg zu-rt4i8kl>h2bWbu!)ky*IV}W0$ zNTr`^-OdG;_d?r;`?SlyvKkDN<&IFFH8Yy(5s$U;fbL*8PeXO|0PM%b{5>uBA{@pE z@jP!$;21@Pq7fu@_3&rXZcf1saqltuD@;!FWu|ho$5ZDXhE+{tiaLoeT~UI&Vld>H z#zZ-VFCsn4)#q$UDU&+`I&53?332#IYufAyC~{AgUjn#v#u?a9%k433`@caPlO-ha4z@YbQy zh=Xc23)x&v!%|GsQT+yXLgqJ7M-7Q5KD(Hrxu_fH;&X~R25H0OL0%jQRVXhFqd*zV z+HC~p`W7f%GlV`VuHvW=7?KF=_SccG=rdvdYcPcLH1MoxWHp4WDnbRB1McPIWPzoF zV9QSeD>8f7VW*jkyyezF$S5_;0yXPuf)i~G4N)YhA?>m`-q5Rl_;IxivhHcB+pkn@ zK}zcqx;~WEnC!mBprO0Aa|Dn2s>s&VzRIY@9XTQTbvc{kC7iE&+_(n0Inn#e!jyT# zfYWLiJ6_|rA)doub>VT7CN(Lf*}3yCVESc)??BfdJk__s#m`_ zzwt-X9iJ;toB>Z2JA(93=rDIQw+BF5e&y_4eM7{?o2$>9V;at7hs#eNMZ!d%A z+znsg+^Q@q1)7MNurdjL)HSyWhU4bvMKhWa&Ke31mr3^cTucPK#P_*(9Nkq&gP9Z1 zJLBytEzQRrK0+&WuVPg2oT^1(VU?0uw<4XkDM{L7=!$<7ab7_F0FKeBFeBufIi2gh z5OS7LIPXolZXGV$1oQ2>*Z+Qlcrm$W?4uuVr@5>njsA+q<6nn+puugi-s-_LLxHuV zZXEbppiiPZ+DDOyFU;`c;pcw2GWhP^#UDqU+;v;nkDs~}OU_HF&~vt}2rY=su6H#<^-0VxnYK48%%dKf&|b- zGLI`Jz|98}ToB*xODz2Eqr^K55y$JMoXizjIsbjHh%3&F8O*mjxeq;nAn*(a0#|A5 zKeRpB*&ZN-sdmz8S;!*fq`T+YcwbrLG88Y|WxmI(7d3It@!q_KHqFI)wFHU z)?J(xdviPp6#Y3%~zRouq9Dby87{hORx!Ol<#K>8Nk*!}~Cqhs@^yMo~8IBe2SCd-yD zM|dhO=TLUll5;VuMZd|LY(s?UjMUKj78OLLxPGshAevIG1Z49Jwv+ z*bfobU_lRzLEarCJz(9k@1a)@x6C?2Pq>>c?Sp!=_`K&dtNJPQjdD;lGA#nN!%9QM z>(TP8X48^lsj9H+pZKiPbnOUriWIk0JCB6{U_lb}hV(Om^re-!dO4xj976{<{eUW&RhrjuO z^f3zU6?%~j;7CK`86shd02vAG4|1y5rRtogaDEzpPUyp9pS0;67x{Eov();nOxcDq zXWqiu(o~4%dy!V~z)tr4HOcWa(%CcVKhl)=t`3tk(fxz>ihgZ>nQIQaC7f=Lxg9Y% zo^qitp>^?u+5n%+L+!IFP?ea4itkx)ISbJbA`!VN&c2OFQN;IW?Q_XU(P?90tkNm} z3R-i}q3t@I`^lBQm%L7Vi2qtB_R5WULye*CFF1dYP$r>xzr@ryz-H~a?L@25e51yS z;ZmuCV3lnmwgjn*cuN7!L_wLK4lym;5<$jB&g>8WuD|^;9Cbo>y8V^> zC^6e|VPL!#$0)))m?-3f4q4S6SFBN3t8sl1(>U~#mk3_9{=;KwZWZ=^z#DOw+8x7wgYtz{J8>U+ zi!k6qlK|-595%+`OL|G4uA|y|5)BVZ; zmVv+Y3Ti(TbjCIjy?ek?!-RpE`RUoNH{9P~@oI!l|AT~K%B@&(-DX5bxkh~13EB!J zfy+$u(PSmX!SVT}(xr3V6eNCzR&}W0V}Lb#z{);(cpfyVn{V?cZl;k{UwgSVx+M5q*zt85$THCgzE#vuaF}s8b;WPmKs2{Gzt_vL9g~I`Jxf1K z%Dn~x%=3m4=0abq@*_}^hMk+@TVLO2QqK&1^Xd*AEduvWA~e6FcYgvpNBoD{stLlM zH|iw0BeR@cShfycXQLW5-dRt6|Ic=i0YAFGT3TBE`t{4*-QC>L&(k}=(GAkiIBQ3QwH6=Gat2jHg zr8G4sJ3A}4D6g=jC@-fZuc){%uei84x1=h&thJ=1s;sgszY^S1R#j76-CUWMRaKl@ zT~gdoUS3mHSyfrqTvgWIP+t94Y8z@A>S`LBnrf<>>YAGx>)P7daw|KFYP*XXJ4zY` z3fmT{o4TvpMp{}s+uH`3x?0ORm+Ct@>N-YSy1JXYhS~;3YC9)udRLqKXWIv6nuk_e zMmBpJ$~tSRz+FwX-7U?7E!6|9&7G~CUG0M-9c5h|b={q916{2X!>v6%J>5M+eFL36 zgTuo;-GhCD!vnp;!^2&@Q$0g7T_ejQV^ag8OQRDbofC8YGwY+1(<3vB;|pt(z1@?8 zy^|xu6XO%plcUSiqtkz7ZgFm5es*zbX?A9DZgCmBFt@U@(lfa|G`l-Ae=xGJH?nXr zxwJE}e7Ll>wZ5@FyLqy*xxKu7wzhY%ba1_N`n0h)ySci&v9`Irv39b(e7QNh{a1Dm z_YU@V4o?nuw-5FXjt=&YkB_&HF1Jn}kIt^PuU}6uZ%?luP9C1`PIfNOPA@Oc9L9sCHb- zuEt{JJ(g~+ij(h8UA2uy!)9-ipN9Uje85>Oh?KZA)r|Z@H1aMiRlZrN2OeY#y|km; zMF&L{u)!Aa2T_IVtzQ?N+!gpOid^pN7C4%<5H9FGaQ(hv{T0w=EU@ns!L6X?e&~80 zrJ~pfaCwbI+VDqgQSzQH0}avRiQLp60aBcZ(1(y}bY8g*K^tB8oyocV2h{Ns<;nRf zFvj?~1&8xS?c(pGjewaBYw{ZT(%A~Hz6=nzYeeAVGlzt_;4cth7{)4Eba|Bld>Sh= zHy&pMOC$*+wDD`T^=)ea2Az0Mltbc-@;2_ad?NwaT>#PdxW6vrN+AZmoMt2zo3ON( zIV7n9%>H^N`XvP{fE^vhX#{i-fqshK*Rc1KYV~|XKMIki*Sob~%8fXtA)glN3}I@r zX6u({VN5jMSVXDkCwnULC;)gT5P5;fMZzN!WfvxAnJiDJ?Q+oYnHL>h3IT%JU45W|GO(&q0p>nCXW^vcsXmq4^ zul~ggFWDn(3*DoxJSzYf^3Y${?;HL*McUThcDz}f2WO&~1}ZRtCl}26ko$+a%z9Xh z(T=!fI5Do?kVREUafx7()fd;g7B7*B+Rf^>fmsFLIRRv55FhdzcL`aC`mk z_BLKW&$E>E_f0t#Wzm`9kO#3vwlEP76K-$N*D)dh^!c`l{mI0?>*V56J-}%!QTPZr z2#6Ny_6RRffCA{x>2|8-bd;+ji1`-P3;*bp-?Y$EP%>X!5l+RafHQ%T`2wI% zw$2DHMofHcJ|Ilg(6=R?SP(Uv0}}<*O{bSFBh}Uf%sp6^7J`3_rfE60L4tLP)p%bV zq5%zc8022W-hkHPEweEh_3w+!PC~E4!pDcNyx(9@QKsPw(o&n%^<}5q=w~JiaoT1% zvDJc~5t z@D|P;xcSt34Zc|UQ&`xHXEfQLoA=nsh?fn<3l?x1{5g3TG&Ja#0>SL&vIQ}qbBSSW zl!Ij6CvtTaHe&-Uryq(89X+}AJk+ckoX-@3UWkUj83<=;-Th25S;QHA&~!ROY=)*{ z8Ww!;f6tA!)Djbu1SzSZ&}L-m`-KHVyo5AWEG$N4z`+Avk`qcn{LcA38tS{2>c@Lp zb;$?5NmHrcNJKjDz7g_on{Ki+pOHgO6(a{>^%=-_c@hk(td`>eKiccQtUT)3vIPEm zxQ~2RrAFz+xA8h?vDJv8eVKVNdfUfgq|A8hv1<~1=9OfH6nC^~YoI=42?HHPai8oM zSS0a);NM0TUz~}HshgS2o<_ArT7+TN81CYp>ulK-97*&70UMBCH=Rd07DKg+~V zW)oy|L19f+kQ%o1UU(5nwlOQ7@lTGA+j?#}l-Z{zn_L~XShnUNOI*-Kl|X!876G!$ z2I9=P9a=aq8cHGLfOmerNw-|#KGb!b1`_fSTy5*tcU7}~##8^bT)Y#_Fe(Yk*2%(C z;5&dyq(D9Ndjkk#Lj$X-I=G2Rir(?+~wwcYXmd z)dyqphPRJld2ZhUkmYLZG+7Ka3DNUDeNe<2(nWWlBMJ1*`?Vy^>J1`f11616y~Dmz z6Pv5sJND>92L?8}RmV5%9wi&&vR|Cg=rE91aQ8_lsJeKFr~lUq4khNe-Tf4?>PewU z+T*D9kl zSBmfqbjSAq( zxk`?zLoq~EKng~@wk{BTqh@VncgJL@T2hxwcceHk9>ch%gf8T+hCG=wh!PwkF0rXD zy7t?o@XbRFAUyP%R0K_chmQ|`%ThN*UJeW(d7XgPY-j^C+G(lWv{q$ZMQV4u`)29D zv_$KNzy|v-oJ(6ylzp~UBnoDaK)T3|yY z$M@z(IRCII!FWUv^T;=>o!z!YL_?I-L^S?{vxdCn(b68MQpFP6l9;>2J$2?j%#7S! zE`?{I?d#d*U zlH90AdXmJda1h9NQ!a;_gD^8@!SapRR*v?E?Kep!70a(#+1JY6qLLF!kTnSaUcpcV zE9%3*QR{jvQ@h{p(Mhyf=i4(z+gscLen8(mhQy#85~2;Opw~xLwn>8?)fP+08ReY}=DzM#b^i=fVk;V~XLXl0&YC2B4YD zrtVdpr>t5I7T=XXl59TZW7%!)AT0zbKm~j7JsyAeSe-5qEZjQ}ju*9J+q1G)H{bzA zPr_7$0L)LgoBF^}C@#35o${>rFQ_~wMwUS)goiB&)6d zsT9J(n&#_ELIhehFE8Fr(mUNvf||a%pvX}<31zNQy)EH8njAkKWNu)J7j+SKZ5Z*CjrdC>2Iy{rDkYqh57(JxraNx>XcE z_;v3n%5Ri{D#Z52PJ5!Y zVJ17*UDdHbfFL~ZN{sV&_^7V*!m;e7IVWi=AIW<;y-W>)l&QVPGQ9~eS@^fqx)+~_ zk*JrwTr!g^y!`UTPP?!7`L8f76o9Lo-9US z8zXXdOR>`@{e~Gdkm0{uxokX%Xovn0ExX2?{Vq6pJ)!l`*(>6|^-(isi6+wulgn zZau8}W_<4`2Jyx8ax))iUyIGM-pLITI8bw6V(4aXI`{zf#s@) z-O8P+J_F8*twCx=*r285-CxnH*RuifkSZSsksq$Tg;d+a*Xg&$RH)~{E@~oU9562f zxyZ*K#fKB2Lz^f|wykzPF59=G7(@9{AAAt``i)bPQbgmn9I+_t2n7vzfJj%QO&zSd zv|e5`3;HG9R3Dcbt8-BR*+Bd_3Qj-M(z3xGAqwK%>ioSaO*8MSK4<_9PY`GDwPCFA zJLn_va3{8O%G8wa33!4nS=SZ^`4MA78OR&c5`y(%V!pf&s}c;9Y!?quA|v08xhzvZ z=m8>U5JO{caWGP0ROqVD3by89wsf>*J>9`zt1q9=UJOvEiA=OYCuoQqgRRfARR)`& zM%~u0PKLsu#7o9HC^rVpp)-_tkW^1TPtYtt8f+&2))NeyZk(_Ei1{F|;$09A=ulG2 zR_q`S>x(-$?=E&5E=-_(; zun~)!)&G>c_|vG5CbgE&g1LeL9OUZlEcL#a8@Hf7Z;KidXn`Mx;bXdD5vRPeCYMK5 zb39fM3eOaOTNKQXuD{+?;lFZeQet#4+XnN0ts_`NS_zieoE1w4z*=3fM4sl&zqB^Av-h~ zLPdB{GruNj$)dm{a-)5~Xuxf;^|}W@8D^z3Iwcu)(xsIQ?n8_!`dsDdYl|u+1EN!A z!JpVaWL@B-P~}huZq$Jh2|6j0XD)q<08^1pd?KJ1K_(CyS_P z)A8)Y1&`z(UC4F=)=-2&2L`V8G@inwIS3*CgnIeHh3dq+9u~zK|2Lr$5d4boLv+S9 zit1_|D)(wnF0&|09pI%AUHmbnL5rHPmZ=YQ4Pt*vJxg$7V`cLKwS69V_cq`X`M6?I zQ11AvwpC^FUZ6OUf!t`;RFG(blpgh9CSjml`!g}6>1UZaFrXifOiH7*jw+MdaGTPQ zTYI50gl;{mqaDt$Zv-m(wpnd>zyOW;x6hQzg7WAPSIPm-vED(gvG_M>T*n zIhX3e9T1LQAQCF0-0<{u5d!-wR{DzwM1BUmL5C@kQyi&& zCBs230EJO4s91!@h=|zYTtw3Q6af@OESQrw=V(K~fX6jX6f>~BzwH3}3l!iznAii2u_5g0brV>W1YH1^^z$I*GvFDE zt4aO_gh34r z?ux`L137eHs$>Y1SOG-9_R1L3*5-~DuOnA$+I`@G&9cME_v!L^16tf?`w~P!n#UCk zjSstTKX9SHQ_5UjjV)*ZJ#+U`6#7{}NqK@q!9)!HA{qITtyXPosztjjoT0%j*OibVBe^+l;FR`T~{AJpz-T54W{}{I`eopv*Y}>zb z?-&*V7LN062Oh_S3ex`@(7z5Mo4dVaZ0Yv|eWBi8~Aw&!u{?A2iLPY-ze^Eg2q%oT$ z#QzUENQg8>SeS;DJ(#vLjE delta 12353 zcmZ9yWmH`;*Dbsc2PksTqQ%{XywXmL5Glu}A@iff^`7Po`DySux)-u6EC z{l@!z`^R3%Ofpw?l97x(vpNDmWiSv#T?vec2LLDlARZnCQA7CqHe`fi1b#ybosfC2 zQT0wEzae-gEi~7JW?p%$xs;2FE;X-j>^jYLxDM-mL~axMQZ1ikuV4ob8kjxbOp<)> zr2C4Sv8{VcDmyJ5X)};X@XA1M#C0AyoEalg!%e_eLDMdfs{F8yDh`*|sZPD;l}h6X z=^Ho6r-F7uyB7$nr=FqEaE0F&ptW+=U&HL`vK+Oh6RC1sXkOh6NMPr{)qqseB|F=; z5;lw^lK79s6n%cYQz>q2*%O@?(#bDYin~#=o%}hh$A26db)ur@?Y+pYJ1()DQyg8^ zw`^;2^&1IwtBG3^W*AX{SFw4%e7NCi6#Vk+p>I?#lHR&^vR0-GEwR^=)40u6AB6L- zAbP!|NdZ@a7#Gc?vFQ~EHksO--&*J*IdU?~_DZsWLO{$lwUi{?vTwgTClR8y;TxD# zFk7|NV*xXHe#Kk!d~D73YsXe$9=CR{9#w=Kk_4V!_=gX#fa4eb#5$yP7@e0kxh2Rj z_GN9XD)gLI-s@UuH?U%8!xl3pS#k-eC$he&W$h5j550!6457sj+vXJVXpgjXPx=?E zuv`7C#;gzyR6#10#d7q!-ojE>dVwHKpi2mn|S0pLILi-LmkcYb4Z5Xhm6disuQ z0(kz*#&3V=+Gw-%6(8bFyhih|gh`@QZVrCOsC7H&ahKmMH5M9i_=b>;sv8#fg8lnr z>hRU+n{>6>yQhul7^F1>Ztv8-R7(wpU_pqPV1sH{k?h^;OZY=KezNMHFN%?GnttRd zqtj;FQmbluFe?_$Pcx;DOKX8%Qap`t{CVbmbsu`P~${v~7>wDRHaVp3gKgROm zwFGtw@>h*6t3-o8Is<_o#!23!s7Oc_@;97c9Pb->_c;YSE2Q3P7cXB~g~Fq!$h5)e z-?uAfD+czimF!l{T=Li!`3^a!HBvsF^&5af7Ntx-&3j}S{h1qv-}L#xp*oHRwCT*v zH|;-2ewI$fRNTp%e>XU!Vc73aT6a@SWM$(-GlDZz6)%_ib?NM&ata_2oWJAX-yGB6 z=ZejD5%fr8G5W9s_Css@lHQrlJ zQ8GsxeHoBktzPC=)h61v3cWeQ?qalV$4HWN*+k1PcMmnFOtf}^%$tc&keu+DBZ88c z)j&9mnEqe5>)&*Di#z_HLQ3nbj5R!ozULafHwmhT4Rhl65|18}DUYhYluO7Vxd*)| zZ=LMyD85LXlkSD&sQHc};Nj9jaA6+;jtULm`{g@xk`xrnx^t*~f@0;pJTOC}-QzBY z&Iz$sdq0#FLnKTd5JY7~b1Njv7q4=nAHB}^wN<6d&z9cj5-b-i3aWyU(q7?02a5C#m6S5UfdudWE8#;E-TyX#0GvU(L8}15YPr2WvUrk~`>?5jIb@me% zw;VSPN2ensiog*KIhGg4{?3Tr<=5ZG-g^%NpDlzXNO;{AFrjn!OLy zl`@PZRf&R=1y^B)C^t#nKC^ z4SaomF1z^{lFclMQ+jz)S-Z7vn-)AO%k-QGmy@D)*og~`Us)QEN#MXZkv94H@oc8qQij~TFX#4Fn#5bF|`N9aU)$JYGm0hev2j0s67JF zFgywgRnK*De6E$aTerug)HeBkSgKnYYXjP)t=Zjv`=M8@BcJN$@P*%=JoK1~%g9-M z+J`w*q@b17Ap;?$n^twg@#8^pYByhIp!jRIacubK50c&vA2aY}O+V5^jrm$jWnD)z zCw?PfRaP&Do?EO+-|V9lAvl|@(lfImXM6`Nejfb1=8|2M5x*e~+i7r_(~}~|oMxXK z9hWuOMJKc`4U_)5WzzMTpW?10S@Q%#0X2sxf zn5lb=QLoLaczG-;=KTk!`Ww4fg3fG)A~U$t?bi*C<}~TPnA{+8YN!vniyR@?&IHmE zk(MfE3^|iAC7dG!*WVR?bDZ$;vopvKCF#6_dK&B|t=~?(!r#xC1w zaz9Gs-L7kAX4y=P*R@#2KnXM?_8Ii=2->os%hW~&06Y5sK7tft4p1ndF6#o(e#@om z)@D~>xUGd7AAK@?1eq<(3%o50Z7n^vvIFR;z8m7T(lPZOrO$LfHa|wIzzA_DncniP zusoXRi{mPjQ>$677h8Df$FitG z^Yg{WhSqdCm)z10tsWynOTsG(Gq1esmDX9-KA5`W`{<__Za(2FI2jnaP5x{$yJl7_ ze-M4;`{t#CQR;ew?@p&?T*FiYnZFhNLZhHOynW#r7opnPS3PCPRZS-<2M2n8cw6^7&kZy8DyDd z8-oA3dpnz>cS%V~x~_ zgfyl{-0X~e9pougp&=AwoZU833t~)1K2gRrs?~-WpGlLx1O{DK_D{=7f9~;S=iHKU zV@pATt33bZHGaTY@|IgYX)Gh?(mm>wvnc;agyD})IX`X#7a(20&$I9U^lpyW8>eQQ zNmV{+n!}oR0ky?2^i`HhQ`j9-=#+NmJ`akZj0Bl0<|kweXy&1m@6F=RbJbj-t#>;K zp?kxIZGlNmD;r4i=^BYisu_jkWbf-s{Psf*)-pV?kYG3Ltv2$7jlqWQomC^g`Z!+V zG1+1cl`U`bvE}exCnF|iAyjjGU&0~CO3{T~la0elH6HCrS+a@&u``+CI{tBqUhknd zcV4RdJbP!Y(EL~r+d#pti<}TUH1hr}w^p<@l8>9WI_PB-ANa-ap7Pn#@Y3^_rpF_w z1cZ=}H+~R;m0&OPrCWK9OLL$1=xFcxB}y1mRBLnc8>_px0FY*UbTOeTu0q273gpV@ zRrwM>Mae6kx>vtR@O{xX{kxjIq06aVMO574*$1Ni(9^58g4wi?nL~Q9bvU7qU2U0h z1N(07)cF@enVPg`zu>sogP5J0DEl^Fl+etT80+iAh3J$|JDTtF8tjL%@CIIemn!NQ(-`fep#f)4j9F~{wvZ3G)3if=PH@leP3>I?*uSqptrC zx&oA2?stTVky@1KxX`G9LGV_>s|`r?5XzRMyA)Or#u9l#e>0+kfBb%lGk3MPLK})ztW)e5*a7b$S~p@Oxz?QYxz*VMgAESswG!!+7+hl^?s%{g(?YTb^*i>$K-%*90@=HBmar?GO za7F2%O@M9WJ@$T8x@2G&*(LD@%^iGYY{ly2-Qyq+%@SuY5+|IpJ*iKSEzxiKT(B0m z@y4)vN{et+Yp8Mr;}<=fk&PDb&EaE}49iKm@D=7B|GRjeWz<7%qxv8R4Q4I3-q)b0=1 zl0S<2{6RRtB}i^w8hW=gXzLj}>y1*a9-!DwyXZaoCsz1!tw_gGUtN53h&{{q<%^c4 zgFD<@;l)Yn1D6bu0?)z0Fy<@qTY9<%=w%M2$`irIUk{=<7Bg_4xE!sBxUbC;ysx7h z-)b+0Luc&Qkv=6lD20)kB)&EjkSW~4+_cM|V=-hHa;4O!oK868vJTK-De)o(mTUTU z8I{sAquJ83b$bm|b^BRHM~(x5@xYS8uoJ`QK2C{by(YQz`X=Kna-5(yOY|hAP*1Po z_i1a49fje9GFOJj`AQiFf4Y}^K!ugEC+z02?}{rd#&{ek#;bm{yFJXEc~(~K_JF5I z)_sy%;Ml#BYe0;*~8or)8P! z(u+EOY+?VncO2*{_~!kF4?0yk%2M@b3is=1*HU~~n7?veSe153DBo44J*4Cp za;56-(*cb`h6|S+pWdo|S=&@JL$5Xp{$yb2kiSvXWEkHxrE8 z;;yXxnxih>zixRc`qfeldkjBG|C31j=0uDU?8_+%X$#Bk2qW@YD?W-N7L~>;No&hS zg+SKtC~Ql#lGQwcp^2CDI4-}bESeO24ZLm|-=-PKOZ9kX3B!K|kIZk_)N8%RmA=}i z-jj7Bwj1_QdthR5P;fGaGD0J+>TW+5FaLV+fXCt$GLzyjdnvhi@4d+(M3ZM=oIE-a ziWcW)T);c^A^C|NEMqO3u;Q+C(39c4%2v~u!0y;MFZ4wg*dv`5&S2$0VpS3P(d;bsf$Qvkbh#tXW&TV29WJPI!xPIy`@KrP zhve6S>zEYlNr7?Z2`DR`nZ^3=l0K%mj@k$+-c`9;7UEF<#(Ak)?NJB+jCW}f4X3t|gPc%dPGNRoyW2bCs4@ei)UV5)bY!<)4r|)jQ z+enWwo}sDg$@3Ky3>xiJlI7sgecW*UrZ*A5csbJ@AOw~sRqYT6(R3`CN+{ruR2Vc> z4iTW2iRaGmtlra9wk4{d>;A38q}&I2j8$iPRP!$^oH*ZQJb?DN(M-cNOJ0Uj{5dy6 zEa$dY?XvC>4mvC{wYPGyw-Tjv5bku#IibW_7ktGQrkNYKr!&O!dZ#C&^qWL+qF1;$ zOH}tsu1KiZ$8fR3^9NlB7ccRIX>!#5zsRgcPEOqT8k?=lNUUSL8^b^6|8i8yrs68f*)3GMrIgJnU!mFKtw-5a%1EQ_t~O!HA<#M(~R9x5$zPQ1LkcW9tluqf#)^I35Waz2Rl>@FmpNT6#u~UEPowMyKFSN zK&+*ua+Bt%>rR=Ekjj0Kn~G);h;@-)GRp4SoZiJ2DP0&O(*X;1lMhR|}1z zX&OhTdR@2XR@ts6DOr!xc>pS9w@0JF(R?w%%q4TO&-0t|)IO5hZ>!Rbo7TkEC@|j* z)nyCk&2OPfAw8#S_!cX`YyQjQGjb>FWNlZ%?gUD``2{(|_d-!=A#wb*kyNmgU7`kO zb%SND;XD}NGe9dt=U+^4XQ-s#j{rM~y!7Ds*15<|=+OXPJK|m!lpoCVijHRUV*9e? zfa6t2+`_7l+>4e8^~lppZI_w7(Ye4iSE zN2*61xzgw5d-*(wb>l4N>Oz45GG-8eK@}9s4&n)m= zMK8o|iwovqQD%8UjMg_kL`(^ry4h3-j-Q^Xl<`{{yOT#EPULKP`t+V(La(l_|5`51 zNJAtdgRGFI8mw#PBD%9F8VbW<^Au< z6C1xunb@h`W^82R7pmj&LLY|&-us92a|330W!N)SaLy5&u0nF2JHC@0tPV$iiEWSO zPiJZ420>OrYfp+c9oHbqUr|>Ug$1;uY~X3EKE}!GXy07QkFRu(or@R}pbY!7{Zn3Y z?{pkjK9dEDF}=hPU_NKv*UjNXql>tFVuc=Oz;pJ*P76`qyPEe(>uV@G;lkT?w5DkAN6wfwqM$#$q6^;rx@KpHx5WxGplL}L~C^@Se zAhNi*oC6?)GdBvuRY?Xu}WU!vc-*TIH^Q)_--=%*0#D14_n51w&Jt@?LdNH zkiaGzNJC#VC)^Z0;g$FGTa(I%#QR-IQq4$M{<#x+4Pnp>MQU1Aq59Ln!OR)UN4dqW zqtL9QYZk&cwzT!hIa#8+j%kw`H4kBk()W*pUvNG+1WQ3Leo}a=O3(YtBV<1M@B9iT z_zPZC{>7A43e9&X&A}JwSUtqJ8T!?*{Mo_ZIi~}#YO;nv)w$ytia7=J<{`JS@$g4o zjONW5I+K5({msDgc@T7L6|3W7U?z?01Yqb$UkMzdSVi>Ruf$Zxm%FxSZ;yXde|>Ex zwG0)gXVBOBuulZ1MA^0fPU!d61zltDU9Zda4h0QIj7S)ts&w;+N_f?eml97{dY4dNJ%Bh-hgOqFz4p;T|+)+ppK(#%<`U*w3n`tbvlqiU8BYF*Q z&m~AX{)UqX!X{D!22v~9`GIcc@M3lMeNfP=5!2r-E#EN{8Q^88*)kn;ia_gD97 zXo7^y4QmQ0nrt-qIbG0miW|1s1t#AJB?k{o3J7f~dq zj`>c8`wvMa6ZmJQ$%Ouye+3lcXffjCDF4awV2Xz;s8V_Czqi5#04v;>P;yBqfx5D$ zjIgknwqlzv=&r#V{L;Ay@TVu!*hcpLtP^agQH^unt*TLUvYBhcy9@wtuBh24e4)!F5prIn@W^{uIugT>YL`L)C4t&@eL>!stz z)#>4l>9MuB$wL ze$6mhwT9heQXNbVwaALAo}t%q=$P~sAi7a?$qPL=-Z;10_saV4T1uYs7)vplhnK9L zNnvjlSXnf_G~|BFI$!SB=iqLa&$zN~dejqI16DL1y`kT+yE^O>sm4|>T}*8>0hsar z^u0!>c#Cz908T*T9Pq}g2k`9GQ?|-xCu*|o{D6NMGY%zC?cfG1h$8@S^-FA3{(JIl z=vC2UK_YP%`cFo4t*c7s4p7gUX7%$2#pkWF;Z_h)Bw&j2dt_`hPJB1hqS8cw=;=EN z_<#eBa8ldHXICj{E0+SAe10P)p0}$`iCep9uhe44Ue*L*A6CE(A#(=EE0Vx~D5`vM zdgPQzBL>Ikf+isZBNGx+%>=lTMP&@sy_H=AC)t`@9Dyz*iDm_<+#-?48PlO2lu>S_ ze1echr|!l>BL@Mx;6Q*{ncL5SDB)d-Vc7D6Fe`8I%T{t?lk9fK#9gPSJO!Wz|Ecd5 zm)^6`zOn9PPt5HnM^M9@L(Jjp)M~nx(fX3_Dw8DqfikD|yYDe8D5)`2{b!)-2WPTt z>z%e(V0%9CR&~`N!UkOHhaSY#%YXQm!+1|gS4nS=5>0U>pTCX`w;4i4BSq{BC^Lw-kQ4H?*J?8pB;wX(?$fd zKUmgiMzdj?X>wZP?S@sfGC^s)lcFV8cgrd>-W#t+O=t!eG6<8EZ{qPs2!lCOq)se9 z^E;`G z6HjD&5BugVw%|Zf_-Qxp)FFh?;&59~4BT?>#BTN=4y^X!!~rfq1{Rocl;j6CgFU22 z0>ujFXFnM#r;kQN5u$^|YrQV}<67WEm48ildT`Zw2v9tPQ2y50%K5GFIC614w39^% za+nLF*k27z4WfhwWw^cyLexg3LDK0FJDhxAcT>C^A{iT ziGY4CO+S!~_~f!#+GYc!q5HyO=RGm$?8uORJJ67TE1~+LyS4I^D$W|gh!`AB&2r0= z-SF*#Izj?DRfOFL$8NL5an8Rk0OrqUDBLaD*!iDQ(wIO;NM~S>daK#(9Zu+VxlwFb8?WMm$|Kk5c#`S2D0Sc}MN zBLq?^uk{ju@8l_2^;F9ZW)gl-jS=}FKX|;RX9x?C5W;q8e`_IbDErF-jcS3^3-Csk zLqbg<@csH0OL)@%%~dwEbRChB$O@m7-=G!x{#in2w262}_ox}=imllRH80joH5l<; zK12UwuAU!pwgv5nKe4ZEI`I9G?~KT7S~|h@6hNZ(o&RFNMsbnHed)ZneQf<9zH`~S zY|XmWmg;~v3fx5ANGx?$?-vTIc5xA>9BXw^(fO*Ki ze@UhWR}MEdtw(2W*fAN8^Lp*R&QPPIRcx^k|0O-ULM|Vy(LWw_q?hl=#nVD`e&GK6om$Zk0X# zu)aT4FnQqNm&@R1zTC+8vm>u*nuY05Ww{x-Y1vEe{$hD3mH1o@(f=bmzjibC)73)4 z^6@#`(!IaQ^`+=?0dckyFt&W|*S|w{zok_nv`K-Uatc4qGDd->kA#2~Ysz~OUCjV( zl((Ernq&(msQ8?x7T{O!H~9&0Bu5e?1~_Eh$W;eAR%0``@@Gg9$H;Gn6u0BNf!d(9 zn1$h_Fm7>`&ZU%y?#MTUUSE&#RXcF8TX#JNcAn&;{CYhp&5GbHST|xDEDutW*k_l7 zpZsLLr%E{ou1!HPc}c*WwaK;`EnPr%LJy7=jZTojj}t?l9&~Il3?rIlE9AOIL{b?j zmq}qUi>BKukHQq9!<&{5KVch8+@8J}#XG`3J{8$;@pWVoY|y5hH7gP4q>{mGL0cxH zzaE$jd&AniqSVNugce8yL`q`nI})ql19|Hqr~ZSVLC~+%)I*bZ!ZNh?z;=BVMZ7?Z zNy}WWITYXho!^6#eYX)FoSUo``$T5@5O;)uy3KaMI0E&T#`+UOHQe^DVLVmbFPY={ zaKTUi+K2F3V!;f?DpxxayXB8;5{j0`9rozUUwGGDqvRYJ`PMZOgOe`Oln<{kn_=J& z>yWoS49e?K?}Mi0T(JbVZCI?rAZcN%E%u4vvI52~5g6of91pBo5coeM#*-3_47}$W z%64+iAmpTtL{<55IkcCwahyn@PJFF$lZ}ol1e|TAlqKEqqoQ=!6e)@e^Qe3trv~PH zo<9C*U>vOFgmEdN&=j|Hb-@JNe@<1W(5e@YLqkTDbllWQM|8}qS&aM!yon;+S(&XH zifqhbA1k{2?u~Bf972HKKJ}OE65c@Gz@oGXPRGkZBV<-*5|T~JiBV+fEY4ROi=)!U z94+k!UA88Ac&@xGNQ6FgFj62mhy#7xYO+~5D4H64;4}G?<((EHC1L|5APF@b~GqJSKJkB@vN(^IJgC}wl8 z#jTQ5F`prbx`HOi>8|E^e+8+Q#H}BRZpcQVQI&f} zEl+=J5XQo!ibw*sAJoPwYvguS{=^`rH#qnw0yLf zm^T`geEVbTyKTsyhrpFV4Cqv}I2LfZxrWS?8?qU|^`_Snk?B+Z3twP}cswOLNJAnp zry4#1Rz~e%q!0C;bb0;L$^ucL^zW7LW#eK9I5JdRTH;Wifj|aZHu)o}^h@>Kfrix^ z+O=NKIy>;+1w(WxBFDiQ3}VNpa)fZwl@&PM#v&pUjS9%>PMsp?Lq}244v{po@Fk-| zt1ZW~Jy3@S<*UuXp0CuYQeP#>qBkbjA+&JrCBgiGU?UiFHW)PW0mk)uLZ_lsZ(dA7 z5+p7O|CVbC21#@VI((ADdIL1Zqxq{c&Iti!{nLE7G=hj=O%LRYD$vd3kJuZCpFB)x$7kE@=lF}ZL$z>hEs#MOyZHLFc}HKWwjmh6+0kM+ zAI$i9u;2?KX&3XN9M=oX(A`7gpIzf2mxrfYr933sm;m&kbDNC1^$A#@z=V0D_2n(R zfR*j*euaZMUH2~3#6-mW@6-;}oEsC91PZk6zP9mb?IW#VZK1uN|Kj*pllLs?>%JGK`d~>u`EP)mcjK_DC`!U^3y0iNKIp)@*8M+!K{)fV=wei zkh;VvbImXT9+>L~sM4VSop4PA5tU=VV63`(!Ns0oh0mJ*g(A50j{V&}1%4FYku-rm1boVOC0}yL&)4#${3&LE+DOE)@`t)oF1^g$ z6s!riF17b+h)>W)9USNk2ZJ@8kx#LK1g4Htla|l48KTOW0`$f=j~hk+xM=U5f361O zybmTAq)!yH)x+Ild!v*Zp9T{D_O!Ws;=15Gee2VZo^hq?leBhf0#mO%afgaY3>x8! zsX{2pyOHGAMnDOPdyhk#pP{tEMTp*dTbzI=*I~zV1Ww4`A8n53`GxQCEeg+$t|kZB zh(?Ml*@Ob4xSqFIgvQ>VV=!RP6K|1Mjvx1#;4j+l9{(x`fP##wbcv)%!2b?UR#5#{ z@}H;Tjw=TBuRK)|A>;=7CsQGd@SyyYss6<_$4H8>WBkkfe^F*Jej;qT|B(MJm!ba; z+5fc*e?#2O9UVS>aQMXT`O#io350+L-~s=MjQ)>ng#Xuo;lCOZlg4iJuL-GG2#aqQm5r#Npmc@zwxx4+Fa} Math.round(v), + set: (v) => Math.round(v), + required: true, + }, + singleMinFps: { + type: Number, + get: (v) => Math.round(v), + set: (v) => Math.round(v), + required: true, + }, avgFps: [{ type: Number, get: (v) => Math.round(v), @@ -27,7 +39,7 @@ const LogServerFpsSchema = new Schema({ }], }, { collection: 'logServerFps', - versionKey: false + versionKey: false, }); // optional more indices LogServerFpsSchema.index({war: 1}); diff --git a/server/models/logs/transport.js b/server/models/logs/transport.js index ccf4d89..6bddc4d 100644 --- a/server/models/logs/transport.js +++ b/server/models/logs/transport.js @@ -34,7 +34,7 @@ const LogTransportSchema = new Schema({ }, }, { collection: 'logTransport', - versionKey: false + versionKey: false, }); // optional more indices LogTransportSchema.index({war: 1, driver: 1}); diff --git a/server/models/logs/vehicle.js b/server/models/logs/vehicle.js index c898cfa..d796636 100644 --- a/server/models/logs/vehicle.js +++ b/server/models/logs/vehicle.js @@ -41,7 +41,7 @@ const LogVehicleKillSchema = new Schema({ }, }, { collection: 'logVehicle', - versionKey: false + versionKey: false, }); // optional more indices LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1}); diff --git a/server/models/player.js b/server/models/player.js index a407a8a..85bd6f3 100644 --- a/server/models/player.js +++ b/server/models/player.js @@ -82,6 +82,11 @@ const PlayerSchema = new Schema({ get: (v) => Math.round(v), set: (v) => Math.round(v), }, + performance: { + type: mongoose.Schema.Types.ObjectId, + ref: 'LogServerFpsSchema', + required: true, + }, }, { collection: 'player', timestamps: {createdAt: 'timestamp'}, diff --git a/server/routes/wars.js b/server/routes/wars.js index 9bb1fac..62984b4 100644 --- a/server/routes/wars.js +++ b/server/routes/wars.js @@ -34,6 +34,7 @@ const LogFlagModel = require('../models/logs/flag'); const LogBudgetModel = require('../models/logs/budget'); const LogPointsModel = require('../models/logs/points'); const LogPlayerCountModel = require('../models/logs/player-count'); +const LogServerFpsModel = require('../models/logs/server-fps'); // util const genericPatch = require('./_generic').genericPatch; @@ -59,25 +60,20 @@ wars.route('/') }) .post(apiAuthenticationMiddleware, checkMT, upload.single('log'), (req, res, next) => { - const body = req.body; - const warBody = new WarModel(body); + const body = req.body; + const warBody = new WarModel(body); - if (req.file) { - fs.readFile(req.file.buffer, (file, err) => { - if (err) { - return next(err); - } - const lineArray = file.toString().split('\n'); - const statsResult = parseWarLog(lineArray, warBody); - statsResult.war.save((err, war) => { + if (req.file) { + fs.readFile(req.file.buffer, (file, err) => { if (err) { return next(err); } - PlayerModel.create(statsResult.players, (err) => { + const lineArray = file.toString().split('\n'); + const statsResult = parseWarLog(lineArray, warBody); + statsResult.war.save((err, war) => { if (err) { return next(err); } - LogKillModel.create(statsResult.kills, () => { LogVehicleKillModel.create(statsResult.vehicles, () => { LogRespawnModel.create(statsResult.respawn, () => { @@ -87,27 +83,43 @@ wars.route('/') LogTransportModel.create(statsResult.transport, () => { LogPlayerCountModel.create(statsResult.playerCount, () => { LogPointsModel.create(statsResult.points, () => { - const folderName = resourceLocation.concat(war._id); - mkdirp(folderName, (err) => { - if (err) return next(err); - - // save clean log file - const cleanFile = fs.createWriteStream(folderName + '/clean.log'); - statsResult.clean.forEach((cleanLine) => { - cleanFile.write(cleanLine + '\n\n'); + LogServerFpsModel.create(statsResult.serverFps, (err, serverPerformanceEntries) => { + serverPerformanceEntries.forEach((entry) => { + const idx = statsResult.players + .findIndex((player) => player.name === entry.entityName); + if (idx !== -1) { + const player = statsResult.players[idx]; + player['performance'] = entry._id; + statsResult.players[idx] = player; + } }); - cleanFile.end(); + PlayerModel.create(statsResult.players, (err) => { + if (err) { + return next(err); + } + const folderName = resourceLocation.concat(war._id); + mkdirp(folderName, (err) => { + if (err) return next(err); - // save raw log file - const rawFile = fs.createWriteStream(folderName + '/war.log'); - lineArray.forEach((rawLine) => { - rawFile.write(rawLine + '\n'); + // save clean log file + const cleanFile = fs.createWriteStream(folderName + '/clean.log'); + statsResult.clean.forEach((cleanLine) => { + cleanFile.write(cleanLine + '\n\n'); + }); + cleanFile.end(); + + // save raw log file + const rawFile = fs.createWriteStream(folderName + '/war.log'); + lineArray.forEach((rawLine) => { + rawFile.write(rawLine + '\n'); + }); + rawFile.end(); + + res.status(codes.created); + res.locals.items = war; + next(); + }); }); - rawFile.end(); - - res.status(codes.created); - res.locals.items = war; - next(); }); }); }); @@ -120,13 +132,13 @@ wars.route('/') }); }); }); - }); - } else { - const err = new Error('no Logfile provided'); - err.status = codes.wrongmediasend; - next(err); + } else { + const err = new Error('no Logfile provided'); + err.status = codes.wrongmediasend; + next(err); + } } - }) + ) .all( routerHandling.httpMethodNotAllowed diff --git a/server/tools/log-parse-tool.js b/server/tools/log-parse-tool.js index bdaaf63..e51ae68 100644 --- a/server/tools/log-parse-tool.js +++ b/server/tools/log-parse-tool.js @@ -27,7 +27,15 @@ const bluforPlayerCountRegex = /NATO\s(\d*)/; const opforPlayerCountRegex = /CSAT\s(\d*)/; -const timestampRegex= /LOG:\s(\d*:\d*:\d*)\s---/; +const timestampRegex = /LOG:\s(\d*:\d*:\d*)\s---/; + +const singleMinFpsRegex = /Single min\. FPS for (.*):\s(\d*.\d*)"/; // group1 = entity name, group2 = value + +const singleAvgFpsRegex = /Single avg\. FPS for (.*):\s(\d*.\d*)"/; // group1 = entity name, group2 = value + +const minFpsRegex = /Min\. FPS for (.*):\s\[(.*)\]"/; // group1 = entity name, group2 = comma separated values + +const avgFpsRegex = /Avg\. FPS for (.*):\s\[(.*)\]"/; // group1 = entity name, group2 = comma separated values const parseWarLog = (lineArray, war) => { let flagBlufor = true; @@ -48,6 +56,7 @@ const parseWarLog = (lineArray, war) => { transport: [], players: [], playerCount: [], + serverFps: [], }; const VEHICLE_BLACKLIST = [ @@ -265,6 +274,43 @@ const parseWarLog = (lineArray, war) => { countBlufor: countBlufor, countOpfor: countOpfor, }); + } else if (line.includes('(FPS)')) { + stats.clean.push(line); + + const updateServerFpsLogEntry = (entityName, addKey, addValue) => { + const idx = stats.serverFps.findIndex((entry) => entry.entityName === entityName); + if (idx === -1) { + stats.serverFps.push({ + war: war.id, + entityName: entityName, + [addKey]: addValue, + }); + return; + } + const entity = stats.serverFps[idx]; + entity[addKey] = addValue; + stats.serverFps[idx] = entity; + }; + + const singleMinMatch = singleMinFpsRegex.exec(line); + if (singleMinMatch) { + updateServerFpsLogEntry(singleMinMatch[1], 'singleMinFps', singleMinMatch[2]); + } else { + const singleAvgMatch = singleAvgFpsRegex.exec(line); + if (singleAvgMatch) { + updateServerFpsLogEntry(singleAvgMatch[1], 'singleAvgFps', singleAvgMatch[2]); + } else { + const minCollectionMatch = minFpsRegex.exec(line); + if (minCollectionMatch) { + updateServerFpsLogEntry(minCollectionMatch[1], 'minFps', minCollectionMatch[2].split(',')); + } else { + const avgCollectionMatch = avgFpsRegex.exec(line); + if (avgCollectionMatch) { + updateServerFpsLogEntry(avgCollectionMatch[1], 'avgFps', avgCollectionMatch[2].split(',')); + } + } + } + } } else if (line.includes('(Fraktionsuebersicht)') || line.includes('Fraktionsübersicht')) { /** * PLAYERS