Q3Stats is now open source! :)

This commit is contained in:
2017-03-06 20:33:09 +01:00
commit bfdcb87cef
197 changed files with 16395 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="../../../basics/stats141.xsl"?>
<match id="0" datetime="2017/02/20 14:36:26" map="q3dm7" type="FFA" isTeamGame="false" duration="583">
<player name="Player 1">
<stat name="Score" value="30"/>
<stat name="Kills" value="30"/>
<stat name="Deaths" value="21"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="9"/>
<stat name="DamageGiven" value="4894"/>
<stat name="DamageTaken" value="4329"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="1"/>
<weapon name="MG" hits="82" shots="325" kills="1"/>
<weapon name="SG" hits="29" shots="192" kills="2"/>
<weapon name="RL" hits="51" shots="140" kills="21"/>
<weapon name="RG" hits="9" shots="34" kills="4"/>
<weapon name="PG" hits="14" shots="117" kills="1"/>
</weapons>
<stat name="HealthTotal" value="925"/>
<stat name="ArmorTotal" value="1255"/>
<items>
<item name="MH" pickups="3"/>
<item name="RA" pickups="5"/>
<item name="YA" pickups="5"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 2">
<stat name="Score" value="27"/>
<stat name="Kills" value="28"/>
<stat name="Deaths" value="19"/>
<stat name="Suicides" value="1"/>
<stat name="Net" value="8"/>
<stat name="DamageGiven" value="5822"/>
<stat name="DamageTaken" value="3792"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="1"/>
<weapon name="MG" hits="56" shots="244" kills="1"/>
<weapon name="SG" hits="55" shots="256" kills="3"/>
<weapon name="RL" hits="70" shots="163" kills="19"/>
<weapon name="RG" hits="6" shots="19" kills="1"/>
<weapon name="PG" hits="18" shots="173" kills="3"/>
</weapons>
<stat name="HealthTotal" value="810"/>
<stat name="ArmorTotal" value="930"/>
<items>
<item name="MH" pickups="1"/>
<item name="RA" pickups="1"/>
<item name="YA" pickups="7"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="5" time="51188"/>
</powerups>
</player>
</match>

View File

@@ -0,0 +1,168 @@
<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="../../../basics/stats141.xsl"?>
<match id="0" datetime="2017/02/20 14:26:14" map="gen-q2dm1" type="FFA" isTeamGame="false" duration="566">
<player name="Player 1">
<stat name="Score" value="25"/>
<stat name="Kills" value="25"/>
<stat name="Deaths" value="19"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="6"/>
<stat name="DamageGiven" value="4424"/>
<stat name="DamageTaken" value="3294"/>
<weapons>
<weapon name="G" hits="9" shots="0" kills="2"/>
<weapon name="MG" hits="66" shots="252" kills="1"/>
<weapon name="SG" hits="36" shots="160" kills="1"/>
<weapon name="RL" hits="52" shots="136" kills="16"/>
<weapon name="RG" hits="9" shots="23" kills="4"/>
<weapon name="PG" hits="12" shots="57" kills="1"/>
</weapons>
<stat name="HealthTotal" value="885"/>
<stat name="ArmorTotal" value="800"/>
<items>
<item name="MH" pickups="3"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="7"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 2">
<stat name="Score" value="30"/>
<stat name="Kills" value="31"/>
<stat name="Deaths" value="14"/>
<stat name="Suicides" value="1"/>
<stat name="Net" value="16"/>
<stat name="DamageGiven" value="4121"/>
<stat name="DamageTaken" value="3319"/>
<weapons>
<weapon name="MG" hits="26" shots="87" kills="1"/>
<weapon name="SG" hits="14" shots="80" kills="0"/>
<weapon name="GL" hits="0" shots="2" kills="0"/>
<weapon name="RL" hits="54" shots="135" kills="21"/>
<weapon name="LG" hits="72" shots="308" kills="8"/>
<weapon name="RG" hits="1" shots="6" kills="0"/>
<weapon name="PG" hits="8" shots="71" kills="1"/>
</weapons>
<stat name="HealthTotal" value="925"/>
<stat name="ArmorTotal" value="1210"/>
<items>
<item name="MH" pickups="6"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="10"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 3">
<stat name="Score" value="24"/>
<stat name="Kills" value="24"/>
<stat name="Deaths" value="20"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="4"/>
<stat name="DamageGiven" value="4289"/>
<stat name="DamageTaken" value="3590"/>
<weapons>
<weapon name="MG" hits="98" shots="287" kills="1"/>
<weapon name="RL" hits="46" shots="133" kills="17"/>
<weapon name="LG" hits="78" shots="289" kills="5"/>
<weapon name="RG" hits="1" shots="6" kills="0"/>
<weapon name="PG" hits="13" shots="47" kills="1"/>
</weapons>
<stat name="HealthTotal" value="610"/>
<stat name="ArmorTotal" value="875"/>
<items>
<item name="MH" pickups="2"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="8"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 4">
<stat name="Score" value="8"/>
<stat name="Kills" value="9"/>
<stat name="Deaths" value="19"/>
<stat name="Suicides" value="1"/>
<stat name="Net" value="-11"/>
<stat name="DamageGiven" value="1865"/>
<stat name="DamageTaken" value="3124"/>
<weapons>
<weapon name="G" hits="2" shots="0" kills="1"/>
<weapon name="MG" hits="55" shots="378" kills="1"/>
<weapon name="SG" hits="7" shots="224" kills="0"/>
<weapon name="GL" hits="2" shots="6" kills="2"/>
<weapon name="RL" hits="16" shots="58" kills="3"/>
<weapon name="RG" hits="4" shots="14" kills="2"/>
<weapon name="PG" hits="12" shots="114" kills="0"/>
</weapons>
<stat name="HealthTotal" value="765"/>
<stat name="ArmorTotal" value="440"/>
<items>
<item name="MH" pickups="3"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="3"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 5">
<stat name="Score" value="8"/>
<stat name="Kills" value="8"/>
<stat name="Deaths" value="17"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="-9"/>
<stat name="DamageGiven" value="1977"/>
<stat name="DamageTaken" value="2249"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="0"/>
<weapon name="MG" hits="11" shots="133" kills="1"/>
<weapon name="GL" hits="2" shots="11" kills="1"/>
<weapon name="RL" hits="23" shots="63" kills="5"/>
<weapon name="LG" hits="19" shots="100" kills="1"/>
</weapons>
<stat name="HealthTotal" value="405"/>
<stat name="ArmorTotal" value="20"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="0"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 6">
<stat name="Score" value="3"/>
<stat name="Kills" value="3"/>
<stat name="Deaths" value="2"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="1"/>
<stat name="DamageGiven" value="410"/>
<stat name="DamageTaken" value="480"/>
<weapons>
<weapon name="MG" hits="4" shots="50" kills="0"/>
<weapon name="RL" hits="4" shots="7" kills="3"/>
<weapon name="LG" hits="7" shots="83" kills="0"/>
</weapons>
<stat name="HealthTotal" value="75"/>
<stat name="ArmorTotal" value="120"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="1"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
</match>

