From 1e08f6035eaca6e4e788e4b6a270938793d9a20e Mon Sep 17 00:00:00 2001 From: JAJames Date: Mon, 1 Feb 2016 23:53:34 -0500 Subject: [PATCH] * Added full support for multiple ladder databases. * Removed ladder database from RenX.Ladder * Added ladder databases: All-Time, Yearly, Monthly, Weekly, Daily * Search/database input objects are now generated in RenX.Ladder.Web * "gameover" IRC Command now accepts "stop" as a parameter for cancelling delayed gameovers --- Jupiter | 2 +- Jupiter Bot.sln | 53 +++++- Release/Bot.lib | Bin 24762 -> 24762 bytes Release/Plugins/RenX.Core.lib | Bin 188612 -> 190556 bytes RenX.Commands/RenX_Commands.cpp | 25 ++- RenX.Core/RenX_LadderDatabase.cpp | 70 ++++++-- RenX.Core/RenX_LadderDatabase.h | 71 +++++--- RenX.Core/RenX_Server.h | 7 + RenX.Core/RenX_Tags.h | 2 +- .../RenX.Ladder.All-Time.vcxproj | 85 +++++++++ .../RenX.Ladder.All-Time.vcxproj.filters | 38 +++++ RenX.Ladder.All-Time/RenX_Ladder_All_Time.cpp | 42 +++++ RenX.Ladder.All-Time/RenX_Ladder_All_Time.h | 38 +++++ RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj | 85 +++++++++ .../RenX.Ladder.Daily.vcxproj.filters | 38 +++++ RenX.Ladder.Daily/RenX_Ladder_Daily.cpp | 54 ++++++ RenX.Ladder.Daily/RenX_Ladder_Daily.h | 42 +++++ .../RenX.Ladder.Monthly.vcxproj | 85 +++++++++ .../RenX.Ladder.Monthly.vcxproj.filters | 38 +++++ RenX.Ladder.Monthly/RenX_Ladder_Monthly.cpp | 54 ++++++ RenX.Ladder.Monthly/RenX_Ladder_Monthly.h | 42 +++++ RenX.Ladder.Web/RenX_Ladder_Web.cpp | 161 ++++++++++++++---- RenX.Ladder.Web/RenX_Ladder_Web.h | 8 +- RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj | 85 +++++++++ .../RenX.Ladder.Weekly.vcxproj.filters | 38 +++++ RenX.Ladder.Weekly/RenX_Ladder_Weekly.cpp | 55 ++++++ RenX.Ladder.Weekly/RenX_Ladder_Weekly.h | 43 +++++ RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj | 85 +++++++++ .../RenX.Ladder.Yearly.vcxproj.filters | 38 +++++ RenX.Ladder.Yearly/RenX_Ladder_Yearly.cpp | 54 ++++++ RenX.Ladder.Yearly/RenX_Ladder_Yearly.h | 42 +++++ RenX.Ladder/RenX_Ladder.cpp | 13 +- RenX.Ladder/RenX_Ladder.h | 4 +- 33 files changed, 1402 insertions(+), 95 deletions(-) create mode 100644 RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj create mode 100644 RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj.filters create mode 100644 RenX.Ladder.All-Time/RenX_Ladder_All_Time.cpp create mode 100644 RenX.Ladder.All-Time/RenX_Ladder_All_Time.h create mode 100644 RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj create mode 100644 RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj.filters create mode 100644 RenX.Ladder.Daily/RenX_Ladder_Daily.cpp create mode 100644 RenX.Ladder.Daily/RenX_Ladder_Daily.h create mode 100644 RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj create mode 100644 RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj.filters create mode 100644 RenX.Ladder.Monthly/RenX_Ladder_Monthly.cpp create mode 100644 RenX.Ladder.Monthly/RenX_Ladder_Monthly.h create mode 100644 RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj create mode 100644 RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj.filters create mode 100644 RenX.Ladder.Weekly/RenX_Ladder_Weekly.cpp create mode 100644 RenX.Ladder.Weekly/RenX_Ladder_Weekly.h create mode 100644 RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj create mode 100644 RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj.filters create mode 100644 RenX.Ladder.Yearly/RenX_Ladder_Yearly.cpp create mode 100644 RenX.Ladder.Yearly/RenX_Ladder_Yearly.h diff --git a/Jupiter b/Jupiter index 0fba343..1df5bee 160000 --- a/Jupiter +++ b/Jupiter @@ -1 +1 @@ -Subproject commit 0fba343102afa3d397e613c85ca451d0085522f8 +Subproject commit 1df5bee1d49817471d9151b019dd244a610069eb diff --git a/Jupiter Bot.sln b/Jupiter Bot.sln index 32a6ffc..ad75497 100644 --- a/Jupiter Bot.sln +++ b/Jupiter Bot.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bot", "Bot\Bot.vcxproj", "{C188871B-5F32-4946-B301-24CA2EBB275D}" EndProject @@ -178,7 +178,36 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Ladder.Web", "RenX.Lad {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D} {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} {BB048D6F-F001-4E9B-95F4-886081E0807A} = {BB048D6F-F001-4E9B-95F4-886081E0807A} - {B2846BD6-2332-4DA6-A13B-113318F76D5E} = {B2846BD6-2332-4DA6-A13B-113318F76D5E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Ladder.All-Time", "RenX.Ladder.All-Time\RenX.Ladder.All-Time.vcxproj", "{24B039D0-5A71-4F76-8908-BAD772FDBE1A}" + ProjectSection(ProjectDependencies) = postProject + {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D} + {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Ladder.Monthly", "RenX.Ladder.Monthly\RenX.Ladder.Monthly.vcxproj", "{34FDE301-A29D-44ED-8ECC-15693F137DE2}" + ProjectSection(ProjectDependencies) = postProject + {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D} + {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Ladder.Yearly", "RenX.Ladder.Yearly\RenX.Ladder.Yearly.vcxproj", "{075AF69B-71D6-43B9-B102-4649CB2CA40C}" + ProjectSection(ProjectDependencies) = postProject + {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D} + {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Ladder.Weekly", "RenX.Ladder.Weekly\RenX.Ladder.Weekly.vcxproj", "{6F0141F3-CF64-47D9-8EC2-80A38FAFDAC7}" + ProjectSection(ProjectDependencies) = postProject + {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D} + {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Ladder.Daily", "RenX.Ladder.Daily\RenX.Ladder.Daily.vcxproj", "{73F0EEF6-CE5E-46EB-80B4-2B319AE2B258}" + ProjectSection(ProjectDependencies) = postProject + {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D} + {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} EndProjectSection EndProject Global @@ -311,6 +340,26 @@ Global {57661A2A-EE94-4E9C-B792-AB756533DEFA}.Debug|Win32.Build.0 = Debug|Win32 {57661A2A-EE94-4E9C-B792-AB756533DEFA}.Release|Win32.ActiveCfg = Release|Win32 {57661A2A-EE94-4E9C-B792-AB756533DEFA}.Release|Win32.Build.0 = Release|Win32 + {24B039D0-5A71-4F76-8908-BAD772FDBE1A}.Debug|Win32.ActiveCfg = Debug|Win32 + {24B039D0-5A71-4F76-8908-BAD772FDBE1A}.Debug|Win32.Build.0 = Debug|Win32 + {24B039D0-5A71-4F76-8908-BAD772FDBE1A}.Release|Win32.ActiveCfg = Release|Win32 + {24B039D0-5A71-4F76-8908-BAD772FDBE1A}.Release|Win32.Build.0 = Release|Win32 + {34FDE301-A29D-44ED-8ECC-15693F137DE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {34FDE301-A29D-44ED-8ECC-15693F137DE2}.Debug|Win32.Build.0 = Debug|Win32 + {34FDE301-A29D-44ED-8ECC-15693F137DE2}.Release|Win32.ActiveCfg = Release|Win32 + {34FDE301-A29D-44ED-8ECC-15693F137DE2}.Release|Win32.Build.0 = Release|Win32 + {075AF69B-71D6-43B9-B102-4649CB2CA40C}.Debug|Win32.ActiveCfg = Debug|Win32 + {075AF69B-71D6-43B9-B102-4649CB2CA40C}.Debug|Win32.Build.0 = Debug|Win32 + {075AF69B-71D6-43B9-B102-4649CB2CA40C}.Release|Win32.ActiveCfg = Release|Win32 + {075AF69B-71D6-43B9-B102-4649CB2CA40C}.Release|Win32.Build.0 = Release|Win32 + {6F0141F3-CF64-47D9-8EC2-80A38FAFDAC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {6F0141F3-CF64-47D9-8EC2-80A38FAFDAC7}.Debug|Win32.Build.0 = Debug|Win32 + {6F0141F3-CF64-47D9-8EC2-80A38FAFDAC7}.Release|Win32.ActiveCfg = Release|Win32 + {6F0141F3-CF64-47D9-8EC2-80A38FAFDAC7}.Release|Win32.Build.0 = Release|Win32 + {73F0EEF6-CE5E-46EB-80B4-2B319AE2B258}.Debug|Win32.ActiveCfg = Debug|Win32 + {73F0EEF6-CE5E-46EB-80B4-2B319AE2B258}.Debug|Win32.Build.0 = Debug|Win32 + {73F0EEF6-CE5E-46EB-80B4-2B319AE2B258}.Release|Win32.ActiveCfg = Release|Win32 + {73F0EEF6-CE5E-46EB-80B4-2B319AE2B258}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Release/Bot.lib b/Release/Bot.lib index 8016e2f30f9c6a163e2f99347094c8e515b42e2a..42759c56965bbba946aeb98c6d607282e3ee3ec2 100644 GIT binary patch delta 1756 zcmZuxJxo(!6m10*g$Po>M=C!R5DdmbK(W-)J_?1>meNA`k(QPS(Zvu4VjLKVAr7cW zZk&uU3{D22VIU##rz3+QjwU9=!8kaGgK;oX@AvL^;llt6obTLo@3}v3Gh^P&m>-|X zX};3f)SR|WTj?*b^=a!X*1PiGCEICBOKWQt{iIF=%~__K#cS)a)^BDCKnBDeg;@ff zc4R5&qc%d9+pH3WjI%)y;k&a-rb`DJ@(>w1YciS4rfm38uE7I6560VzC4*x=UR7cY zm59r|$I)QLWyu#x)u@z>zhEw~z>cd{p*-;tr2;8AL@9+uJ@-I14HnxihW?9omkh?H zz+Z`$xJMOq!A;y{cT7QtM+rUe8Ib6lhn%l^W+l?36OzUs%v^-fXrl1+oR zy|h8~=&Vv~(5b>I_|wb1*L@na1}H8RNXo1{k)42SnNV^Di53ZRDcr~HpzPz4tqd-Q zii{BjLSgoRySNdO6)Pxt4fjP9-s?U~p|}YLmRpDAx+f+lAu@IeW}_vNW{y!{B78$4 z!u)EK68s8F^Dxm*yv6?O3a=nyF(w_r1PwUpOlc=njOHr(pOX}qiSTxaW8$-MMfq%G zR^x=bQSBmLC_F#r26sO%&T_mAdIqQ;iGlkE%Q!B4iZU8uJ5~*zL63aL0*to{_|{~+ zeHyHiZ*1NkWAi+Otr(X(=h47EL^h+S(SkPL)CABbPhFHg(M1jWI>bsMu3&`Fx#8O~ zql(s!9ENV~p`uazCAl@Kd`XO!C$W|`tR=r_1ZJY#BT>u4YgBCr8BS!R&-wlv3ZI}p zrk>!&nB1zdy&aMl6p8OGX`IHn9lxjae>y=KgP75S8F%Y!@G7B9z}R8iIQNwA@Y%T3 l6&I0{r1aJ#e-OoS&P()ZQr{n_Ay<%MIl-GrQS?H}{tt43@?HP{ delta 1756 zcmZuxJ4};N6mA6+g;=D3KdC$_Aeb5v12m|K z;$)0ra8g9VKtkf9BZDCh4kjkVK^+{#!8n+x=ldo+gVEL^$>5j|my{So zCGPR=ax_@>So4Ka6)I)pFPJS>*!I*Ylm~vIlp`gFC?&9<=kCj%^DlaOlp(4O4dVu&-0kx5z161Jez<`pCM={sQ zqY!2o{mG~>6YU~1lU;1a9;8I?x5XD78X_=KLvK^8w6H4wd(c)n)h5NV_mVI2bmqK%- z&=^rD5@Qdzi|Y|tv4WD&OyIwv@CoX} z>Itq7%dHyT-645F@zm~;rf8g7sas0_r$#7a7&H1X<4&y|o{uOKFm~8J%01;fd^9R` l#YN<#DZMStA4GASa}s@+*7pW#$XUi%PVlD3D0+UZ{vTP9PeT9z diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib index aeff6452633aac49c52ce45f31235f73ebca4a97..3c0edd01d727406c66ff178a83f0e0674a7a16ae 100644 GIT binary patch delta 23091 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 S;2e+{O$vkTbNxYvD)wJ$vLRsr delta 22393 zcmc(G37C%6`~Q8PkgQ{0hZ)Pn*v1mF%~+FVFd@re>`P+CmV`kn$uhjmk?dcg5+j9# zkR-Au*=mL)m4r$q%kOia^SsZz&%F9y|Lc4G|JSeU`n-?cbDw*^@3XwmoIjR(-=5ql zq1o%zt^asb>J2WIT>tUf^~2=9gj_@qjU_%DL433u@v#)*zZVnVT12YrbW*W1i2qoH z?+OzCS%&!gc#Gqgi2*gdxW$Nqqy+QwSacahO7KK0i`HSJ1n1WalJQZ_;_NI^f_Fz) zJoP>)!G_fq?+hUY@b48YF6<`;RLe33{MAe{IF*eUP~-Pmw7|aszE;)24m^QVUL$YR+lQi3HnDOo=Fw~`K4;0a{3aqtD6z)#yPF0_No+mXuXZIOPPltBufz@Z)% z?Q@V4v^ilhWE?5M94IN6-p}Hdi-`X#7fCHRX|Z`PDZ%>?B6t<<6U>BX1g}7VUsP)hiz=0p7ZD%;Frz05$vzixFE;3BbG*i(V@*2k7#b#gkAhSw5b; zXz>l)WzY;y;9OCQ4REEPb1RFDbx8@dS+OKR(nc)VSb8VTkILTDi3(;!2Tyv0EoJb_Wi5Py8A&fi*W zJc7gm*6%go9}mJJ;F}l&)v6Y%q!#h@F%~y+pn8Ba8!XN?AQoIfpAekgXQ1Nq!D3WP zdNYe}(@;%7`srl(AXTliMMbz@z`HFPBff&dl`L{LASEc9XpyTvDM20wxh~=Vf!uJj zAPnIZl&fG7K8}^AG^k?q*R30tAoduy`DX0DSkPfvT7j9tLXOGDudBR{{Z0?Vd%gMWh7TuUnLZ zP{AXq7FEi@VxaC#i-r-T1lgddpk@P$Mrou34S%wzzJipXDHIZvGC=+3*kVxuF%)D6 zb3xu&7Wv{y3G#!n!S8qip;s)*yiZC{w~j^8W~2;YKv5tB-VziTZjt8*@&$anM}QbArWN-AD;Oyy9RGp1?L_wP5Qy ziybgP@X=|D_rJjM4eaS{@$nr}g1Jycup9FPo5mylo5quR4;l&DCRiLTOiC~~)?!cy zDT7^j0?#e8cs`z#U=frTq>Qq7{uaIm79;rt!!j(!?#BWIyq0P)Gx;Vq7Qjo{EXFJ% zCHNSM2wsLT!Om$GgW+PquDup7O~E{%(_#n3@dVZ(2?cBSS#&>7$^c&K4)nNck=$bh z{sDA5;vf!B;LV#3#^VY2;2pvIMHa_~VN(gL!#qLSUls@91wqGI7Do@jlfc>v7P}&# zIMBbkL9*(XjV#je1Wuo}I0Neiy_;BUj>6UqcyEJ62Rse(;R&>d7X-0+Ecy&0CFl)L z305C;5Q!(y7fSXWfcPgM>je{MTD)+QltDQ>fe9!_!GJ~@)>l`OW;AhkUiA6r8#-nd0duozkkQqNkvF&y6mx}U|8QP?^I zi!NHc4oeI!;|VN4_yqcr0pGz!Q*gJNfjV>oyJVE<@2iQE<>QYE7T?`O-2#_JSX>Rm zZWXw6#o`y#y8&wc7vN-02ea@5E_b!~3QH}Z4nn~XpoHKpKHaAe=h4;ra*6pN**4$r|N0Q!wi>t8Aq)B8%~6Lp zmGYb+>-*1;`FjKdqOex2h7XQt(=oZuTu8L;FDq8giQ$c)J=1->h@0l(iXDU8i zQNa<4^2}2-s*9plPbdm&t!VvuMdg55XBCZjSJC@VDO$Zj(U5l(RrsB0{{`@AsVI5o zS4`PXG3^_#C|e6fRj)Da0LJ4x^)*wgADCw1ne&vQ247+vC%zp(o70MVpHy@enD7+@ zo=|k_n4+SeDT>>tsO|wp`+$z0L$Oa4-2-OsSG4~V(Ck%IeYv9Pt5h--{Ewn#KN_0v!ZtIL%~;}%uLYZ`+hSNU2m&s{FY=)ybO0PRFrF|qB-!uf~!oY z;9eZ@X?H6{rEfAV0d{@ERR3G1)=(nkX+`;ZDO!P09J_+=&Ot$hVhci%f>5l$*k1@o zt|y@gaN-+9&48lkpe(}Bsxv&a5ur<74{H&JHor1u0J%;h?!bPyz0w(`gK+sGxV|vl zJMFll47heRTpR^Au7DeNz>PQIu{`kD#HETN|G|8q_h<+ht7sh*y#{MzKY%wA6eWy= ztW-s74kILAApY&}F=`;Reg+mLLcnZAjez2_6m18p-a(@L#Z(fB81)nw#(^Q2#~o30 z`2*mRbnYnCnbA z5V8&MT7$F56NF_Sp7|iSSvpf1LU$U^&edQBjxi{g`Uq+rf^XJU6wwe&v%w(HrZrOZ6aIfib?|{wUqFd1IbdJ~ z&|~hbyoi5%J`m?u^gD1R6frELs16u4D+&R?h7d)=3&7>@O4kT5C;`QQ1y#{Z>MNT3 zu%ZE#AhZa)R8rBldU%#c-hkHu7?4sL9)Y!UqENE%N{>kJsEo`9<~Kw9`!$EapP8Cn zM55hhS_8a||39%1ZvKvG8@@07G8zVAUvfS&_Z$SKK|mbb-xJYBbW9ly7Mv0crM0vBd0cj&wHqZwy3J3h=1&0MInO}?E;oP2cgeHz#_ye z1un3R@7Os8`Zk~xw`4U1f228+s7nGZ}6Y&P0y}J}m!Pw$Xs34%(I^@k- zgta@A0^c(hF@wgY1aw;}o9(iz*~Ex7pB8(_W|EjtzYfq(bY z@YoV`yG0Q4I?5J^TYyT!_ovW9x*>^A976NL;!^<&*-eCY#3fFqFtpn%mk|435PKl! zNi++fE822CEKV2Ug-aj6BZ%{wx8Y{QaqL4xd1yVoL+{cq{+Rc0D3zh|RDmLB3QeUK z=@=cSFKGmAruS$QeL;h12%Vy@=xb_4PtcQ8iW+lsZpO*m_(T4Pb5lPwgkDsUrqKy{ zmeS}D4W-u9h+}v=_oW@Ylf$VTO{QczLPx1T4WvQTf?85Z+QM6TGr!N-_-FcsuF+Nc zlg`pDs>6R%2$$eoT#T#mH}n^(Kb1@?3#`qxsJD;HlR$Pm#^5a~e>v3NGl`8XT z%E^WK2G!-qxB%ziN0^xTCjCQUoR4d8BtOg#@omb_g*dq&pQ9h>C%QsE(se4r4Y(nP zQ392wNpzS7Pys4PV`waOpzhq0KB8Dk;dwll=kPR6;zWLu*U?%kMib}&h0thPK+p4d z9?N6+IUdJt_#|ziQS=)7cs^^=oXW5841Sq6(h~j;FHNR+?!`U%S?)-EXaz6l0lbXz z(n#7#`6!VV(Q;bK%eWD<7q8-;8NuZ8VkJ(+9kS-k`!KRMowBo*(nzdr#I;XdW5o36OQH-nn$bYzb+e2{@*Q|g313? z**r}DUN||hk$6z?JoCWvNp|Yzf2({NIQ8>imQR0w`Mgj6Ukj+16wuxWmr${PDWT1k z|Lp(J{E!^Jy0!9cPQQJo*4A^?xcMXcttqOu@7#`>}avDT`fVemC4WvUV>UkyLa9sH!H*?e{NG(Y8hwc>mGRpJ@$lsU1O?(-uT$}NUg zf#e*NZT{sl`u@+Z(2(nP+K97$h2_Uq9evf>apf#Gceq8Jvy}1YxV!UJ*f15DM|jr* z?_6j$x9=$1QfItoWGqpUhOQFmiVIzgWwY?Qip(xD#C$0c=#OWeW{5S6To z>5Z41WNU?qC1qk!p+Vd)ain9I1i9t+4qZ9WmC}8`=LQZNNhV`VO^lR=F}oi{g`MFV z&N%F_8r0B7zvr?#@iJF)h9seka+P(b%NV+TnIFxZW%JQkCHYuZclg1tJMzv>tf<@m zz@_w^pWTVaK6O0t6y}8MrdN2lU(w&4NiB8bD_qK#c&EHhyaYdHb-I*+E4I8&`iYC^ zlpkG#L~Ao#84@bk;XFV2jdDxEkdy~WMImVvXqQyJahXIl0xnCx6RNMD;_{h9RzeMo zKdSru%&jv=vbd#^PX9T;Ew&t8*_CzAtA5#%pk^QnTqE_-t1ee59y3xGBUN;VUpUs0 zC$*4Y(x)~?s-kM6qigz-2A0j5t-{+_B)qG^qMdikXR*juf@^klG5c<)Zhym@$)4J% z0iqlI!h};`n2e7-85yOI|LSI>1jw`+2~bUGHS-1{NisW`q>r(;A_!{fo!7aEwO0m= zhB8na!V~Tl7Y&`Z>&Dh_m)O<;cVE<{A_2^`v=qa=0SF$`p*J}$)0@Tg{iVugSA7iE z)ir+Oa=x(da_b|1x$*bJqn?oXfw=;@tp+D+YD+L_08>}qubP!b$HyEN&GpgWxmFey(prqOnt?+jaOgYWv7r8H z6wcq)F*yd5jrH7H+%3=}o&~RoF8ilzuJjHgLJA=oBGPIW^E)drAxuX###YlS|Kw0# z%%hL!W4Ap?qs6PnZIb0pC2$=c4fS*Lm)`YzPLrskmt(p0GjfJKY2KW&Exf_yb-SDX zz{#+YAXU&pB-H$_Twq{LPam0}3K^>EplWHUie(X`Jq^8;uJVt+p&L^}q$FkWcmg~4 z=;%K6e0%;Zrgz`vf`QEp#hYa}(OQS!ah;pE%!zI-9eRh0>yPemT_-HAo<@-9*~Tv@ z>9OLv;XMcnSVToxW09;rZ9(a46kAfayX*Ih?2xjwt#-QXJ%8KMvNtdlBYT7P`i*pNGv$(VZ%5=AGzbQ_RQ_Du!btCciwkffy_6YWqwDDwzG^EPH`lL;rmVt zH>>*2_sD4@PjWg=EGgZhj_$$ApC5@89fBSpcuELAuNsN9K+swDQL2r{ zsoy!JP!+>n^aZ6_IK#VTOP6**6*RNEV7RO9^^h9j3?F;QskV5GJdILF8q-0RFTY}D zy6gze^iCk^rZ;9&!veW`hP&%d*#n1dvxw8}v#Vmh5o7DTN|pUJfi#?w~)^rX@fD| z+l=>kFsCw`9D93#vXAcbh#KeE8+O?VLo7xTblzNQP^Ke`>AAU_8k~gTzS2Vbj^vR# zG`I4%&$JrQG$qQ>bS%jFL6hhiLms3_F z1<}5?sf7aR5C>b@!@y^xgkX1SyzW}UO>!ZSv(t{ks0(dn20L(qAqwW?=Bja!U$ocf+0hZVS?B@JWHSO{DjF_BU=5F~&+0 zc@dPy-|QX4)09J(@=iB;0hH5qQhBw&uY6snNe|c0mRB`VC?R@61@(k8>{;Gk7PnuR z$n8XkzXb_}Q9>5LS76zm0yZvwf~aYZU;BYzhHf9BCirCscCT0U{Rp>vdD3tum~JY_ zaY3dbE;g2N;QX5IRmp8{Cb>$Vazc`X;aU2AB{kC#Y<%)&WydE|Fg#oDsjL<`!@=>M zqvu7s@y6`p+OyKk)itZQx|`vM#*XX+Fi+9xRWj2|(!rzJJUzFntD2hvCP^g)=Ic(? z)PPLQv&i=8U#exw{?utBa@bvfaQX7T(=sS|JV)Y%I=Y7PABo{N8_ef0KNT6(^Q~b) zZa2>Ltb`g7$|%YYTng>-Zmf~gU8Iw0y4}Wb>NwhQRU(F8*P*rCy7Q#gVrX+?u&H=| zW=Z@_PmuV(A<0>FI=2Yir?4g!`&Ahp-gM1=88l$A_XqM`ub<{-1<#OmT zQkr9AnMf(~5G3a=pxq4(v{=ba;K&OYZt&Cd&HxAAO;|df8DwC9}Z4sjvFUqEjGnA(NHI zct=*AH{qR)<2wh1JUFM<=)4WRIW4P#Q9%~NwR&emSB2n&SqC}%+P~zBr*_`bO&e#* z33S5S`bJ~F6H@0p(d!J^@90fUGBf(5W8TvkS&uyZJe1o6Mc>n--qm-b-5zChm+oy$ zlkUAiZ;Vm19Ph?7b;3FhBO4_-s=a3Gz#mt`piDDW&}>IW>5)xUQQzI!T>^WkXRX`> z-=q)qtd++7o?Y^LAnKG9`=CJC9g@j4*&%I~T;nlG`tufU!n$>5bV}5nTBsuPN13qy zo7&+mRU!TQZ0@GpwaVNfp@ADgvi;m5g3_Mr7-*Oqc|#?e=B?tR_H%gfzpHLMEvj$R zrCNKNvK&|pE2)nUg;mYD+&q|7;El_6J^M-Jzj1NzON`~w`qd{@DZP6xhibfK;8|gD zShfv8Zn}2pwQc-IMY$;{rae~}J9U+|%729+_bkSQ#+bNEf7DiWb&@6c{Qa?hvYqnZ zTtt15wAqty9aCy-9eG5tZz*#~YnDsq&b-O**_ zy3|lbgX&XIg+*|!Kq@(w8v;4f?*~Dr2#ySFqL$4OXH9Mbs?RjXxxO=52U}(?}e<4ZR$@4_f*%`e;9|CxZia zNEhhr226J2hKcOPzmRN9S-_=zX4wN$)OcE%)hO_mF+(!`!v3&8R#NE3r&8z_EJ5i9t0r3_BUQFU7a_Id zrn<7@so=@8K!M*0zukkvbZkFYch3(+m%t^uO9j2+2(l^Q2N*HXXe9=IFX6aQtG0y0 zLnXI6Mj^S~xs0qytb)smfD0?R_cH{Nx<7y*tqM{%GwVGYh$}jMfV+Y4Yz%*tk&3>A zFKY*_IVQP({n*Lgb`bLu#3WVaXgz+AYqRIV=4U;1u!_;YRJGCfFTKIXkE=rHKW?Ix z*!q$q?k_rgh`XJZpGr*9$xZMz841YmEz;PEFW2Y=Of5>o@PFRM9``H{hxS@6% zkV!acKz|`^b;dHhJRUpJjiD{4z%KeXJd{|YtUj1YWP+G0(b=wa1Fze{D`q)%pDU7G zUY?ETKl*T@yYWPri)+tT_>N9aa<{?~p zep-i&b|t%eK*L4OUiV24AFW<-YFK_9F*zc?ju2<_UFcR>BJ5d;JicVTX^iVjWB;7@ z9Q(V2g<{yhVI{W}`#sg`3HL+#{#ZBMX@R@4oUTJYcBSCD?FDg*+I3uHtxwGb($o#2?m&$Ga!6;0;PnJ@R>XgJOm~yTV8G-RIq1 zq30qcm$)K)H7-)lPjCYwJuII@RC-u$P(%;b3DMjnFkRgAHyJAFp9h4#8!c+;M<%*X zF`JDiCpw!A4XV5%@cL?gHPBu|R&$cG9IpUbKHYwj+U8#=1J|GY@K;h@uBfy9>@IYk z;D_jsC%eJ-tf2)&_N+DBAkdI0+G%2KAhw`hIz{z!#EKh?b>fCXVqN&on82x?b*iv1 zU$&NO=!d7d_DfNj)Rh~jB1qj`r@Y54xq+AFWQgR#t|-jgSf7jdLQk~_JinlnEGM}m zE@p|$HNC%A8y^mx?znm#sEUh5zpUfMfwzu^tnW*XtLK5Ngr4-0dfTztv_sFvsHE=m zvb!-dNiIi7qwgrpE(KNkHsFD}_bYDx7#T}naW?d+dg^psMTErX_RZ}*GSDVNC+7&$ zLKlNus9rupy%(s9v}O|oY0YKCqV#vLkR5u}^|5I(o?kJ_O04?!3H}vBE>?}^a9IROpJv|V`>!zfk-WaUI+;_gs=cfPBay9^uaWEn26 z_snwd&qRzF5iu2Xui0*Sn~8GwYKGy77^UhMtJ*R)DG z-FmJY9na3b62jNC36d6bVIL38yM^aThylEr13al*8hO8QF9Px35K;OCz(nM2^;ME~}cQoRZ^}QL- z=Cy{U3ioBS&lXS>o;_ETp0vR2A09hv>hOi`h;$YsU3TZSpkhd5!@#xKIIvl&gnT)+#3kHd%)h<%&(5&`j{WmjKhOgSC11P2US!vu9&*m%_-03zkwYO zvxmOfi&Z73piR^~cc2a7x5RU;gMudUH)hv_R*l5$V;Ar`!%FXJ4cqNYE5-nMX{9kl z-)P2FvZk|nJ%(>O6&nG{CgSo7oAGi1_WAxEDsKxIUh=j8ve~!m-BLPgsXOkjtcEBC zL@^)=Z(UpO&Lj%fswuQeZVs)EiU9#{CwSc246LeVR1_;6eLSVyTom5)J~p?R1m4&6 zT0qRN%{eT{PaZKXL6xrs*3SSoo^opiJwh&2$jZf|%oCzarw_c!NGiH-WVHrG^w811 z)$Ya$!&YtiVYvf%gg37r#6u3< z#x}VR=m?^ai0VN^o{PIqdgK~+Z|6CL#=#ul)MmAV=6g=|PwBa9AAIT1+03tK4kcVY0XuGZcR+L^PIbSGu{%q@gdF)0dM6PGWki@ zWQF{s+Xr5cI%MvW{d&oH+NdPw=>$<}@~34*B~N~eHw~3Isjt|$VLMk3ynOI12K{vY zGH8!^8hJggqBupYp zlXzC=-|D`7;_GgfA zH*)2oEJ;Y>oyoE~m=U?%8>N%BtMU)L+%q(C_cdB*{5PqdS4zj|*&nI0I-v!}XZy$DV82@yLxnm+ML5`V9{b z`t$n3oq<8O!etvbL3i5aj)-4OHHlwdkXRqzTtSC??53`#^Gvh^rFF<&tgTr$p+*V0 zk~0kDEHFvv@1JiHsH$h3o(xlty;m`-KvO0iz#!R-hdx-Ir<$iAmohrwCH7q%@J?t} z)jYK|)shCk;NVeh8mMY^gqc~K;p+CHCHNQRcKf$&Cg`$lo30z~^WW`z4hJuZm-_B) z73d}7OF14HU&`_5WudxvsBw^OhEyur+-ArL@)eLqkM{AtVmje7g*Rz4|EeK4Ml(RH zU*Cs|kAQqKJy3oDHQLLI1h47~pSd@mX4@|(dZV43=x2&{Q@3{0R}Q$TBkvI!0(p<{ zH4!uCQ|=zDKQ=;n-p&|1yZh;jS8CXIRwlD(YzS+#w@q!p8d~!5KRuR9z-My znbB7kGM}+~UU#l0bpEmy5)%O-S)fNAadkCaL3SX<_im|;tcyy_b{?b3H<*yM;?#N#w$gMU0hP1Tq z`K7z=dhUdm>zXIsJ7Ldt=n70t?22tojj!CPo+WvuD4x+eRtP*Rve_%hD@evsNl;@I zNcEh9+&`!oJh!I*LFP31u&ef+4ZJk986g)ctM$8I`>z|cC$Hbs9ZtKs;>pG}Fe9oP zHcVM_)|1$4EmaX6wI3}tE2(KBa(`z0DnBf)1AR(2xpT}?37$>;P2lXbf0g$!=CHq zjrx~wT%V7{wO!AV3R6QtS9m-haV z4Ex_`cD-$6#9(-b$cTNsmX814?WOLDYCIw<>P~oMc03lo(p$XF^Sr#iOW(Mx%KPSa z&aSV=getType(); bool match = false; + std::chrono::seconds delay; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) { RenX::Server *server = RenX::getCore()->getServer(i); @@ -1317,15 +1319,28 @@ void GameOverIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString server->gameoverWhenEmpty(); if (parameters.equalsi("if empty"_jrs)) { - if (server->players.size() == 0) + if (server->players.size() == server->getBotCount()) server->gameover(); } else if (parameters.equalsi("now"_jrs)) server->gameover(); - else if (parameters.isEmpty()) - server->gameover(std::chrono::seconds(10)); + else if (parameters.equalsi("stop"_jrs) || parameters.equalsi("cancel"_jrs)) + { + if (server->gameoverStop()) + server->sendMessage("Notice: The scheduled gameover has been cancelled."_jrs); + else + source->sendNotice(nick, "Error: There is no gameover scheduled."_jrs); + } else - server->gameover(std::chrono::seconds(parameters.asInt())); + { + if (parameters.isEmpty()) + delay = std::chrono::seconds(10); + else + delay = std::chrono::seconds(parameters.asLongLong()); + + server->sendMessage(Jupiter::StringS::Format("Notice: This server will gameover in %lld seconds.", static_cast(delay.count()))); + server->gameover(delay); + } } } if (match == false) @@ -1335,7 +1350,7 @@ void GameOverIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString const Jupiter::ReadableString &GameOverIRCCommand::getHelp(const Jupiter::ReadableString &) { - static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Ends the game immediately. Syntax: Gameover [NOW | Empty | Seconds = 10]"); + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Forcefully ends the game in progress. Syntax: Gameover [NOW | STOP | Empty | Seconds = 10]"); return defaultHelp; } diff --git a/RenX.Core/RenX_LadderDatabase.cpp b/RenX.Core/RenX_LadderDatabase.cpp index 36e83e8..9b9624a 100644 --- a/RenX.Core/RenX_LadderDatabase.cpp +++ b/RenX.Core/RenX_LadderDatabase.cpp @@ -1,32 +1,41 @@ /** -* Copyright (C) 2015-2016 Jessica James. -* -* Permission to use, copy, modify, and/or distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -* -* Written by Jessica James -*/ + * Copyright (C) 2015-2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ #include "RenX_LadderDatabase.h" #include "RenX_Server.h" #include "RenX_PlayerInfo.h" #include "RenX_BanDatabase.h" +RenX::LadderDatabase *RenX::default_ladder_database = nullptr; Jupiter::ArrayList _ladder_databases; Jupiter::ArrayList &RenX::ladder_databases = _ladder_databases; RenX::LadderDatabase::LadderDatabase() { _ladder_databases.add(this); + + if (RenX::default_ladder_database == nullptr) + RenX::default_ladder_database = this; +} + +RenX::LadderDatabase::LadderDatabase(const Jupiter::ReadableString &in_name) : LadderDatabase() +{ + RenX::LadderDatabase::setName(in_name); } RenX::LadderDatabase::~LadderDatabase() @@ -37,6 +46,21 @@ RenX::LadderDatabase::~LadderDatabase() RenX::LadderDatabase::head = RenX::LadderDatabase::head->next; delete RenX::LadderDatabase::end; } + + for (size_t index = 0; index != _ladder_databases.size(); ++index) + if (_ladder_databases.get(index) == this) + { + _ladder_databases.remove(index); + break; + } + + if (RenX::default_ladder_database == this) + { + if (_ladder_databases.size() == 0) + RenX::default_ladder_database = nullptr; + else + RenX::default_ladder_database = _ladder_databases.get(0); + } } void RenX::LadderDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) @@ -371,6 +395,10 @@ void RenX::LadderDatabase::updateLadder(RenX::Server *server, const RenX::TeamTy { if (server->players.size() != server->getBotCount()) { + // call the PreUpdateLadder event + if (this->OnPreUpdateLadder != nullptr) + this->OnPreUpdateLadder(*this, server, team, output_times); + // update player stats in memory RenX::PlayerInfo *player; RenX::LadderDatabase::Entry *entry; @@ -482,3 +510,13 @@ void RenX::LadderDatabase::erase() RenX::LadderDatabase::end = nullptr; } } + +const Jupiter::ReadableString &RenX::LadderDatabase::getName() const +{ + return RenX::LadderDatabase::name; +} + +void RenX::LadderDatabase::setName(const Jupiter::ReadableString &in_name) +{ + RenX::LadderDatabase::name = in_name; +} diff --git a/RenX.Core/RenX_LadderDatabase.h b/RenX.Core/RenX_LadderDatabase.h index 0609a7d..54a73b9 100644 --- a/RenX.Core/RenX_LadderDatabase.h +++ b/RenX.Core/RenX_LadderDatabase.h @@ -1,20 +1,20 @@ /** -* Copyright (C) 2015-2016 Jessica James. -* -* Permission to use, copy, modify, and/or distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -* -* Written by Jessica James -*/ + * Copyright (C) 2015-2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ #if !defined _RENX_LADDERDATABASE_H_HEADER #define _RENX_LADDERDATABASE_H_HEADER @@ -39,13 +39,14 @@ namespace RenX class RENX_API LadderDatabase : public Jupiter::Database { public: // Jupiter::Database - /** - * @brief Processes a chunk of data in a database. - * - * @param buffer Buffer to process - * @param file File being processed - * @param pos position that the buffer starts at in the file - */ + + /** + * @brief Processes a chunk of data in a database. + * + * @param buffer Buffer to process + * @param file File being processed + * @param pos position that the buffer starts at in the file + */ void process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) override; /** @@ -174,27 +175,47 @@ namespace RenX */ void erase(); + /** + * @brief Gets the name of this database. + */ + const Jupiter::ReadableString &getName() const; + + /** + * @brief Sets the name of this database. + */ + void setName(const Jupiter::ReadableString &in_name); + /** * @brief Constructor for the LadderDatabase class */ LadderDatabase(); + /** + * @brief Named constructor for the LadderDatabase class + */ + LadderDatabase(const Jupiter::ReadableString &in_name); + /** * @brief Deconstructor for the LadderDatabase class */ ~LadderDatabase(); - private: + typedef void PreUpdateLadderFunction(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times); + PreUpdateLadderFunction *OnPreUpdateLadder = nullptr; + + private: /** Database version */ const uint8_t write_version = 0; uint8_t read_version = write_version; + Jupiter::StringS name; std::chrono::steady_clock::time_point last_sort = std::chrono::steady_clock::now(); size_t entries = 0; Entry *head = nullptr; - Entry *end; + Entry *end = nullptr; }; + RENX_API extern RenX::LadderDatabase *default_ladder_database; RENX_API extern Jupiter::ArrayList &ladder_databases; } diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h index bb779d5..41e1339 100644 --- a/RenX.Core/RenX_Server.h +++ b/RenX.Core/RenX_Server.h @@ -430,6 +430,13 @@ namespace RenX */ void gameover(std::chrono::seconds delay); + /** + * @brief Prevents a delayed gameover from starting. + * + * @return True if a delayed gameover was stopped, false otherwise. + */ + bool gameoverStop(); + /** * @brief Forces the game to end when the server is empty */ diff --git a/RenX.Core/RenX_Tags.h b/RenX.Core/RenX_Tags.h index a0eb0b7..2f0b7d0 100644 --- a/RenX.Core/RenX_Tags.h +++ b/RenX.Core/RenX_Tags.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 Jessica James. + * Copyright (C) 2015-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj b/RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj new file mode 100644 index 0000000..5bab885 --- /dev/null +++ b/RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {24B039D0-5A71-4F76-8908-BAD772FDBE1A} + RenX.Ladder.All-Time + + + + Application + true + v140 + MultiByte + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\Plugins\ + AllRules.ruleset + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ../Bot;../Jupiter;../RenX.Core + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj.filters b/RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj.filters new file mode 100644 index 0000000..3199366 --- /dev/null +++ b/RenX.Ladder.All-Time/RenX.Ladder.All-Time.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/RenX.Ladder.All-Time/RenX_Ladder_All_Time.cpp b/RenX.Ladder.All-Time/RenX_Ladder_All_Time.cpp new file mode 100644 index 0000000..27c3e37 --- /dev/null +++ b/RenX.Ladder.All-Time/RenX_Ladder_All_Time.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#include "Jupiter/INIFile.h" +#include "Jupiter/IRC_Client.h" +#include "RenX_Ladder_All_Time.h" + +using namespace Jupiter::literals; + +RenX_Ladder_All_TimePlugin::RenX_Ladder_All_TimePlugin() +{ + // Load database + this->database.process_file(Jupiter::IRC::Client::Config->get(this->getName(), "LadderDatabase"_jrs, "Ladder.db"_jrs)); + this->database.setName(Jupiter::IRC::Client::Config->get(this->getName(), "DatabaseName"_jrs, "All-Time"_jrs)); + + // Force database to default, if desired + if (Jupiter::IRC::Client::Config->getBool(this->getName(), "ForceDefault"_jrs, false)) + RenX::default_ladder_database = &this->database; +} + +// Plugin instantiation and entry point. +RenX_Ladder_All_TimePlugin pluginInstance; + +extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin() +{ + return &pluginInstance; +} diff --git a/RenX.Ladder.All-Time/RenX_Ladder_All_Time.h b/RenX.Ladder.All-Time/RenX_Ladder_All_Time.h new file mode 100644 index 0000000..2b47656 --- /dev/null +++ b/RenX.Ladder.All-Time/RenX_Ladder_All_Time.h @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#if !defined _RENX_LADDER_ALL_TIME +#define _RENX_LADDER_ALL_TIME + +#include "Jupiter/Plugin.h" +#include "Jupiter/Reference_String.h" +#include "RenX_Plugin.h" +#include "RenX_LadderDatabase.h" + +class RenX_Ladder_All_TimePlugin : public RenX::Plugin +{ +public: + const Jupiter::ReadableString &getName() override { return name; } + + RenX_Ladder_All_TimePlugin(); +private: + RenX::LadderDatabase database; + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Ladder.All-Time"); +}; + +#endif // _RENX_LADDER_ALL_TIME \ No newline at end of file diff --git a/RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj b/RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj new file mode 100644 index 0000000..a43cd17 --- /dev/null +++ b/RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {73F0EEF6-CE5E-46EB-80B4-2B319AE2B258} + RenX.Ladder.Daily + + + + Application + true + v140 + MultiByte + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\Plugins\ + AllRules.ruleset + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ../Bot;../Jupiter;../RenX.Core + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj.filters b/RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj.filters new file mode 100644 index 0000000..21fc8b3 --- /dev/null +++ b/RenX.Ladder.Daily/RenX.Ladder.Daily.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/RenX.Ladder.Daily/RenX_Ladder_Daily.cpp b/RenX.Ladder.Daily/RenX_Ladder_Daily.cpp new file mode 100644 index 0000000..5b90824 --- /dev/null +++ b/RenX.Ladder.Daily/RenX_Ladder_Daily.cpp @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#include +#include "Jupiter/INIFile.h" +#include "Jupiter/IRC_Client.h" +#include "RenX_Ladder_Daily.h" + +using namespace Jupiter::literals; + +RenX_Ladder_Daily_TimePlugin::RenX_Ladder_Daily_TimePlugin() +{ + // Load database + this->database.process_file(Jupiter::IRC::Client::Config->get(this->getName(), "LadderDatabase"_jrs, "Ladder.Daily.db"_jrs)); + this->database.setName(Jupiter::IRC::Client::Config->get(this->getName(), "DatabaseName"_jrs, "Daily"_jrs)); + + this->last_sorted_day = gmtime(std::addressof(time(0)))->tm_wday; + this->database.OnPreUpdateLadder = OnPreUpdateLadder; + + // Force database to default, if desired + if (Jupiter::IRC::Client::Config->getBool(this->getName(), "ForceDefault"_jrs, false)) + RenX::default_ladder_database = &this->database; +} + +// Plugin instantiation and entry point. +RenX_Ladder_Daily_TimePlugin pluginInstance; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times) +{ + tm *tm_ptr = gmtime(std::addressof(time(0))); + if (pluginInstance.last_sorted_day != tm_ptr->tm_wday) + database.erase(); + pluginInstance.last_sorted_day = tm_ptr->tm_wday; +} + +extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin() +{ + return &pluginInstance; +} diff --git a/RenX.Ladder.Daily/RenX_Ladder_Daily.h b/RenX.Ladder.Daily/RenX_Ladder_Daily.h new file mode 100644 index 0000000..be3f87c --- /dev/null +++ b/RenX.Ladder.Daily/RenX_Ladder_Daily.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#if !defined _RENX_LADDER_ALL_TIME +#define _RENX_LADDER_ALL_TIME + +#include "Jupiter/Plugin.h" +#include "Jupiter/Reference_String.h" +#include "RenX_Plugin.h" +#include "RenX_LadderDatabase.h" + +class RenX_Ladder_Daily_TimePlugin : public RenX::Plugin +{ +public: + const Jupiter::ReadableString &getName() override { return name; } + + RenX_Ladder_Daily_TimePlugin(); + + int last_sorted_day = 0; +private: + RenX::LadderDatabase database; + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Ladder.Daily"); +}; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times); + +#endif // _RENX_LADDER_ALL_TIME \ No newline at end of file diff --git a/RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj b/RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj new file mode 100644 index 0000000..bbe7002 --- /dev/null +++ b/RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {34FDE301-A29D-44ED-8ECC-15693F137DE2} + RenX.Ladder.Monthly + + + + Application + true + v140 + MultiByte + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\Plugins\ + AllRules.ruleset + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ../Bot;../Jupiter;../RenX.Core + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj.filters b/RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj.filters new file mode 100644 index 0000000..81306c7 --- /dev/null +++ b/RenX.Ladder.Monthly/RenX.Ladder.Monthly.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/RenX.Ladder.Monthly/RenX_Ladder_Monthly.cpp b/RenX.Ladder.Monthly/RenX_Ladder_Monthly.cpp new file mode 100644 index 0000000..f4a46e1 --- /dev/null +++ b/RenX.Ladder.Monthly/RenX_Ladder_Monthly.cpp @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#include +#include "Jupiter/INIFile.h" +#include "Jupiter/IRC_Client.h" +#include "RenX_Ladder_Monthly.h" + +using namespace Jupiter::literals; + +RenX_Ladder_Monthly_TimePlugin::RenX_Ladder_Monthly_TimePlugin() +{ + // Load database + this->database.process_file(Jupiter::IRC::Client::Config->get(this->getName(), "LadderDatabase"_jrs, "Ladder.Monthly.db"_jrs)); + this->database.setName(Jupiter::IRC::Client::Config->get(this->getName(), "DatabaseName"_jrs, "Monthly"_jrs)); + + this->last_sorted_month = gmtime(std::addressof(time(0)))->tm_mon; + this->database.OnPreUpdateLadder = OnPreUpdateLadder; + + // Force database to default, if desired + if (Jupiter::IRC::Client::Config->getBool(this->getName(), "ForceDefault"_jrs, false)) + RenX::default_ladder_database = &this->database; +} + +// Plugin instantiation and entry point. +RenX_Ladder_Monthly_TimePlugin pluginInstance; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times) +{ + tm *tm_ptr = gmtime(std::addressof(time(0))); + if (pluginInstance.last_sorted_month != tm_ptr->tm_mon) + database.erase(); + pluginInstance.last_sorted_month = tm_ptr->tm_mon; +} + +extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin() +{ + return &pluginInstance; +} diff --git a/RenX.Ladder.Monthly/RenX_Ladder_Monthly.h b/RenX.Ladder.Monthly/RenX_Ladder_Monthly.h new file mode 100644 index 0000000..a556d37 --- /dev/null +++ b/RenX.Ladder.Monthly/RenX_Ladder_Monthly.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#if !defined _RENX_LADDER_ALL_TIME +#define _RENX_LADDER_ALL_TIME + +#include "Jupiter/Plugin.h" +#include "Jupiter/Reference_String.h" +#include "RenX_Plugin.h" +#include "RenX_LadderDatabase.h" + +class RenX_Ladder_Monthly_TimePlugin : public RenX::Plugin +{ +public: + const Jupiter::ReadableString &getName() override { return name; } + + RenX_Ladder_Monthly_TimePlugin(); + + int last_sorted_month = 0; +private: + RenX::LadderDatabase database; + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Ladder.Monthly"); +}; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times); + +#endif // _RENX_LADDER_ALL_TIME \ No newline at end of file diff --git a/RenX.Ladder.Web/RenX_Ladder_Web.cpp b/RenX.Ladder.Web/RenX_Ladder_Web.cpp index 3982630..60cd309 100644 --- a/RenX.Ladder.Web/RenX_Ladder_Web.cpp +++ b/RenX.Ladder.Web/RenX_Ladder_Web.cpp @@ -150,15 +150,62 @@ int RenX_Ladder_WebPlugin::OnRehash() return 0; } -/** Ladder page */ +/** Search bar */ +Jupiter::String generate_search(RenX::LadderDatabase *db) +{ + Jupiter::String result(256); + + result = R"database-search()database-search"_jrs; + return result; +} -Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(size_t index, size_t count) +/** Database selector */ +Jupiter::String generate_database_selector(RenX::LadderDatabase *db) { - if (RenX::ladder_databases.size() == 0) - return Jupiter::String("Error: No ladder databases loaded"_jrs); + RenX::LadderDatabase *db_ptr; + Jupiter::String result(256); + + result = R"database-select(
)database-select"_jrs; + return result; +} - RenX::LadderDatabase *db = RenX::ladder_databases.get(0); +/** Ladder page */ +Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(RenX::LadderDatabase *db, size_t index, size_t count) +{ if (db->getEntries() == 0) // No ladder data return Jupiter::String("Error: No ladder data"_jrs); @@ -197,27 +244,22 @@ Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(size_t index, size_t return result; } -Jupiter::String *RenX_Ladder_WebPlugin::generate_ladder_page(size_t index, size_t count) +Jupiter::String *RenX_Ladder_WebPlugin::generate_ladder_page(RenX::LadderDatabase *db, size_t index, size_t count) { Jupiter::String *result = new Jupiter::String(RenX_Ladder_WebPlugin::header); - result->concat(this->generate_entry_table(index, count)); + result->concat(generate_search(db)); + result->concat(generate_database_selector(db)); + result->concat(this->generate_entry_table(db, index, count)); result->concat(RenX_Ladder_WebPlugin::footer); return result; } /** Search page */ -Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(const Jupiter::ReadableString &name) +Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(RenX::LadderDatabase *db, const Jupiter::ReadableString &name) { Jupiter::String *result = new Jupiter::String(RenX_Ladder_WebPlugin::header); - - if (RenX::ladder_databases.size() == 0) - { - result->concat("Error: No ladder databases loaded"_jrs); - result->concat(RenX_Ladder_WebPlugin::footer); - return result; - } - - RenX::LadderDatabase *db = RenX::ladder_databases.get(0); + result->concat(generate_search(db)); + result->concat(generate_database_selector(db)); if (db->getEntries() == 0) // No ladder data { @@ -248,18 +290,11 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(const Jupiter::Read } /** Profile page */ -Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(uint64_t steam_id) +Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(RenX::LadderDatabase *db, uint64_t steam_id) { Jupiter::String *result = new Jupiter::String(RenX_Ladder_WebPlugin::header); - - if (RenX::ladder_databases.size() == 0) - { - result->concat("Error: No ladder databases loaded"_jrs); - result->concat(RenX_Ladder_WebPlugin::footer); - return result; - } - - RenX::LadderDatabase *db = RenX::ladder_databases.get(0); + result->concat(generate_search(db)); + result->concat(generate_database_selector(db)); if (db->getEntries() == 0) // No ladder data { @@ -294,8 +329,24 @@ RenX_Ladder_WebPlugin pluginInstance; /** Content functions */ +Jupiter::ReadableString *generate_no_db_page() +{ + Jupiter::String *result = new Jupiter::String(pluginInstance.header); + if (RenX::ladder_databases.size() != 0) + { + result->concat(generate_search(nullptr)); + result->concat(generate_database_selector(nullptr)); + result->concat("Error: No such database exists"_jrs); + } + else + result->concat("Error: No ladder databases loaded"_jrs); + result->concat(pluginInstance.footer); + return result; +} + Jupiter::ReadableString *handle_ladder_page(const Jupiter::ReadableString &query_string) { + RenX::LadderDatabase *db = RenX::default_ladder_database; size_t start_index = 0, count = 50; if (query_string.isNotEmpty()) @@ -303,35 +354,85 @@ Jupiter::ReadableString *handle_ladder_page(const Jupiter::ReadableString &query Jupiter::HTTP::HTMLFormResponse html_form_response(query_string); start_index = static_cast(html_form_response.table.getInt("start"_jrs, 0)); count = static_cast(html_form_response.table.getInt("count"_jrs, 50)); + + const Jupiter::ReadableString &db_name = html_form_response.table.get("database"_jrs); + if (db_name.isNotEmpty()) + { + db = nullptr; + for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) + if (RenX::ladder_databases.get(index)->getName().equalsi(db_name)) + { + db = RenX::ladder_databases.get(index); + break; + } + } } - return pluginInstance.generate_ladder_page(start_index, count); + + if (db == nullptr) + return generate_no_db_page(); + + return pluginInstance.generate_ladder_page(db, start_index, count); } Jupiter::ReadableString *handle_search_page(const Jupiter::ReadableString &query_string) { + RenX::LadderDatabase *db = RenX::default_ladder_database; Jupiter::ReferenceString name; + if (query_string.isNotEmpty()) { Jupiter::HTTP::HTMLFormResponse html_form_response(query_string); name = html_form_response.table.get("name"_jrs); + + const Jupiter::ReadableString &db_name = html_form_response.table.get("database"_jrs); + if (db_name.isNotEmpty()) + { + db = nullptr; + for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) + if (RenX::ladder_databases.get(index)->getName().equalsi(db_name)) + { + db = RenX::ladder_databases.get(index); + break; + } + } } + if (db == nullptr) + return generate_no_db_page(); + if (name.isEmpty()) // Generate ladder page when no name specified return handle_ladder_page(query_string); - return pluginInstance.generate_search_page(name); + return pluginInstance.generate_search_page(db, name); } Jupiter::ReadableString *handle_profile_page(const Jupiter::ReadableString &query_string) { + RenX::LadderDatabase *db = RenX::default_ladder_database; uint64_t steam_id = 0; + if (query_string.isNotEmpty()) { Jupiter::HTTP::HTMLFormResponse html_form_response(query_string); steam_id = html_form_response.table.getLongLong("id"_jrs); + + const Jupiter::ReadableString &db_name = html_form_response.table.get("database"_jrs); + if (db_name.isNotEmpty()) + { + db = nullptr; + for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) + if (RenX::ladder_databases.get(index)->getName().equalsi(db_name)) + { + db = RenX::ladder_databases.get(index); + break; + } + } } - return pluginInstance.generate_profile_page(steam_id); + if (db == nullptr) + return generate_no_db_page(); + + return pluginInstance.generate_profile_page(db, steam_id); } extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin() diff --git a/RenX.Ladder.Web/RenX_Ladder_Web.h b/RenX.Ladder.Web/RenX_Ladder_Web.h index c4478e3..0715a57 100644 --- a/RenX.Ladder.Web/RenX_Ladder_Web.h +++ b/RenX.Ladder.Web/RenX_Ladder_Web.h @@ -27,14 +27,14 @@ class RenX_Ladder_WebPlugin : public RenX::Plugin { protected: - Jupiter::String generate_entry_table(size_t index, size_t count); + Jupiter::String generate_entry_table(RenX::LadderDatabase *db, size_t index, size_t count); public: Jupiter::StringS header; Jupiter::StringS footer; - Jupiter::String *generate_ladder_page(size_t start_index, size_t count); - Jupiter::String *generate_search_page(const Jupiter::ReadableString &name); - Jupiter::String *generate_profile_page(uint64_t steam_id); + Jupiter::String *generate_ladder_page(RenX::LadderDatabase *db, size_t start_index, size_t count); + Jupiter::String *generate_search_page(RenX::LadderDatabase *db, const Jupiter::ReadableString &name); + Jupiter::String *generate_profile_page(RenX::LadderDatabase *db, uint64_t steam_id); RenX_Ladder_WebPlugin(); ~RenX_Ladder_WebPlugin(); diff --git a/RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj b/RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj new file mode 100644 index 0000000..e2492f6 --- /dev/null +++ b/RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {6F0141F3-CF64-47D9-8EC2-80A38FAFDAC7} + RenX.Ladder.Weekly + + + + Application + true + v140 + MultiByte + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\Plugins\ + AllRules.ruleset + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ../Bot;../Jupiter;../RenX.Core + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj.filters b/RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj.filters new file mode 100644 index 0000000..4e22405 --- /dev/null +++ b/RenX.Ladder.Weekly/RenX.Ladder.Weekly.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/RenX.Ladder.Weekly/RenX_Ladder_Weekly.cpp b/RenX.Ladder.Weekly/RenX_Ladder_Weekly.cpp new file mode 100644 index 0000000..fe58a1e --- /dev/null +++ b/RenX.Ladder.Weekly/RenX_Ladder_Weekly.cpp @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#include +#include "Jupiter/INIFile.h" +#include "Jupiter/IRC_Client.h" +#include "RenX_Ladder_Weekly.h" + +using namespace Jupiter::literals; + +RenX_Ladder_Weekly_TimePlugin::RenX_Ladder_Weekly_TimePlugin() +{ + // Load database + this->database.process_file(Jupiter::IRC::Client::Config->get(this->getName(), "LadderDatabase"_jrs, "Ladder.Weekly.db"_jrs)); + this->database.setName(Jupiter::IRC::Client::Config->get(this->getName(), "DatabaseName"_jrs, "Weekly"_jrs)); + + this->last_sorted_day = gmtime(std::addressof(time(0)))->tm_wday; + this->reset_day = Jupiter::IRC::Client::Config->getInt(this->getName(), "ResetDay"_jrs); + this->database.OnPreUpdateLadder = OnPreUpdateLadder; + + // Force database to default, if desired + if (Jupiter::IRC::Client::Config->getBool(this->getName(), "ForceDefault"_jrs, false)) + RenX::default_ladder_database = &this->database; +} + +// Plugin instantiation and entry point. +RenX_Ladder_Weekly_TimePlugin pluginInstance; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times) +{ + tm *tm_ptr = gmtime(std::addressof(time(0))); + if (pluginInstance.last_sorted_day != tm_ptr->tm_wday && tm_ptr->tm_wday == pluginInstance.reset_day) + database.erase(); + pluginInstance.last_sorted_day = tm_ptr->tm_wday; +} + +extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin() +{ + return &pluginInstance; +} diff --git a/RenX.Ladder.Weekly/RenX_Ladder_Weekly.h b/RenX.Ladder.Weekly/RenX_Ladder_Weekly.h new file mode 100644 index 0000000..b3d5542 --- /dev/null +++ b/RenX.Ladder.Weekly/RenX_Ladder_Weekly.h @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#if !defined _RENX_LADDER_ALL_TIME +#define _RENX_LADDER_ALL_TIME + +#include "Jupiter/Plugin.h" +#include "Jupiter/Reference_String.h" +#include "RenX_Plugin.h" +#include "RenX_LadderDatabase.h" + +class RenX_Ladder_Weekly_TimePlugin : public RenX::Plugin +{ +public: + const Jupiter::ReadableString &getName() override { return name; } + + RenX_Ladder_Weekly_TimePlugin(); + + int last_sorted_day; + int reset_day; +private: + RenX::LadderDatabase database; + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Ladder.Weekly"); +}; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times); + +#endif // _RENX_LADDER_ALL_TIME \ No newline at end of file diff --git a/RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj b/RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj new file mode 100644 index 0000000..ce5eef8 --- /dev/null +++ b/RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {075AF69B-71D6-43B9-B102-4649CB2CA40C} + RenX.Ladder.Yearly + + + + Application + true + v140 + MultiByte + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\Plugins\ + AllRules.ruleset + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + ../Bot;../Jupiter;../RenX.Core + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj.filters b/RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj.filters new file mode 100644 index 0000000..6a93ff7 --- /dev/null +++ b/RenX.Ladder.Yearly/RenX.Ladder.Yearly.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/RenX.Ladder.Yearly/RenX_Ladder_Yearly.cpp b/RenX.Ladder.Yearly/RenX_Ladder_Yearly.cpp new file mode 100644 index 0000000..acee35f --- /dev/null +++ b/RenX.Ladder.Yearly/RenX_Ladder_Yearly.cpp @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#include +#include "Jupiter/INIFile.h" +#include "Jupiter/IRC_Client.h" +#include "RenX_Ladder_Yearly.h" + +using namespace Jupiter::literals; + +RenX_Ladder_Yearly_TimePlugin::RenX_Ladder_Yearly_TimePlugin() +{ + // Load database + this->database.process_file(Jupiter::IRC::Client::Config->get(this->getName(), "LadderDatabase"_jrs, "Ladder.Yearly.db"_jrs)); + this->database.setName(Jupiter::IRC::Client::Config->get(this->getName(), "DatabaseName"_jrs, "Yearly"_jrs)); + + this->last_sorted_year = gmtime(std::addressof(time(0)))->tm_year; + this->database.OnPreUpdateLadder = OnPreUpdateLadder; + + // Force database to default, if desired + if (Jupiter::IRC::Client::Config->getBool(this->getName(), "ForceDefault"_jrs, false)) + RenX::default_ladder_database = &this->database; +} + +// Plugin instantiation and entry point. +RenX_Ladder_Yearly_TimePlugin pluginInstance; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times) +{ + tm *tm_ptr = gmtime(std::addressof(time(0))); + if (pluginInstance.last_sorted_year != tm_ptr->tm_year) + database.erase(); + pluginInstance.last_sorted_year = tm_ptr->tm_year; +} + +extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin() +{ + return &pluginInstance; +} diff --git a/RenX.Ladder.Yearly/RenX_Ladder_Yearly.h b/RenX.Ladder.Yearly/RenX_Ladder_Yearly.h new file mode 100644 index 0000000..85ae403 --- /dev/null +++ b/RenX.Ladder.Yearly/RenX_Ladder_Yearly.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#if !defined _RENX_LADDER_ALL_TIME +#define _RENX_LADDER_ALL_TIME + +#include "Jupiter/Plugin.h" +#include "Jupiter/Reference_String.h" +#include "RenX_Plugin.h" +#include "RenX_LadderDatabase.h" + +class RenX_Ladder_Yearly_TimePlugin : public RenX::Plugin +{ +public: + const Jupiter::ReadableString &getName() override { return name; } + + RenX_Ladder_Yearly_TimePlugin(); + + int last_sorted_year = 0; +private: + RenX::LadderDatabase database; + STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Ladder.Yearly"); +}; + +void OnPreUpdateLadder(RenX::LadderDatabase &database, RenX::Server *server, const RenX::TeamType &team, bool output_times); + +#endif // _RENX_LADDER_ALL_TIME \ No newline at end of file diff --git a/RenX.Ladder/RenX_Ladder.cpp b/RenX.Ladder/RenX_Ladder.cpp index c53ce15..cb722cf 100644 --- a/RenX.Ladder/RenX_Ladder.cpp +++ b/RenX.Ladder/RenX_Ladder.cpp @@ -35,10 +35,6 @@ RenX_LadderPlugin::RenX_LadderPlugin() RenX_LadderPlugin::max_ladder_command_part_name_output = 0; else RenX_LadderPlugin::max_ladder_command_part_name_output = mlcpno; - RenX_LadderPlugin::db_filename = Jupiter::IRC::Client::Config->get(this->getName(), "LadderDatabase"_jrs, "Ladder.db"_jrs); - - // load database - RenX_LadderPlugin::database.process_file(RenX_LadderPlugin::db_filename); } /** Wait until the client list has been updated to update the ladder */ @@ -62,7 +58,8 @@ void RenX_LadderPlugin::RenX_OnCommand(RenX::Server *server, const Jupiter::Read { server->varData.set(this->name, "w"_jrs, "0"_jrs); RenX::TeamType team = static_cast(server->varData.get(this->name, "t"_jrs, "\0"_jrs).get(0)); - RenX_LadderPlugin::database.updateLadder(server, team, RenX_LadderPlugin::output_times); + for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) + RenX::ladder_databases.get(index)->updateLadder(server, team, RenX_LadderPlugin::output_times); } } } @@ -103,14 +100,14 @@ GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupiter::Reada if (rank == 0) return new GenericCommand::ResponseLine("Error: Invalid parameters"_jrs, GenericCommand::DisplayType::PrivateError); - entry = pluginInstance.database.getPlayerEntryByIndex(rank - 1); + entry = RenX::default_ladder_database->getPlayerEntryByIndex(rank - 1); if (entry == nullptr) return new GenericCommand::ResponseLine("Error: Player not found"_jrs, GenericCommand::DisplayType::PrivateError); return new GenericCommand::ResponseLine(FormatLadderResponse(entry, rank), GenericCommand::DisplayType::PublicSuccess); } - Jupiter::SLList> list = pluginInstance.database.getPlayerEntriesAndIndexByPartName(parameters, pluginInstance.getMaxLadderCommandPartNameOutput()); + Jupiter::SLList> list = RenX::default_ladder_database->getPlayerEntriesAndIndexByPartName(parameters, pluginInstance.getMaxLadderCommandPartNameOutput()); if (list.size() == 0) return new GenericCommand::ResponseLine("Error: Player not found"_jrs, GenericCommand::DisplayType::PrivateError); @@ -152,7 +149,7 @@ void LadderGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, { if (player->steamid != 0) { - std::pair pair = pluginInstance.database.getPlayerEntryAndIndex(player->steamid); + std::pair pair = RenX::default_ladder_database->getPlayerEntryAndIndex(player->steamid); if (pair.first != nullptr) source->sendMessage(FormatLadderResponse(pair.first, pair.second + 1)); else diff --git a/RenX.Ladder/RenX_Ladder.h b/RenX.Ladder/RenX_Ladder.h index 88b97a7..f7cc16d 100644 --- a/RenX.Ladder/RenX_Ladder.h +++ b/RenX.Ladder/RenX_Ladder.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2015 Jessica James. + * Copyright (C) 2015-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -42,12 +42,10 @@ public: size_t getMaxLadderCommandPartNameOutput() const; RenX_LadderPlugin(); - RenX::LadderDatabase database; private: /** Configuration variables */ bool only_pure, output_times; size_t max_ladder_command_part_name_output; - Jupiter::CStringS db_filename; STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Ladder"); };