generalized user information

This commit is contained in:
Max-Wilhelm Bruker 2010-09-18 21:05:28 +02:00
parent adaa1d5323
commit f9446f9822
61 changed files with 3710 additions and 175 deletions

View file

@ -58,7 +58,7 @@ HEADERS += src/counter.h \
src/remotedecklist_treewidget.h \
src/deckview.h \
src/playerlistwidget.h \
src/pingpixmapgenerator.h \
src/pixmapgenerator.h \
src/settingscache.h \
src/localserver.h \
src/localserverinterface.h \
@ -131,7 +131,7 @@ SOURCES += src/counter.cpp \
src/remotedecklist_treewidget.cpp \
src/deckview.cpp \
src/playerlistwidget.cpp \
src/pingpixmapgenerator.cpp \
src/pixmapgenerator.cpp \
src/settingscache.cpp \
src/localserver.cpp \
src/localserverinterface.cpp \

View file

@ -37,5 +37,32 @@
<file>resources/icon_conceded.svg</file>
<file>resources/icon_player.svg</file>
<file>resources/icon_spectator.svg</file>
<file>resources/countries/at.svg</file>
<file>resources/countries/au.svg</file>
<file>resources/countries/be.svg</file>
<file>resources/countries/br.svg</file>
<file>resources/countries/ca.svg</file>
<file>resources/countries/ch.svg</file>
<file>resources/countries/cn.svg</file>
<file>resources/countries/de.svg</file>
<file>resources/countries/dk.svg</file>
<file>resources/countries/es.svg</file>
<file>resources/countries/fi.svg</file>
<file>resources/countries/fr.svg</file>
<file>resources/countries/gr.svg</file>
<file>resources/countries/hu.svg</file>
<file>resources/countries/ie.svg</file>
<file>resources/countries/il.svg</file>
<file>resources/countries/it.svg</file>
<file>resources/countries/jp.svg</file>
<file>resources/countries/mx.svg</file>
<file>resources/countries/nl.svg</file>
<file>resources/countries/pl.svg</file>
<file>resources/countries/ru.svg</file>
<file>resources/countries/se.svg</file>
<file>resources/countries/tr.svg</file>
<file>resources/countries/uk.svg</file>
<file>resources/countries/us.svg</file>
</qresource>
</RCC>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="600">
<rect fill="#ed2939" width="900" height="600"/>
<rect fill="#fff" y="200" width="900" height="200"/>
</svg>

After

Width:  |  Height:  |  Size: 216 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1280" height="640" viewBox="0 0 30240 15120"><defs id="defs6"><polygon points="0,-9 1.735535,-3.6038755 7.0364833,-5.6114082 3.8997116,-0.89008374 8.7743512,2.0026884 3.1273259,2.4939592 3.9049537,8.1087198 0,4 -3.9049537,8.1087198 -3.1273259,2.4939592 -8.7743512,2.0026884 -3.8997116,-0.89008374 -7.0364833,-5.6114082 -1.735535,-3.6038755 0,-9 " id="Star7"/><polygon points="0,-9 2.351141,-3.236068 8.5595086,-2.7811529 3.8042261,1.236068 5.2900673,7.2811529 0,4 -5.2900673,7.2811529 -3.8042261,1.236068 -8.5595086,-2.7811529 -2.351141,-3.236068 0,-9 " id="Star5"/></defs><path d="M 0,0 L 30240,0 L 30240,15120 L 0,15120 L 0,0 z" style="fill:#00008b"/><use transform="matrix(252,0,0,252,7560,11340)" id="Commonwealth_Star" style="fill:#fff" xlink:href="#Star7"/><use transform="matrix(120,0,0,120,22680,12600)" id="Star_Alpha_Crucis" style="fill:#fff" xlink:href="#Star7"/><use transform="matrix(120,0,0,120,18900,6615)" id="Star_Beta_Crucis" style="fill:#fff" xlink:href="#Star7"/><use transform="matrix(120,0,0,120,22680,2520)" id="Star_Gamma_Crucis" style="fill:#fff" xlink:href="#Star7"/><use transform="matrix(120,0,0,120,26040,5607)" id="Star_Delta_Crucis" style="fill:#fff" xlink:href="#Star7"/><use transform="matrix(70,0,0,70,24192,8190)" id="Star_Epsilon_Crucis" style="fill:#fff" xlink:href="#Star5"/><path d="M 6300,0 L 8820,0 L 8820,2520 L 15120,2520 L 15120,5040 L 8820,5040 L 8820,7560 L 6300,7560 L 6300,5040 L 0,5040 L 0,2520 L 6300,2520 L 6300,0 z" id="White_Cross" style="fill:#fff"/><path d="M 0,0 L 1690.4674,0 L 15120,6714.7663 L 15120,7560 L 13429.533,7560 L 0,845.2337 L 0,0 z" id="White_Diagonal" style="fill:#fff"/><use transform="matrix(-1,0,0,1,15120,0)" id="White_Diagonal_Flipped" style="fill:#fff" xlink:href="#White_Diagonal"/><path d="M 6804,0 L 8316,0 L 8316,3024 L 15120,3024 L 15120,4536 L 8316,4536 L 8316,7560 L 6804,7560 L 6804,4536 L 0,4536 L 0,3024 L 6804,3024 L 6804,0 z" id="Red_Cross" style="fill:red"/><path d="M 0,0 L 5040,2520 L 3913.0217,2520 L 0,563.48913 L 0,0 z M 15120,0 L 13993.022,0 L 8953.0217,2520 L 10080,2520 L 15120,0 z" id="Red_Diagonals" style="fill:red"/><use transform="matrix(-1,0,0,-1,15120,7560)" id="Red_Diagonals_Rotated" style="fill:red" xlink:href="#Red_Diagonals"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="450" height="390"><rect width="150" height="390"/><rect x="150" width="150" height="390" fill="#FECB00"/><rect x="300" width="150" height="390" fill="#ed2939"/></svg>

After

Width:  |  Height:  |  Size: 368 B