View File

@@ -0,0 +1,174 @@
<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="../../../basics/stats141.xsl"?>
<match id="0" datetime="2017/02/20 14:36:26" map="q3dm7" type="FFA" isTeamGame="false" duration="583">
<player name="Player 1">
<stat name="Score" value="30"/>
<stat name="Kills" value="30"/>
<stat name="Deaths" value="21"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="9"/>
<stat name="DamageGiven" value="4894"/>
<stat name="DamageTaken" value="4329"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="1"/>
<weapon name="MG" hits="82" shots="325" kills="1"/>
<weapon name="SG" hits="29" shots="192" kills="2"/>
<weapon name="RL" hits="51" shots="140" kills="21"/>
<weapon name="RG" hits="9" shots="34" kills="4"/>
<weapon name="PG" hits="14" shots="117" kills="1"/>
</weapons>
<stat name="HealthTotal" value="925"/>
<stat name="ArmorTotal" value="1255"/>
<items>
<item name="MH" pickups="3"/>
<item name="RA" pickups="5"/>
<item name="YA" pickups="5"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="2" time="13063"/>
</powerups>
</player>
<player name="Player 2">
<stat name="Score" value="27"/>
<stat name="Kills" value="28"/>
<stat name="Deaths" value="19"/>
<stat name="Suicides" value="1"/>
<stat name="Net" value="8"/>
<stat name="DamageGiven" value="5822"/>
<stat name="DamageTaken" value="3792"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="1"/>
<weapon name="MG" hits="56" shots="244" kills="1"/>
<weapon name="SG" hits="55" shots="256" kills="3"/>
<weapon name="RL" hits="70" shots="163" kills="19"/>
<weapon name="RG" hits="6" shots="19" kills="1"/>
<weapon name="PG" hits="18" shots="173" kills="3"/>
</weapons>
<stat name="HealthTotal" value="810"/>
<stat name="ArmorTotal" value="930"/>
<items>
<item name="MH" pickups="1"/>
<item name="RA" pickups="1"/>
<item name="YA" pickups="7"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="5" time="51188"/>
</powerups>
</player>
<player name="Player 3">
<stat name="Score" value="26"/>
<stat name="Kills" value="27"/>
<stat name="Deaths" value="30"/>
<stat name="Suicides" value="1"/>
<stat name="Net" value="-4"/>
<stat name="DamageGiven" value="5753"/>
<stat name="DamageTaken" value="4840"/>
<weapons>
<weapon name="G" hits="2" shots="0" kills="1"/>
<weapon name="MG" hits="89" shots="404" kills="1"/>
<weapon name="SG" hits="22" shots="96" kills="2"/>
<weapon name="RL" hits="38" shots="100" kills="11"/>
<weapon name="RG" hits="16" shots="37" kills="7"/>
<weapon name="PG" hits="73" shots="470" kills="5"/>
</weapons>
<stat name="HealthTotal" value="580"/>
<stat name="ArmorTotal" value="620"/>
<items>
<item name="MH" pickups="1"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="6"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="2" time="29078"/>
</powerups>
</player>
<player name="Player 4">
<stat name="Score" value="13"/>
<stat name="Kills" value="15"/>
<stat name="Deaths" value="22"/>
<stat name="Suicides" value="2"/>
<stat name="Net" value="-9"/>
<stat name="DamageGiven" value="2665"/>
<stat name="DamageTaken" value="4312"/>
<weapons>
<weapon name="MG" hits="36" shots="285" kills="0"/>
<weapon name="SG" hits="23" shots="256" kills="1"/>
<weapon name="RL" hits="29" shots="84" kills="9"/>
<weapon name="RG" hits="3" shots="13" kills="0"/>
<weapon name="PG" hits="43" shots="356" kills="5"/>
</weapons>
<stat name="HealthTotal" value="870"/>
<stat name="ArmorTotal" value="1030"/>
<items>
<item name="MH" pickups="3"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="9"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="4" time="13086"/>
</powerups>
</player>
<player name="Player 5">
<stat name="Score" value="8"/>
<stat name="Kills" value="8"/>
<stat name="Deaths" value="21"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="-13"/>
<stat name="DamageGiven" value="2652"/>
<stat name="DamageTaken" value="3825"/>
<weapons>
<weapon name="G" hits="2" shots="0" kills="1"/>
<weapon name="MG" hits="65" shots="456" kills="1"/>
<weapon name="RL" hits="29" shots="116" kills="5"/>
<weapon name="RG" hits="1" shots="9" kills="0"/>
<weapon name="PG" hits="38" shots="451" kills="1"/>
</weapons>
<stat name="HealthTotal" value="910"/>
<stat name="ArmorTotal" value="900"/>
<items>
<item name="MH" pickups="1"/>
<item name="RA" pickups="2"/>
<item name="YA" pickups="6"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="1" time="1015"/>
</powerups>
</player>
<player name="Player 6">
<stat name="Score" value="18"/>
<stat name="Kills" value="18"/>
<stat name="Deaths" value="13"/>
<stat name="Suicides" value="0"/>
<stat name="Net" value="5"/>
<stat name="DamageGiven" value="2917"/>
<stat name="DamageTaken" value="3605"/>
<weapons>
<weapon name="MG" hits="37" shots="209" kills="0"/>
<weapon name="SG" hits="36" shots="224" kills="3"/>
<weapon name="RL" hits="17" shots="61" kills="7"/>
<weapon name="RG" hits="1" shots="10" kills="0"/>
<weapon name="PG" hits="65" shots="619" kills="8"/>
</weapons>
<stat name="HealthTotal" value="1125"/>
<stat name="ArmorTotal" value="1470"/>
<items>
<item name="MH" pickups="5"/>
<item name="RA" pickups="3"/>
<item name="YA" pickups="10"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="3" time="59465"/>
</powerups>
</player>
</match>

