fix: Unable to clone units if game master with spawn restrictions on

Other minor graphical fixes
This commit is contained in:
Pax1601 2025-03-25 19:30:00 +01:00
parent bc65bf546f
commit 41b4328eaf
18 changed files with 622 additions and 78 deletions

View File

@ -194,7 +194,10 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
int spawnPoints = value[L"spawnPoints"].as_number().to_int32();
if (!checkSpawnPoints(spawnPoints, coalition)) return;
if (!checkSpawnPoints(spawnPoints, coalition)) {
log(username + " insufficient spawn points ", true);
return;
}
vector<SpawnOptions> spawnOptions;
for (auto unit : value[L"units"].as_array()) {
@ -228,7 +231,10 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
string country = to_string(value[L"country"]);
int spawnPoints = value[L"spawnPoints"].as_number().to_int32();
if (!checkSpawnPoints(spawnPoints, coalition)) return;
if (!checkSpawnPoints(spawnPoints, coalition)) {
log(username + " insufficient spawn points ", true);
return;
}
vector<SpawnOptions> spawnOptions;
for (auto unit : value[L"units"].as_array()) {
@ -380,7 +386,10 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
string coalition = to_string(value[L"coalition"]);
int spawnPoints = value[L"spawnPoints"].as_number().to_int32();
if (!checkSpawnPoints(spawnPoints, coalition)) return;
if (coalition.compare("all") != 0 && !checkSpawnPoints(spawnPoints, coalition)) {
log(username + " insufficient spawn points ", true);
return;
}
for (auto unit : value[L"units"].as_array()) {
unsigned int ID = unit[L"ID"].as_integer();

View File

@ -10,7 +10,7 @@
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Olympus v{{OLYMPUS_VERSION_NUMBER}}</title>
<title>Olympus {{OLYMPUS_VERSION_NUMBER}}</title>
</head>
<body>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
version="1.1"
viewBox="0 0 50 50"
xml:space="preserve"
id="svg2"
sodipodi:docname="artillery.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs2" /><sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="11.73"
inkscape:cx="30.051151"
inkscape:cy="16.325661"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" /><path
d="m 25.042626,4.9834433 c 1.386884,0 2.50734,1.1204928 2.50734,2.5073392 V 8.3056781 C 34.89187,9.3948151 40.690261,15.20096 41.779243,22.534956 h 0.814896 c 1.386886,0 2.50734,1.120493 2.50734,2.50734 0,1.386848 -1.120493,2.50734 -2.50734,2.50734 h -0.814896 c -1.089135,7.341904 -6.89528,13.140295 -14.229277,14.229277 v 0.814896 c 0,1.386886 -1.120492,2.50734 -2.50734,2.50734 -1.386847,0 -2.50734,-1.120493 -2.50734,-2.50734 V 41.778913 C 15.193383,40.689778 9.3949904,34.89154 8.3060081,27.549636 H 7.4911125 c -1.3868851,0 -2.5073392,-1.120492 -2.5073392,-2.50734 0,-1.386847 1.1204928,-2.50734 2.5073392,-2.50734 H 8.3060081 C 9.3951451,15.193053 15.193383,9.3946604 22.535286,8.3056781 V 7.4907825 c 0,-1.3868851 1.120493,-2.5073392 2.50734,-2.5073392 z M 13.398981,27.549886 c 0.979447,4.568056 4.575963,8.156857 9.136305,9.136305 v -1.614133 c 0,-1.386885 1.120493,-2.507338 2.50734,-2.507338 1.386848,0 2.50734,1.120492 2.50734,2.507338 v 1.614133 c 4.568056,-0.979448 8.156856,-4.575964 9.136303,-9.136305 h -1.614131 c -1.386885,0 -2.507338,-1.120492 -2.507338,-2.507339 0,-1.386847 1.120492,-2.50734 2.507338,-2.50734 h 1.614131 C 35.706822,17.96715 32.118214,14.378349 27.549966,13.398902 v 1.614131 c 0,1.386885 -1.120492,2.507341 -2.50734,2.507341 -1.386847,0 -2.50734,-1.120493 -2.50734,-2.507341 v -1.614131 c -4.568056,0.979447 -8.156858,4.568056 -9.136305,9.136305 h 1.614132 c 1.386885,0 2.50734,1.120493 2.50734,2.50734 0,1.386847 -1.120493,2.507339 -2.50734,2.507339 z m 11.643645,-5.014679 a 2.5073398,2.5073398 0 1 1 0,5.014679 2.5073398,2.5073398 0 1 1 0,-5.014679 z"
fill="#082e44"
stroke="#082e44"
stroke-width="0.0783558"
id="path2" /></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
viewBox="0 0 50 50"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="radar.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="16.588725"
inkscape:cx="33.305754"
inkscape:cy="31.437015"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
style="fill:none;fill-opacity:1;stroke:#082e44;stroke-width:4.11474;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 17.740075,30.890065 31.982602,22.799923 22.687533,17.179659 36.603086,8.4392652"
id="path942"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-opacity:1;stroke:#082e44;stroke-width:4.11474;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 29.114015,6.2180572 7.95605,2.001889 -1.789716,7.1094928"
id="path1230" />
<path
style="fill:none;fill-opacity:1;stroke:#082e44;stroke-width:5.48632;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:5.6;stroke-opacity:1;paint-order:stroke fill markers"
id="path1657"
sodipodi:type="arc"
sodipodi:cx="30.185064"
sodipodi:cy="18.125761"
sodipodi:rx="24.331261"
sodipodi:ry="24.3619"
sodipodi:start="1.0594149"
sodipodi:end="3.5325464"
sodipodi:arc-type="arc"
sodipodi:open="true"
d="M 42.092355,39.371026 A 24.331261,24.3619 0 0 1 14.046786,36.357651 24.331261,24.3619 0 0 1 7.6896937,8.8421626" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
version="1.1"
viewBox="0 0 50 50"
id="svg2"
sodipodi:docname="infantry.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="23.46"
inkscape:cx="25"
inkscape:cy="25"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
d="m 23.94212,20.425236 c 1.815812,0 3.560113,0.507579 5.061418,1.422608 V 43.301568 H 15.277723 V 30.841297 l -3.831679,6.476739 C 10.64539,38.67632 8.8867161,39.126686 7.5283812,38.326033 6.1700967,37.525354 5.7197307,35.766705 6.5204095,34.40837 L 11.96787,25.200589 c 1.751462,-2.959491 4.932568,-4.775479 8.371145,-4.775479 z m -7.520642,-8.006788 a 5.7190265,5.7190265 0 1 1 11.438053,0 5.7190265,5.7190265 0 1 1 -11.438053,0 z M 37.010073,6.699422 c 0.629091,0 1.143806,0.5147149 1.143806,1.1438053 v 8.3141597 c 0.686303,0.393203 1.143805,1.136669 1.143805,1.980214 v 7.81364 l 1.143805,-0.378881 v -4.003394 c 0,-0.629091 0.514715,-1.143805 1.143805,-1.143805 H 42.7291 c 0.62909,0 1.143805,0.514714 1.143805,1.143805 v 6.04077 c 0,0.493257 -0.314533,0.929351 -0.779221,1.086618 l -3.796126,1.25818 v 1.908729 h 3.431516 c 0.629091,0 1.143806,0.514715 1.143806,1.143806 v 1.143805 c 0,0.62909 -0.514715,1.143805 -1.143806,1.143805 h -3.145577 l 1.644223,6.584155 c 0.178724,0.722033 -0.36461,1.422608 -1.108076,1.422608 h -4.253527 c -0.62909,0 -1.143805,-0.514715 -1.143805,-1.143805 v -6.862781 h -1.143806 c -1.265341,0 -2.28761,-1.022269 -2.28761,-2.287611 V 22.712948 c 0,-1.265342 1.022269,-2.287611 2.28761,-2.287611 v -2.287636 c 0,-0.843544 0.457528,-1.587035 1.143806,-1.980213 V 8.9873351 c -0.629091,0 -1.143806,-0.5147149 -1.143806,-1.1438052 0,-0.6291156 0.514715,-1.1438053 1.143806,-1.1438053 h 1.143805 z"
fill="none"
stroke="#082e44"
id="path2"
style="stroke-width:2.52151" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
viewBox="0 0 50 50"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="launcher.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="11.73"
inkscape:cx="45.311168"
inkscape:cy="34.739983"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
stroke="#082e44"
stroke-width="3.65626"
id="path849"
sodipodi:type="arc"
sodipodi:cx="25.113663"
sodipodi:cy="50.13221"
sodipodi:rx="15.070933"
sodipodi:ry="15.109776"
sodipodi:start="3.8397244"
sodipodi:end="5.5850536"
sodipodi:arc-type="arc"
d="m 13.568658,40.419833 a 15.070933,15.109776 0 0 1 11.545005,-5.397399 15.070933,15.109776 0 0 1 11.545004,5.397399"
sodipodi:open="true" />
<path
stroke="#082e44"
stroke-width="1.5"
d="M 24.802923,34.634011 V 7.211128"
id="path1085"
style="stroke-width:3.1;stroke-dasharray:none" />
<path
stroke="#082e44"
stroke-width="1.5"
d="M 21.074033,13.348261 24.69735,7.07249 28.214275,13.163982"
id="path1087"
style="stroke-width:3.1;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
viewBox="0 0 50 50"
fill="none"
version="1.1"
id="svg6"
sodipodi:docname="radar.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="16.588725"
inkscape:cx="33.305754"
inkscape:cy="31.437015"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
style="fill:none;fill-opacity:1;stroke:#082e44;stroke-width:4.11474;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 17.740075,30.890065 31.982602,22.799923 22.687533,17.179659 36.603086,8.4392652"
id="path942"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-opacity:1;stroke:#082e44;stroke-width:4.11474;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 29.114015,6.2180572 7.95605,2.001889 -1.789716,7.1094928"
id="path1230" />
<path
style="fill:none;fill-opacity:1;stroke:#082e44;stroke-width:5.48632;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:5.6;stroke-opacity:1;paint-order:stroke fill markers"
id="path1657"
sodipodi:type="arc"
sodipodi:cx="30.185064"
sodipodi:cy="18.125761"
sodipodi:rx="24.331261"
sodipodi:ry="24.3619"
sodipodi:start="1.0594149"
sodipodi:end="3.5325464"
sodipodi:arc-type="arc"
sodipodi:open="true"
d="M 42.092355,39.371026 A 24.331261,24.3619 0 0 1 14.046786,36.357651 24.331261,24.3619 0 0 1 7.6896937,8.8421626" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,7 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M45.7733 41.3423L25.9481 7.63951C25.5228 6.91648 24.4772 6.91646 24.0519 7.63951L4.22671 41.3423C3.79536 42.0756 4.32409 43 5.17484 43H44.8252C45.6759 43 46.2046 42.0756 45.7733 41.3423Z"
fill="#3BB9FF" stroke="none" stroke-width="2" />
<path d="M6.74842 41L25 9.97231L43.2516 41H6.74842Z" fill="none" stroke="#082E44"
stroke-width="2" />
</svg>

After

Width:  |  Height:  |  Size: 482 B

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
version="1.1"
viewBox="0 0 50 50"
xml:space="preserve"
id="svg2"
sodipodi:docname="tactical.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs2" /><sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="23.46"
inkscape:cx="25"
inkscape:cy="25"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" /><path
d="m 15.117444,13.661846 -2.135107,6.10289 h 24.034529 l -2.135107,-6.10289 C 34.513654,12.61474 33.523796,11.911194 32.41121,11.911194 H 17.588147 c -1.112547,0 -2.102406,0.703546 -2.470549,1.750652 z m -7.8206864,6.495309 2.8795504,-8.221569 c 1.104391,-3.1495117 4.073851,-5.2599583 7.411724,-5.2599583 h 14.823063 c 3.337641,0 6.307179,2.1106005 7.411724,5.2599583 l 2.879549,8.221569 c 1.897887,0.785301 3.239499,2.65868 3.239499,4.842917 v 15.706776 c 0,1.44795 -1.169833,2.617744 -2.617783,2.617744 h -2.617745 c -1.44795,0 -2.617783,-1.169833 -2.617783,-2.617744 V 36.780346 H 11.910724 v 3.926502 c 0,1.44795 -1.169833,2.617744 -2.6177831,2.617744 H 6.6751962 c -1.4479504,0 -2.6177832,-1.169833 -2.6177832,-2.617744 V 25.000072 c 0,-2.184199 1.3416125,-4.057693 3.2394985,-4.842917 z m 7.2316724,7.460584 a 2.6178601,2.6178601 0 1 0 -5.2357199,0 2.6178601,2.6178601 0 1 0 5.2357199,0 z m 23.560164,2.617783 a 2.6178601,2.6178601 0 1 0 0,-5.23572 2.6178601,2.6178601 0 1 0 0,5.23572 z"
fill="none"
stroke="#082e44"
id="path2"
style="stroke-width:3.84725" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="50"
height="50"
version="1.1"
viewBox="0 0 50 50"
id="svg2"
sodipodi:docname="truck.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="23.46"
inkscape:cx="25"
inkscape:cy="25"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
d="m 6.7874459,7.8589804 c -1.7743426,0 -3.21404,1.4395716 -3.21404,3.2140396 v 21.426094 c 0,1.774343 1.4395716,3.21404 3.21404,3.21404 h 1.0713047 c 0,3.548685 2.8791114,6.427766 6.4277654,6.427766 3.548685,0 6.427765,-2.879112 6.427765,-6.427766 h 8.570564 c 0,3.548685 2.879143,6.427766 6.427765,6.427766 3.548685,0 6.427765,-2.879112 6.427765,-6.427766 h 2.14261 c 1.185128,0 2.142609,-0.957481 2.142609,-2.142609 0,-1.185128 -0.957481,-2.14261 -2.142609,-2.14261 v -7.679853 c 0,-1.138266 -0.448626,-2.229668 -1.252089,-3.033131 l -5.175677,-5.175676 c -0.803462,-0.803463 -1.894865,-1.252089 -3.03313,-1.252089 h -3.394572 v -3.21404 c 0,-1.7743424 -1.439572,-3.2140398 -3.21404,-3.2140398 z M 31.427265,18.572027 h 3.394572 l 5.175677,5.175677 v 1.252089 H 31.426951 Z M 11.072413,35.71284 a 3.2140399,3.2140399 0 1 1 6.427765,0 3.2140399,3.2140399 0 1 1 -6.427765,0 z m 24.63982,-3.21404 a 3.2140399,3.2140399 0 1 1 0,6.427765 3.2140399,3.2140399 0 1 1 0,-6.427765 z"
fill="none"
stroke="#082e44"
id="path2"
style="stroke-width:3.14516" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -34,7 +34,6 @@ export var IP = window.location.toString();
export class OlympusApp {
/* Global data */
#latestVersion: string | undefined = undefined;
#config: OlympusConfig;
#state: OlympusState = OlympusState.NOT_INITIALIZED;
#subState: OlympusSubState = NO_SUBSTATE;
@ -135,25 +134,6 @@ export class OlympusApp {
this.#coalitionAreasManager = new CoalitionAreasManager();
this.#drawingsManager = new DrawingsManager();
/* Check if we are running the latest version */
const request = new Request("https://raw.githubusercontent.com/Pax1601/DCSOlympus/main/version.json");
fetch(request)
.then((response) => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("Error connecting to Github to retrieve latest version");
}
})
.then((res) => {
this.#latestVersion = res["version"];
const latestVersionSpan = document.getElementById("latest-version") as HTMLElement;
if (latestVersionSpan) {
latestVersionSpan.innerHTML = this.#latestVersion ?? "Unknown";
latestVersionSpan.classList.toggle("new-version", this.#latestVersion !== VERSION);
}
});
/* Load the config file from the server */
const configRequest = new Request("./resources/config", {
headers: {

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,14 @@ import {
olButtonsVisibilityGroundunitSam,
olButtonsVisibilityHelicopter,
olButtonsVisibilityNavyunit,
olIconsApc,
olIconsArtillery,
olIconsEwr,
olIconsInfantry,
olIconsRadar,
olIconsTactical,
olIconsTank,
olIconsTruck,
} from "../components/olicons";
import { OlUnitListEntry } from "../components/olunitlistentry";
import { OlSearchBar } from "../components/olsearchbar";
@ -306,9 +314,15 @@ export function SpawnContextMenu(props: {}) {
/>
);
})}
{blueprints?.length === 0 && <span className={`
{blueprints?.length === 0 && (
<span
className={`
text-gray-200
`}>No aircraft available</span>}
`}
>
No aircraft available
</span>
)}
</div>
</>
)}
@ -356,9 +370,15 @@ export function SpawnContextMenu(props: {}) {
/>
);
})}
{blueprints?.length === 0 && <span className={`
{blueprints?.length === 0 && (
<span
className={`
text-gray-200
`}>No helicopter available</span>}
`}
>
No helicopter available
</span>
)}
</div>
</>
)}
@ -409,9 +429,15 @@ export function SpawnContextMenu(props: {}) {
/>
);
})}
{blueprints?.length === 0 && <span className={`
{blueprints?.length === 0 && (
<span
className={`
text-gray-200
`}>No air defence unit available</span>}
`}
>
No air defence unit available
</span>
)}
</div>
</>
)}
@ -454,7 +480,21 @@ export function SpawnContextMenu(props: {}) {
return (
<OlUnitListEntry
key={blueprint.name}
icon={olButtonsVisibilityGroundunit}
icon={
{
Infantry: olIconsInfantry,
APC: olIconsApc,
Artillery: olIconsArtillery,
Radar: olIconsRadar,
"Radar (EWR)": olIconsEwr,
Tank: olIconsTank,
"Tactical Vehicle": olIconsTactical,
None: olButtonsVisibilityGroundunit,
Unarmed: olIconsTruck,
AAA: olButtonsVisibilityGroundunitSam,
"SAM Site Parts": olButtonsVisibilityGroundunitSam,
}[blueprint.type ?? "None"]
}
blueprint={blueprint}
onClick={() => setBlueprint(blueprint)}
showCost={showCost}
@ -462,9 +502,15 @@ export function SpawnContextMenu(props: {}) {
/>
);
})}
{blueprints?.length === 0 && <span className={`
{blueprints?.length === 0 && (
<span
className={`
text-gray-200
`}>No ground unit available</span>}
`}
>
No ground unit available
</span>
)}
</div>
</>
)}
@ -512,13 +558,19 @@ export function SpawnContextMenu(props: {}) {
/>
);
})}
{blueprints?.length === 0 && <span className={`
{blueprints?.length === 0 && (
<span
className={`
text-gray-200
`}>No navy unit available</span>}
`}
>
No navy unit available
</span>
)}
</div>
</>
)}
{openAccordion === CategoryGroup.EFFECT && commandModeOptions.commandMode === GAME_MASTER && (
{openAccordion === CategoryGroup.EFFECT && commandModeOptions.commandMode === GAME_MASTER && (
<>
<div
className={`
@ -545,10 +597,8 @@ export function SpawnContextMenu(props: {}) {
</div>
</>
)}
{openAccordion === CategoryGroup.EFFECT && commandModeOptions.commandMode !== GAME_MASTER && (
<div className="text-white">
Not available in this mode
</div>
{openAccordion === CategoryGroup.EFFECT && commandModeOptions.commandMode !== GAME_MASTER && (
<div className="text-white">Not available in this mode</div>
)}
{openAccordion === CategoryGroup.SEARCH && (
<div className="flex flex-col gap-2">

View File

@ -46,7 +46,7 @@ export function AWACSMenu(props: { open: boolean; onClose: () => void; children?
/>
<div className="flex flex-col gap-1 text-sm text-gray-500">
<p>1 Use the coalition toggle to change your coalition as AWACS.</p>
<p>2 Optionally, set a friendly unit as reference by right clicking on it and selecting "Set AWACS reference" to create tactical calls.</p>
<p>2 Optionally, set a friendly unit as reference by left clicking and holding on it and selecting "Set AWACS reference" to create tactical calls.</p>
</div>
</div>
<div className="flex gap-4">

View File

@ -1,23 +1,9 @@
import React, { useEffect, useRef, useState } from "react";
import { OlRoundStateButton, OlStateButton, OlLockStateButton } from "../components/olstatebutton";
import {
faSkull,
faCamera,
faFlag,
faVolumeHigh,
faDownload,
faUpload,
faDrawPolygon,
faCircle,
faTriangleExclamation,
faWifi,
faHourglass,
faInfo,
faObjectGroup,
} from "@fortawesome/free-solid-svg-icons";
import { faSkull, faCamera, faFlag, faVolumeHigh, faDrawPolygon, faTriangleExclamation, faWifi, faObjectGroup } from "@fortawesome/free-solid-svg-icons";
import { OlDropdownItem, OlDropdown } from "../components/oldropdown";
import { OlLabelToggle } from "../components/ollabeltoggle";
import { getApp, IP } from "../../olympusapp";
import { getApp, IP, VERSION } from "../../olympusapp";
import {
olButtonsVisibilityAirbase,
olButtonsVisibilityAircraft,
@ -39,20 +25,10 @@ import {
SessionDataChangedEvent,
SessionDataSavedEvent,
} from "../../events";
import {
BLUE_COMMANDER,
COMMAND_MODE_OPTIONS_DEFAULTS,
ImportExportSubstate,
MAP_HIDDEN_TYPES_DEFAULTS,
MAP_OPTIONS_DEFAULTS,
OlympusState,
RED_COMMANDER,
} from "../../constants/constants";
import { BLUE_COMMANDER, COMMAND_MODE_OPTIONS_DEFAULTS, MAP_HIDDEN_TYPES_DEFAULTS, MAP_OPTIONS_DEFAULTS, RED_COMMANDER } from "../../constants/constants";
import { OlympusConfig } from "../../interfaces";
import { FaCheck, FaQuestionCircle, FaSave, FaSpinner } from "react-icons/fa";
import { FaCheck, FaSpinner } from "react-icons/fa";
import { OlExpandingTooltip } from "../components/olexpandingtooltip";
import { ftToM } from "../../other/utils";
import { LatLng } from "leaflet";
export function Header() {
const [mapHiddenTypes, setMapHiddenTypes] = useState(MAP_HIDDEN_TYPES_DEFAULTS);
@ -64,12 +40,16 @@ export function Header() {
const [audioEnabled, setAudioEnabled] = useState(false);
const [commandModeOptions, setCommandModeOptions] = useState(COMMAND_MODE_OPTIONS_DEFAULTS);
const [savingSessionData, setSavingSessionData] = useState(false);
const [latestVersion, setLatestVersion] = useState("");
const [isLatestVersion, setIsLatestVersion] = useState(false);
const [isBetaVersion, setIsBetaVersion] = useState(false);
const [isDevVersion, setIsDevVersion] = useState(false);
useEffect(() => {
HiddenTypesChangedEvent.on((hiddenTypes) => setMapHiddenTypes({ ...hiddenTypes }));
MapOptionsChangedEvent.on((mapOptions) => {
setMapOptions({ ...mapOptions })
});
setMapOptions({ ...mapOptions });
});
MapSourceChangedEvent.on((source) => setMapSource(source));
ConfigLoadedEvent.on((config: OlympusConfig) => {
// Timeout needed to make sure the map configuration has updated
@ -83,6 +63,48 @@ export function Header() {
});
SessionDataChangedEvent.on(() => setSavingSessionData(true));
SessionDataSavedEvent.on(() => setSavingSessionData(false));
/* Check if we are running the latest version */
const request = new Request("https://raw.githubusercontent.com/Pax1601/DCSOlympus/main/version.json");
fetch(request)
.then((response) => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("Error connecting to Github to retrieve latest version");
}
})
.then((res) => {
setLatestVersion(res["version"]);
if (VERSION === "{{OLYMPUS_VERSION_NUMBER}}") {
console.log("OLYMPUS_VERSION_NUMBER is not set. Skipping version check.");
setIsDevVersion(true);
return;
}
/* Check if the new version is newer than the current one */
/* Extract the version numbers */
const currentVersion = VERSION.replace("v", "").split(".");
const newVersion = res["version"].replace("v", "").split(".");
setIsBetaVersion(true);
setIsLatestVersion(true);
/* Compare the version numbers */
for (var i = 0; i < currentVersion.length; i++) {
if (parseInt(newVersion[i]) > parseInt(currentVersion[i])) {
setIsLatestVersion(false);
}
}
/* Check if this is a beta version checking if this version is newer */
for (var i = 0; i < currentVersion.length; i++) {
if (parseInt(newVersion[i]) < parseInt(currentVersion[i])) {
setIsBetaVersion(false);
}
}
});
}, []);
/* Initialize the "scroll" position of the element */
@ -174,6 +196,20 @@ export function Header() {
</div>
)}
</div>
{isDevVersion ? (
<div className={`text-gray-400`}>Development build</div>
) : (
<>
<div>
{!isLatestVersion && (
<div className={`animate-pulse text-gray-400`}>
<span className={`font-bold`}>New version available:</span> {latestVersion}
</div>
)}
</div>
<div>{!isBetaVersion && <div className={`text-gray-400`}>beta version</div>}</div>
</>
)}
</div>
{commandModeOptions.commandMode === BLUE_COMMANDER && (

View File

@ -7,11 +7,17 @@ import { OlUnitListEntry } from "../components/olunitlistentry";
import { UnitSpawnMenu } from "./unitspawnmenu";
import { SpawnRequestTable, UnitBlueprint } from "../../interfaces";
import {
olButtonsVisibilityAircraft,
olButtonsVisibilityGroundunit,
olButtonsVisibilityGroundunitSam,
olButtonsVisibilityHelicopter,
olButtonsVisibilityNavyunit,
olIconsApc,
olIconsArtillery,
olIconsEwr,
olIconsInfantry,
olIconsRadar,
olIconsTactical,
olIconsTank,
olIconsTruck,
} from "../components/olicons";
import { faExplosion, faSmog } from "@fortawesome/free-solid-svg-icons";
import { OlEffectListEntry } from "../components/oleffectlistentry";
@ -99,6 +105,8 @@ export function SpawnMenu(props: { open: boolean; onClose: () => void; children?
});
}
filteredBlueprints.sort((a, b) => a.label.localeCompare(b.label));
useEffect(() => {
if (!props.open) {
if (blueprint !== null) setBlueprint(null);
@ -263,7 +271,7 @@ export function SpawnMenu(props: { open: boolean; onClose: () => void; children?
return (
<OlUnitListEntry
key={blueprint.name}
icon={olButtonsVisibilityHelicopter}
silhouette={blueprint.filename}
blueprint={blueprint}
onClick={() => setBlueprint(blueprint)}
showCost={showCost}
@ -339,9 +347,13 @@ export function SpawnMenu(props: { open: boolean; onClose: () => void; children?
/>
);
})}
{filteredBlueprints.filter((blueprint) => blueprint.canAAA).length === 0 && <span className={`
text-gray-400
`}>No AAA unit available</span>}
{filteredBlueprints.filter((blueprint) => blueprint.canAAA).length === 0 && (
<span
className={`text-gray-400`}
>
No AAA unit available
</span>
)}
</div>
</OlAccordion>
<OlAccordion
@ -389,7 +401,21 @@ export function SpawnMenu(props: { open: boolean; onClose: () => void; children?
return (
<OlUnitListEntry
key={blueprint.name}
icon={olButtonsVisibilityGroundunit}
icon={
{
Infantry: olIconsInfantry,
APC: olIconsApc,
Artillery: olIconsArtillery,
Radar: olIconsRadar,
"Radar (EWR)": olIconsEwr,
Tank: olIconsTank,
"Tactical Vehicle": olIconsTactical,
None: olButtonsVisibilityGroundunit,
Unarmed: olIconsTruck,
AAA: olButtonsVisibilityGroundunitSam,
"SAM Site Parts": olButtonsVisibilityGroundunitSam,
}[blueprint.type ?? "None"]
}
blueprint={blueprint}
onClick={() => setBlueprint(blueprint)}
showCost={showCost}