View file

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720px" height="504px" viewBox="-2100 -1470 4200 2940">
<title>Flag of Brazil</title>
<defs>
<path id="O" d="M 0,0 a 31.5,35 0 0,0 0,-70 a 31.5,35 0 0,0 0,70 M 0,-13 a 18.5,22 0 0,0 0,-44 a 18.5,22 0 0,0 0,44" fill-rule="evenodd"/>
<g id="R">
<use xlink:href="#P"/>
<path d="M 28,0 c 0,-10 0,-32 -15,-32 h -19 c 22,0 22,22 22,32"/>
</g>
<path id="D" d="M -31.5,0 h 33 a 30,30 0 0,0 30,-30 v -10 a 30,30 0 0,0 -30,-30 H -31.5 z M -18.5,-13 h 19 a 19,19 0 0,0 19,-19 v -6 a 19,19 0 0,0 -19,-19 H -18.5 z" fill-rule="evenodd"/>
<path id="E" d="M 0,0 h 63 v -13 H 12 v -18 h 40 v -12 h -40 v -14 H 60 v -13 H 0 z" transform="translate(-31.5)"/>
<path id="M" d="M -31.5,0 h 12 v -48 l 14,48 h 11 l 14,-48 V 0 h 12 V -70 h -17.5 l -14,48 l -14,-48 H -31.5 z"/>
<path id="E_" d="M -26.25,0 h 52.5 v -12 h -40.5 v -16 h 33 v -12 h -33 v -11 H 25 v -12 H -26.25 z"/>
<path id="P" d="M -31.5,0 h 13 v -26 h 28 a 22,22 0 0,0 0,-44 h -40 z M -18.5,-39 h 27 a 9,9 0 0,0 0,-18 h -27 z" fill-rule="evenodd"/>
<g id="G">
<clipPath id="gcut">
<path d="M -31.5,0 v -70 h 63 v 70 z M 0,-47 v 12 h 31.5 v -12 z"/>
</clipPath>
<use xlink:href="#O" clip-path="url(#gcut)"/>
<rect x="5" y="-35" width="26.5" height="10"/>
<rect x="21.5" y="-35" width="10" height="35"/>
</g>
<path id="S" d="M -15.75,-22 C -15.75,-15 -9,-11.5 1,-11.5 C 11,-11.5 15.74,-14.75 15.75,-19.25 C 15.75,-33.5 -31,-24.5 -30.75,-49.5 C -30.5,-71 -6,-70 3,-70 C 12,-70 29,-66 28.75,-48.75 L 13.5,-48.75 C 13.5,-56.25 6.5,-59 -1.5,-59 C -9.25,-59 -14.75,-57.75 -14.75,-50.5 C -15,-38.75 31.5,-46.5 31.5,-21.75 C 31.5,-3.5 13.5,0 0,0 C -11.5,0 -31.55,-4.5 -31.5,-22 z"/>
<g id="star">
<g id="cone">
<polygon id="triangle" points="0,0 0,1 .5,1" transform="translate(0,-1) rotate(18)"/>
<use xlink:href="#triangle" transform="scale(-1,1)"/>
</g>
<use xlink:href="#cone" transform="rotate(72)"/>
<use xlink:href="#cone" transform="rotate(-72)"/>
<use xlink:href="#cone" transform="rotate(144)"/>
<use xlink:href="#cone" transform="rotate(-144)"/>
</g>
<use id="star1" xlink:href="#star" transform="scale(31.5)"/>
<use id="star2" xlink:href="#star" transform="scale(26.25)"/>
<use id="star3" xlink:href="#star" transform="scale(21)"/>
<use id="star4" xlink:href="#star" transform="scale(15)"/>
<use id="star5" xlink:href="#star" transform="scale(10.5)"/>
</defs>
<rect id="field" fill="#00923f" x="-50%" y="-50%" width="100%" height="100%"/>
<path id="rhombus" fill="#f8c300" d="M -1743,0 L 0,1113 L 1743,0 L 0,-1113 z"/>
<circle id="circle" fill="#28166f" r="735"/>
<clipPath id="clipcircle">
<use xlink:href="#circle"/>
</clipPath>
<path id="band" d="M-2205,1470 a1785,1785 0 0,1 3570,0 h-105 a1680,1680 0 1,0 -3360,0 z" clip-path="url(#clipcircle)" fill="white"/>
<g fill="#00923f" transform="translate(-420,1470)">
<g id="ORDEM" transform="rotate(-7)">
<use xlink:href="#O" transform="translate(0,-1697.5)"/>
<use xlink:href="#R" transform="rotate(3) translate(0,-1697.5)"/>
<use xlink:href="#D" transform="rotate(6) translate(0,-1697.5)"/>
<use xlink:href="#E" transform="rotate(9) translate(0,-1697.5)"/>
<use xlink:href="#M" transform="rotate(12) translate(0,-1697.5)"/>
</g>
<use xlink:href="#E_" transform="rotate(9.75) translate(0,-1697.5)"/>
<g id="PROGRESSO" transform="rotate(14.5)">
<use xlink:href="#P" transform="translate(0,-1697.5)"/>
<use xlink:href="#R" transform="rotate(3) translate(0,-1697.5)"/>
<use xlink:href="#O" transform="rotate(6) translate(0,-1697.5)"/>
<use xlink:href="#G" transform="rotate(9) translate(0,-1697.5)"/>
<use xlink:href="#R" transform="rotate(12) translate(0,-1697.5)"/>
<use xlink:href="#E" transform="rotate(15) translate(0,-1697.5)"/>
<use xlink:href="#S" transform="rotate(18) translate(0,-1697.5)"/>
<use xlink:href="#S" transform="rotate(21) translate(0,-1697.5)"/>
<use xlink:href="#O" transform="rotate(24) translate(0,-1697.5)"/>
</g>
</g>
<g id="stars" fill="white">
<use id="Alpha_Canis_Minoris" xlink:href="#star1" transform="translate(-600,-132)"/>
<g id="Canis_Majoris">
<use id="Alpha_Canis_Majoris" xlink:href="#star1" transform="translate(-535,177)"/>
<use id="Beta_Canis_Majoris" xlink:href="#star3" transform="translate(-625,243)"/>
<use id="Gamma_Canis_Majoris" xlink:href="#star4" transform="translate(-463,132)"/>
<use id="Delta_Canis_Majoris" xlink:href="#star2" transform="translate(-382,250)"/>
<use id="Epsilon_Canis_Majoris" xlink:href="#star2" transform="translate(-404,323)"/>
</g>
<use id="Alpha_Virginis" xlink:href="#star1" transform="translate(228,-228)"/>
<g id="Scorpio">
<use id="Alpha_Scorpii" xlink:href="#star1" transform="translate(515,258)"/>
<use id="Beta_Scorpii" xlink:href="#star3" transform="translate(617,265)"/>
<use id="Epsilon_Scorpii" xlink:href="#star2" transform="translate(545,323)"/>
<use id="Theta_Scorpii" xlink:href="#star2" transform="translate(368,477)"/>
<use id="Iota_Scorpii" xlink:href="#star3" transform="translate(367,551)"/>
<use id="Kappa_Scorpii" xlink:href="#star3" transform="translate(441,419)"/>
<use id="Lambda_Scorpii" xlink:href="#star2" transform="translate(500,382)"/>
<use id="Mu_Scorpii" xlink:href="#star3" transform="translate(365,405)"/>
</g>
<g id="Hydra">
<use id="Alpha_Hydrae" xlink:href="#star2" transform="translate(-280,30)"/>
<use id="Gamma_Hydrae" xlink:href="#star3" transform="translate(200,-37)"/>
</g>
<g id="Crux">
<use id="Alpha_Crucis" xlink:href="#star1" transform="translate(0,330)"/>
<use id="Beta_Crucis" xlink:href="#star2" transform="translate(85,184)"/>
<use id="Gamma_Crucis" xlink:href="#star2" transform="translate(0,118)"/>
<use id="Delta_Crucis" xlink:href="#star3" transform="translate(-74,184)"/>
<use id="Epsilon_Crucis" xlink:href="#star4" transform="translate(-37,235)"/>
</g>
<g id="Triangulum_Australe">
<use id="Alpha_Trianguli_Australe" xlink:href="#star2" transform="translate(220,495)"/>
<use id="Beta_Trianguli_Australe" xlink:href="#star3" transform="translate(283,430)"/>
<use id="Gamma_Trianguli_Australe" xlink:href="#star3" transform="translate(162,412)"/>
</g>
<use id="Alpha_Carinae" xlink:href="#star1" transform="translate(-295,390)"/>
<use id="Sigma_Octantis" xlink:href="#star5" transform="translate(0,575)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="1000" height="500"><rect width="1000" height="500" fill="#f00"/><rect width="500" height="500" fill="#fff" x="250"/><path fill="#ff0000" d="m 499.99228,46.875 -34.11312,63.62529 c -3.87086,6.91501 -10.80627,6.27363 -17.74169,2.41138 l -24.69699,-12.78858 18.40705,97.72711 c 3.87086,17.85419 -8.54859,17.85419 -14.67765,10.13435 l -43.10105,-48.25099 -6.99738,24.503 c -0.80692,3.21777 -4.35481,6.59744 -9.67748,5.79261 l -54.50177,-11.45912 14.31524,52.04475 c 3.06451,11.58054 5.4549,16.37528 -3.09375,19.42959 l -19.42619,9.13025 93.82127,76.20838 c 3.7135,2.88151 5.58971,8.067 4.26768,12.7621 l -8.21136,26.94707 c 32.30405,-3.72371 61.24898,-9.32594 93.56939,-12.77619 2.85323,-0.30459 7.62988,4.40408 7.61029,7.71058 l -4.28024,98.72342 15.70639,0 -2.47237,-98.5117 c -0.0197,-3.3065 4.31372,-8.22689 7.16695,-7.9223 32.32041,3.45026 61.26538,9.05248 93.56942,12.77619 l -8.21134,-26.94707 c -1.32203,-4.6951 0.55417,-9.88059 4.26767,-12.7621 l 93.82125,-76.20838 -19.42617,-9.13025 c -8.54867,-3.05431 -6.15828,-7.84905 -3.09377,-19.42959 l 14.31527,-52.04475 -54.5018,11.45912 c -5.32267,0.80483 -8.87056,-2.57484 -9.6775,-5.79261 l -6.99737,-24.503 -43.10103,48.25099 c -6.12908,7.71984 -18.54854,7.71984 -14.67768,-10.13435 l 18.40702,-97.72711 -24.69694,12.78858 c -6.93559,3.86225 -13.87083,4.50363 -17.7417,-2.41138"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 32 32"><rect fill="#f00" height="32" width="32"/><rect fill="#fff" height="6" width="20" x="6" y="13"/><rect fill="#fff" height="20" width="6" x="13" y="6"/></svg>

After

Width:  |  Height:  |  Size: 281 B

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3000" height="2000" viewBox="0 0 30 20">
<rect fill="#de2910" width="30" height="20"/>
<g id="bstar" transform="translate(5,5) scale(3)" fill="#ffde00"><g id="cone">
<polygon id="triangle" points="0,0 0,1 .5,1" transform="translate(0,-1) rotate(18)"/><use xlink:href="#triangle" transform="scale(-1,1)" id="use5"/></g>
<use xlink:href="#cone" transform="rotate(72)" id="use1"/>
<use xlink:href="#cone" transform="rotate(-72)" id="use2"/>
<use xlink:href="#cone" transform="rotate(144)" id="use3"/>
<use xlink:href="#cone" transform="rotate(-144)" id="use4"/></g>
<use xlink:href="#bstar" transform="matrix(0,0.33,-0.33,0,11.641927,7.359454)"/>
<use xlink:href="#bstar" transform="matrix(0,0.33,-0.33,0,11.641927,0.359454)"/>
<use xlink:href="#bstar" transform="matrix(0.33328261,-0.00581747,0.00581747,0.33328261,10.3045,5.3626743)"/>
<use xlink:href="#bstar" transform="matrix(-0.00581747,-0.33328261,0.33328261,-0.00581747,10.362674,5.6955004)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="600" viewBox="0 0 5 3">
<desc>Flag of Germany</desc>
<rect id="black_stripe" width="5" height="3" y="0" x="0" fill="#000"/>
<rect id="red_stripe" width="5" height="2" y="1" x="0" fill="#D00"/>
<rect id="gold_stripe" width="5" height="1" y="2" x="0" fill="#FFCE00"/>
</svg>