View File

@@ -0,0 +1,156 @@
<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="../../../basics/stats141.xsl"?>
<match id="0" datetime="2017/02/20 15:10:16" map="q3dm17" type="FFA" isTeamGame="false" duration="454">
<player name="Player 1">
<stat name="Score" value="30"/>
<stat name="Kills" value="34"/>
<stat name="Deaths" value="15"/>
<stat name="Suicides" value="4"/>
<stat name="Net" value="15"/>
<stat name="DamageGiven" value="4527"/>
<stat name="DamageTaken" value="2507"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="0"/>
<weapon name="MG" hits="43" shots="226" kills="3"/>
<weapon name="SG" hits="71" shots="560" kills="2"/>
<weapon name="RL" hits="70" shots="155" kills="29"/>
<weapon name="RG" hits="0" shots="6" kills="0"/>
</weapons>
<stat name="HealthTotal" value="600"/>
<stat name="ArmorTotal" value="750"/>
<items>
<item name="MH" pickups="4"/>
<item name="RA" pickups="2"/>
<item name="YA" pickups="4"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 2">
<stat name="Score" value="23"/>
<stat name="Kills" value="25"/>
<stat name="Deaths" value="24"/>
<stat name="Suicides" value="2"/>
<stat name="Net" value="-1"/>
<stat name="DamageGiven" value="3977"/>
<stat name="DamageTaken" value="4412"/>
<weapons>
<weapon name="MG" hits="89" shots="353" kills="2"/>
<weapon name="SG" hits="13" shots="80" kills="1"/>
<weapon name="RL" hits="69" shots="185" kills="22"/>
<weapon name="RG" hits="0" shots="1" kills="0"/>
</weapons>
<stat name="HealthTotal" value="600"/>
<stat name="ArmorTotal" value="1045"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="3"/>
<item name="YA" pickups="5"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 3">
<stat name="Score" value="21"/>
<stat name="Kills" value="29"/>
<stat name="Deaths" value="23"/>
<stat name="Suicides" value="8"/>
<stat name="Net" value="-2"/>
<stat name="DamageGiven" value="4136"/>
<stat name="DamageTaken" value="3893"/>
<weapons>
<weapon name="MG" hits="84" shots="464" kills="1"/>
<weapon name="SG" hits="37" shots="176" kills="3"/>
<weapon name="RL" hits="65" shots="185" kills="25"/>
<weapon name="RG" hits="0" shots="1" kills="0"/>
</weapons>
<stat name="HealthTotal" value="300"/>
<stat name="ArmorTotal" value="580"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="4"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 7">
<stat name="Score" value="-5"/>
<stat name="Kills" value="0"/>
<stat name="Deaths" value="2"/>
<stat name="Suicides" value="5"/>
<stat name="Net" value="-7"/>
<stat name="DamageGiven" value="15"/>
<stat name="DamageTaken" value="290"/>
<weapons>
<weapon name="MG" hits="3" shots="114" kills="0"/>
</weapons>
<stat name="HealthTotal" value="0"/>
<stat name="ArmorTotal" value="0"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="0"/>
<item name="YA" pickups="0"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 5">
<stat name="Score" value="9"/>
<stat name="Kills" value="12"/>
<stat name="Deaths" value="30"/>
<stat name="Suicides" value="3"/>
<stat name="Net" value="-21"/>
<stat name="DamageGiven" value="2575"/>
<stat name="DamageTaken" value="3982"/>
<weapons>
<weapon name="MG" hits="110" shots="817" kills="1"/>
<weapon name="SG" hits="56" shots="544" kills="1"/>
<weapon name="RL" hits="34" shots="101" kills="10"/>
</weapons>
<stat name="HealthTotal" value="0"/>
<stat name="ArmorTotal" value="505"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="3"/>
<item name="YA" pickups="0"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 6">
<stat name="Score" value="12"/>
<stat name="Kills" value="14"/>
<stat name="Deaths" value="20"/>
<stat name="Suicides" value="2"/>
<stat name="Net" value="-8"/>
<stat name="DamageGiven" value="2964"/>
<stat name="DamageTaken" value="3110"/>
<weapons>
<weapon name="MG" hits="33" shots="256" kills="2"/>
<weapon name="SG" hits="82" shots="464" kills="3"/>
<weapon name="RL" hits="28" shots="83" kills="9"/>
</weapons>
<stat name="HealthTotal" value="100"/>
<stat name="ArmorTotal" value="1080"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="7"/>
<item name="YA" pickups="0"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="3" time="88716"/>
</powerups>
</player>
</match>