After

Width:  |  Height:  |  Size: 502 B

View file

@ -0,0 +1 @@
<?xml version="1.0"?><svg width="370" height="280"><rect width="370" height="280" fill="#d00c33"/><path d="M140,0 v280" stroke-width="40" stroke="#FFF"/><path d="M0,140 h370" stroke-width="40" stroke="#FFF"/></svg>

After

Width:  |  Height:  |  Size: 214 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 230 KiB

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1800" height="1100">
<rect width="1800" height="1100" fill="#fff"/>
<rect width="1800" height="300" y="400" fill="#003580"/>
<rect width="300" height="1100" x="500" fill="#003580"/>
</svg>

After

Width:  |  Height:  |  Size: 275 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="900" height="600"><rect width="900" height="600" fill="#ED2939"/><rect width="600" height="600" fill="#fff"/><rect width="300" height="600" fill="#002395"/></svg>

After

Width:  |  Height:  |  Size: 377 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 27 18" width="810" height="540"><rect fill="#000080" width="27" height="18"/><path fill="#fff" d="M 4,0 6,0 6,4 10,4 10,6 6,6 6,10 27,10 27,12 0,12 0,10 4,10 4,6 0,6 0,4 4,4 4,0 z M 10,2 27,2 27,4 10,4 10,2 z M 10,6 27,6 27,8 10,8 10,6 z M 0,10 0,12 0,10 z M 0,14 27,14 27,16 0,16 0,14 z"/></svg>

After

Width:  |  Height:  |  Size: 351 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600">
<rect fill="#ce1126" width="1200" height="200"/>
<rect fill="#fff" y="200" width="1200" height="200"/>
<rect fill="#008751" y="400" width="1200" height="200"/>
</svg>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600">
<rect fill="#009B48" width="400" height="600"/>
<rect fill="#fff" x="400" width="400" height="600"/>
<rect fill="#FF7900" x="800" width="400" height="600"/>
</svg>

After

Width:  |  Height:  |  Size: 271 B

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="660" height="480" viewBox="0 0 220 160">
<desc>Flag of Israel</desc>
<defs>
<!-- Specs are taken from "The Provisional Council of State Proclamation of
the Flag of the State of Israel," 25 Tishrei 5709 (28 October 1948)
For Magen David, the "Israel Science and Technology Homepage" at
http://www.science.co.il/Israel-flag.asp specifies each side as 60 cm.
Outer radius is then 30 / cos(30) = 20 * sqrt(3)
For equilateral triangles, middle radius = outer radius - width:
20 * sqrt(3) - 5.5
Coordinates for upward-pointing triangle relative to center are then:
( 0,-(20*sqrt(3) - 5.5) )
(-(20*sqrt(3) - 5.5) * cos(30), (20*sqrt(3) - 5.5) * sin(30))
( (20*sqrt(3) - 5.5) * cos(30), (20*sqrt(3) - 5.5) * sin(30)) -->
<polygon id="triangle" points="0,-29.1410161513775421
-25.2368602791855814, 14.5705080756887710
25.2368602791855814, 14.5705080756887710"
stroke="#0038b8" stroke-width="5.5" fill-opacity="0"/>
</defs>
<!-- "The flag is 220 cm long and 160 cm wide. The background is white" -->
<rect width="220" height="160" fill="white"/>
<!-- "...two stripes of dark sky-blue, 25 cm broad, over the whole length of
the flag, at a distance of 15 cm from the top and from the bottom..."
Legislation does not specify exact shade of blue; "#0038b8" is typical of
flags used in Israel -->
<rect width="220" height="25" fill="#0038b8" y="15"/>
<rect width="220" height="25" fill="#0038b8" y="120"/>
<use xlink:href="#triangle" transform="translate(110,80)"/>
<use xlink:href="#triangle" transform="translate(110,80) rotate(180)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="1000" viewBox="0 0 3 2">
<rect width="1" height="2" fill="#009246"/>
<rect width="1" height="2" x="1" fill="#fff"/>
<rect width="1" height="2" x="2" fill="#ce2b37"/>
</svg>

After

Width:  |  Height:  |  Size: 273 B

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="600">
<rect fill="#fff" height="600" width="900"/>
<circle fill="#bc002d" cx="450" cy="300" r="180"/>
</svg>

After

Width:  |  Height:  |  Size: 209 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 414 KiB

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="600" viewBox="0 0 9 6">
<rect fill="#21468B" width="9" height="6"/>
<rect fill="#FFF" width="9" height="4"/>
<rect fill="#AE1C28" width="9" height="2"/>
</svg>

After

Width:  |  Height:  |  Size: 223 B

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="1280" height="800" id="Flag_of_Poland" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 10">
<rect width="16" height="5" fill="#fff"/>
<rect width="16" height="5" fill="#dc143c" y="5"/>
</svg>

After

Width:  |  Height:  |  Size: 345 B

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9 6" width="1800" height="1200"><rect fill="#fff" width="9" height="3"/><rect fill="#f00" y="3" width="9" height="3"/><rect fill="#00f" y="2" width="9" height="2"/></svg>

After

Width:  |  Height:  |  Size: 261 B

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1000" viewBox="0 0 16 10">
<rect width="16" height="10" fill="#005293"/>
<rect width="2" height="10" x="5" fill="#FECB00"/>
<rect width="16" height="2" y="4" fill="#FECB00"/>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View file

@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 360 240" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect fill="#e30a17" width="360" height="240"/>
<rect fill="#fff" width="8" height="240"/>
<circle fill="#fff" cx="128" cy="120" r="60"/>
<circle fill="#e30a17" cx="143" cy="120" r="48"/>
<g fill="#fff" transform="translate(205,120) scale(30) rotate(-90)">
<g id="g2">
<polygon id="g1" points="0,0 0,1 .5,1" transform="translate(0,-1) rotate(18)"/>
<use xlink:href="#g1" transform="scale(-1,1)"/>
</g>
<use xlink:href="#g2" transform="rotate(72)"/>
<use xlink:href="#g2" transform="rotate(-72)"/>
<use xlink:href="#g2" transform="rotate(144)"/>
<use xlink:href="#g2" transform="rotate(-144)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 764 B

View file

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30" width="1200" height="600">
<clipPath id="t">
<path d="M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z"/>
</clipPath>
<path d="M0,0 v30 h60 v-30 z" fill="#00247d"/>
<path d="M0,0 L60,30 M60,0 L0,30" stroke="#fff" stroke-width="6"/>
<path d="M0,0 L60,30 M60,0 L0,30" clip-path="url(#t)" stroke="#cf142b" stroke-width="4"/>
<path d="M30,0 v30 M0,15 h60" stroke="#fff" stroke-width="10"/>
<path d="M30,0 v30 M0,15 h60" stroke="#cf142b" stroke-width="6"/>
</svg>

After

Width:  |  Height:  |  Size: 522 B

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1235" height="650">
<defs>
<polygon id="pt" points="-0.1624598481164531,0 0,-0.5 0.1624598481164531,0" transform="scale(0.0616)" fill="#FFF"/>
<g id="star"><use xlink:href="#pt" transform="rotate(-144)"/><use xlink:href="#pt" transform="rotate(-72)"/><use xlink:href="#pt"/><use xlink:href="#pt" transform="rotate(72)"/><use xlink:href="#pt" transform="rotate(144)"/></g>
<g id="s5"><use xlink:href="#star" x="-0.252"/><use xlink:href="#star" x="-0.126"/><use xlink:href="#star"/><use xlink:href="#star" x="0.126"/><use xlink:href="#star" x="0.252"/></g>
<g id="s6"><use xlink:href="#s5" x="-0.063"/><use xlink:href="#star" x="0.315"/></g>
<g id="x4"><use xlink:href="#s6"/><use xlink:href="#s5" y="0.054"/><use xlink:href="#s6" y="0.108"/><use xlink:href="#s5" y="0.162"/></g>
<g id="u"><use xlink:href="#x4" y="-0.216"/><use xlink:href="#x4"/><use xlink:href="#s6" y="0.216"/></g>
<rect id="stripe" width="1235" height="50" fill="#B22234"/>
</defs>
<rect width="1235" height="650" fill="#FFF"/><use xlink:href="#stripe"/><use xlink:href="#stripe" y="100"/><use xlink:href="#stripe" y="200"/><use xlink:href="#stripe" y="300"/><use xlink:href="#stripe" y="400"/><use xlink:href="#stripe" y="500"/><use xlink:href="#stripe" y="600"/><rect width="494" height="350" fill="#3C3B6E"/><use xlink:href="#u" transform="translate(247,175) scale(650)"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -26,7 +26,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
ServerInfo_Game *g = gameList[index.row()];
switch (index.column()) {
case 0: return g->getDescription();
case 1: return g->getCreatorName();
case 1: return g->getCreatorInfo()->getName();
case 2: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no");
case 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
case 4: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed"));
@ -56,7 +56,7 @@ ServerInfo_Game *GamesModel::getGame(int row)
void GamesModel::updateGameList(ServerInfo_Game *_game)
{
ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), _game->getCreatorName(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount());
ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), new ServerInfo_User(_game->getCreatorInfo()), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount());
for (int i = 0; i < gameList.size(); i++)
if (gameList[i]->getGameId() == game->getGameId()) {
if (game->getPlayerCount() == 0) {

View file

@ -16,3 +16,8 @@ LocalServerInterface *LocalServer::newConnection()
addClient(lsi);
return lsi;
}
ServerInfo_User *LocalServer::getUserData(const QString &name)
{
return new ServerInfo_User(name);
}

View file

@ -18,6 +18,8 @@ public:
int getMaxPlayerInactivityTime() const { return 9999999; }
LocalServerInterface *newConnection();
protected:
ServerInfo_User *getUserData(const QString &name);
};
#endif

View file

@ -34,14 +34,12 @@
#include "dlg_settings.h"
#include "carddatabase.h"
#include "settingscache.h"
#include "pingpixmapgenerator.h"
//Q_IMPORT_PLUGIN(qjpeg)
CardDatabase *db;
QTranslator *translator, *qtTranslator;
SettingsCache *settingsCache;
PingPixmapGenerator *pingPixmapGenerator;
void myMessageOutput(QtMsgType /*type*/, const char *msg)
{
@ -87,7 +85,6 @@ int main(int argc, char *argv[])
settingsCache = new SettingsCache;
db = new CardDatabase;
pingPixmapGenerator = new PingPixmapGenerator;
qtTranslator = new QTranslator;
translator = new QTranslator;
@ -125,7 +122,6 @@ int main(int argc, char *argv[])
app.exec();
}
delete pingPixmapGenerator;
delete db;
delete settingsCache;

View file

@ -1,27 +0,0 @@
#include "pingpixmapgenerator.h"
#include <QPainter>
QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max)
{
int key = size * 1000000 + max * 1000 + value;
if (pmCache.contains(key))
return pmCache.value(key);
QPixmap pixmap(size, size);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
QColor color;
if ((max == -1) || (value == -1))
color = Qt::black;
else
color.setHsv(120 * (1.0 - ((double) value / max)), 255, 255);
QRadialGradient g(QPointF((double) pixmap.width() / 2, (double) pixmap.height() / 2), qMin(pixmap.width(), pixmap.height()) / 2.0);
g.setColorAt(0, color);
g.setColorAt(1, Qt::transparent);
painter.fillRect(0, 0, pixmap.width(), pixmap.height(), QBrush(g));
pmCache.insert(key, pixmap);
return pixmap;
}

View file

@ -1,16 +0,0 @@
#ifndef PINGPIXMAPGENERATOR_H
#define PINGPIXMAPGENERATOR_H
#include <QPixmap>
#include <QMap>
class PingPixmapGenerator {
private:
QMap<int, QPixmap> pmCache;
public:
QPixmap generatePixmap(int size, int value, int max);
};
extern PingPixmapGenerator *pingPixmapGenerator;
#endif

View file

@ -0,0 +1,52 @@
#include "pixmapgenerator.h"
#include <QPainter>
#include <QSvgRenderer>
#include <math.h>
QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max)
{
int key = size * 1000000 + max * 1000 + value;
if (pmCache.contains(key))
return pmCache.value(key);
QPixmap pixmap(size, size);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
QColor color;
if ((max == -1) || (value == -1))
color = Qt::black;
else
color.setHsv(120 * (1.0 - ((double) value / max)), 255, 255);
QRadialGradient g(QPointF((double) pixmap.width() / 2, (double) pixmap.height() / 2), qMin(pixmap.width(), pixmap.height()) / 2.0);
g.setColorAt(0, color);
g.setColorAt(1, Qt::transparent);
painter.fillRect(0, 0, pixmap.width(), pixmap.height(), QBrush(g));
pmCache.insert(key, pixmap);
return pixmap;
}
QMap<int, QPixmap> PingPixmapGenerator::pmCache;
QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countryCode)
{
if (countryCode.size() != 2)
return QPixmap();
QString key = countryCode + QString::number(height);
if (pmCache.contains(key))
return pmCache.value(key);
QSvgRenderer svg(QString(":/resources/countries/" + countryCode + ".svg"));
double aspect = (double) svg.defaultSize().width() / (double) svg.defaultSize().height();
QPixmap pixmap((int) round(aspect * height), height);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
svg.render(&painter, QRectF(0, 0, aspect * height, height));
pmCache.insert(key, pixmap);
return pixmap;
}
QMap<QString, QPixmap> CountryPixmapGenerator::pmCache;

View file

@ -0,0 +1,21 @@
#ifndef PINGPIXMAPGENERATOR_H
#define PINGPIXMAPGENERATOR_H
#include <QPixmap>
#include <QMap>
class PingPixmapGenerator {
private:
static QMap<int, QPixmap> pmCache;
public:
static QPixmap generatePixmap(int size, int value, int max);
};
class CountryPixmapGenerator {
private:
static QMap<QString, QPixmap> pmCache;
public:
static QPixmap generatePixmap(int height, const QString &countryCode);
};
#endif

View file

@ -1,7 +1,8 @@
#include <QHeaderView>
#include "playerlistwidget.h"
#include "protocol_datastructures.h"
#include "pingpixmapgenerator.h"
#include "pixmapgenerator.h"
#include <QDebug>
PlayerListWidget::PlayerListWidget(QWidget *parent)
: QTreeWidget(parent), gameStarted(false)
@ -44,14 +45,16 @@ void PlayerListWidget::updatePlayerProperties(ServerInfo_PlayerProperties *prop)
player->setIcon(1, prop->getSpectator() ? spectatorIcon : playerIcon);
player->setIcon(2, gameStarted ? (prop->getConceded() ? concededIcon : QIcon()) : (prop->getReadyStart() ? readyIcon : notReadyIcon));
player->setText(3, prop->getName());
player->setText(3, prop->getUserInfo()->getName());
if (!prop->getUserInfo()->getCountry().isEmpty())
player->setIcon(3, QIcon(CountryPixmapGenerator::generatePixmap(10, prop->getUserInfo()->getCountry())));
QString deckText;
if (!prop->getSpectator())
switch (prop->getDeckId()) {
case -2: deckText = tr("no deck"); break;
case -1: deckText = tr("local deck"); break;
default: deckText = tr("ID #%1").arg(prop->getDeckId());
case -2: deckText = tr("---"); break;
case -1: deckText = tr("local"); break;
default: deckText = tr("#%1").arg(prop->getDeckId());
}
player->setText(4, deckText);
}
@ -81,7 +84,7 @@ void PlayerListWidget::updatePing(int playerId, int pingTime)
QTreeWidgetItem *twi = players.value(playerId, 0);
if (!twi)
return;
twi->setIcon(0, QIcon(pingPixmapGenerator->generatePixmap(10, pingTime, 10)));
twi->setIcon(0, QIcon(PingPixmapGenerator::generatePixmap(10, pingTime, 10)));
}
void PlayerListWidget::setGameStarted(bool _gameStarted)

View file

@ -77,15 +77,15 @@ void TabChatChannel::processChatEvent(ChatEvent *event)
void TabChatChannel::processListPlayersEvent(Event_ChatListPlayers *event)
{
const QList<ServerInfo_ChatUser *> &players = event->getPlayerList();
const QList<ServerInfo_User *> &players = event->getPlayerList();
for (int i = 0; i < players.size(); ++i)
playerList->addItem(players[i]->getName());
}
void TabChatChannel::processJoinChannelEvent(Event_ChatJoinChannel *event)
{
textEdit->append(tr("%1 has joined the channel.").arg(event->getPlayerName()));
playerList->addItem(event->getPlayerName());
textEdit->append(tr("%1 has joined the channel.").arg(event->getUserInfo()->getName()));
playerList->addItem(event->getUserInfo()->getName());
emit userEvent();
}

View file