View File

@@ -0,0 +1,162 @@
<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="../../../basics/stats141.xsl"?>
<match id="0" datetime="2017/02/21 14:43:40" map="q3dm17" type="FFA" isTeamGame="false" duration="407">
<player name="Player 1">
<stat name="Score" value="30"/>
<stat name="Kills" value="32"/>
<stat name="Deaths" value="10"/>
<stat name="Suicides" value="2"/>
<stat name="Net" value="20"/>
<stat name="DamageGiven" value="4131"/>
<stat name="DamageTaken" value="2391"/>
<weapons>
<weapon name="G" hits="3" shots="0" kills="1"/>
<weapon name="MG" hits="60" shots="253" kills="0"/>
<weapon name="SG" hits="75" shots="320" kills="4"/>
<weapon name="RL" hits="50" shots="143" kills="24"/>
<weapon name="RG" hits="7" shots="19" kills="3"/>
</weapons>
<stat name="HealthTotal" value="525"/>
<stat name="ArmorTotal" value="830"/>
<items>
<item name="MH" pickups="2"/>
<item name="RA" pickups="4"/>
<item name="YA" pickups="2"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 2">
<stat name="Score" value="23"/>
<stat name="Kills" value="26"/>
<stat name="Deaths" value="25"/>
<stat name="Suicides" value="3"/>
<stat name="Net" value="-2"/>
<stat name="DamageGiven" value="4293"/>
<stat name="DamageTaken" value="4186"/>
<weapons>
<weapon name="MG" hits="68" shots="276" kills="3"/>
<weapon name="SG" hits="75" shots="288" kills="3"/>
<weapon name="RL" hits="64" shots="172" kills="20"/>
<weapon name="RG" hits="0" shots="4" kills="0"/>
</weapons>
<stat name="HealthTotal" value="550"/>
<stat name="ArmorTotal" value="570"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="1"/>
<item name="YA" pickups="3"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 3">
<stat name="Score" value="19"/>
<stat name="Kills" value="22"/>
<stat name="Deaths" value="24"/>
<stat name="Suicides" value="3"/>
<stat name="Net" value="-5"/>
<stat name="DamageGiven" value="3786"/>
<stat name="DamageTaken" value="3980"/>
<weapons>
<weapon name="MG" hits="71" shots="308" kills="2"/>
<weapon name="SG" hits="80" shots="336" kills="3"/>
<weapon name="RL" hits="53" shots="157" kills="17"/>
</weapons>
<stat name="HealthTotal" value="50"/>
<stat name="ArmorTotal" value="885"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="1"/>
<item name="YA" pickups="6"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="2" time="13059"/>
</powerups>
</player>
<player name="Player 4">
<stat name="Score" value="-10"/>
<stat name="Kills" value="5"/>
<stat name="Deaths" value="11"/>
<stat name="Suicides" value="15"/>
<stat name="Net" value="-21"/>
<stat name="DamageGiven" value="1396"/>
<stat name="DamageTaken" value="2093"/>
<weapons>
<weapon name="MG" hits="61" shots="316" kills="2"/>
<weapon name="SG" hits="6" shots="96" kills="0"/>
<weapon name="RL" hits="3" shots="19" kills="1"/>
<weapon name="RG" hits="11" shots="50" kills="2"/>
</weapons>
<stat name="HealthTotal" value="175"/>
<stat name="ArmorTotal" value="620"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="4"/>
<item name="YA" pickups="0"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 5">
<stat name="Score" value="-5"/>
<stat name="Kills" value="9"/>
<stat name="Deaths" value="17"/>
<stat name="Suicides" value="14"/>
<stat name="Net" value="-22"/>
<stat name="DamageGiven" value="1797"/>
<stat name="DamageTaken" value="2952"/>
<weapons>
<weapon name="G" hits="1" shots="0" kills="1"/>
<weapon name="MG" hits="62" shots="656" kills="1"/>
<weapon name="SG" hits="1" shots="16" kills="0"/>
<weapon name="RL" hits="33" shots="116" kills="5"/>
<weapon name="RG" hits="2" shots="7" kills="2"/>
</weapons>
<stat name="HealthTotal" value="250"/>
<stat name="ArmorTotal" value="190"/>
<items>
<item name="MH" pickups="1"/>
<item name="RA" pickups="1"/>
<item name="YA" pickups="0"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
</powerups>
</player>
<player name="Player 6">
<stat name="Score" value="6"/>
<stat name="Kills" value="9"/>
<stat name="Deaths" value="16"/>
<stat name="Suicides" value="3"/>
<stat name="Net" value="-10"/>
<stat name="DamageGiven" value="2501"/>
<stat name="DamageTaken" value="2302"/>
<weapons>
<weapon name="MG" hits="48" shots="327" kills="0"/>
<weapon name="SG" hits="17" shots="208" kills="0"/>
<weapon name="RL" hits="11" shots="45" kills="9"/>
<weapon name="RG" hits="2" shots="11" kills="0"/>
</weapons>
<stat name="HealthTotal" value="175"/>
<stat name="ArmorTotal" value="575"/>
<items>
<item name="MH" pickups="0"/>
<item name="RA" pickups="3"/>
<item name="YA" pickups="1"/>
<item name="GA" pickups="0"/>
</items>
<powerups>
<item name="Quad" pickups="2" time="55437"/>
</powerups>
</player>
</match>