@ -488,13 +488,13 @@ void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventCont
ServerInfo_PlayerProperties *prop = pl->getProperties();
if (prop->getSpectator()) {
if (!spectators.contains(prop->getPlayerId())) {
spectators.insert(prop->getPlayerId(), prop->getName());
spectators.insert(prop->getPlayerId(), prop->getUserInfo()->getName());
playerListWidget->addPlayer(prop);
}
} else {
Player *player = players.value(prop->getPlayerId(), 0);
if (!player) {
player = addPlayer(prop->getPlayerId(), prop->getName());
player = addPlayer(prop->getPlayerId(), prop->getUserInfo()->getName());
playerListWidget->addPlayer(prop);
}
player->processPlayerInfo(pl);
@ -554,11 +554,11 @@ void TabGame::eventJoin(Event_Join *event, GameEventContext * /*context*/)
{
ServerInfo_PlayerProperties *playerInfo = event->getPlayer();
if (playerInfo->getSpectator()) {
spectators.insert(playerInfo->getPlayerId(), playerInfo->getName());
messageLog->logJoinSpectator(playerInfo->getName());
spectators.insert(playerInfo->getPlayerId(), playerInfo->getUserInfo()->getName());
messageLog->logJoinSpectator(playerInfo->getUserInfo()->getName());
playerListWidget->addPlayer(playerInfo);
} else {
Player *newPlayer = addPlayer(playerInfo->getPlayerId(), playerInfo->getName());
Player *newPlayer = addPlayer(playerInfo->getPlayerId(), playerInfo->getUserInfo()->getName());
messageLog->logJoin(newPlayer);
playerListWidget->addPlayer(playerInfo);
}

View file

@ -6,7 +6,7 @@
#include "tab_game.h"
#include "tab_deck_storage.h"
#include "protocol_items.h"
#include "pingpixmapgenerator.h"
#include "pixmapgenerator.h"
#include <QDebug>
TabSupervisor:: TabSupervisor(QWidget *parent)
@ -97,10 +97,10 @@ void TabSupervisor::stop()
clear();
delete tabServer;
tabServer->deleteLater();
tabServer = 0;
delete tabDeckStorage;
tabDeckStorage->deleteLater();
tabDeckStorage = 0;
QMapIterator<QString, TabChatChannel *> chatChannelIterator(chatChannelTabs);
@ -119,7 +119,7 @@ void TabSupervisor::updatePingTime(int value, int max)
if (!tabServer)
return;
setTabIcon(0, QIcon(pingPixmapGenerator->generatePixmap(15, value, max)));
setTabIcon(0, QIcon(PingPixmapGenerator::generatePixmap(15, value, max)));
}
void TabSupervisor::gameJoined(Event_GameJoined *event)

View file

@ -15,7 +15,7 @@ void ProtocolItem::initializeHash()
registerSerializableItem("move_card_to_zone", MoveCardToZone::newItem);
registerSerializableItem("chat_channel", ServerInfo_ChatChannel::newItem);
registerSerializableItem("chat_user", ServerInfo_ChatUser::newItem);
registerSerializableItem("user", ServerInfo_User::newItem);
registerSerializableItem("game", ServerInfo_Game::newItem);
registerSerializableItem("card_counter", ServerInfo_CardCounter::newItem);
registerSerializableItem("card", ServerInfo_Card::newItem);
@ -52,6 +52,7 @@ void ProtocolItem::initializeHash()
registerSerializableItem("game_eventdraw_cards", Event_DrawCards::newItem);
registerSerializableItem("game_eventping", Event_Ping::newItem);
registerSerializableItem("chat_eventchat_list_players", Event_ChatListPlayers::newItem);
registerSerializableItem("chat_eventchat_join_channel", Event_ChatJoinChannel::newItem);
}
TopLevelProtocolItem::TopLevelProtocolItem()
@ -275,13 +276,21 @@ Event_ListChatChannels::Event_ListChatChannels(const QList<ServerInfo_ChatChanne
itemList.append(_channelList[i]);
}
Event_ChatListPlayers::Event_ChatListPlayers(const QString &_channel, const QList<ServerInfo_ChatUser *> &_playerList)
Event_ChatListPlayers::Event_ChatListPlayers(const QString &_channel, const QList<ServerInfo_User *> &_playerList)
: ChatEvent("chat_list_players", _channel)
{
for (int i = 0; i < _playerList.size(); ++i)
itemList.append(_playerList[i]);
}
Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, ServerInfo_User *_info)
: ChatEvent("chat_join_channel", _channel)
{
if (!_info)
_info = new ServerInfo_User;
insertItem(_info);
}
Event_ListGames::Event_ListGames(const QList<ServerInfo_Game *> &_gameList)
: GenericEvent("list_games")
{

View file

@ -27,14 +27,15 @@ enum ItemId {
ItemId_Command_SetSideboardPlan = ItemId_Other + 102,
ItemId_Event_ListChatChannels = ItemId_Other + 200,
ItemId_Event_ChatListPlayers = ItemId_Other + 201,
ItemId_Event_ListGames = ItemId_Other + 202,
ItemId_Event_GameStateChanged = ItemId_Other + 203,
ItemId_Event_PlayerPropertiesChanged = ItemId_Other + 204,
ItemId_Event_CreateArrows = ItemId_Other + 205,
ItemId_Event_CreateCounters = ItemId_Other + 206,
ItemId_Event_DrawCards = ItemId_Other + 207,
ItemId_Event_Join = ItemId_Other + 208,
ItemId_Event_Ping = ItemId_Other + 209,
ItemId_Event_ChatJoinChannel = ItemId_Other + 202,
ItemId_Event_ListGames = ItemId_Other + 203,
ItemId_Event_GameStateChanged = ItemId_Other + 204,
ItemId_Event_PlayerPropertiesChanged = ItemId_Other + 205,
ItemId_Event_CreateArrows = ItemId_Other + 206,
ItemId_Event_CreateCounters = ItemId_Other + 207,
ItemId_Event_DrawCards = ItemId_Other + 208,
ItemId_Event_Join = ItemId_Other + 209,
ItemId_Event_Ping = ItemId_Other + 210,
ItemId_Response_DeckList = ItemId_Other + 300,
ItemId_Response_DeckDownload = ItemId_Other + 301,
ItemId_Response_DeckUpload = ItemId_Other + 302,
@ -298,10 +299,19 @@ public:
class Event_ChatListPlayers : public ChatEvent {
Q_OBJECT
public:
Event_ChatListPlayers(const QString &_channel = QString(), const QList<ServerInfo_ChatUser *> &_playerList = QList<ServerInfo_ChatUser *>());
Event_ChatListPlayers(const QString &_channel = QString(), const QList<ServerInfo_User *> &_playerList = QList<ServerInfo_User *>());
int getItemId() const { return ItemId_Event_ChatListPlayers; }
static SerializableItem *newItem() { return new Event_ChatListPlayers; }
QList<ServerInfo_ChatUser *> getPlayerList() const { return typecastItemList<ServerInfo_ChatUser *>(); }
QList<ServerInfo_User *> getPlayerList() const { return typecastItemList<ServerInfo_User *>(); }
};
class Event_ChatJoinChannel : public ChatEvent {
Q_OBJECT
public:
Event_ChatJoinChannel(const QString &_channel = QString(), ServerInfo_User *_info = 0);
int getItemId() const { return ItemId_Event_ChatJoinChannel; }
static SerializableItem *newItem() { return new Event_ChatJoinChannel; }
ServerInfo_User *getUserInfo() const { return static_cast<ServerInfo_User *>(itemMap.value("user")); }
};
class Event_ListGames : public GenericEvent {

View file

@ -12,13 +12,23 @@ ServerInfo_ChatChannel::ServerInfo_ChatChannel(const QString &_name, const QStri
insertItem(new SerializableItem_Bool("auto_join", _autoJoin));
}
ServerInfo_ChatUser::ServerInfo_ChatUser(const QString &_name)
: SerializableItem_Map("chat_user")
ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QString &_country)
: SerializableItem_Map("user")
{
insertItem(new SerializableItem_String("name", _name));
insertItem(new SerializableItem_Int("userlevel", _userLevel));
insertItem(new SerializableItem_String("country", _country));
}
ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, const QString &_creatorName, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount)
ServerInfo_User::ServerInfo_User(const ServerInfo_User *other)
: SerializableItem_Map("user")
{
insertItem(new SerializableItem_String("name", other->getName()));
insertItem(new SerializableItem_Int("userlevel", other->getUserLevel()));
insertItem(new SerializableItem_String("country", other->getCountry()));
}
ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, ServerInfo_User *_creatorInfo, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount)
: SerializableItem_Map("game")
{
insertItem(new SerializableItem_Int("game_id", _gameId));
@ -26,7 +36,9 @@ ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool
insertItem(new SerializableItem_Bool("has_password", _hasPassword));
insertItem(new SerializableItem_Int("player_count", _playerCount));
insertItem(new SerializableItem_Int("max_players", _maxPlayers));
insertItem(new SerializableItem_String("creator_name", _creatorName));
if (!_creatorInfo)
_creatorInfo = new ServerInfo_User;
insertItem(_creatorInfo);
insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed));
insertItem(new SerializableItem_Bool("spectators_need_password", _spectatorsNeedPassword));
insertItem(new SerializableItem_Int("spectator_count", _spectatorCount));
@ -124,11 +136,13 @@ ServerInfo_Arrow::ServerInfo_Arrow(int _id, int _startPlayerId, const QString &_
insertItem(new SerializableItem_Color("color", _color));
}
ServerInfo_PlayerProperties::ServerInfo_PlayerProperties(int _playerId, const QString &_name, bool _spectator, bool _conceded, bool _readyStart, int _deckId)
ServerInfo_PlayerProperties::ServerInfo_PlayerProperties(int _playerId, ServerInfo_User *_userInfo, bool _spectator, bool _conceded, bool _readyStart, int _deckId)
: SerializableItem_Map("player_properties")
{
insertItem(new SerializableItem_Int("player_id", _playerId));
insertItem(new SerializableItem_String("name", _name));
if (!_userInfo)
_userInfo = new ServerInfo_User;
insertItem(_userInfo);
insertItem(new SerializableItem_Bool("spectator", _spectator));
insertItem(new SerializableItem_Bool("conceded", _conceded));
insertItem(new SerializableItem_Bool("ready_start", _readyStart));

View file

@ -30,23 +30,33 @@ public:
bool getAutoJoin() const { return static_cast<SerializableItem_Bool *>(itemMap.value("auto_join"))->getData(); }
};
class ServerInfo_ChatUser : public SerializableItem_Map {
class ServerInfo_User : public SerializableItem_Map {
public:
ServerInfo_ChatUser(const QString &_name = QString());
static SerializableItem *newItem() { return new ServerInfo_ChatUser; }
enum UserLevelFlags {
IsNothing = 0x00,
IsUser = 0x01,
IsRegistered = 0x02,
IsAdmin = 0x04
};
ServerInfo_User(const QString &_name = QString(), int _userLevel = IsNothing, const QString &_country = QString());
ServerInfo_User(const ServerInfo_User *other);
static SerializableItem *newItem() { return new ServerInfo_User; }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
int getUserLevel() const { return static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->getData(); }
void setUserLevel(int _userLevel) { static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->setData(_userLevel); }
QString getCountry() const { return static_cast<SerializableItem_String *>(itemMap.value("country"))->getData(); }
};
class ServerInfo_Game : public SerializableItem_Map {
public:
ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, const QString &_creatorName = QString(), bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1);
ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, ServerInfo_User *creatorInfo = 0, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1);
static SerializableItem *newItem() { return new ServerInfo_Game; }
int getGameId() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); }
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); }
bool getHasPassword() const { return static_cast<SerializableItem_Bool *>(itemMap.value("has_password"))->getData(); }
int getPlayerCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_count"))->getData(); }
int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); }
QString getCreatorName() const { return static_cast<SerializableItem_String *>(itemMap.value("creator_name"))->getData(); }
ServerInfo_User *getCreatorInfo() const { return static_cast<ServerInfo_User *>(itemMap.value("user")); }
bool getSpectatorsAllowed() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_allowed"))->getData(); }
bool getSpectatorsNeedPassword() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_need_password"))->getData(); }
int getSpectatorCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("spectator_count"))->getData(); }
@ -121,10 +131,10 @@ public:
class ServerInfo_PlayerProperties : public SerializableItem_Map {
public:
ServerInfo_PlayerProperties(int _playerId = -1, const QString &_name = QString(), bool _spectator = false, bool _conceded = false, bool _readyStart = false, int _deckId = -1);
ServerInfo_PlayerProperties(int _playerId = -1, ServerInfo_User *_userInfo = 0, bool _spectator = false, bool _conceded = false, bool _readyStart = false, int _deckId = -1);
static SerializableItem *newItem() { return new ServerInfo_PlayerProperties; }
int getPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_id"))->getData(); }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
ServerInfo_User *getUserInfo() const { return static_cast<ServerInfo_User *>(itemMap.value("user")); }
bool getSpectator() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectator"))->getData(); }
bool getConceded() const { return static_cast<SerializableItem_Bool *>(itemMap.value("conceded"))->getData(); }
bool getReadyStart() const { return static_cast<SerializableItem_Bool *>(itemMap.value("ready_start"))->getData(); }

View file

@ -59,11 +59,10 @@ ItemId_Event_DumpZone = 1057,
ItemId_Event_StopDumpZone = 1058,
ItemId_Event_ServerMessage = 1059,
ItemId_Event_GameJoined = 1060,
ItemId_Event_ChatJoinChannel = 1061,
ItemId_Event_ChatLeaveChannel = 1062,
ItemId_Event_ChatSay = 1063,
ItemId_Context_ReadyStart = 1064,
ItemId_Context_Concede = 1065,
ItemId_Context_DeckSelect = 1066,
ItemId_Other = 1067
ItemId_Event_ChatLeaveChannel = 1061,
ItemId_Event_ChatSay = 1062,
ItemId_Context_ReadyStart = 1063,
ItemId_Context_Concede = 1064,
ItemId_Context_DeckSelect = 1065,
ItemId_Other = 1066
};

View file

@ -381,11 +381,6 @@ Event_GameJoined::Event_GameJoined(int _gameId, const QString &_gameDescription,
insertItem(new SerializableItem_Bool("spectators_see_everything", _spectatorsSeeEverything));
insertItem(new SerializableItem_Bool("resuming", _resuming));
}
Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, const QString &_playerName)
: ChatEvent("chat_join_channel", _channel)
{
insertItem(new SerializableItem_String("player_name", _playerName));
}
Event_ChatLeaveChannel::Event_ChatLeaveChannel(const QString &_channel, const QString &_playerName)
: ChatEvent("chat_leave_channel", _channel)
{
@ -472,7 +467,6 @@ void ProtocolItem::initializeHashAuto()
itemNameHash.insert("game_eventstop_dump_zone", Event_StopDumpZone::newItem);
itemNameHash.insert("generic_eventserver_message", Event_ServerMessage::newItem);
itemNameHash.insert("generic_eventgame_joined", Event_GameJoined::newItem);
itemNameHash.insert("chat_eventchat_join_channel", Event_ChatJoinChannel::newItem);
itemNameHash.insert("chat_eventchat_leave_channel", Event_ChatLeaveChannel::newItem);
itemNameHash.insert("chat_eventchat_say", Event_ChatSay::newItem);
itemNameHash.insert("game_event_contextready_start", Context_ReadyStart::newItem);

View file

@ -58,7 +58,6 @@
3:stop_dump_zone:i,zone_owner_id:s,zone
4:server_message:s,message
4:game_joined:i,game_id:s,game_description:i,player_id:b,spectator:b,spectators_can_talk:b,spectators_see_everything:b,resuming
5:chat_join_channel:s,player_name
5:chat_leave_channel:s,player_name
5:chat_say:s,player_name:s,message
6:ready_start

View file

@ -563,14 +563,6 @@ public:
static SerializableItem *newItem() { return new Event_GameJoined; }
int getItemId() const { return ItemId_Event_GameJoined; }
};
class Event_ChatJoinChannel : public ChatEvent {
Q_OBJECT
public:
Event_ChatJoinChannel(const QString &_channel = QString(), const QString &_playerName = QString());
QString getPlayerName() const { return static_cast<SerializableItem_String *>(itemMap.value("player_name"))->getData(); };
static SerializableItem *newItem() { return new Event_ChatJoinChannel; }
int getItemId() const { return ItemId_Event_ChatJoinChannel; }
};
class Event_ChatLeaveChannel : public ChatEvent {
Q_OBJECT
public:

View file

@ -22,6 +22,7 @@
#include "server_counter.h"
#include "server_chatchannel.h"
#include "server_protocolhandler.h"
#include "protocol_datastructures.h"
#include <QDebug>
Server::Server(QObject *parent)
@ -35,6 +36,35 @@ Server::~Server()
delete clients.takeFirst();
}
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password)
{
AuthenticationResult authState = checkUserPassword(name, password);
if (authState == PasswordWrong)
return authState;
if (authState == PasswordRight) {
Server_ProtocolHandler *oldSession = users.value(name);
if (oldSession)
delete oldSession; // ~Server_ProtocolHandler() will call Server::removeClient
} else if (authState == UnknownUser) {
// Change user name so that no two users have the same names
QString tempName = name;
int i = 0;
while (users.contains(tempName))
tempName = name + "_" + QString::number(++i);
name = tempName;
}
ServerInfo_User *data = getUserData(name);
if (authState == PasswordRight)
data->setUserLevel(data->getUserLevel() | ServerInfo_User::IsRegistered);
session->setUserInfo(data);
users.insert(name, session);
return authState;
}
Server_Game *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
{
Server_Game *newGame = new Server_Game(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this);
@ -54,19 +84,10 @@ void Server::addClient(Server_ProtocolHandler *client)
void Server::removeClient(Server_ProtocolHandler *client)
{
clients.removeAt(clients.indexOf(client));
qDebug(QString("Server::removeClient: %1 clients left").arg(clients.size()).toLatin1());
}
void Server::closeOldSession(const QString &playerName)
{
Server_ProtocolHandler *session = 0;
for (int i = 0; i < clients.size(); ++i)
if (clients[i]->getPlayerName() == playerName) {
session = clients[i];
break;
}
if (session)
delete session; // ~Server_ProtocolHandler() will call Server::removeClient
ServerInfo_User *data = client->getUserInfo();
if (data)
users.remove(data->getName());
qDebug() << "Server::removeClient: " << clients.size() << "clients; " << users.size() << "users left";
}
Server_Game *Server::getGame(int gameId) const
@ -85,14 +106,14 @@ void Server::broadcastGameListUpdate(Server_Game *game)
!game->getPassword().isEmpty(),
game->getPlayerCount(),
game->getMaxPlayers(),
game->getCreatorName(),
new ServerInfo_User(game->getCreatorInfo()),
game->getSpectatorsAllowed(),
game->getSpectatorsNeedPassword(),
game->getSpectatorCount()
));
else
// Game is closing
eventGameList.append(new ServerInfo_Game(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), QString(), false, 0));
eventGameList.append(new ServerInfo_Game(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), 0, false, 0));
Event_ListGames *event = new Event_ListGames(eventGameList);
for (int i = 0; i < clients.size(); i++)