View File

@@ -0,0 +1,122 @@
# -*- coding: utf-8 -*-
import datetime
import mock
from q3stats.lib.charts import day
from q3stats.lib.scripts import utils
from q3stats.models import Game, Score
from q3stats.testing import BaseQ3StatsTestCase
class Test_LibChartsDay(BaseQ3StatsTestCase):
@classmethod
def setUpClass(cls):
super(Test_LibChartsDay, cls).setUpClass()
with utils.db_session(cls._config) as session:
game1_dt = datetime.datetime(2017, 2, 14, 20, 21, 0)
game1 = Game(
uuid='game1',
map='Q3DM7',
date=game1_dt.date(),
time=game1_dt.time(),
fraglimit=20,
attrs={}
)
game1.scores.extend([
Score(
player='Player 1',
score=20,
kills=21,
deaths=10,
suicides=1,
net=11,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
Score(
player='Player 2',
score=10,
kills=11,
deaths=20,
suicides=1,
net=10,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
])
game2_dt = game1_dt + datetime.timedelta(seconds=60)
game2 = Game(
uuid='game2',
map='Q3DM17',
date=game2_dt.date(),
time=game2_dt.time(),
fraglimit=20,
attrs={}
)
game2.scores.extend([
Score(
player='Player 1',
score=10,
kills=11,
deaths=20,
suicides=1,
net=10,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
Score(
player='Player 2',
score=20,
kills=21,
deaths=10,
suicides=1,
net=11,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
])
session.add_all([game1, game2])
session.commit()
cls._day = game1_dt.date()
def test_get_day_chart(self):
with utils.db_session(self._config) as session:
maps, scores = day.get_day_chart(self._day, session)
assert maps == ['Q3DM7', 'Q3DM17']
pl1_scores, pl2_scores = scores
assert pl1_scores['name'] == 'Player 1'
assert pl1_scores['data'] == [20, 10]
assert pl2_scores['name'] == 'Player 2'
assert pl2_scores['data'] == [10, 20]

View File

@@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
import datetime
import mock
from q3stats.lib.charts import player
from q3stats.lib.scripts import utils
from q3stats.models import Game, Score
from q3stats.testing import BaseQ3StatsTestCase
class Test_LibChartsPlayer(BaseQ3StatsTestCase):
@classmethod
def setUpClass(cls):
super(Test_LibChartsPlayer, cls).setUpClass()
with utils.db_session(cls._config) as session:
game1_dt = datetime.datetime(2017, 2, 14, 20, 21, 0)
game1 = Game(
uuid='game1',
map='Q3DM7',
date=game1_dt.date(),
time=game1_dt.time(),
fraglimit=20,
attrs={}
)
game1.scores.extend([
Score(
player='Player 1',
score=20,
kills=21,
deaths=10,
suicides=1,
net=11,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={
'BFG': {'hits': 0, 'shots': 0},
'G': {'hits': 1, 'shots': 1},
'LG': {'hits': 0, 'shots': 1},
'MG': {'hits': 1, 'shots': 2},
},
items={},
powerups={}
),
Score(
player='Player 2',
score=10,
kills=11,
deaths=20,
suicides=1,
net=10,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
])
game2_dt = game1_dt + datetime.timedelta(seconds=60)
game2 = Game(
uuid='game2',
map='Q3DM17',
date=game2_dt.date(),
time=game2_dt.time(),
fraglimit=20,
attrs={}
)
game2.scores.extend([
Score(
player='Player 1',
score=10,
kills=11,
deaths=20,
suicides=1,
net=10,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={
'BFG': {'hits': 0, 'shots': 0},
'G': {'hits': 1, 'shots': 1},
'LG': {'hits': 0, 'shots': 1},
'MG': {'hits': 1, 'shots': 2},
},
items={},
powerups={}
),
Score(
player='Player 2',
score=20,
kills=21,
deaths=10,
suicides=1,
net=11,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
])
session.add_all([game1, game2])
session.commit()
cls._day = game1_dt.date()
def test_get_player_wins_chart_date(self):
with utils.db_session(self._config) as session:
categories, wins, loses = player.get_player_wins_chart(
session, 'Player 1', agg_by='date'
)
assert categories == [self._day]
assert wins == [1]
assert loses == [1]
def test_get_player_wins_chart_map(self):
with utils.db_session(self._config) as session:
categories, wins, loses = player.get_player_wins_chart(
session, 'Player 1', agg_by='map'
)
assert categories == ['Q3DM17', 'Q3DM7']
assert wins == [0, 1]
assert loses == [1, 0]
def test_get_player_avg_accuracy_chart_date(self):
with utils.db_session(self._config) as session:
categories, series = player.get_player_avg_accuracy_chart(
session, 'Player 1', agg_by='date'
)
assert categories == [self._day]
weapon_accuracies = {
x['name']: x['data'] for x in series
}
assert 'Gauntlet' not in weapon_accuracies
assert weapon_accuracies['BFG10k'] == [None]
assert weapon_accuracies['Lightning Gun'] == [0.0]
assert weapon_accuracies['Machine Gun'] == [50.0]
assert weapon_accuracies['Plasma Gun'] == [None]
def test_get_player_avg_accuracy_chart_map(self):
with utils.db_session(self._config) as session:
categories, series = player.get_player_avg_accuracy_chart(
session, 'Player 1', agg_by='map'
)
weapon_accuracies = {
x['name']: x['data'] for x in series
}
assert 'Gauntlet' not in weapon_accuracies
assert weapon_accuracies['BFG10k'] == [None, None]
assert weapon_accuracies['Lightning Gun'] == [0.0, 0.0]
assert weapon_accuracies['Machine Gun'] == [50.0, 50.0]
assert weapon_accuracies['Plasma Gun'] == [None, None]

View File

@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
import datetime
from q3stats.lib import queries
from q3stats.lib.scripts import utils
from q3stats.models import Game, Score
from q3stats.testing import BaseQ3StatsTestCase
class Test_LibQueries(BaseQ3StatsTestCase):
@classmethod
def setUpClass(cls):
super(Test_LibQueries, cls).setUpClass()
with utils.db_session(cls._config) as session:
game1_dt = datetime.datetime.now() - datetime.timedelta(days=1)
game1 = Game(
uuid='game1',
map='Q3DM7',
date=game1_dt.date(),
time=game1_dt.time(),
fraglimit=20,
attrs={}
)
game1.scores.extend([
Score(
player='Player 1',
score=20,
kills=20,
deaths=0,
suicides=10,
net=0,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
])
game2_dt = datetime.datetime.now()
game2 = Game(
uuid='game2',
map='Q3DM7',
date=game2_dt.date(),
time=game2_dt.time(),
fraglimit=10,
attrs={}
)
game2.scores.extend([
Score(
player='Player 2',
score=-10,
kills=10,
deaths=0,
suicides=20,
net=0,
damage_taken=123,
damage_given=456,
total_health=123,
total_armor=456,
weapons={},
items={},
powerups={}
),
])
session.add_all([game1, game2])
session.commit()
cls._days = [game2_dt.date(), game1_dt.date()]
def test_get_game_dates(self):
with utils.db_session(self._config) as session:
dates = queries.get_game_dates(session)
assert dates == self._days
def test_get_palyer_sessions(self):
with utils.db_session(self._config) as session:
sessions = queries.get_player_sessions(session, 'Player 1')
assert sessions == [self._days[1]]
def test_get_top_players_kills(self):
with utils.db_session(self._config) as session:
result = queries.get_top_players(session, agg_by='kills')
assert len(result) == 2
assert result[0] == ('Player 1', 20)
assert result[1] == ('Player 2', 10)
def test_get_top_players_suicides(self):
with utils.db_session(self._config) as session:
result = queries.get_top_players(session, agg_by='suicides')
assert len(result) == 2
assert result[0] == ('Player 2', 20)
assert result[1] == ('Player 1', 10)

View File

@@ -0,0 +1,201 @@
# -*- coding: utf-8 -*-
import argparse
import codecs
import datetime
import logging
import os
import lxml
import mock
from q3stats.lib.scripts import import_games, utils
from q3stats.models import Game
from q3stats.testing import BaseQ3StatsTestCase
class FakeArgs(object):
DEFAULTS = {
'stats_path': '/path/to/q3/stats',
'verbose': False,
}
def __init__(self, **update):
args = dict(self.DEFAULTS)
args.update(update)
for k, v in args.items():
setattr(self, k, v)
class Test_LibScriptsImportGames(BaseQ3StatsTestCase):
@classmethod
def setUpClass(cls):
super(Test_LibScriptsImportGames, cls).setUpClass()
cls._stats_path = os.path.join(
os.path.abspath(os.path.dirname(__file__)), 'fixtures', 'stats'
)
cls._game_xml_path = os.path.join(
os.path.abspath(os.path.dirname(__file__)), 'fixtures', 'game.xml'
)
def test_find_stats_files(self):
result = import_games._find_stats_files(self._stats_path)
assert len(result) == 4
unique_days = set()
for path in result:
assert path.startswith(self._stats_path)
assert path.endswith('.xml')
unique_days.add(
os.path.dirname(path).replace(self._stats_path + '/', '')
)
assert unique_days == set(['2017/02/20', '2017/02/21'])
def test_read_match(self):
result = import_games._read_match(self._game_xml_path)
assert result is not None
assert result.tag == 'match'
def test_read_game(self):
match = import_games._read_match(self._game_xml_path)
result = import_games._read_game(match)
assert result is not None
assert result.uuid is not None
assert result.map == 'Q3DM7'
assert result.date == datetime.date(2017, 2, 20)
assert result.time == datetime.time(14, 36, 26)
assert result.attrs['type'] == 'FFA'
assert result.attrs['team_game'] is False
assert result.attrs['duration'] == 583
def test_read_scores(self):
match = import_games._read_match(self._game_xml_path)
result = import_games._read_scores(match)
assert len(result) == 2
pl1_score, pl2_score = result[0]
assert pl1_score.player == 'Player 1'
assert pl1_score.score == 30
assert pl1_score.kills == 30
assert pl1_score.deaths == 21
assert pl1_score.suicides == 0
assert pl1_score.net == 9
assert pl1_score.damage_given == 4894
assert pl1_score.damage_taken == 4329
assert pl1_score.total_health == 925
assert pl1_score.total_armor == 1255
assert pl1_score.weapons['G']['hits'] == 1
assert pl1_score.weapons['G']['shots'] == 0
assert pl1_score.weapons['G']['kills'] == 1
assert pl1_score.weapons['MG']['hits'] == 82
assert pl1_score.weapons['MG']['shots'] == 325
assert pl1_score.weapons['MG']['kills'] == 1
assert pl1_score.weapons['SG']['hits'] == 29
assert pl1_score.weapons['SG']['shots'] == 192
assert pl1_score.weapons['SG']['kills'] == 2
assert pl1_score.weapons['RL']['hits'] == 51
assert pl1_score.weapons['RL']['shots'] == 140
assert pl1_score.weapons['RL']['kills'] == 21
assert pl1_score.weapons['RG']['hits'] == 9
assert pl1_score.weapons['RG']['shots'] == 34
assert pl1_score.weapons['RG']['kills'] == 4
assert pl1_score.weapons['PG']['hits'] == 14
assert pl1_score.weapons['PG']['shots'] == 117
assert pl1_score.weapons['PG']['kills'] == 1
assert pl1_score.items['MH'] == 3
assert pl1_score.items['RA'] == 5
assert pl1_score.items['YA'] == 5
assert pl1_score.items['GA'] == 0
assert pl1_score.powerups == {}
assert pl2_score.player == 'Player 2'
assert pl2_score.score == 27
assert pl2_score.kills == 28
assert pl2_score.deaths == 19
assert pl2_score.suicides == 1
assert pl2_score.net == 8
assert pl2_score.damage_given == 5822
assert pl2_score.damage_taken == 3792
assert pl2_score.total_health == 810
assert pl2_score.total_armor == 930
assert pl2_score.weapons['G']['hits'] == 1
assert pl2_score.weapons['G']['shots'] == 0
assert pl2_score.weapons['G']['kills'] == 1
assert pl2_score.weapons['MG']['hits'] == 56
assert pl2_score.weapons['MG']['shots'] == 244
assert pl2_score.weapons['MG']['kills'] == 1
assert pl2_score.weapons['SG']['hits'] == 55
assert pl2_score.weapons['SG']['shots'] == 256
assert pl2_score.weapons['SG']['kills'] == 3
assert pl2_score.weapons['RL']['hits'] == 70
assert pl2_score.weapons['RL']['shots'] == 163
assert pl2_score.weapons['RL']['kills'] == 19
assert pl2_score.weapons['RG']['hits'] == 6
assert pl2_score.weapons['RG']['shots'] == 19
assert pl2_score.weapons['RG']['kills'] == 1
assert pl2_score.weapons['PG']['hits'] == 18
assert pl2_score.weapons['PG']['shots'] == 173
assert pl2_score.weapons['PG']['kills'] == 3
assert pl2_score.items['MH'] == 1
assert pl2_score.items['RA'] == 1
assert pl2_score.items['YA'] == 7
assert pl2_score.items['GA'] == 0
assert pl2_score.powerups['Quad'] == [5, 51188]
def test_read_stats_file(self):
result = import_games._read_stats_file(self._game_xml_path)
assert result is not None
assert result.map == 'Q3DM7'
assert len(result.scores) == 2
def test_get_argument_parser(self):
new_argument_parser = mock.Mock(spec=argparse.ArgumentParser)
with mock.patch.object(import_games, 'ArgumentParser',
return_value=new_argument_parser):
result = import_games._get_argument_parser()
import_games.ArgumentParser.assert_called_with(
description='Import Q3A stats'
)
assert result == new_argument_parser
result.add_argument.assert_any_call(
'stats_path', help='path to stats directory'
)
result.add_argument.assert_any_call(
'-v', '--verbose', action='store_true', default=False,
help='be verbose'
)
def test_script_main(self):
new_argument_parser = mock.Mock(spec=argparse.ArgumentParser)
new_logger = mock.Mock(spec=logging.Logger)
with mock.patch.object(import_games, '_get_argument_parser',
return_value=new_argument_parser):
with mock.patch.object(import_games.utils, 'get_logger',
return_value=new_logger):
with mock.patch.object(import_games, '_find_stats_files',
return_value=[self._game_xml_path]):
result = import_games.script_main(
None, config=self._config
)
assert result == utils.RET_OK
with utils.db_session(self._config) as session:
games = session.query(Game).all()
assert len(games) == 1
assert games[0].map == 'Q3DM7'
assert len(games[0].scores) == 2

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from q3stats.lib import stats
from q3stats.testing import BaseQ3StatsTestCase
class Test_LibStats(BaseQ3StatsTestCase):
def test_weapon_accuracy_gauntlet(self):
result = stats.weapon_accuracy('G', {'hits': 0, 'shots': 0})
assert result == '---'
def test_weapon_accuracy_no_shots(self):
result = stats.weapon_accuracy('BFG', {'hits': 1, 'shots': 0})
assert result == 'NaN'
def test_weapon_accuracy(self):
result = stats.weapon_accuracy('BFG', {'hits': 1, 'shots': 2})
assert result == '50.00%'
def test_powerup_time_no_time(self):
result = stats.powerup_time(0)
assert result == 'NaN'
def test_powerup_time_less_than_1s(self):
result = stats.powerup_time(123)
assert result == '0.123'
def test_powerup_time(self):
result = stats.powerup_time(12345)
assert result == '12.345'