View file

@ -8,6 +8,7 @@
class Server_Game;
class Server_ChatChannel;
class Server_ProtocolHandler;
class ServerInfo_User;
enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 };
@ -22,7 +23,7 @@ private slots:
public:
Server(QObject *parent = 0);
~Server();
virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0;
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password);
QList<Server_Game *> getGames() const { return games.values(); }
Server_Game *getGame(int gameId) const;
const QMap<QString, Server_ChatChannel *> &getChatChannels() { return chatChannels; }
@ -30,7 +31,6 @@ public:
void addClient(Server_ProtocolHandler *player);
void removeClient(Server_ProtocolHandler *player);
void closeOldSession(const QString &playerName);
virtual QString getLoginMessage() const = 0;
Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
@ -40,8 +40,11 @@ public:
private:
QMap<int, Server_Game *> games;
QList<Server_ProtocolHandler *> clients;
QMap<QString, Server_ProtocolHandler *> users;
QMap<QString, Server_ChatChannel *> chatChannels;
protected:
virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0;
virtual ServerInfo_User *getUserData(const QString &name) = 0;
int nextGameId;
void addChatChannel(Server_ChatChannel *newChannel);
};

View file

@ -8,12 +8,12 @@ Server_ChatChannel::Server_ChatChannel(const QString &_name, const QString &_des
void Server_ChatChannel::addClient(Server_ProtocolHandler *client)
{
sendChatEvent(new Event_ChatJoinChannel(name, client->getPlayerName()));
sendChatEvent(new Event_ChatJoinChannel(name, new ServerInfo_User(client->getUserInfo())));
append(client);
QList<ServerInfo_ChatUser *> eventUserList;
QList<ServerInfo_User *> eventUserList;
for (int i = 0; i < size(); ++i)
eventUserList.append(new ServerInfo_ChatUser(at(i)->getPlayerName()));
eventUserList.append(new ServerInfo_User(at(i)->getUserInfo()));
Event_ChatListPlayers *eventCLP = new Event_ChatListPlayers(name, eventUserList);
client->enqueueProtocolItem(eventCLP);
@ -25,13 +25,13 @@ void Server_ChatChannel::addClient(Server_ProtocolHandler *client)
void Server_ChatChannel::removeClient(Server_ProtocolHandler *client)
{
removeAt(indexOf(client));
sendChatEvent(new Event_ChatLeaveChannel(name, client->getPlayerName()));
sendChatEvent(new Event_ChatLeaveChannel(name, client->getUserInfo()->getName()));
emit channelInfoChanged();
}
void Server_ChatChannel::say(Server_ProtocolHandler *client, const QString &s)
{
sendChatEvent(new Event_ChatSay(name, client->getPlayerName(), s));
sendChatEvent(new Event_ChatSay(name, client->getUserInfo()->getName(), s));
}
void Server_ChatChannel::sendChatEvent(ChatEvent *event)

View file

@ -28,9 +28,9 @@
#include <QDebug>
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server *parent)
: QObject(parent), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0)
: QObject(parent), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0)
{
creator = addPlayer(_creator, false, false);
addPlayer(_creator, false, false);
if (parent->getGameShouldPing()) {
pingClock = new QTimer(this);
@ -49,6 +49,7 @@ Server_Game::~Server_Game()
players.clear();
emit gameClosing();
delete creatorInfo;
qDebug("Server_Game destructor");
}
@ -187,7 +188,7 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
const QList<int> &keyList = players.keys();
int playerId = keyList.isEmpty() ? 0 : (keyList.last() + 1);
Server_Player *newPlayer = new Server_Player(this, playerId, handler->getPlayerName(), spectator, handler);
Server_Player *newPlayer = new Server_Player(this, playerId, handler->getUserInfo(), spectator, handler);
sendGameEvent(new Event_Join(newPlayer->getProperties()));
players.insert(playerId, newPlayer);
@ -350,8 +351,7 @@ QList<ServerInfo_Player *> Server_Game::getGameState(Server_Player *playerWhosAs
zoneList.append(new ServerInfo_Zone(zone->getName(), zone->getType(), zone->hasCoords(), zone->cards.size(), cardList));
}
ServerInfo_PlayerProperties *properties = new ServerInfo_PlayerProperties(player->getPlayerId(), player->getPlayerName(), player->getSpectator(), player->getConceded(), player->getReadyStart(), player->getDeckId());
result.append(new ServerInfo_Player(properties, player == playerWhosAsking ? player->getDeck() : 0, zoneList, counterList, arrowList));
result.append(new ServerInfo_Player(player->getProperties(), player == playerWhosAsking ? player->getDeck() : 0, zoneList, counterList, arrowList));
}
return result;
}

View file

@ -28,11 +28,12 @@
class QTimer;
class Server;
class ServerInfo_User;
class Server_Game : public QObject {
Q_OBJECT
private:
QPointer<Server_Player> creator;
ServerInfo_User *creatorInfo;
QMap<int, Server_Player *> players;
bool gameStarted;
int gameId;
@ -53,8 +54,7 @@ private slots:
public:
Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server *parent);
~Server_Game();
Server_Player *getCreator() const { return creator; }
QString getCreatorName() const { return creator ? creator->getPlayerName() : QString(); }
ServerInfo_User *getCreatorInfo() const { return creatorInfo; }
bool getGameStarted() const { return gameStarted; }
int getPlayerCount() const;
int getSpectatorCount() const;

View file

@ -9,8 +9,8 @@
#include "protocol_items.h"
#include "decklist.h"
Server_Player::Server_Player(Server_Game *_game, int _playerId, const QString &_playerName, bool _spectator, Server_ProtocolHandler *_handler)
: game(_game), handler(_handler), deck(0), playerId(_playerId), playerName(_playerName), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), deckId(-2)
Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler)
: game(_game), handler(_handler), userInfo(new ServerInfo_User(_userInfo)), deck(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), deckId(-2)
{
}
@ -20,6 +20,7 @@ Server_Player::~Server_Player()
if (handler)
handler->playerRemovedFromGame(game);
delete userInfo;
}
int Server_Player::newCardId()
@ -151,7 +152,7 @@ void Server_Player::clearZones()
ServerInfo_PlayerProperties *Server_Player::getProperties()
{
return new ServerInfo_PlayerProperties(playerId, playerName, spectator, conceded, readyStart, deckId);
return new ServerInfo_PlayerProperties(playerId, new ServerInfo_User(userInfo), spectator, conceded, readyStart, deckId);
}
void Server_Player::setDeck(DeckList *_deck, int _deckId)

View file

@ -13,6 +13,7 @@ class Server_Counter;
class Server_Arrow;
class Server_ProtocolHandler;
class ProtocolItem;
class ServerInfo_User;
class ServerInfo_PlayerProperties;
class Server_Player : public Server_ArrowTarget {
@ -20,12 +21,12 @@ class Server_Player : public Server_ArrowTarget {
private:
Server_Game *game;
Server_ProtocolHandler *handler;
ServerInfo_User *userInfo;
DeckList *deck;
QMap<QString, Server_CardZone *> zones;
QMap<int, Server_Counter *> counters;
QMap<int, Server_Arrow *> arrows;
int playerId;
QString playerName;
bool spectator;
int initialCards;
int nextCardId;
@ -33,7 +34,7 @@ private:
bool conceded;
int deckId;
public:
Server_Player(Server_Game *_game, int _playerId, const QString &_playerName, bool _spectator, Server_ProtocolHandler *_handler);
Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler);
~Server_Player();
Server_ProtocolHandler *getProtocolHandler() const { return handler; }
void setProtocolHandler(Server_ProtocolHandler *_handler) { handler = _handler; }
@ -48,7 +49,7 @@ public:
bool getConceded() const { return conceded; }
void setConceded(bool _conceded) { conceded = _conceded; }
int getDeckId() const { return deckId; }
QString getPlayerName() const { return playerName; }
ServerInfo_User *getUserInfo() const { return userInfo; }
void setDeck(DeckList *_deck, int _deckId);
DeckList *getDeck() const { return deck; }
const QMap<QString, Server_CardZone *> &getZones() const { return zones; }

View file

@ -14,7 +14,7 @@
#include <QDateTime>
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), lastCommandTime(QDateTime::currentDateTime())
: QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), userInfo(0), lastCommandTime(QDateTime::currentDateTime())
{
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
}
@ -40,6 +40,8 @@ Server_ProtocolHandler::~Server_ProtocolHandler()
QMapIterator<QString, Server_ChatChannel *> chatChannelIterator(chatChannels);
while (chatChannelIterator.hasNext())
chatChannelIterator.next().value()->removeClient(this);
delete userInfo;
}
void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
@ -200,15 +202,12 @@ ResponseCode Server_ProtocolHandler::cmdPing(Command_Ping * /*cmd*/, CommandCont
ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContainer *cont)
{
QString userName = cmd->getUsername().simplified();
if (userName.isEmpty())
if (userName.isEmpty() || (userInfo != 0))
return RespContextError;
authState = server->checkUserPassword(userName, cmd->getPassword());
authState = server->loginUser(this, userName, cmd->getPassword());
if (authState == PasswordWrong)
return RespWrongPassword;
if (authState == PasswordRight)
server->closeOldSession(userName);
playerName = userName;
enqueueProtocolItem(new Event_ServerMessage(server->getLoginMessage()));
if (authState == PasswordRight) {
@ -217,7 +216,7 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
for (int i = 0; i < serverGames.size(); ++i) {
const QList<Server_Player *> &gamePlayers = serverGames[i]->getPlayers().values();
for (int j = 0; j < gamePlayers.size(); ++j)
if (gamePlayers[j]->getPlayerName() == playerName) {
if (gamePlayers[j]->getUserInfo()->getName() == userInfo->getName()) {
gamePlayers[j]->setProtocolHandler(this);
games.insert(serverGames[i]->getGameId(), QPair<Server_Game *, Server_Player *>(serverGames[i], gamePlayers[j]));
@ -293,7 +292,7 @@ ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/, C
!g->getPassword().isEmpty(),
g->getPlayerCount(),
g->getMaxPlayers(),
g->getCreatorName(),
g->getCreatorInfo(),
g->getSpectatorsAllowed(),
g->getSpectatorsNeedPassword(),
g->getSpectatorCount()
@ -311,7 +310,7 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm
return RespLoginNeeded;
Server_Game *game = server->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this);
Server_Player *creator = game->getCreator();
Server_Player *creator = game->getPlayers().values().first();
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
enqueueProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false));

View file

@ -9,6 +9,7 @@
class Server_Player;
class Server_Card;
class ServerInfo_User;
class QTimer;
class Server_ProtocolHandler : public QObject {
@ -17,7 +18,6 @@ protected:
Server *server;
QMap<int, QPair<Server_Game *, Server_Player *> > games;
QMap<QString, Server_ChatChannel *> chatChannels;
QString playerName;
Server *getServer() const { return server; }
QPair<Server_Game *, Server_Player *> getGame(int gameId) const;
@ -25,6 +25,7 @@ protected:
AuthenticationResult authState;
bool acceptsGameListChanges;
bool acceptsChatChannelListChanges;
ServerInfo_User *userInfo;
private:
QList<ProtocolItem *> itemQueue;
@ -91,7 +92,8 @@ public:
bool getAcceptsGameListChanges() const { return acceptsGameListChanges; }
bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; }
const QString &getPlayerName() const { return playerName; }
ServerInfo_User *getUserInfo() const { return userInfo; }
void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; }
const QDateTime &getLastCommandTime() const { return lastCommandTime; }
void processCommandContainer(CommandContainer *cont);

View file

@ -48,7 +48,6 @@ void testRNG()
numbers[max - minMax] = rng->makeNumbersVector(n * (max - min + 1), min, max);
chisq[max - minMax] = rng->testRandom(numbers[max - minMax]);
}
qDebug() << numbers;
for (int i = 0; i <= maxMax - min; ++i) {
std::cerr << (min + i);
for (int j = 0; j < numbers.size(); ++j) {

View file

@ -19,6 +19,7 @@
***************************************************************************/
#include <QtSql>
#include <QSettings>
#include <QDebug>
#include "servatrice.h"
#include "server_chatchannel.h"
#include "serversocketinterface.h"
@ -88,7 +89,7 @@ bool Servatrice::openDatabase()
if (!query.next())
return false;
nextGameId = query.value(0).toInt() + 1;
qDebug(QString("set nextGameId to %1").arg(nextGameId).toLatin1());
qDebug() << "set nextGameId to " << nextGameId;
}
return true;
}
@ -103,7 +104,7 @@ bool Servatrice::execSqlQuery(QSqlQuery &query)
{
if (query.exec())
return true;
qCritical(QString("Database error: %1").arg(query.lastError().text()).toLatin1());
qCritical() << "Database error:" << query.lastError().text();
return false;
}
@ -139,4 +140,35 @@ AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QS
return UnknownUser;
}
const QString Servatrice::versionString = "Servatrice 0.20100915";
ServerInfo_User *Servatrice::getUserData(const QString &name)
{
const QString method = settings->value("authentication/method").toString();
if (method == "sql") {
checkSql();
QSqlQuery query;
query.prepare("select admin, country from users where name = :name");
query.bindValue(":name", name);
if (!execSqlQuery(query))
return new ServerInfo_User(name);
if (query.next()) {
bool is_admin = query.value(0).toInt();
QString country = query.value(1).toString();
int userLevel = ServerInfo_User::IsUser;
if (is_admin)
userLevel |= ServerInfo_User::IsAdmin;
return new ServerInfo_User(
name,
userLevel,
country
);
} else
return new ServerInfo_User(name);
} else
return new ServerInfo_User(name);
}
const QString Servatrice::versionString = "Servatrice 0.20100918";

View file

@ -40,11 +40,13 @@ public:
bool openDatabase();
void checkSql();
bool execSqlQuery(QSqlQuery &query);
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
QString getLoginMessage() const { return loginMessage; }
bool getGameShouldPing() const { return true; }
int getMaxGameInactivityTime() const { return maxGameInactivityTime; }
int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; }
protected:
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
ServerInfo_User *getUserData(const QString &name);
private:
QTimer *pingClock;
QTcpServer *tcpServer;

View file

@ -109,7 +109,7 @@ int ServerSocketInterface::getDeckPathId(int basePathId, QStringList path)
query.prepare("select id from decklist_folders where id_parent = :id_parent and name = :name and user = :user");
query.bindValue(":id_parent", basePathId);
query.bindValue(":name", path.takeFirst());
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
if (!servatrice->execSqlQuery(query))
return -1;
if (!query.next())
@ -131,7 +131,7 @@ bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder)
QSqlQuery query;
query.prepare("select id, name from decklist_folders where id_parent = :id_parent and user = :user");
query.bindValue(":id_parent", folder->getId());
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
if (!servatrice->execSqlQuery(query))
return false;
@ -144,7 +144,7 @@ bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder)
query.prepare("select id, name, upload_time from decklist_files where id_folder = :id_folder and user = :user");
query.bindValue(":id_folder", folder->getId());
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
if (!servatrice->execSqlQuery(query))
return false;
@ -190,7 +190,7 @@ ResponseCode ServerSocketInterface::cmdDeckNewDir(Command_DeckNewDir *cmd, Comma
QSqlQuery query;
query.prepare("insert into decklist_folders (id_parent, user, name) values(:id_parent, :user, :name)");
query.bindValue(":id_parent", folderId);
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
query.bindValue(":name", cmd->getDirName());
if (!servatrice->execSqlQuery(query))
return RespContextError;
@ -243,7 +243,7 @@ ResponseCode ServerSocketInterface::cmdDeckDel(Command_DeckDel *cmd, CommandCont
query.prepare("select id from decklist_files where id = :id and user = :user");
query.bindValue(":id", cmd->getDeckId());
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
servatrice->execSqlQuery(query);
if (!query.next())
return RespNameNotFound;
@ -281,7 +281,7 @@ ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd, Comma
QSqlQuery query;
query.prepare("insert into decklist_files (id_folder, user, name, upload_time, content) values(:id_folder, :user, :name, NOW(), :content)");
query.bindValue(":id_folder", folderId);
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
query.bindValue(":name", deckName);
query.bindValue(":content", deckContents);
servatrice->execSqlQuery(query);
@ -298,7 +298,7 @@ DeckList *ServerSocketInterface::getDeckFromDatabase(int deckId)
query.prepare("select content from decklist_files where id = :id and user = :user");
query.bindValue(":id", deckId);
query.bindValue(":user", playerName);
query.bindValue(":user", userInfo->getName());
servatrice->execSqlQuery(query);
if (!query.next())
throw RespNameNotFound;